re PR c++/12945 (MIPS g++.old-deja/g++.abi/ptrflags.C fails.)
PR target/12945 * coverage.c (coverage_counter_alloc): Set SYMBOL_FLAG_LOCAL for for counter labels. * config/mips/mips.c (INTERNAL_SYMBOL_P): Delete. (mips_classify_symbol): Always treat SYMBOL_REF_FLAG as indicating string constants if TARGET_MIPS16. Use SYMBOL_REF_DECL to check the binding of decl symbols, otherwise check SYMBOL_REF_LOCAL_P. (mips_symbol_insns): Don't trust the local/global classification. (m16_usym8_4, m16_usym5_4): Same mips16 change as mips_classify_symbol. (override_options): Make -mabicalls -fno-unit-at-a-time imply -mno-explicit-relocs. (mips_encode_section_info): Don't use SYMBOL_REF_FLAG to distinguish between local and global symbols. From-SVN: r75422
This commit is contained in:
parent
816bc01fa3
commit
f614987783
@ -1,3 +1,19 @@
|
|||||||
|
2004-01-05 Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
|
PR target/12945
|
||||||
|
* coverage.c (coverage_counter_alloc): Set SYMBOL_FLAG_LOCAL for
|
||||||
|
for counter labels.
|
||||||
|
* config/mips/mips.c (INTERNAL_SYMBOL_P): Delete.
|
||||||
|
(mips_classify_symbol): Always treat SYMBOL_REF_FLAG as indicating
|
||||||
|
string constants if TARGET_MIPS16. Use SYMBOL_REF_DECL to check
|
||||||
|
the binding of decl symbols, otherwise check SYMBOL_REF_LOCAL_P.
|
||||||
|
(mips_symbol_insns): Don't trust the local/global classification.
|
||||||
|
(m16_usym8_4, m16_usym5_4): Same mips16 change as mips_classify_symbol.
|
||||||
|
(override_options): Make -mabicalls -fno-unit-at-a-time imply
|
||||||
|
-mno-explicit-relocs.
|
||||||
|
(mips_encode_section_info): Don't use SYMBOL_REF_FLAG to distinguish
|
||||||
|
between local and global symbols.
|
||||||
|
|
||||||
2004-01-05 Richard Sandiford <rsandifo@redhat.com>
|
2004-01-05 Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
* config/mips/mips-protos.h (mips_dangerous_for_la25_p): Declare.
|
* config/mips/mips-protos.h (mips_dangerous_for_la25_p): Declare.
|
||||||
|
@ -77,10 +77,6 @@ enum internal_test {
|
|||||||
#define SINGLE_WORD_MODE_P(MODE) \
|
#define SINGLE_WORD_MODE_P(MODE) \
|
||||||
((MODE) != BLKmode && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
|
((MODE) != BLKmode && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
|
||||||
|
|
||||||
/* True if the given SYMBOL_REF is for an internally-generated symbol. */
|
|
||||||
#define INTERNAL_SYMBOL_P(SYM) \
|
|
||||||
(XSTR (SYM, 0)[0] == '*' && XSTR (SYM, 0)[1] == LOCAL_LABEL_PREFIX[0])
|
|
||||||
|
|
||||||
/* True if X is an unspec wrapper around a SYMBOL_REF or LABEL_REF. */
|
/* True if X is an unspec wrapper around a SYMBOL_REF or LABEL_REF. */
|
||||||
#define UNSPEC_ADDRESS_P(X) \
|
#define UNSPEC_ADDRESS_P(X) \
|
||||||
(GET_CODE (X) == UNSPEC \
|
(GET_CODE (X) == UNSPEC \
|
||||||
@ -823,23 +819,44 @@ mips_classify_symbol (rtx x)
|
|||||||
return SYMBOL_GENERAL;
|
return SYMBOL_GENERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INTERNAL_SYMBOL_P (x))
|
|
||||||
{
|
|
||||||
/* The symbol is a local label. For TARGET_MIPS16, SYMBOL_REF_FLAG
|
|
||||||
will be set if the symbol refers to a string in the current
|
|
||||||
function's constant pool. */
|
|
||||||
if (TARGET_MIPS16 && SYMBOL_REF_FLAG (x))
|
|
||||||
return SYMBOL_CONSTANT_POOL;
|
|
||||||
|
|
||||||
if (TARGET_ABICALLS)
|
|
||||||
return SYMBOL_GOT_LOCAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SYMBOL_REF_SMALL_P (x))
|
if (SYMBOL_REF_SMALL_P (x))
|
||||||
return SYMBOL_SMALL_DATA;
|
return SYMBOL_SMALL_DATA;
|
||||||
|
|
||||||
|
/* When generating mips16 code, SYMBOL_REF_FLAG indicates a string
|
||||||
|
in the current function's constant pool. */
|
||||||
|
if (TARGET_MIPS16 && SYMBOL_REF_FLAG (x))
|
||||||
|
return SYMBOL_CONSTANT_POOL;
|
||||||
|
|
||||||
if (TARGET_ABICALLS)
|
if (TARGET_ABICALLS)
|
||||||
return (SYMBOL_REF_FLAG (x) ? SYMBOL_GOT_LOCAL : SYMBOL_GOT_GLOBAL);
|
{
|
||||||
|
if (SYMBOL_REF_DECL (x) == 0)
|
||||||
|
return SYMBOL_REF_LOCAL_P (x) ? SYMBOL_GOT_LOCAL : SYMBOL_GOT_GLOBAL;
|
||||||
|
|
||||||
|
/* There are three cases to consider:
|
||||||
|
|
||||||
|
- o32 PIC (either with or without explicit relocs)
|
||||||
|
- n32/n64 PIC without explicit relocs
|
||||||
|
- n32/n64 PIC with explicit relocs
|
||||||
|
|
||||||
|
In the first case, both local and global accesses will use an
|
||||||
|
R_MIPS_GOT16 relocation. We must correctly predict which of
|
||||||
|
the two semantics (local or global) the assembler and linker
|
||||||
|
will apply. The choice doesn't depend on the symbol's
|
||||||
|
visibility, so we deliberately ignore decl_visibility and
|
||||||
|
binds_local_p here.
|
||||||
|
|
||||||
|
In the second case, the assembler will not use R_MIPS_GOT16
|
||||||
|
relocations, but it chooses between local and global accesses
|
||||||
|
in the same way as for o32 PIC.
|
||||||
|
|
||||||
|
In the third case we have more freedom since both forms of
|
||||||
|
access will work for any kind of symbol. However, there seems
|
||||||
|
little point in doing things differently. */
|
||||||
|
if (DECL_P (SYMBOL_REF_DECL (x)) && TREE_PUBLIC (SYMBOL_REF_DECL (x)))
|
||||||
|
return SYMBOL_GOT_GLOBAL;
|
||||||
|
|
||||||
|
return SYMBOL_GOT_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
return SYMBOL_GENERAL;
|
return SYMBOL_GENERAL;
|
||||||
}
|
}
|
||||||
@ -1073,27 +1090,28 @@ mips_symbol_insns (enum mips_symbol_type type)
|
|||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case SYMBOL_GOT_LOCAL:
|
case SYMBOL_GOT_LOCAL:
|
||||||
/* For o32 and o64, the sequence is:
|
|
||||||
|
|
||||||
lw $at,%got(symbol)
|
|
||||||
nop
|
|
||||||
|
|
||||||
and the final address is $at + %lo(symbol). A load/add
|
|
||||||
sequence is also needed for n32 and n64. Some versions
|
|
||||||
of GAS insert a nop in the n32/n64 sequences too so, for
|
|
||||||
simplicity, use the worst case of 3 instructions. */
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
case SYMBOL_GOT_GLOBAL:
|
case SYMBOL_GOT_GLOBAL:
|
||||||
/* When using a small GOT, we just fetch the address using
|
/* Unless -funit-at-a-time is in effect, we can't be sure whether
|
||||||
a gp-relative load. For a big GOT, we need a sequence
|
the local/global classification is accurate. See override_options
|
||||||
such as:
|
for details.
|
||||||
|
|
||||||
lui $at,%got_hi(symbol)
|
The worst cases are:
|
||||||
daddu $at,$at,$gp
|
|
||||||
|
|
||||||
and the final address is $at + %got_lo(symbol). */
|
(1) For local symbols when generating o32 or o64 code. The assembler
|
||||||
return (TARGET_XGOT ? 3 : 1);
|
will use:
|
||||||
|
|
||||||
|
lw $at,%got(symbol)
|
||||||
|
nop
|
||||||
|
|
||||||
|
...and the final address will be $at + %lo(symbol).
|
||||||
|
|
||||||
|
(2) For global symbols when -mxgot. The assembler will use:
|
||||||
|
|
||||||
|
lui $at,%got_hi(symbol)
|
||||||
|
(d)addu $at,$at,$gp
|
||||||
|
|
||||||
|
...and the final address will be $at + %got_lo(symbol). */
|
||||||
|
return 3;
|
||||||
|
|
||||||
case SYMBOL_GOTOFF_PAGE:
|
case SYMBOL_GOTOFF_PAGE:
|
||||||
case SYMBOL_GOTOFF_GLOBAL:
|
case SYMBOL_GOTOFF_GLOBAL:
|
||||||
@ -2078,7 +2096,6 @@ m16_usym8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
|||||||
if (GET_CODE (op) == SYMBOL_REF
|
if (GET_CODE (op) == SYMBOL_REF
|
||||||
&& SYMBOL_REF_FLAG (op)
|
&& SYMBOL_REF_FLAG (op)
|
||||||
&& cfun->machine->insns_len > 0
|
&& cfun->machine->insns_len > 0
|
||||||
&& INTERNAL_SYMBOL_P (op)
|
|
||||||
&& (cfun->machine->insns_len + get_pool_size () + mips_string_length
|
&& (cfun->machine->insns_len + get_pool_size () + mips_string_length
|
||||||
< 4 * 0x100))
|
< 4 * 0x100))
|
||||||
{
|
{
|
||||||
@ -2101,7 +2118,6 @@ m16_usym5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
|||||||
if (GET_CODE (op) == SYMBOL_REF
|
if (GET_CODE (op) == SYMBOL_REF
|
||||||
&& SYMBOL_REF_FLAG (op)
|
&& SYMBOL_REF_FLAG (op)
|
||||||
&& cfun->machine->insns_len > 0
|
&& cfun->machine->insns_len > 0
|
||||||
&& INTERNAL_SYMBOL_P (op)
|
|
||||||
&& (cfun->machine->insns_len + get_pool_size () + mips_string_length
|
&& (cfun->machine->insns_len + get_pool_size () + mips_string_length
|
||||||
< 4 * 0x20))
|
< 4 * 0x20))
|
||||||
{
|
{
|
||||||
@ -4785,6 +4801,28 @@ override_options (void)
|
|||||||
&& (target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0)
|
&& (target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0)
|
||||||
target_flags &= ~MASK_EXPLICIT_RELOCS;
|
target_flags &= ~MASK_EXPLICIT_RELOCS;
|
||||||
|
|
||||||
|
/* Make -mabicalls -fno-unit-at-a-time imply -mno-explicit-relocs
|
||||||
|
unless the user says otherwise.
|
||||||
|
|
||||||
|
There are two problems here:
|
||||||
|
|
||||||
|
(1) The value of an R_MIPS_GOT16 relocation depends on whether
|
||||||
|
the symbol is local or global. We therefore need to know
|
||||||
|
a symbol's binding before refering to it using %got().
|
||||||
|
|
||||||
|
(2) R_MIPS_CALL16 can only be applied to global symbols.
|
||||||
|
|
||||||
|
When not using -funit-at-a-time, a symbol's binding may change
|
||||||
|
after it has been used. For example, the C++ front-end will
|
||||||
|
initially assume that the typeinfo for an incomplete type will be
|
||||||
|
comdat, on the basis that the type could be completed later in the
|
||||||
|
file. But if the type never is completed, the typeinfo will become
|
||||||
|
local instead. */
|
||||||
|
if (!flag_unit_at_a_time
|
||||||
|
&& TARGET_ABICALLS
|
||||||
|
&& (target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0)
|
||||||
|
target_flags &= ~MASK_EXPLICIT_RELOCS;
|
||||||
|
|
||||||
/* -mrnames says to use the MIPS software convention for register
|
/* -mrnames says to use the MIPS software convention for register
|
||||||
names instead of the hardware names (ie, $a0 instead of $4).
|
names instead of the hardware names (ie, $a0 instead of $4).
|
||||||
We do this by switching the names in mips_reg_names, which the
|
We do this by switching the names in mips_reg_names, which the
|
||||||
@ -7052,10 +7090,7 @@ mips_in_small_data_p (tree decl)
|
|||||||
constants which are put in the .text section. We also record the
|
constants which are put in the .text section. We also record the
|
||||||
total length of all such strings; this total is used to decide
|
total length of all such strings; this total is used to decide
|
||||||
whether we need to split the constant table, and need not be
|
whether we need to split the constant table, and need not be
|
||||||
precisely correct.
|
precisely correct. */
|
||||||
|
|
||||||
When generating -mabicalls code, SYMBOL_REF_FLAG is set if we
|
|
||||||
should treat the symbol as SYMBOL_GOT_LOCAL. */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_encode_section_info (tree decl, rtx rtl, int first)
|
mips_encode_section_info (tree decl, rtx rtl, int first)
|
||||||
@ -7107,35 +7142,6 @@ mips_encode_section_info (tree decl, rtx rtl, int first)
|
|||||||
SYMBOL_REF_FLAG (symbol) = 1;
|
SYMBOL_REF_FLAG (symbol) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (TARGET_ABICALLS)
|
|
||||||
{
|
|
||||||
/* Mark the symbol if we should treat it as SYMBOL_GOT_LOCAL.
|
|
||||||
There are three cases to consider:
|
|
||||||
|
|
||||||
- o32 PIC (either with or without explicit relocs)
|
|
||||||
- n32/n64 PIC without explicit relocs
|
|
||||||
- n32/n64 PIC with explicit relocs
|
|
||||||
|
|
||||||
In the first case, both local and global accesses will use an
|
|
||||||
R_MIPS_GOT16 relocation. We must correctly predict which of
|
|
||||||
the two semantics (local or global) the assembler and linker
|
|
||||||
will apply. The choice doesn't depend on the symbol's
|
|
||||||
visibility, so we deliberately ignore decl_visibility and
|
|
||||||
binds_local_p here.
|
|
||||||
|
|
||||||
In the second case, the assembler will not use R_MIPS_GOT16
|
|
||||||
relocations, but it chooses between local and global accesses
|
|
||||||
in the same way as for o32 PIC.
|
|
||||||
|
|
||||||
In the third case we have more freedom since both forms of
|
|
||||||
access will work for any kind of symbol. However, there seems
|
|
||||||
little point in doing things differently. */
|
|
||||||
if (DECL_P (decl) && TREE_PUBLIC (decl))
|
|
||||||
SYMBOL_REF_FLAG (symbol) = 0;
|
|
||||||
else
|
|
||||||
SYMBOL_REF_FLAG (symbol) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
default_encode_section_info (decl, rtl, first);
|
default_encode_section_info (decl, rtl, first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,6 +374,7 @@ coverage_counter_alloc (unsigned counter, unsigned num)
|
|||||||
|
|
||||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
|
ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
|
||||||
ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
|
ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
|
||||||
|
SYMBOL_REF_FLAGS (ctr_labels[counter]) = SYMBOL_FLAG_LOCAL;
|
||||||
}
|
}
|
||||||
fn_b_ctrs[counter] = fn_n_ctrs[counter];
|
fn_b_ctrs[counter] = fn_n_ctrs[counter];
|
||||||
fn_n_ctrs[counter] += num;
|
fn_n_ctrs[counter] += num;
|
||||||
|
Loading…
Reference in New Issue
Block a user