From d055668e809b15b17f53124efd6a093c3b97ec2e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 16 Apr 2003 12:34:02 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 23 ++++ gcc/config/alpha/alpha.c | 290 +++++++++++---------------------------- 2 files changed, 106 insertions(+), 207 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 898b3532788..7812d844a23 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2003-04-16 Richard Henderson + + * 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 * config.gcc: Add t-spe for eabispe. diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index cfc3fc566f0..4d5be29a8d9 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 (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;