aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2003-04-16 12:34:02 -0700
committerRichard Henderson <rth@gcc.gnu.org>2003-04-16 12:34:02 -0700
commitd055668e809b15b17f53124efd6a093c3b97ec2e (patch)
tree3954fbc5870aad5faa3af4971dc2d9c5574c14c7
parentffd25996cbbbfa8abd26b02ff4c093dbc1242241 (diff)
downloadgcc-d055668e809b15b17f53124efd6a093c3b97ec2e.zip
gcc-d055668e809b15b17f53124efd6a093c3b97ec2e.tar.gz
gcc-d055668e809b15b17f53124efd6a093c3b97ec2e.tar.bz2
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
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/config/alpha/alpha.c284
2 files changed, 103 insertions, 204 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 898b353..7812d84 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index cfc3fc5..4d5be29 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -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 (SYMBOL_REF_LOCAL_P (op))
{
- if (size != 64)
+ if (alpha_tls_size > size)
return 0;
}
- else if (str[0] == '@')
+ else
{
- if (alpha_tls_size > size)
+ if (size != 64)
return 0;
}
- else
- return 0;
- switch (str[1])
+ switch (SYMBOL_REF_TLS_MODEL (op))
{
- case 'D':
+ 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,92 +1927,20 @@ 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;
- }
-
- /* Early out if we're not going to do anything with this data. */
- if (! TARGET_EXPLICIT_RELOCS)
- return;
+ flags |= SYMBOL_FLAG_SAMEGP;
- 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);
+ SYMBOL_REF_FLAGS (symbol) = flags;
}
}
-/* 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
static bool
alpha_linkage_symbol_p (symname)
@@ -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;