[NDS32] Have sibling calls optmization to be performed on nds32 target.
gcc/ * config/nds32/nds32-protos.h (nds32_expand_epilogue): Change prototype. (nds32_expand_epilogue_v3pop): Likewise. * config/nds32/nds32.md (sibcall): Define this for sibling call optimization. (sibcall_register): Likewise. (sibcall_immediate): Likewise. (sibcall_value): Likewise. (sibcall_value_register): Likewise. (sibcall_value_immediate): Likewise. (sibcall_epilogue): Likewise. (epilogue): Pass false to indicate this is not a sibcall epilogue. * config/nds32/nds32.c (nds32_expand_epilogue): Consider sibcall case. (nds32_expand_epilogue_v3pop): Likewise. From-SVN: r219712
This commit is contained in:
parent
03390cda42
commit
d6529176b2
4 changed files with 139 additions and 9 deletions
|
@ -1,3 +1,20 @@
|
|||
2015-01-16 Chung-Ju Wu <jasonwucj@gmail.com>
|
||||
|
||||
* config/nds32/nds32-protos.h (nds32_expand_epilogue): Change
|
||||
prototype.
|
||||
(nds32_expand_epilogue_v3pop): Likewise.
|
||||
* config/nds32/nds32.md (sibcall): Define this for sibling call
|
||||
optimization.
|
||||
(sibcall_register): Likewise.
|
||||
(sibcall_immediate): Likewise.
|
||||
(sibcall_value): Likewise.
|
||||
(sibcall_value_register): Likewise.
|
||||
(sibcall_value_immediate): Likewise.
|
||||
(sibcall_epilogue): Likewise.
|
||||
(epilogue): Pass false to indicate this is not a sibcall epilogue.
|
||||
* config/nds32/nds32.c (nds32_expand_epilogue): Consider sibcall case.
|
||||
(nds32_expand_epilogue_v3pop): Likewise.
|
||||
|
||||
2015-01-16 Chung-Ju Wu <jasonwucj@gmail.com>
|
||||
|
||||
* config/nds32/nds32-protos.h (nds32_can_use_return_insn): New.
|
||||
|
|
|
@ -58,9 +58,9 @@ extern void nds32_init_cumulative_args (CUMULATIVE_ARGS *,
|
|||
/* -- Function Entry and Exit. */
|
||||
|
||||
extern void nds32_expand_prologue (void);
|
||||
extern void nds32_expand_epilogue (void);
|
||||
extern void nds32_expand_epilogue (bool);
|
||||
extern void nds32_expand_prologue_v3push (void);
|
||||
extern void nds32_expand_epilogue_v3pop (void);
|
||||
extern void nds32_expand_epilogue_v3pop (bool);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
|
|
@ -3044,7 +3044,7 @@ nds32_expand_prologue (void)
|
|||
|
||||
/* Function for normal multiple pop epilogue. */
|
||||
void
|
||||
nds32_expand_epilogue (void)
|
||||
nds32_expand_epilogue (bool sibcall_p)
|
||||
{
|
||||
int sp_adjust;
|
||||
int en4_const;
|
||||
|
@ -3089,7 +3089,8 @@ nds32_expand_epilogue (void)
|
|||
|
||||
/* Generate return instruction by using 'return_internal' pattern.
|
||||
Make sure this instruction is after gen_blockage(). */
|
||||
emit_jump_insn (gen_return_internal ());
|
||||
if (!sibcall_p)
|
||||
emit_jump_insn (gen_return_internal ());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3194,7 +3195,8 @@ nds32_expand_epilogue (void)
|
|||
}
|
||||
|
||||
/* Generate return instruction. */
|
||||
emit_jump_insn (gen_return_internal ());
|
||||
if (!sibcall_p)
|
||||
emit_jump_insn (gen_return_internal ());
|
||||
}
|
||||
|
||||
/* Function for v3push prologue. */
|
||||
|
@ -3327,7 +3329,7 @@ nds32_expand_prologue_v3push (void)
|
|||
|
||||
/* Function for v3pop epilogue. */
|
||||
void
|
||||
nds32_expand_epilogue_v3pop (void)
|
||||
nds32_expand_epilogue_v3pop (bool sibcall_p)
|
||||
{
|
||||
int sp_adjust;
|
||||
|
||||
|
@ -3348,7 +3350,8 @@ nds32_expand_epilogue_v3pop (void)
|
|||
{
|
||||
/* Generate return instruction by using 'return_internal' pattern.
|
||||
Make sure this instruction is after gen_blockage(). */
|
||||
emit_jump_insn (gen_return_internal ());
|
||||
if (!sibcall_p)
|
||||
emit_jump_insn (gen_return_internal ());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1988,6 +1988,102 @@ create_template:
|
|||
(const_int 4)))])
|
||||
|
||||
|
||||
;; ----------------------------------------------------------------------------
|
||||
|
||||
;; The sibcall patterns.
|
||||
|
||||
;; sibcall
|
||||
;; sibcall_register
|
||||
;; sibcall_immediate
|
||||
|
||||
(define_expand "sibcall"
|
||||
[(parallel [(call (match_operand 0 "memory_operand" "")
|
||||
(const_int 0))
|
||||
(clobber (reg:SI TA_REGNUM))
|
||||
(return)])]
|
||||
""
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn "*sibcall_register"
|
||||
[(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
|
||||
(match_operand 1))
|
||||
(clobber (reg:SI TA_REGNUM))
|
||||
(return)])]
|
||||
""
|
||||
"@
|
||||
jr5\t%0
|
||||
jr\t%0"
|
||||
[(set_attr "type" "branch,branch")
|
||||
(set_attr "length" " 2, 4")])
|
||||
|
||||
(define_insn "*sibcall_immediate"
|
||||
[(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
|
||||
(match_operand 1))
|
||||
(clobber (reg:SI TA_REGNUM))
|
||||
(return)])]
|
||||
""
|
||||
{
|
||||
if (TARGET_CMODEL_LARGE)
|
||||
return "b\t%0";
|
||||
else
|
||||
return "j\t%0";
|
||||
}
|
||||
[(set_attr "type" "branch")
|
||||
(set (attr "length")
|
||||
(if_then_else (match_test "TARGET_CMODEL_LARGE")
|
||||
(const_int 12)
|
||||
(const_int 4)))])
|
||||
|
||||
;; sibcall_value
|
||||
;; sibcall_value_register
|
||||
;; sibcall_value_immediate
|
||||
|
||||
(define_expand "sibcall_value"
|
||||
[(parallel [(set (match_operand 0)
|
||||
(call (match_operand 1 "memory_operand" "")
|
||||
(const_int 0)))
|
||||
(clobber (reg:SI TA_REGNUM))
|
||||
(return)])]
|
||||
""
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn "*sibcall_value_register"
|
||||
[(parallel [(set (match_operand 0)
|
||||
(call (mem (match_operand:SI 1 "register_operand" "r, r"))
|
||||
(match_operand 2)))
|
||||
(clobber (reg:SI TA_REGNUM))
|
||||
(return)])]
|
||||
""
|
||||
"@
|
||||
jr5\t%1
|
||||
jr\t%1"
|
||||
[(set_attr "type" "branch,branch")
|
||||
(set_attr "length" " 2, 4")])
|
||||
|
||||
(define_insn "*sibcall_value_immediate"
|
||||
[(parallel [(set (match_operand 0)
|
||||
(call (mem (match_operand:SI 1 "immediate_operand" "i"))
|
||||
(match_operand 2)))
|
||||
(clobber (reg:SI TA_REGNUM))
|
||||
(return)])]
|
||||
""
|
||||
{
|
||||
if (TARGET_CMODEL_LARGE)
|
||||
return "b\t%1";
|
||||
else
|
||||
return "j\t%1";
|
||||
}
|
||||
[(set_attr "type" "branch")
|
||||
(set (attr "length")
|
||||
(if_then_else (match_test "TARGET_CMODEL_LARGE")
|
||||
(const_int 12)
|
||||
(const_int 4)))])
|
||||
|
||||
|
||||
;; ----------------------------------------------------------------------------
|
||||
|
||||
;; prologue and epilogue.
|
||||
|
||||
(define_expand "prologue" [(const_int 0)]
|
||||
|
@ -2014,9 +2110,23 @@ create_template:
|
|||
if (TARGET_V3PUSH
|
||||
&& !nds32_isr_function_p (current_function_decl)
|
||||
&& (cfun->machine->va_args_size == 0))
|
||||
nds32_expand_epilogue_v3pop ();
|
||||
nds32_expand_epilogue_v3pop (false);
|
||||
else
|
||||
nds32_expand_epilogue ();
|
||||
nds32_expand_epilogue (false);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "sibcall_epilogue" [(const_int 0)]
|
||||
""
|
||||
{
|
||||
/* Pass true to indicate that this is sibcall epilogue and
|
||||
exit from a function without the final branch back to the
|
||||
calling function. */
|
||||
if (TARGET_V3PUSH && !nds32_isr_function_p (current_function_decl))
|
||||
nds32_expand_epilogue_v3pop (true);
|
||||
else
|
||||
nds32_expand_epilogue (true);
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue