aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2017-07-03 13:20:03 +0200
committerYvan Roux <yvan.roux@linaro.org>2017-07-04 08:57:10 +0000
commit5a09ac2e874ec4b018f7502c3a7758903ed448f9 (patch)
treeb0de4ca4e56c07be60d1bf0963fedc8a97313b3a /gcc
parentf68579b530689bb695947706c7a4f7060e16917d (diff)
gcc/
Backport from trunk r248056. 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. Change-Id: Ib1ed477ff34808d3299f29c1cc3fc950116fd7cc
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64.c44
-rw-r--r--gcc/config/aarch64/aarch64.md146
-rw-r--r--gcc/config/aarch64/constraints.md3
4 files changed, 65 insertions, 129 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 2895a2a97b5..ac91865b75f 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -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);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 36df3684135..bb8212351a0 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -4659,6 +4659,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
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 7cc32dd037c..93972d134b1 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -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
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index b43f08b7bbd..88e840f2898 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -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