Commit d6529176 by Chung-Ju Wu Committed by Chung-Ju Wu

[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
parent 03390cda
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.
* config/nds32/nds32.md (unspec_volatile_func_return): Remove.
(return_internal): 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 (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 ();
nds32_expand_epilogue (true);
DONE;
})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment