alpha.c (SYMBOL_FLAG_NEAR, [...]): New.

* config/alpha/alpha.c (SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP): New.
        (samegp_function_operand): Use SYMBOL_FLAG_SAMEGP.
        (direct_call_operand): Use SYMBOL_FLAG_NEAR.
        (local_symbolic_operand): Use SYMBOL_REF_LOCAL_P.
        (small_symbolic_operand): Use SYMBOL_REF_SMALL_P.
        (global_symbolic_operand): Similarly.
        (tls_symbolic_operand_1): Use SYMBOL_REF_TLS_MODEL.
        (tls_symbolic_operand_type): Likewise.
        (alpha_encode_section_info): Use default_encode_section_info.
        (alpha_strip_name_encoding): Remove.
        (get_tls_get_addr): Split out from ...
        (alpha_legitimize_address): ... here.
        (alpha_emit_xfloating_libcall): Use init_one_libfunc.
        (get_some_local_dynamic_name_1): Use SYMBOL_REF_TLS_MODEL.
        (alpha_initialize_trampoline): Use init_one_libfunc.
        (alpha_setup_incoming_varargs): Mark unused parameters.
        (alpha_initial_elimination_offset): Likewise.
        (alpha_end_function): Use SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP.
        (unicosmk_unique_section): Use default_strip_name_encoding.
        (unicosmk_ssib_name, unicosmk_output_externs): Likewise.

From-SVN: r65696
This commit is contained in:
Richard Henderson 2003-04-16 12:34:02 -07:00 committed by Richard Henderson
parent ffd25996cb
commit d055668e80
2 changed files with 106 additions and 207 deletions

View File

@ -1,3 +1,26 @@
2003-04-16 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.c (SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP): New.
(samegp_function_operand): Use SYMBOL_FLAG_SAMEGP.
(direct_call_operand): Use SYMBOL_FLAG_NEAR.
(local_symbolic_operand): Use SYMBOL_REF_LOCAL_P.
(small_symbolic_operand): Use SYMBOL_REF_SMALL_P.
(global_symbolic_operand): Similarly.
(tls_symbolic_operand_1): Use SYMBOL_REF_TLS_MODEL.
(tls_symbolic_operand_type): Likewise.
(alpha_encode_section_info): Use default_encode_section_info.
(alpha_strip_name_encoding): Remove.
(get_tls_get_addr): Split out from ...
(alpha_legitimize_address): ... here.
(alpha_emit_xfloating_libcall): Use init_one_libfunc.
(get_some_local_dynamic_name_1): Use SYMBOL_REF_TLS_MODEL.
(alpha_initialize_trampoline): Use init_one_libfunc.
(alpha_setup_incoming_varargs): Mark unused parameters.
(alpha_initial_elimination_offset): Likewise.
(alpha_end_function): Use SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP.
(unicosmk_unique_section): Use default_strip_name_encoding.
(unicosmk_ssib_name, unicosmk_output_externs): Likewise.
2003-04-16 Aldy Hernandez <aldyh@redhat.com>
* config.gcc: Add t-spe for eabispe.

View File

@ -171,6 +171,10 @@ static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
},
};
/* Machine-specific symbol_ref flags. */
#define SYMBOL_FLAG_NEAR (SYMBOL_FLAG_MACH_DEP << 0)
#define SYMBOL_FLAG_SAMEGP (SYMBOL_FLAG_MACH_DEP << 1)
/* Declarations of static functions. */
static bool alpha_function_ok_for_sibcall
PARAMS ((tree, tree));
@ -186,8 +190,8 @@ static bool alpha_in_small_data_p
PARAMS ((tree));
static void alpha_encode_section_info
PARAMS ((tree, int));
static const char *alpha_strip_name_encoding
PARAMS ((const char *));
static rtx get_tls_get_addr
PARAMS ((void));
static int some_small_symbolic_operand_1
PARAMS ((rtx *, void *));
static int split_small_symbolic_operand_1
@ -299,8 +303,6 @@ static void vms_asm_out_destructor PARAMS ((rtx, int));
#define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO alpha_encode_section_info
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING alpha_strip_name_encoding
#if TARGET_ABI_UNICOSMK
static void unicosmk_asm_named_section PARAMS ((const char *, unsigned int));
@ -1051,7 +1053,7 @@ samegp_function_operand (op, mode)
/* Otherwise, encode_section_info recorded whether we are to treat
this symbol as having the same GP. */
return SYMBOL_REF_FLAG (op);
return (SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_SAMEGP) != 0;
}
/* Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr. */
@ -1061,6 +1063,8 @@ direct_call_operand (op, mode)
rtx op;
enum machine_mode mode;
{
bool is_near;
/* Must share the same GP. */
if (!samegp_function_operand (op, mode))
return 0;
@ -1075,14 +1079,16 @@ direct_call_operand (op, mode)
if (!TARGET_PROFILING_NEEDS_GP && profile_flag)
return 0;
is_near = (SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_NEAR) != 0;
/* Must be "near" so that the branch is assumed to reach. With
-msmall-text, this is true of all local symbols. */
if (TARGET_SMALL_TEXT)
return op->jump;
return is_near;
/* Otherwise, a decl is "near" if it is defined in the same section.
See alpha_encode_section_info for commentary. */
return op->jump && decl_in_text_section (cfun->decl);
return is_near && decl_in_text_section (cfun->decl);
}
/* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
@ -1093,8 +1099,6 @@ 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;
@ -1109,26 +1113,7 @@ local_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
/* 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 @[LS], 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 SYMBOL_REF_LOCAL_P (op) && !SYMBOL_REF_TLS_MODEL (op);
}
/* Return true if OP is a SYMBOL_REF or CONST referencing a variable
@ -1139,8 +1124,6 @@ small_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
const char *str;
if (! TARGET_SMALL_DATA)
return 0;
@ -1155,13 +1138,14 @@ small_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
/* ??? There's no encode_section_info equivalent for the rtl
constant pool, so SYMBOL_FLAG_SMALL never gets set. */
if (CONSTANT_POOL_ADDRESS_P (op))
return GET_MODE_SIZE (get_pool_mode (op)) <= (unsigned) g_switch_value;
else
{
str = XSTR (op, 0);
return str[0] == '@' && str[1] == 'S';
}
return (SYMBOL_REF_LOCAL_P (op)
&& SYMBOL_REF_SMALL_P (op)
&& SYMBOL_REF_TLS_MODEL (op) == 0);
}
/* Return true if OP is a SYMBOL_REF or CONST referencing a variable
@ -1172,8 +1156,6 @@ 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;
@ -1185,12 +1167,7 @@ global_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
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 !SYMBOL_REF_LOCAL_P (op) && !SYMBOL_REF_TLS_MODEL (op);
}
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
@ -1251,8 +1228,6 @@ tls_symbolic_operand_1 (op, mode, size, unspec)
enum machine_mode mode;
int size, unspec;
{
const char *str;
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@ -1266,29 +1241,26 @@ tls_symbolic_operand_1 (op, mode, size, unspec)
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 (SYMBOL_REF_LOCAL_P (op))
{
if (alpha_tls_size > size)
return 0;
}
else
return 0;
switch (str[1])
{
case 'D':
if (size != 64)
return 0;
}
switch (SYMBOL_REF_TLS_MODEL (op))
{
case TLS_MODEL_LOCAL_DYNAMIC:
return unspec == UNSPEC_DTPREL;
case 'T':
case TLS_MODEL_INITIAL_EXEC:
return unspec == UNSPEC_TPREL && size == 64;
case 't':
return unspec == UNSPEC_TPREL && size < 64;
case TLS_MODEL_LOCAL_EXEC:
return unspec == UNSPEC_TPREL;
default:
abort ();
}
@ -1833,42 +1805,18 @@ static enum tls_model
tls_symbolic_operand_type (symbol)
rtx symbol;
{
const char *str;
enum tls_model model;
if (GET_CODE (symbol) != SYMBOL_REF)
return 0;
str = XSTR (symbol, 0);
model = SYMBOL_REF_TLS_MODEL (symbol);
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')
return TLS_MODEL_INITIAL_EXEC;
if (str[1] == 't')
return TLS_MODEL_LOCAL_EXEC;
}
/* Local-exec with a 64-bit size is the same code as initial-exec. */
if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
model = TLS_MODEL_INITIAL_EXEC;
return 0;
return model;
}
/* Return true if the function DECL will be placed in the default text
section. */
@ -1952,33 +1900,21 @@ alpha_in_small_data_p (exp)
static void
alpha_encode_section_info (decl, first)
tree decl;
int first ATTRIBUTE_UNUSED;
int first;
{
const char *symbol_str;
bool is_local;
char encoding = 0;
rtx rtl, symbol;
rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
/* Careful not to prod global register variables. */
if (GET_CODE (rtl) != MEM)
return;
symbol = XEXP (rtl, 0);
if (GET_CODE (symbol) != SYMBOL_REF)
return;
/* A variable is considered "local" if it is defined in this module. */
is_local = (*targetm.binds_local_p) (decl);
default_encode_section_info (decl, first);
if (TREE_CODE (decl) == FUNCTION_DECL)
{
rtx symbol = XEXP (DECL_RTL (decl), 0);
int flags = SYMBOL_REF_FLAGS (symbol);
/* Mark whether the decl is "near" in distance. If -msmall-text is
in effect, this is trivially true of all local symbols. */
if (TARGET_SMALL_TEXT)
{
if (is_local)
symbol->jump = 1;
if (flags & SYMBOL_FLAG_LOCAL)
flags |= SYMBOL_FLAG_NEAR;
}
else
{
@ -1991,90 +1927,18 @@ alpha_encode_section_info (decl, first)
Delay marking public functions until they are emitted; otherwise
we don't know that they exist in this unit of translation. */
/* Now we *DO* have access to SYMBOL_REF_DECL. Fixme. */
if (!TREE_PUBLIC (decl) && decl_in_text_section (decl))
symbol->jump = 1;
flags |= SYMBOL_FLAG_NEAR;
}
/* Indicate whether the target function shares the same GP as any
function emitted in this unit of translation. */
if (decl_has_samegp (decl))
SYMBOL_REF_FLAG (symbol) = 1;
return;
flags |= SYMBOL_FLAG_SAMEGP;
SYMBOL_REF_FLAGS (symbol) = flags;
}
/* Early out if we're not going to do anything with this data. */
if (! TARGET_EXPLICIT_RELOCS)
return;
symbol_str = XSTR (symbol, 0);
/* Care for TLS variables. */
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
{
switch (decl_tls_model (decl))
{
case TLS_MODEL_GLOBAL_DYNAMIC:
encoding = 'G';
break;
case TLS_MODEL_LOCAL_DYNAMIC:
encoding = 'D';
break;
case TLS_MODEL_INITIAL_EXEC:
encoding = 'T';
break;
case TLS_MODEL_LOCAL_EXEC:
encoding = (alpha_tls_size == 64 ? 'T' : '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 (encoding)
{
char *newstr;
size_t len;
char want_prefix = (is_local ? '@' : '%');
char other_prefix = (is_local ? '%' : '@');
if (symbol_str[0] == want_prefix)
{
if (symbol_str[1] == encoding)
return;
symbol_str += 2;
}
else if (symbol_str[0] == other_prefix)
symbol_str += 2;
len = strlen (symbol_str) + 1;
newstr = alloca (len + 2);
newstr[0] = want_prefix;
newstr[1] = encoding;
memcpy (newstr + 2, symbol_str, len);
XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
}
}
/* Undo the effects of the above. */
static const char *
alpha_strip_name_encoding (str)
const char *str;
{
if (str[0] == '@' || str[0] == '%')
str += 2;
if (str[0] == '*')
str++;
return str;
}
#if TARGET_ABI_OPEN_VMS
@ -2208,6 +2072,18 @@ alpha_legitimate_address_p (mode, x, strict)
return false;
}
/* Build the SYMBOL_REF for __tls_get_addr. */
static GTY(()) rtx tls_get_addr_libfunc;
static rtx
get_tls_get_addr ()
{
if (!tls_get_addr_libfunc)
tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
return tls_get_addr_libfunc;
}
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address. */
@ -2275,7 +2151,7 @@ alpha_legitimize_address (x, scratch, mode)
r0 = gen_rtx_REG (Pmode, 0);
r16 = gen_rtx_REG (Pmode, 16);
tga = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
tga = get_tls_get_addr ();
dest = gen_reg_rtx (Pmode);
seq = GEN_INT (alpha_next_sequence_number++);
@ -2296,7 +2172,7 @@ alpha_legitimize_address (x, scratch, mode)
r0 = gen_rtx_REG (Pmode, 0);
r16 = gen_rtx_REG (Pmode, 16);
tga = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
tga = get_tls_get_addr ();
scratch = gen_reg_rtx (Pmode);
seq = GEN_INT (alpha_next_sequence_number++);
@ -4233,7 +4109,7 @@ alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
abort ();
}
tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
tmp = gen_rtx_MEM (QImode, init_one_libfunc (func));
tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
const0_rtx, const0_rtx));
CALL_INSN_FUNCTION_USAGE (tmp) = usage;
@ -5861,14 +5737,11 @@ get_some_local_dynamic_name_1 (px, data)
{
rtx x = *px;
if (GET_CODE (x) == SYMBOL_REF)
if (GET_CODE (x) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
{
const char *str = XSTR (x, 0);
if (str[0] == '@' && str[1] == 'D')
{
cfun->machine->some_ld_name = str;
return 1;
}
cfun->machine->some_ld_name = XSTR (x, 0);
return 1;
}
return 0;
@ -6389,7 +6262,7 @@ alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
}
#ifdef TRANSFER_FROM_TRAMPOLINE
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
emit_library_call (init_one_libfunc ("__enable_execute_stack"),
0, VOIDmode, 1, tramp, Pmode);
#endif
@ -6576,8 +6449,8 @@ alpha_build_va_list ()
void
alpha_setup_incoming_varargs(cum, mode, type, pretend_size, no_rtl)
CUMULATIVE_ARGS cum;
enum machine_mode mode;
tree type;
enum machine_mode mode ATTRIBUTE_UNUSED;
tree type ATTRIBUTE_UNUSED;
int *pretend_size;
int no_rtl;
{
@ -7254,8 +7127,8 @@ alpha_sa_size ()
and the other its replacement, at the start of a routine. */
HOST_WIDE_INT
alpha_initial_elimination_offset(from, to)
unsigned int from, to;
alpha_initial_elimination_offset (from, to)
unsigned int from, to ATTRIBUTE_UNUSED;
{
HOST_WIDE_INT ret;
@ -8217,16 +8090,19 @@ alpha_end_function (file, fnname, decl)
if ((*targetm.binds_local_p) (decl))
{
rtx symbol = XEXP (DECL_RTL (decl), 0);
int flags = SYMBOL_REF_FLAGS (symbol);
/* Mark whether the decl is "near". See the commentary in
alpha_encode_section_info wrt the .text section. */
if (decl_in_text_section (decl))
symbol->jump = 1;
flags |= SYMBOL_FLAG_NEAR;
/* Mark whether the decl shares a GP with other functions
in this unit of translation. This is trivially true of
local symbols. */
SYMBOL_REF_FLAG (symbol) = 1;
flags |= SYMBOL_FLAG_SAMEGP;
SYMBOL_REF_FLAGS (symbol) = flags;
}
/* Output jump tables and the static subroutine information block. */
@ -9940,7 +9816,7 @@ unicosmk_unique_section (decl, reloc)
abort ();
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
name = alpha_strip_name_encoding (name);
name = default_strip_name_encoding (name);
len = strlen (name);
if (TREE_CODE (decl) == FUNCTION_DECL)
@ -10171,7 +10047,7 @@ unicosmk_ssib_name ()
x = XEXP (x, 0);
if (GET_CODE (x) != SYMBOL_REF)
abort ();
fnname = alpha_strip_name_encoding (XSTR (x, 0));
fnname = default_name_encoding (XSTR (x, 0));
len = strlen (fnname);
if (len + SSIB_PREFIX_LEN > 255)
@ -10347,7 +10223,7 @@ unicosmk_output_externs (file)
/* We have to strip the encoding and possibly remove user_label_prefix
from the identifier in order to handle -fleading-underscore and
explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
real_name = alpha_strip_name_encoding (p->name);
real_name = default_strip_name_encoding (p->name);
if (len && p->name[0] == '*'
&& !memcmp (real_name, user_label_prefix, len))
real_name += len;