Commit 47210a04 by Renlin Li Committed by Renlin Li

[PATCH][AARCH64]Simplify call, call_value, sibcall, sibcall_value patterns.

gcc/ChangeLog

2017-05-15  Renlin Li  <renlin.li@arm.com>

	* config/aarch64/aarch64-protos.h (aarch64_expand_call): Declare.
	* config/aarch64/aarch64.c (aarch64_expand_call): Define.
	* config/aarch64/constraints.md (Usf): Add long call check.
	* config/aarch64/aarch64.md (call): Use aarch64_expand_call.
	(call_value): Likewise.
	(sibcall): Likewise.
	(sibcall_value): Likewise.
	(call_insn): New.
	(call_value_insn): New.
	(sibcall_insn): Update rtx pattern.
	(sibcall_value_insn): Likewise.
	(call_internal): Remove.
	(call_value_internal): Likewise.
	(sibcall_internal): Likewise.
	(sibcall_value_internal): Likewise.
	(call_reg): Likewise.
	(call_symbol): Likewise.
	(call_value_reg): Likewise.
	(call_value_symbol): Likewise.

From-SVN: r248056
parent 7543c8b6
2017-05-15 Renlin Li <renlin.li@arm.com>
* config/aarch64/aarch64-protos.h (aarch64_expand_call): Declare.
* config/aarch64/aarch64.c (aarch64_expand_call): Define.
* config/aarch64/constraints.md (Usf): Add long call check.
* config/aarch64/aarch64.md (call): Use aarch64_expand_call.
(call_value): Likewise.
(sibcall): Likewise.
(sibcall_value): Likewise.
(call_insn): New.
(call_value_insn): New.
(sibcall_insn): Update rtx pattern.
(sibcall_value_insn): Likewise.
(call_internal): Remove.
(call_value_internal): Likewise.
(sibcall_internal): Likewise.
(sibcall_value_internal): Likewise.
(call_reg): Likewise.
(call_symbol): Likewise.
(call_value_reg): Likewise.
(call_value_symbol): Likewise.
2017-05-14 Krister Walfridsson <krister.walfridsson@gmail.com>
PR target/80600
......
......@@ -312,6 +312,7 @@ bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
bool aarch64_constant_address_p (rtx);
bool aarch64_emit_approx_div (rtx, rtx, rtx);
bool aarch64_emit_approx_sqrt (rtx, rtx, bool);
void aarch64_expand_call (rtx, rtx, bool);
bool aarch64_expand_movmem (rtx *);
bool aarch64_float_const_zero_rtx_p (rtx);
bool aarch64_function_arg_regno_p (unsigned);
......
......@@ -4651,6 +4651,50 @@ aarch64_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
return true;
}
/* This function is used by the call expanders of the machine description.
RESULT is the register in which the result is returned. It's NULL for
"call" and "sibcall".
MEM is the location of the function call.
SIBCALL indicates whether this function call is normal call or sibling call.
It will generate different pattern accordingly. */
void
aarch64_expand_call (rtx result, rtx mem, bool sibcall)
{
rtx call, callee, tmp;
rtvec vec;
machine_mode mode;
gcc_assert (MEM_P (mem));
callee = XEXP (mem, 0);
mode = GET_MODE (callee);
gcc_assert (mode == Pmode);
/* Decide if we should generate indirect calls by loading the
address of the callee into a register before performing
the branch-and-link. */
if (SYMBOL_REF_P (callee)
? (aarch64_is_long_call_p (callee)
|| aarch64_is_noplt_call_p (callee))
: !REG_P (callee))
XEXP (mem, 0) = force_reg (mode, callee);
call = gen_rtx_CALL (VOIDmode, mem, const0_rtx);
if (result != NULL_RTX)
call = gen_rtx_SET (result, call);
if (sibcall)
tmp = ret_rtx;
else
tmp = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNUM));
vec = gen_rtvec (2, call, tmp);
call = gen_rtx_PARALLEL (VOIDmode, vec);
aarch64_emit_call_insn (call);
}
/* Emit call insn with PAT and do aarch64-specific handling. */
void
......
......@@ -717,12 +717,6 @@
;; Subroutine calls and sibcalls
;; -------------------------------------------------------------------
(define_expand "call_internal"
[(parallel [(call (match_operand 0 "memory_operand" "")
(match_operand 1 "general_operand" ""))
(use (match_operand 2 "" ""))
(clobber (reg:DI LR_REGNUM))])])
(define_expand "call"
[(parallel [(call (match_operand 0 "memory_operand" "")
(match_operand 1 "general_operand" ""))
......@@ -731,57 +725,22 @@
""
"
{
rtx callee, pat;
/* In an untyped call, we can get NULL for operand 2. */
if (operands[2] == NULL)
operands[2] = const0_rtx;
/* Decide if we should generate indirect calls by loading the
64-bit address of the callee into a register before performing
the branch-and-link. */
callee = XEXP (operands[0], 0);
if (GET_CODE (callee) == SYMBOL_REF
? (aarch64_is_long_call_p (callee)
|| aarch64_is_noplt_call_p (callee))
: !REG_P (callee))
XEXP (operands[0], 0) = force_reg (Pmode, callee);
pat = gen_call_internal (operands[0], operands[1], operands[2]);
aarch64_emit_call_insn (pat);
aarch64_expand_call (NULL_RTX, operands[0], false);
DONE;
}"
)
(define_insn "*call_reg"
[(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
(define_insn "*call_insn"
[(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "r, Usf"))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:DI LR_REGNUM))]
""
"blr\\t%0"
[(set_attr "type" "call")]
)
(define_insn "*call_symbol"
[(call (mem:DI (match_operand:DI 0 "" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:DI LR_REGNUM))]
"GET_CODE (operands[0]) == SYMBOL_REF
&& !aarch64_is_long_call_p (operands[0])
&& !aarch64_is_noplt_call_p (operands[0])"
"bl\\t%a0"
[(set_attr "type" "call")]
"@
blr\\t%0
bl\\t%a0"
[(set_attr "type" "call, call")]
)
(define_expand "call_value_internal"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand 1 "memory_operand" "")
(match_operand 2 "general_operand" "")))
(use (match_operand 3 "" ""))
(clobber (reg:DI LR_REGNUM))])])
(define_expand "call_value"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand 1 "memory_operand" "")
......@@ -791,60 +750,23 @@
""
"
{
rtx callee, pat;
/* In an untyped call, we can get NULL for operand 3. */
if (operands[3] == NULL)
operands[3] = const0_rtx;
/* Decide if we should generate indirect calls by loading the
64-bit address of the callee into a register before performing
the branch-and-link. */
callee = XEXP (operands[1], 0);
if (GET_CODE (callee) == SYMBOL_REF
? (aarch64_is_long_call_p (callee)
|| aarch64_is_noplt_call_p (callee))
: !REG_P (callee))
XEXP (operands[1], 0) = force_reg (Pmode, callee);
pat = gen_call_value_internal (operands[0], operands[1], operands[2],
operands[3]);
aarch64_emit_call_insn (pat);
aarch64_expand_call (operands[0], operands[1], false);
DONE;
}"
)
(define_insn "*call_value_reg"
(define_insn "*call_value_insn"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "register_operand" "r"))
(call (mem:DI (match_operand:DI 1 "aarch64_call_insn_operand" "r, Usf"))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:DI LR_REGNUM))]
""
"blr\\t%1"
[(set_attr "type" "call")]
)
(define_insn "*call_value_symbol"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:DI LR_REGNUM))]
"GET_CODE (operands[1]) == SYMBOL_REF
&& !aarch64_is_long_call_p (operands[1])
&& !aarch64_is_noplt_call_p (operands[1])"
"bl\\t%a1"
[(set_attr "type" "call")]
"@
blr\\t%1
bl\\t%a1"
[(set_attr "type" "call, call")]
)
(define_expand "sibcall_internal"
[(parallel [(call (match_operand 0 "memory_operand" "")
(match_operand 1 "general_operand" ""))
(return)
(use (match_operand 2 "" ""))])])
(define_expand "sibcall"
[(parallel [(call (match_operand 0 "memory_operand" "")
(match_operand 1 "general_operand" ""))
......@@ -852,29 +774,11 @@
(use (match_operand 2 "" ""))])]
""
{
rtx pat;
rtx callee = XEXP (operands[0], 0);
if (!REG_P (callee)
&& ((GET_CODE (callee) != SYMBOL_REF)
|| aarch64_is_noplt_call_p (callee)))
XEXP (operands[0], 0) = force_reg (Pmode, callee);
if (operands[2] == NULL_RTX)
operands[2] = const0_rtx;
pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
aarch64_emit_call_insn (pat);
aarch64_expand_call (NULL_RTX, operands[0], true);
DONE;
}
)
(define_expand "sibcall_value_internal"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand 1 "memory_operand" "")
(match_operand 2 "general_operand" "")))
(return)
(use (match_operand 3 "" ""))])])
(define_expand "sibcall_value"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand 1 "memory_operand" "")
......@@ -883,19 +787,7 @@
(use (match_operand 3 "" ""))])]
""
{
rtx pat;
rtx callee = XEXP (operands[1], 0);
if (!REG_P (callee)
&& ((GET_CODE (callee) != SYMBOL_REF)
|| aarch64_is_noplt_call_p (callee)))
XEXP (operands[1], 0) = force_reg (Pmode, callee);
if (operands[3] == NULL_RTX)
operands[3] = const0_rtx;
pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
operands[3]);
aarch64_emit_call_insn (pat);
aarch64_expand_call (operands[0], operands[1], true);
DONE;
}
)
......@@ -903,8 +795,7 @@
(define_insn "*sibcall_insn"
[(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
(match_operand 1 "" ""))
(return)
(use (match_operand 2 "" ""))]
(return)]
"SIBLING_CALL_P (insn)"
"@
br\\t%0
......@@ -917,8 +808,7 @@
(call (mem:DI
(match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
(match_operand 2 "" "")))
(return)
(use (match_operand 3 "" ""))]
(return)]
"SIBLING_CALL_P (insn)"
"@
br\\t%1
......
......@@ -126,7 +126,8 @@
(define_constraint "Usf"
"@internal Usf is a symbol reference under the context where plt stub allowed."
(and (match_code "symbol_ref")
(match_test "!aarch64_is_noplt_call_p (op)")))
(match_test "!(aarch64_is_noplt_call_p (op)
|| aarch64_is_long_call_p (op))")))
(define_constraint "UsM"
"@internal
......
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