mips-protos.h (SYMBOL_GOT_LOCAL): Rename to...

gcc/
	* config/mips/mips-protos.h (SYMBOL_GOT_LOCAL): Rename to...
	(SYMBOL_GOT_PAGE_OFST): ...this.
	(SYMBOL_GOT_GLOBAL): Rename to...
	(SYMBOL_GOT_DISP): ...this.
	(SYMBOL_GOTOFF_GLOBAL): Rename to...
	(SYMBOL_GOTOFF_DISP): ...this.  Update comments accordingly.
	* config/mips/mips.c (mips_global_symbol_p): New function.
	(mips_symbol_binds_local_p): Likewise.
	(mips_classify_symbol): Rename SYMBOL_GOT_GLOBAL to SYMBOL_GOT_DISP
	and SYMBOL_GOT_LOCAL to SYMBOL_GOT_PAGE_OFST.  Use mips_global_symbol_p
	and mips_symbol_binds_local_p.
	(mips_symbolic_constant_p, mips_symbolic_address_p, mips_symbol_insns)
	(override_options): Rename SYMBOL_GOT_GLOBAL to SYMBOL_GOT_DISP,
	SYMBOL_GOT_LOCAL to SYMBOL_GOT_PAGE_OFST and SYMBOL_GOTOFF_GLOBAL to
	SYMBOL_GOTOFF_DISP.
	(mips_ok_for_lazy_binding_p): New function.
	(mips_load_call_address, mips_expand_call): Use it.
	(mips_dangerous_for_la25_p): Likewise.
	* config/mips/mips.md (*xgot_hi<mode>, *xgot_lo<mode>)
	(*got_disp<mode>): Use got_disp_operand instead of
	global_got_operand.  Use SYMBOL_GOTOFF_DISP instead of
	SYMBOL_GOTOFF_GLOBAL.
	(*got_page<mode>): Use got_page_ofst_operand instead of
	local_got_operand.
	* config/mips/predicates.md (const_call_insn_operand): Use
	SYMBOL_GOT_DISP instead of SYMBOL_GOT_GLOBAL.
	(global_got_operand): Rename to...
	(got_disp_operand): ...this and use SYMBOL_GOT_DISP instead of
	SYMBOL_GOT_GLOBAL.
	(local_got_operand): Rename to...
	(got_page_ofst_operand): ...this and use SYMBOL_GOT_PAGE_OFST instead
	of SYMBOL_GOT_LOCAL.

From-SVN: r123752
This commit is contained in:
Richard Sandiford 2007-04-12 17:26:45 +00:00 committed by Richard Sandiford
parent 14976818e7
commit 08e7ceb3d3
5 changed files with 152 additions and 97 deletions

View File

@ -1,3 +1,38 @@
2007-04-12 Richard Sandiford <richard@codesourcery.com>
* config/mips/mips-protos.h (SYMBOL_GOT_LOCAL): Rename to...
(SYMBOL_GOT_PAGE_OFST): ...this.
(SYMBOL_GOT_GLOBAL): Rename to...
(SYMBOL_GOT_DISP): ...this.
(SYMBOL_GOTOFF_GLOBAL): Rename to...
(SYMBOL_GOTOFF_DISP): ...this. Update comments accordingly.
* config/mips/mips.c (mips_global_symbol_p): New function.
(mips_symbol_binds_local_p): Likewise.
(mips_classify_symbol): Rename SYMBOL_GOT_GLOBAL to SYMBOL_GOT_DISP
and SYMBOL_GOT_LOCAL to SYMBOL_GOT_PAGE_OFST. Use mips_global_symbol_p
and mips_symbol_binds_local_p.
(mips_symbolic_constant_p, mips_symbolic_address_p, mips_symbol_insns)
(override_options): Rename SYMBOL_GOT_GLOBAL to SYMBOL_GOT_DISP,
SYMBOL_GOT_LOCAL to SYMBOL_GOT_PAGE_OFST and SYMBOL_GOTOFF_GLOBAL to
SYMBOL_GOTOFF_DISP.
(mips_ok_for_lazy_binding_p): New function.
(mips_load_call_address, mips_expand_call): Use it.
(mips_dangerous_for_la25_p): Likewise.
* config/mips/mips.md (*xgot_hi<mode>, *xgot_lo<mode>)
(*got_disp<mode>): Use got_disp_operand instead of
global_got_operand. Use SYMBOL_GOTOFF_DISP instead of
SYMBOL_GOTOFF_GLOBAL.
(*got_page<mode>): Use got_page_ofst_operand instead of
local_got_operand.
* config/mips/predicates.md (const_call_insn_operand): Use
SYMBOL_GOT_DISP instead of SYMBOL_GOT_GLOBAL.
(global_got_operand): Rename to...
(got_disp_operand): ...this and use SYMBOL_GOT_DISP instead of
SYMBOL_GOT_GLOBAL.
(local_got_operand): Rename to...
(got_page_ofst_operand): ...this and use SYMBOL_GOT_PAGE_OFST instead
of SYMBOL_GOT_LOCAL.
2007-04-12 Richard Sandiford <richard@codesourcery.com>
* config/mips/mips.h (TARGET_SPLIT_CALLS): Check

View File

@ -37,23 +37,23 @@ Boston, MA 02110-1301, USA. */
SYMBOL_CONSTANT_POOL
The symbol refers to something in the mips16 constant pool.
SYMBOL_GOT_LOCAL
The symbol refers to local data that will be found using
the global offset table.
SYMBOL_GOT_PAGE_OFST
The symbol's value will be calculated by loading an address
from the GOT and then applying a 16-bit offset.
SYMBOL_GOT_GLOBAL
Likewise non-local data.
SYMBOL_GOT_DISP
The symbol's value will be loaded directly from the GOT.
SYMBOL_GOTOFF_PAGE
An UNSPEC wrapper around a SYMBOL_GOT_LOCAL. It represents the
offset from _gp of a GOT page entry.
An UNSPEC wrapper around a SYMBOL_GOT_PAGE_OFST. It represents the
offset from _gp of the GOT entry.
SYMBOL_GOTOFF_GLOBAL
An UNSPEC wrapper around a SYMBOL_GOT_GLOBAL. It represents the
SYMBOL_GOTOFF_DISP
An UNSPEC wrapper around a SYMBOL_GOT_DISP. It represents the
the offset from _gp of the symbol's GOT entry.
SYMBOL_GOTOFF_CALL
Like SYMBOL_GOTOFF_GLOBAL, but used when calling a global function.
Like SYMBOL_GOTOFF_DISP, but used when calling a global function.
The GOT entry is allowed to point to a stub rather than to the
function itself.
@ -87,10 +87,10 @@ enum mips_symbol_type {
SYMBOL_GENERAL,
SYMBOL_SMALL_DATA,
SYMBOL_CONSTANT_POOL,
SYMBOL_GOT_LOCAL,
SYMBOL_GOT_GLOBAL,
SYMBOL_GOT_PAGE_OFST,
SYMBOL_GOT_DISP,
SYMBOL_GOTOFF_PAGE,
SYMBOL_GOTOFF_GLOBAL,
SYMBOL_GOTOFF_DISP,
SYMBOL_GOTOFF_CALL,
SYMBOL_GOTOFF_LOADGP,
SYMBOL_TLS,

View File

@ -1212,19 +1212,45 @@ static struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] =
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return true if SYMBOL_REF X is associated with a global symbol
(in the STB_GLOBAL sense). */
static bool
mips_global_symbol_p (rtx x)
{
tree decl;
decl = SYMBOL_REF_DECL (x);
if (!decl)
return !SYMBOL_REF_LOCAL_P (x);
/* Weakref symbols are not TREE_PUBLIC, but their targets are global
or weak symbols. Relocations in the object file will be against
the target symbol, so it's that symbol's binding that matters here. */
return DECL_P (decl) && (TREE_PUBLIC (decl) || DECL_WEAK (decl));
}
/* Return true if SYMBOL_REF X binds locally. */
static bool
mips_symbol_binds_local_p (rtx x)
{
return (SYMBOL_REF_DECL (x)
? targetm.binds_local_p (SYMBOL_REF_DECL (x))
: SYMBOL_REF_LOCAL_P (x));
}
/* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF. */
static enum mips_symbol_type
mips_classify_symbol (rtx x)
{
tree decl;
if (GET_CODE (x) == LABEL_REF)
{
if (TARGET_MIPS16)
return SYMBOL_CONSTANT_POOL;
if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
return SYMBOL_GOT_LOCAL;
return SYMBOL_GOT_PAGE_OFST;
return SYMBOL_GENERAL;
}
@ -1250,49 +1276,34 @@ mips_classify_symbol (rtx x)
if (TARGET_ABICALLS)
{
decl = SYMBOL_REF_DECL (x);
if (decl == 0)
{
if (!SYMBOL_REF_LOCAL_P (x))
return SYMBOL_GOT_GLOBAL;
}
else
{
/* Don't use GOT accesses for locally-binding symbols if
TARGET_ABSOLUTE_ABICALLS. Otherwise, there are three
cases to consider:
/* Don't use GOT accesses for locally-binding symbols; we can use
%hi and %lo instead. */
if (TARGET_ABSOLUTE_ABICALLS && mips_symbol_binds_local_p (x))
return SYMBOL_GENERAL;
- o32 PIC (either with or without explicit relocs)
- n32/n64 PIC without explicit relocs
- n32/n64 PIC with explicit relocs
/* There are three cases to consider:
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.
- o32 PIC (either with or without explicit relocs)
- n32/n64 PIC without explicit relocs
- n32/n64 PIC with explicit relocs
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 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 depends on the symbol's binding rather
than its visibility.
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.
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.
Note that weakref symbols are not TREE_PUBLIC, but their
targets are global or weak symbols. Relocations in the
object file will be against the target symbol, so it's
that symbol's binding that matters here. */
if (DECL_P (decl)
&& (TREE_PUBLIC (decl) || DECL_WEAK (decl))
&& !(TARGET_ABSOLUTE_ABICALLS && targetm.binds_local_p (decl)))
return SYMBOL_GOT_GLOBAL;
}
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 (mips_global_symbol_p (x))
return SYMBOL_GOT_DISP;
if (!TARGET_ABSOLUTE_ABICALLS)
return SYMBOL_GOT_LOCAL;
return SYMBOL_GOT_PAGE_OFST;
}
return SYMBOL_GENERAL;
@ -1355,14 +1366,17 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
PC- or GP-relative offset is within the 16-bit limit. */
return offset_within_block_p (x, INTVAL (offset));
case SYMBOL_GOT_LOCAL:
case SYMBOL_GOT_PAGE_OFST:
case SYMBOL_GOTOFF_PAGE:
/* The linker should provide enough local GOT entries for a
16-bit offset. Larger offsets may lead to GOT overflow. */
/* If the symbol is global, the GOT entry will contain the symbol's
address, and we will apply a 16-bit offset after loading it.
If the symbol is local, the linker should provide enough local
GOT entries for a 16-bit offset, but larger offsets may lead
to GOT overflow. */
return SMALL_INT (offset);
case SYMBOL_GOT_GLOBAL:
case SYMBOL_GOTOFF_GLOBAL:
case SYMBOL_GOT_DISP:
case SYMBOL_GOTOFF_DISP:
case SYMBOL_GOTOFF_CALL:
case SYMBOL_GOTOFF_LOADGP:
case SYMBOL_TLSGD:
@ -1450,15 +1464,15 @@ mips_symbolic_address_p (enum mips_symbol_type symbol_type,
/* PC-relative addressing is only available for lw and ld. */
return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
case SYMBOL_GOT_LOCAL:
case SYMBOL_GOT_PAGE_OFST:
return true;
case SYMBOL_GOT_GLOBAL:
case SYMBOL_GOT_DISP:
/* The address will have to be loaded from the GOT first. */
return false;
case SYMBOL_GOTOFF_PAGE:
case SYMBOL_GOTOFF_GLOBAL:
case SYMBOL_GOTOFF_DISP:
case SYMBOL_GOTOFF_CALL:
case SYMBOL_GOTOFF_LOADGP:
case SYMBOL_TLS:
@ -1623,8 +1637,8 @@ mips_symbol_insns (enum mips_symbol_type type)
extended instruction. */
return 2;
case SYMBOL_GOT_LOCAL:
case SYMBOL_GOT_GLOBAL:
case SYMBOL_GOT_PAGE_OFST:
case SYMBOL_GOT_DISP:
/* Unless -funit-at-a-time is in effect, we can't be sure whether
the local/global classification is accurate. See override_options
for details.
@ -1648,7 +1662,7 @@ mips_symbol_insns (enum mips_symbol_type type)
return 3;
case SYMBOL_GOTOFF_PAGE:
case SYMBOL_GOTOFF_GLOBAL:
case SYMBOL_GOTOFF_DISP:
case SYMBOL_GOTOFF_CALL:
case SYMBOL_GOTOFF_LOADGP:
case SYMBOL_64_HIGH:
@ -3346,6 +3360,18 @@ mips_gen_conditional_trap (rtx *operands)
operands[1]));
}
/* Return true if calls to X can use R_MIPS_CALL* relocations. */
static bool
mips_ok_for_lazy_binding_p (rtx x)
{
return (TARGET_USE_GOT
&& GET_CODE (x) == SYMBOL_REF
&& (TARGET_ABSOLUTE_ABICALLS
? !mips_symbol_binds_local_p (x)
: mips_global_symbol_p (x)));
}
/* Load function address ADDR into register DEST. SIBCALL_P is true
if the address is needed for a sibling call. */
@ -3358,7 +3384,7 @@ mips_load_call_address (rtx dest, rtx addr, int sibcall_p)
to the stub would be our caller's gp, not ours. */
if (TARGET_EXPLICIT_RELOCS
&& !(sibcall_p && TARGET_CALL_SAVED_GP)
&& global_got_operand (addr, VOIDmode))
&& mips_ok_for_lazy_binding_p (addr))
{
rtx high, lo_sum_symbol;
@ -3423,7 +3449,7 @@ mips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
insn = emit_call_insn (pattern);
/* Lazy-binding stubs require $gp to be valid on entry. */
if (global_got_operand (orig_addr, VOIDmode))
if (mips_ok_for_lazy_binding_p (orig_addr))
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
}
@ -5115,26 +5141,26 @@ override_options (void)
then lowered by mips_rewrite_small_data. */
mips_lo_relocs[SYMBOL_SMALL_DATA] = "%gp_rel(";
mips_split_p[SYMBOL_GOT_LOCAL] = true;
mips_split_p[SYMBOL_GOT_PAGE_OFST] = true;
if (TARGET_NEWABI)
{
mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got_page(";
mips_lo_relocs[SYMBOL_GOT_LOCAL] = "%got_ofst(";
mips_lo_relocs[SYMBOL_GOT_PAGE_OFST] = "%got_ofst(";
}
else
{
mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got(";
mips_lo_relocs[SYMBOL_GOT_LOCAL] = "%lo(";
mips_lo_relocs[SYMBOL_GOT_PAGE_OFST] = "%lo(";
}
if (TARGET_XGOT)
{
/* The HIGH and LO_SUM are matched by special .md patterns. */
mips_split_p[SYMBOL_GOT_GLOBAL] = true;
mips_split_p[SYMBOL_GOT_DISP] = true;
mips_split_p[SYMBOL_GOTOFF_GLOBAL] = true;
mips_hi_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_hi(";
mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_lo(";
mips_split_p[SYMBOL_GOTOFF_DISP] = true;
mips_hi_relocs[SYMBOL_GOTOFF_DISP] = "%got_hi(";
mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got_lo(";
mips_split_p[SYMBOL_GOTOFF_CALL] = true;
mips_hi_relocs[SYMBOL_GOTOFF_CALL] = "%call_hi(";
@ -5143,9 +5169,9 @@ override_options (void)
else
{
if (TARGET_NEWABI)
mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_disp(";
mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got_disp(";
else
mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got(";
mips_lo_relocs[SYMBOL_GOTOFF_DISP] = "%got(";
mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call16(";
}
}
@ -7604,13 +7630,7 @@ mips_cannot_change_mode_class (enum machine_mode from,
bool
mips_dangerous_for_la25_p (rtx x)
{
rtx offset;
if (TARGET_EXPLICIT_RELOCS)
return false;
split_const (x, &x, &offset);
return global_got_operand (x, VOIDmode);
return !TARGET_EXPLICIT_RELOCS && mips_ok_for_lazy_binding_p (x);
}
/* Implement PREFERRED_RELOAD_CLASS. */

View File

@ -3156,18 +3156,18 @@
}
[(set_attr "length" "24")])
;; Insns to fetch a global symbol from a big GOT.
;; Insns to fetch a symbol from a big GOT.
(define_insn_and_split "*xgot_hi<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
(high:P (match_operand:P 1 "global_got_operand" "")))]
(high:P (match_operand:P 1 "got_disp_operand" "")))]
"TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
"#"
"&& reload_completed"
[(set (match_dup 0) (high:P (match_dup 2)))
(set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
{
operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
operands[3] = pic_offset_table_rtx;
}
[(set_attr "got" "xgot_high")
@ -3176,21 +3176,21 @@
(define_insn_and_split "*xgot_lo<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
(lo_sum:P (match_operand:P 1 "register_operand" "d")
(match_operand:P 2 "global_got_operand" "")))]
(match_operand:P 2 "got_disp_operand" "")))]
"TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
"#"
"&& reload_completed"
[(set (match_dup 0)
(unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
{ operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
{ operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); }
[(set_attr "got" "load")
(set_attr "mode" "<MODE>")])
;; Insns to fetch a global symbol from a normal GOT.
;; Insns to fetch a symbol from a normal GOT.
(define_insn_and_split "*got_disp<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
(match_operand:P 1 "global_got_operand" ""))]
(match_operand:P 1 "got_disp_operand" ""))]
"TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
"#"
"&& reload_completed"
@ -3198,16 +3198,16 @@
(unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
{
operands[2] = pic_offset_table_rtx;
operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
}
[(set_attr "got" "load")
(set_attr "mode" "<MODE>")])
;; Insns for loading the high part of a local symbol.
;; Insns for loading the "page" part of a page/ofst address from the GOT.
(define_insn_and_split "*got_page<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
(high:P (match_operand:P 1 "local_got_operand" "")))]
(high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
"TARGET_EXPLICIT_RELOCS"
"#"
"&& reload_completed"

View File

@ -118,7 +118,7 @@
addressing. */
return !TARGET_LONG_CALLS && !SYMBOL_REF_LONG_CALL_P (op);
case SYMBOL_GOT_GLOBAL:
case SYMBOL_GOT_DISP:
/* Without explicit relocs, there is no special syntax for
loading the address of a call destination into a register.
Using "la $25,foo; jal $25" would prevent the lazy binding
@ -237,18 +237,18 @@
return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GENERAL;
})
(define_predicate "global_got_operand"
(define_predicate "got_disp_operand"
(match_code "const,symbol_ref,label_ref")
{
enum mips_symbol_type type;
return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_GLOBAL;
return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_DISP;
})
(define_predicate "local_got_operand"
(define_predicate "got_page_ofst_operand"
(match_code "const,symbol_ref,label_ref")
{
enum mips_symbol_type type;
return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_LOCAL;
return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_PAGE_OFST;
})
(define_predicate "stack_operand"