[PATCH][AARCH64]Simplify call, call_value, sibcall, sibcall_value patterns.
authorRenlin Li <renlin.li@arm.com>
Mon, 15 May 2017 11:24:56 +0000 (11:24 +0000)
committerRenlin Li <renlin@gcc.gnu.org>
Mon, 15 May 2017 11:24:56 +0000 (11:24 +0000)
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

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/constraints.md

index cecd6d86ff9fdf86f8f315838a8f7c21e2301901..0654ce757948a53f558923e07a428ed725810f14 100644 (file)
@@ -1,3 +1,25 @@
+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
index 2895a2a97b5a9c63327cf1dc1ef74b8382c69ad1..ac91865b75fda43b94ddf9caa5ac09be17b0f8ab 100644 (file)
@@ -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);
index 71f9819745fd29d4a804fde8371416f78a4a9d75..5e546bf9091918371ac4835fe2f9806e48f16458 100644 (file)
@@ -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
index 7cc32dd037c8f41a2f5631139121f51cd56f2d99..93972d134b1eeba0e339f00528fc2e03f0c02052 100644 (file)
 ;; 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" ""))
   ""
   "
   {
-    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" "")
   ""
   "
   {
-    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" ""))
              (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" "")
              (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;
   }
 )
 (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
        (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
index b43f08b7bbd1f31d9ff3842cebaccd4e953ab9dc..88e840f2898d2da3e51e753578ee59bce4f462fa 100644 (file)
 (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