re PR rtl-optimization/13145 (bootstrap failure on mips-linux)
PR bootstrap/13145 * config/mips/mips.h (FIRST_PSEUDO_REGISTER): Adjust comment. * config/mips/mips.c (mips_reg_names, mips_sw_reg_names): Add $fcall. (mips_load_got): Always create a constant MEM. (mips_expand_call): Use load_callsi and load_calldi. * config/mips/mips.md (UNSPEC_LOAD_CALL, FAKE_CALL_REGNO): New consts. (load_callsi, load_calldi): New patterns. From-SVN: r74323
This commit is contained in:
parent
b00b4b8855
commit
f24e76ebc6
|
@ -1,3 +1,13 @@
|
|||
2003-12-05 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
PR bootstrap/13145
|
||||
* config/mips/mips.h (FIRST_PSEUDO_REGISTER): Adjust comment.
|
||||
* config/mips/mips.c (mips_reg_names, mips_sw_reg_names): Add $fcall.
|
||||
(mips_load_got): Always create a constant MEM.
|
||||
(mips_expand_call): Use load_callsi and load_calldi.
|
||||
* config/mips/mips.md (UNSPEC_LOAD_CALL, FAKE_CALL_REGNO): New consts.
|
||||
(load_callsi, load_calldi): New patterns.
|
||||
|
||||
2003-12-05 Peter Gerwinski <peter@gerwinski.de>
|
||||
|
||||
* tree.def (PLACEHOLDER_EXPR): Clarify commentary.
|
||||
|
|
|
@ -569,7 +569,7 @@ char mips_reg_names[][8] =
|
|||
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
|
||||
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
|
||||
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
|
||||
"$fcc5","$fcc6","$fcc7","", "", "", "", "",
|
||||
"$fcc5","$fcc6","$fcc7","", "", "", "", "$fakec",
|
||||
"$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7",
|
||||
"$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15",
|
||||
"$c0r16","$c0r17","$c0r18","$c0r19","$c0r20","$c0r21","$c0r22","$c0r23",
|
||||
|
@ -598,7 +598,7 @@ char mips_sw_reg_names[][8] =
|
|||
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
|
||||
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
|
||||
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
|
||||
"$fcc5","$fcc6","$fcc7","$rap", "", "", "", "",
|
||||
"$fcc5","$fcc6","$fcc7","$rap", "", "", "", "$fakec",
|
||||
"$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7",
|
||||
"$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15",
|
||||
"$c0r16","$c0r17","$c0r18","$c0r19","$c0r20","$c0r21","$c0r22","$c0r23",
|
||||
|
@ -1658,14 +1658,10 @@ mips_load_got (rtx base, rtx addr, enum mips_symbol_type symbol_type)
|
|||
mem = gen_rtx_MEM (ptr_mode, gen_rtx_LO_SUM (Pmode, base, offset));
|
||||
set_mem_alias_set (mem, mips_got_alias_set);
|
||||
|
||||
/* GOT references can't trap. */
|
||||
/* GOT entries are constant and references to them can't trap. */
|
||||
RTX_UNCHANGING_P (mem) = 1;
|
||||
MEM_NOTRAP_P (mem) = 1;
|
||||
|
||||
/* If we allow a function's address to be lazily bound, its entry
|
||||
may change after the first call. Other entries are constant. */
|
||||
if (symbol_type != SYMBOL_GOTOFF_CALL)
|
||||
RTX_UNCHANGING_P (mem) = 1;
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
@ -3193,11 +3189,19 @@ mips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
|
|||
{
|
||||
if (TARGET_EXPLICIT_RELOCS && global_got_operand (addr, VOIDmode))
|
||||
{
|
||||
rtx high = mips_unspec_offset_high (pic_offset_table_rtx,
|
||||
addr, SYMBOL_GOTOFF_CALL);
|
||||
addr = mips_load_got (high, addr, SYMBOL_GOTOFF_CALL);
|
||||
rtx high, lo_sum_symbol;
|
||||
|
||||
high = mips_unspec_offset_high (pic_offset_table_rtx,
|
||||
addr, SYMBOL_GOTOFF_CALL);
|
||||
lo_sum_symbol = mips_unspec_address (addr, SYMBOL_GOTOFF_CALL);
|
||||
addr = gen_reg_rtx (Pmode);
|
||||
if (Pmode == SImode)
|
||||
emit_insn (gen_load_callsi (addr, high, lo_sum_symbol));
|
||||
else
|
||||
emit_insn (gen_load_calldi (addr, high, lo_sum_symbol));
|
||||
}
|
||||
addr = force_reg (Pmode, addr);
|
||||
else
|
||||
addr = force_reg (Pmode, addr);
|
||||
}
|
||||
|
||||
if (TARGET_MIPS16
|
||||
|
|
|
@ -1468,7 +1468,8 @@ extern const struct mips_cpu_info *mips_tune_info;
|
|||
- 8 condition code registers
|
||||
- 2 accumulator registers (hi and lo)
|
||||
- 32 registers each for coprocessors 0, 2 and 3
|
||||
- 6 dummy entries that were used at various times in the past. */
|
||||
- FAKE_CALL_REGNO (see the comment above load_callsi for details)
|
||||
- 5 dummy entries that were used at various times in the past. */
|
||||
|
||||
#define FIRST_PSEUDO_REGISTER 176
|
||||
|
||||
|
|
|
@ -54,8 +54,11 @@
|
|||
(UNSPEC_SDL 24)
|
||||
(UNSPEC_SDR 25)
|
||||
(UNSPEC_LOADGP 26)
|
||||
(UNSPEC_LOAD_CALL 27)
|
||||
|
||||
(UNSPEC_ADDRESS_FIRST 100)])
|
||||
(UNSPEC_ADDRESS_FIRST 100)
|
||||
|
||||
(FAKE_CALL_REGNO 79)])
|
||||
|
||||
;; ....................
|
||||
;;
|
||||
|
@ -8331,6 +8334,42 @@ ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/"
|
|||
;;
|
||||
;; ....................
|
||||
|
||||
;; Instructions to load a call address from the GOT. The address might
|
||||
;; point to a function or to a lazy binding stub. In the latter case,
|
||||
;; the stub will use the dynamic linker to resolve the function, which
|
||||
;; in turn will change the GOT entry to point to the function's real
|
||||
;; address.
|
||||
;;
|
||||
;; This means that every call, even pure and constant ones, can
|
||||
;; potentially modify the GOT entry. And once a stub has been called,
|
||||
;; we must not call it again.
|
||||
;;
|
||||
;; We represent this restriction using an imaginary fixed register that
|
||||
;; acts like a GOT version number. By making the register call-clobbered,
|
||||
;; we tell the target-independent code that the address could be changed
|
||||
;; by any call insn.
|
||||
(define_insn "load_callsi"
|
||||
[(set (match_operand:SI 0 "register_operand" "=c")
|
||||
(unspec:SI [(match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "immediate_operand" "")
|
||||
(reg:SI FAKE_CALL_REGNO)]
|
||||
UNSPEC_LOAD_CALL))]
|
||||
"TARGET_ABICALLS"
|
||||
"lw\t%0,%R2(%1)"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn "load_calldi"
|
||||
[(set (match_operand:DI 0 "register_operand" "=c")
|
||||
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
||||
(match_operand:DI 2 "immediate_operand" "")
|
||||
(reg:DI FAKE_CALL_REGNO)]
|
||||
UNSPEC_LOAD_CALL))]
|
||||
"TARGET_ABICALLS"
|
||||
"ld\t%0,%R2(%1)"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; Sibling calls. All these patterns use jump instructions.
|
||||
|
||||
;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
|
||||
|
|
Loading…
Reference in New Issue