From 7ab6a03bf54b50672cd941d781cfa087e305845e Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 7 Sep 2007 08:38:42 +0000 Subject: [PATCH] mips.c (build_mips16_call_stub): Emit all direct float calls here, rather than leaving some to the caller. 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 | 8 ++++++++ gcc/config/mips/mips.c | 35 ++++++++++++++--------------------- gcc/config/mips/mips.md | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d527d263b5..e5a2363ec78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2007-09-07 Richard Sandiford + + * 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 * config/mips/mips.c (mips_base_move_loop_invariants): New variable. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index a4771f7d5ea..2bbfec75b35 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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, diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 6cda709aca0..2006f920600 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -5666,6 +5666,18 @@ [(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 "" "")) @@ -5717,6 +5729,16 @@ { 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" "")