diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2017-07-03 13:20:03 +0200 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2017-07-04 08:57:10 +0000 |
commit | 5a09ac2e874ec4b018f7502c3a7758903ed448f9 (patch) | |
tree | b0de4ca4e56c07be60d1bf0963fedc8a97313b3a /gcc | |
parent | f68579b530689bb695947706c7a4f7060e16917d (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.h | 1 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 44 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 146 | ||||
-rw-r--r-- | gcc/config/aarch64/constraints.md | 3 |
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 |