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:
parent
14976818e7
commit
08e7ceb3d3
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue