alpha.md (movdi_er_maybe_g): New.

* config/alpha/alpha.md (movdi_er_maybe_g): New.
        * config/alpha/alpha.c (alpha_expand_mov): Use it.

From-SVN: r52113
This commit is contained in:
Richard Henderson 2002-04-09 22:22:33 -07:00 committed by Richard Henderson
parent aec3e1894e
commit bc8e8e97b4
3 changed files with 61 additions and 1 deletions

View File

@ -1,3 +1,8 @@
2002-04-09 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.md (movdi_er_maybe_g): New.
* config/alpha/alpha.c (alpha_expand_mov): Use it.
2002-04-10 Alan Modra <amodra@bigpond.net.au>
PR optimization/6233

View File

@ -2537,7 +2537,26 @@ alpha_expand_mov (mode, operands)
/* Allow legitimize_address to perform some simplifications. */
if (mode == Pmode && symbolic_operand (operands[1], mode))
{
rtx tmp = alpha_legitimize_address (operands[1], operands[0], mode);
rtx tmp;
/* With RTL inlining, at -O3, rtl is generated, stored, then actually
compiled at the end of compilation. In the meantime, someone can
re-encode-section-info on some symbol changing it e.g. from global
to local-not-small. If this happens, we'd have emitted a plain
load rather than a high+losum load and not recognize the insn.
So if rtl inlining is in effect, we delay the global/not-global
decision until rest_of_compilation by wrapping it in an
UNSPEC_SYMBOL. */
if (TARGET_EXPLICIT_RELOCS && flag_inline_functions
&& rtx_equal_function_value_matters
&& global_symbolic_operand (operands[1], mode))
{
emit_insn (gen_movdi_er_maybe_g (operands[0], operands[1]));
return true;
}
tmp = alpha_legitimize_address (operands[1], operands[0], mode);
if (tmp)
{
operands[1] = tmp;

View File

@ -39,6 +39,7 @@
(UNSPEC_LITERAL 11)
(UNSPEC_LITUSE 12)
(UNSPEC_SIBCALL 13)
(UNSPEC_SYMBOL 14)
])
;; UNSPEC_VOLATILE:
@ -5547,6 +5548,41 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(const_int 0)] UNSPEC_LITERAL))]
"operands[2] = pic_offset_table_rtx;")
;; With RTL inlining, at -O3, rtl is generated, stored, then actually
;; compiled at the end of compilation. In the meantime, someone can
;; re-encode-section-info on some symbol changing it e.g. from global
;; to local-not-small. If this happens, we'd have emitted a plain
;; load rather than a high+losum load and not recognize the insn.
;;
;; So if rtl inlining is in effect, we delay the global/not-global
;; decision until rest_of_compilation by wrapping it in an UNSPEC_SYMBOL.
(define_insn_and_split "movdi_er_maybe_g"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
UNSPEC_SYMBOL))]
"TARGET_EXPLICIT_RELOCS && flag_inline_functions"
"#"
""
[(set (match_dup 0) (match_dup 1))]
{
if (local_symbolic_operand (operands[1], Pmode)
&& !small_symbolic_operand (operands[1], Pmode))
{
rtx subtarget = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
rtx tmp;
tmp = gen_rtx_HIGH (Pmode, operands[1]);
if (reload_completed)
tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
tmp = gen_rtx_LO_SUM (Pmode, subtarget, operands[1]);
emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp));
DONE;
}
})
(define_insn "*movdi_er_nofix"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]