mips.c (build_mips16_call_stub): Emit all direct float calls here, rather than leavin...
authorRichard Sandiford <richard@codesourcery.com>
Fri, 7 Sep 2007 08:38:42 +0000 (08:38 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 7 Sep 2007 08:38:42 +0000 (08:38 +0000)
gcc/
* config/mips/mips.c (build_mips16_call_stub): Emit all direct
float calls here, rather than leaving some to the caller.
Use call_internal_direct and call_value_internal_direct.
* config/mips/mips.md (call_internal_direct): New pattern.
(call_value_internal_direct): Likewise.

From-SVN: r128233

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.md

index 5d527d263b506904b0340033e810c477d0b76de1..e5a2363ec78e15c752b90fe0e2f695cf5076b1dc 100644 (file)
@@ -1,3 +1,11 @@
+2007-09-07  Richard Sandiford  <richard@codesourcery.com>
+
+       * config/mips/mips.c (build_mips16_call_stub): Emit all direct
+       float calls here, rather than leaving some to the caller.
+       Use call_internal_direct and call_value_internal_direct.
+       * config/mips/mips.md (call_internal_direct): New pattern.
+       (call_value_internal_direct): Likewise.
+
 2007-09-07  Richard Sandiford  <richard@codesourcery.com>
 
        * config/mips/mips.c (mips_base_move_loop_invariants): New variable.
index a4771f7d5ea328301fbd0fa5adcbfbbae28a0ca5..2bbfec75b35bed3f20d575f9483da1dadc128ad6 100644 (file)
@@ -9339,6 +9339,7 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
   tree stubid, stubdecl;
   int need_comma;
   unsigned int f;
+  rtx insn;
 
   /* We don't need to do anything if we aren't in mips16 mode, or if
      we were invoked with the -msoft-float option.  */
@@ -9604,34 +9605,26 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
   if (fpret && ! l->fpret)
     error ("cannot handle inconsistent calls to %qs", fnname);
 
+  if (retval == NULL_RTX)
+    insn = gen_call_internal_direct (fn, arg_size);
+  else
+    insn = gen_call_value_internal_direct (retval, fn, arg_size);
+  insn = emit_call_insn (insn);
+
   /* If we are calling a stub which handles a floating point return
      value, we need to arrange to save $18 in the prologue.  We do
      this by marking the function call as using the register.  The
      prologue will later see that it is used, and emit code to save
      it.  */
-
   if (l->fpret)
-    {
-      rtx insn;
+    CALL_INSN_FUNCTION_USAGE (insn) =
+      gen_rtx_EXPR_LIST (VOIDmode,
+                        gen_rtx_USE (VOIDmode, gen_rtx_REG (word_mode, 18)),
+                        CALL_INSN_FUNCTION_USAGE (insn));
 
-      if (retval == NULL_RTX)
-       insn = gen_call_internal (fn, arg_size);
-      else
-       insn = gen_call_value_internal (retval, fn, arg_size);
-      insn = emit_call_insn (insn);
-
-      CALL_INSN_FUNCTION_USAGE (insn) =
-       gen_rtx_EXPR_LIST (VOIDmode,
-                          gen_rtx_USE (VOIDmode, gen_rtx_REG (word_mode, 18)),
-                          CALL_INSN_FUNCTION_USAGE (insn));
-
-      /* Return 1 to tell the caller that we've generated the call
-         insn.  */
-      return 1;
-    }
-
-  /* Return 0 to let the caller generate the call insn.  */
-  return 0;
+  /* Return 1 to tell the caller that we've generated the call
+     insn.  */
+  return 1;
 }
 
 /* An entry in the mips16 constant pool.  VALUE is the pool constant,
index 6cda709aca080c3a47521107cca8116400986721..2006f92060062c4c7406b10857860e89aabcd7b6 100644 (file)
   [(set_attr "jal" "indirect,direct")
    (set_attr "extended_mips16" "no,yes")])
 
+;; A pattern for calls that must be made directly.  It is used for
+;; MIPS16 calls that the linker may need to redirect to a hard-float
+;; stub; the linker relies on the call relocation type to detect when
+;; such redirection is needed.
+(define_insn "call_internal_direct"
+  [(call (mem:SI (match_operand 0 "const_call_insn_operand"))
+        (match_operand 1))
+   (const_int 1)
+   (clobber (reg:SI 31))]
+  ""
+  { return MIPS_CALL ("jal", operands, 0); })
+
 (define_insn "call_split"
   [(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
         (match_operand 1 "" ""))
   { return MIPS_CALL ("jal", operands, 1); }
   [(set_attr "type" "call")])
 
+;; See call_internal_direct.
+(define_insn "call_value_internal_direct"
+  [(set (match_operand 0 "register_operand")
+        (call (mem:SI (match_operand 1 "const_call_insn_operand"))
+              (match_operand 2)))
+   (const_int 1)
+   (clobber (reg:SI 31))]
+  ""
+  { return MIPS_CALL ("jal", operands, 1); })
+
 ;; See comment for call_internal.
 (define_insn_and_split "call_value_multiple_internal"
   [(set (match_operand 0 "register_operand" "")