alpha.md (movdi_er_maybe_g): New.
authorRichard Henderson <rth@redhat.com>
Wed, 10 Apr 2002 05:22:33 +0000 (22:22 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 10 Apr 2002 05:22:33 +0000 (22:22 -0700)
        * config/alpha/alpha.md (movdi_er_maybe_g): New.
        * config/alpha/alpha.c (alpha_expand_mov): Use it.

From-SVN: r52113

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.md

index 1def463bd49d1f4a88dd61642a6b4a66d04bcfe1..e5047f286d6760f812a3809587533060c3eaca95 100644 (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
index e5b1ce37c08126379f56a30098e35d372e4f4c5b..915d6e48996563fc89b25d23be4e0cdb8d21a3ec 100644 (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;
index 9db923c5df6161d29647a0b448987e8ac6c17a48..785a61df01efca0806862f31a154c69b1679a3fa 100644 (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"))]