aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-04-09 22:22:33 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-04-09 22:22:33 -0700
commitbc8e8e97b4ff381c66c3346682ad19f81d613685 (patch)
tree1e0bd2b6c5fea1393d20d974e23331f0eb265779
parentaec3e1894ee750f59a387d006a68377e26f45d16 (diff)
downloadgcc-bc8e8e97b4ff381c66c3346682ad19f81d613685.zip
gcc-bc8e8e97b4ff381c66c3346682ad19f81d613685.tar.gz
gcc-bc8e8e97b4ff381c66c3346682ad19f81d613685.tar.bz2
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
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/alpha/alpha.c21
-rw-r--r--gcc/config/alpha/alpha.md36
3 files changed, 61 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1def463..e5047f2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index e5b1ce3..915d6e4 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -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;
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 9db923c..785a61d 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -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"))]