rx.c (rx_expand_epilogue): Add checks for sibcalls being used incorrectly.

* config/rx/rx.c (rx_expand_epilogue): Add checks for sibcalls
        being used incorrectly.
        (rx_function_ok_for_sibcall): New function.  Do not allow indirect
        sibcalls, or sibcalls from interrupt functions.
        (TARGET_FUNCTION_OK_FOR_SIBCALL): Define.
        * config/rx/rx.md (sibcall): Convert to a define_expand.  Check
        for a MEM inside a MEM.
        (sibcall_value): Likewise.
        (sibcall_internal): New pattern containing old sibcall pattern.
        (sibcall_value_internal): Likewise.

From-SVN: r154671
This commit is contained in:
Nick Clifton 2009-11-26 10:44:28 +00:00 committed by Nick Clifton
parent 5d6b1baca0
commit 0d8f38d337
3 changed files with 103 additions and 15 deletions

View File

@ -1,3 +1,16 @@
2009-11-26 Nick Clifton <nickc@redhat.com>
* config/rx/rx.c (rx_expand_epilogue): Add checks for sibcalls
being used incorrectly.
(rx_function_ok_for_sibcall): New function. Do not allow indirect
sibcalls, or sibcalls from interrupt functions.
(TARGET_FUNCTION_OK_FOR_SIBCALL): Define.
* config/rx/rx.md (sibcall): Convert to a define_expand. Check
for a MEM inside a MEM.
(sibcall_value): Likewise.
(sibcall_internal): New pattern containing old sibcall pattern.
(sibcall_value_internal): Likewise.
2009-11-25 Richard Henderson <rth@redhat.com>
* config/i386/i386-builtin-types.awk (DEF_VECTOR_TYPE): Allow an

View File

@ -1190,7 +1190,7 @@ mark_frame_related (rtx insn)
{
unsigned int i;
for (i = 0; i < XVECLEN (insn, 0); i++)
for (i = 0; i < (unsigned) XVECLEN (insn, 0); i++)
RTX_FRAME_RELATED_P (XVECEXP (insn, 0, i)) = 1;
}
}
@ -1454,8 +1454,26 @@ rx_expand_epilogue (bool is_sibcall)
unsigned int reg;
unsigned HOST_WIDE_INT total_size;
/* FIXME: We do not support indirect sibcalls at the moment becaause we
cannot guarantee that the register holding the function address is a
call-used register. If it is a call-saved register then the stack
pop instructions generated in the epilogue will corrupt the address
before it is used.
Creating a new call-used-only register class works but then the
reload pass gets stuck because it cannot always find a call-used
register for spilling sibcalls.
The other possible solution is for this pass to scan forward for the
sibcall instruction (if it has been generated) and work out if it
is an indirect sibcall using a call-saved register. If it is then
the address can copied into a call-used register in this epilogue
code and the sibcall instruction modified to use that register. */
if (is_naked_func (NULL_TREE))
{
gcc_assert (! is_sibcall);
/* Naked functions use their own, programmer provided epilogues.
But, in order to keep gcc happy we have to generate some kind of
epilogue RTL. */
@ -1547,9 +1565,15 @@ rx_expand_epilogue (bool is_sibcall)
}
if (is_fast_interrupt_func (NULL_TREE))
emit_jump_insn (gen_fast_interrupt_return ());
{
gcc_assert (! is_sibcall);
emit_jump_insn (gen_fast_interrupt_return ());
}
else if (is_interrupt_func (NULL_TREE))
emit_jump_insn (gen_exception_return ());
{
gcc_assert (! is_sibcall);
emit_jump_insn (gen_exception_return ());
}
else if (! is_sibcall)
emit_jump_insn (gen_simple_return ());
@ -2107,6 +2131,26 @@ rx_func_attr_inlinable (const_tree decl)
&& ! is_naked_func (decl);
}
/* Return nonzero if it is ok to make a tail-call to DECL,
a function_decl or NULL if this is an indirect call, using EXP */
static bool
rx_function_ok_for_sibcall (tree decl, tree exp)
{
/* Do not allow indirect tailcalls. The
sibcall patterns do not support them. */
if (decl == NULL)
return false;
/* Never tailcall from inside interrupt handlers or naked functions. */
if (is_fast_interrupt_func (NULL_TREE)
|| is_interrupt_func (NULL_TREE)
|| is_naked_func (NULL_TREE))
return false;
return true;
}
static void
rx_file_start (void)
{
@ -2485,6 +2529,9 @@ rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P rx_func_attr_inlinable
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL rx_function_ok_for_sibcall
#undef TARGET_SET_CURRENT_FUNCTION
#define TARGET_SET_CURRENT_FUNCTION rx_set_current_function

View File

@ -388,7 +388,7 @@
(match_operand:SI 1 "general_operand" "g,g"))]
""
"@
jsr\t%A0
jsr\t%0
bsr\t%A0"
[(set_attr "length" "2,4")
(set_attr "timings" "33")]
@ -415,32 +415,60 @@
(match_operand:SI 2 "general_operand" "g,g")))]
""
"@
jsr\t%A1
jsr\t%1
bsr\t%A1"
[(set_attr "length" "2,4")
(set_attr "timings" "33")]
)
(define_insn "sibcall"
[(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
(match_operand:SI 1 "general_operand" "g"))
(return)
(use (match_operand 2 "" ""))]
;; Note - we do not allow indirect sibcalls (with the address
;; held in a register) because we cannot guarantee that the register
;; chosen will be a call-used one. If it is a call-saved register,
;; then the epilogue code will corrupt it by popping the saved value
;; off of the stack.
(define_expand "sibcall"
[(parallel
[(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
(match_operand:SI 1 "general_operand"))
(return)])]
""
{
if (MEM_P (operands[0]))
operands[0] = XEXP (operands[0], 0);
}
)
(define_insn "sibcall_internal"
[(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
(match_operand:SI 1 "general_operand" "g"))
(return)]
""
"bra\t%A0"
[(set_attr "length" "4")
[(set_attr "length" "4")
(set_attr "timings" "33")]
)
(define_insn "sibcall_value"
(define_expand "sibcall_value"
[(parallel
[(set (match_operand 0 "register_operand")
(call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
(match_operand:SI 2 "general_operand")))
(return)])]
""
{
if (MEM_P (operands[1]))
operands[1] = XEXP (operands[1], 0);
}
)
(define_insn "sibcall_value_internal"
[(set (match_operand 0 "register_operand" "=r")
(call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
(match_operand:SI 2 "general_operand" "g")))
(return)
(use (match_operand 3 "" ""))]
(return)]
""
"bra\t%A1"
[(set_attr "length" "4")
[(set_attr "length" "4")
(set_attr "timings" "33")]
)