diff gcc/config/aarch64/predicates.md @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/config/aarch64/predicates.md	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/config/aarch64/predicates.md	Thu Oct 25 07:37:49 2018 +0900
@@ -1,5 +1,5 @@
 ;; Machine description for AArch64 architecture.
-;; Copyright (C) 2009-2017 Free Software Foundation, Inc.
+;; Copyright (C) 2009-2018 Free Software Foundation, Inc.
 ;; Contributed by ARM Ltd.
 ;;
 ;; This file is part of GCC.
@@ -62,6 +62,10 @@
 	(and (match_code "const_double")
 	     (match_test "aarch64_float_const_zero_rtx_p (op)"))))
 
+(define_predicate "aarch64_reg_zero_or_fp_zero"
+  (ior (match_operand 0 "aarch64_reg_or_fp_zero")
+       (match_operand 0 "aarch64_reg_or_zero")))
+
 (define_predicate "aarch64_reg_zero_or_m1_or_1"
   (and (match_code "reg,subreg,const_int")
        (ior (match_operand 0 "register_operand")
@@ -72,14 +76,14 @@
 (define_predicate "aarch64_reg_or_orr_imm"
    (ior (match_operand 0 "register_operand")
 	(and (match_code "const_vector")
-	     (match_test "aarch64_simd_valid_immediate (op, mode, false,
-						NULL, AARCH64_CHECK_ORR)"))))
+	     (match_test "aarch64_simd_valid_immediate (op, NULL,
+							AARCH64_CHECK_ORR)"))))
 
 (define_predicate "aarch64_reg_or_bic_imm"
    (ior (match_operand 0 "register_operand")
 	(and (match_code "const_vector")
-	     (match_test "aarch64_simd_valid_immediate (op, mode, false,
-						NULL, AARCH64_CHECK_BIC)"))))
+	     (match_test "aarch64_simd_valid_immediate (op, NULL,
+							AARCH64_CHECK_BIC)"))))
 
 (define_predicate "aarch64_fp_compare_operand"
   (ior (match_operand 0 "register_operand")
@@ -93,6 +97,10 @@
 (define_predicate "aarch64_fp_vec_pow2"
   (match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0"))
 
+(define_predicate "aarch64_sve_cnt_immediate"
+  (and (match_code "const_poly_int")
+       (match_test "aarch64_sve_cnt_immediate_p (op)")))
+
 (define_predicate "aarch64_sub_immediate"
   (and (match_code "const_int")
        (match_test "aarch64_uimm12_shift (-INTVAL (op))")))
@@ -114,9 +122,22 @@
   (and (match_operand 0 "aarch64_pluslong_immediate")
        (not (match_operand 0 "aarch64_plus_immediate"))))
 
+(define_predicate "aarch64_sve_addvl_addpl_immediate"
+  (and (match_code "const_poly_int")
+       (match_test "aarch64_sve_addvl_addpl_immediate_p (op)")))
+
+(define_predicate "aarch64_split_add_offset_immediate"
+  (and (match_code "const_poly_int")
+       (match_test "aarch64_add_offset_temporaries (op) == 1")))
+
 (define_predicate "aarch64_pluslong_operand"
   (ior (match_operand 0 "register_operand")
-       (match_operand 0 "aarch64_pluslong_immediate")))
+       (match_operand 0 "aarch64_pluslong_immediate")
+       (match_operand 0 "aarch64_sve_addvl_addpl_immediate")))
+
+(define_predicate "aarch64_pluslong_or_poly_operand"
+  (ior (match_operand 0 "aarch64_pluslong_operand")
+       (match_operand 0 "aarch64_split_add_offset_immediate")))
 
 (define_predicate "aarch64_logical_immediate"
   (and (match_code "const_int")
@@ -160,6 +181,18 @@
   (and (match_code "const_int")
        (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 4")))
 
+;; The imm2 field is a 2-bit field that only accepts immediates in the
+;; range 0..3.
+(define_predicate "aarch64_imm2"
+  (and (match_code "const_int")
+       (match_test "UINTVAL (op) <= 3")))
+
+;; The imm3 field is a 3-bit field that only accepts immediates in the
+;; range 0..7.
+(define_predicate "aarch64_lane_imm3"
+  (and (match_code "const_int")
+       (match_test "UINTVAL (op) <= 7")))
+
 ;; An immediate that fits into 24 bits.
 (define_predicate "aarch64_imm24"
   (and (match_code "const_int")
@@ -186,8 +219,16 @@
 
 (define_predicate "aarch64_mem_pair_operand"
   (and (match_code "mem")
-       (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL,
-					       0)")))
+       (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), false,
+						  ADDR_QUERY_LDP_STP)")))
+
+;; Used for storing two 64-bit values in an AdvSIMD register using an STP
+;; as a 128-bit vec_concat.
+(define_predicate "aarch64_mem_pair_lanes_operand"
+  (and (match_code "mem")
+       (match_test "aarch64_legitimate_address_p (GET_MODE (op), XEXP (op, 0),
+						  false,
+						  ADDR_QUERY_LDP_STP_N)")))
 
 (define_predicate "aarch64_prefetch_operand"
   (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))
@@ -244,21 +285,27 @@
 })
 
 (define_predicate "aarch64_mov_operand"
-  (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high")
+  (and (match_code "reg,subreg,mem,const,const_int,symbol_ref,label_ref,high,
+		    const_poly_int,const_vector")
        (ior (match_operand 0 "register_operand")
 	    (ior (match_operand 0 "memory_operand")
 		 (match_test "aarch64_mov_operand_p (op, mode)")))))
 
-(define_predicate "aarch64_movti_operand"
-  (and (match_code "reg,subreg,mem,const_int")
+(define_predicate "aarch64_nonmemory_operand"
+  (and (match_code "reg,subreg,const,const_int,symbol_ref,label_ref,high,
+		    const_poly_int,const_vector")
        (ior (match_operand 0 "register_operand")
-	    (ior (match_operand 0 "memory_operand")
-		 (match_operand 0 "const_int_operand")))))
+	    (match_test "aarch64_mov_operand_p (op, mode)"))))
+
+(define_predicate "aarch64_movti_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "memory_operand")
+       (and (match_operand 0 "const_scalar_int_operand")
+	    (match_test "aarch64_mov128_immediate (op)"))))
 
 (define_predicate "aarch64_reg_or_imm"
-  (and (match_code "reg,subreg,const_int")
-       (ior (match_operand 0 "register_operand")
-	    (match_operand 0 "const_int_operand"))))
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "const_scalar_int_operand")))
 
 ;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ.
 (define_special_predicate "aarch64_comparison_operator"
@@ -284,6 +331,9 @@
   return aarch64_get_condition_code (op) >= 0;
 })
 
+(define_special_predicate "aarch64_equality_operator"
+  (match_code "eq,ne"))
+
 (define_special_predicate "aarch64_carry_operation"
   (match_code "ne,geu")
 {
@@ -309,6 +359,36 @@
   (and (match_operand 0 "memory_operand")
        (match_code "reg" "0")))
 
+(define_predicate "aarch64_9bit_offset_memory_operand"
+  (and (match_operand 0 "memory_operand")
+       (ior (match_code "reg" "0")
+	    (and (match_code "plus" "0")
+		 (match_code "reg"  "00")
+		 (match_code "const_int" "01"))))
+{
+  rtx mem_op = XEXP (op, 0);
+
+  if (REG_P (mem_op))
+    return GET_MODE (mem_op) == DImode;
+
+  rtx plus_op0 = XEXP (mem_op, 0);
+  rtx plus_op1 = XEXP (mem_op, 1);
+
+  if (GET_MODE (plus_op0) != DImode)
+    return false;
+
+  poly_int64 offset;
+  if (!poly_int_rtx_p (plus_op1, &offset))
+    gcc_unreachable ();
+
+  return aarch64_offset_9bit_signed_unscaled_p (mode, offset);
+})
+
+(define_predicate "aarch64_rcpc_memory_operand"
+  (if_then_else (match_test "AARCH64_ISA_RCPC8_4")
+    (match_operand 0 "aarch64_9bit_offset_memory_operand")
+    (match_operand 0 "aarch64_sync_memory_operand")))
+
 ;; Predicates for parallel expanders based on mode.
 (define_special_predicate "vect_par_cnst_hi_half"
   (match_code "parallel")
@@ -323,22 +403,34 @@
 })
 
 (define_special_predicate "aarch64_simd_lshift_imm"
-  (match_code "const_vector")
+  (match_code "const,const_vector")
 {
   return aarch64_simd_shift_imm_p (op, mode, true);
 })
 
 (define_special_predicate "aarch64_simd_rshift_imm"
-  (match_code "const_vector")
+  (match_code "const,const_vector")
 {
   return aarch64_simd_shift_imm_p (op, mode, false);
 })
 
+(define_predicate "aarch64_simd_imm_zero"
+  (and (match_code "const,const_vector")
+       (match_test "op == CONST0_RTX (GET_MODE (op))")))
+
+(define_predicate "aarch64_simd_or_scalar_imm_zero"
+  (and (match_code "const_int,const_double,const,const_vector")
+       (match_test "op == CONST0_RTX (GET_MODE (op))")))
+
+(define_predicate "aarch64_simd_imm_minus_one"
+  (and (match_code "const,const_vector")
+       (match_test "op == CONSTM1_RTX (GET_MODE (op))")))
+
 (define_predicate "aarch64_simd_reg_or_zero"
-  (and (match_code "reg,subreg,const_int,const_double,const_vector")
+  (and (match_code "reg,subreg,const_int,const_double,const,const_vector")
        (ior (match_operand 0 "register_operand")
-           (ior (match_test "op == const0_rtx")
-                (match_test "aarch64_simd_imm_zero_p (op, mode)")))))
+	    (match_test "op == const0_rtx")
+	    (match_operand 0 "aarch64_simd_or_scalar_imm_zero"))))
 
 (define_predicate "aarch64_simd_struct_operand"
   (and (match_code "mem")
@@ -358,18 +450,6 @@
 		    || GET_CODE (XEXP (op, 0)) == POST_INC
 		    || GET_CODE (XEXP (op, 0)) == REG")))
 
-(define_special_predicate "aarch64_simd_imm_zero"
-  (match_code "const_vector")
-{
-  return aarch64_simd_imm_zero_p (op, mode);
-})
-
-(define_special_predicate "aarch64_simd_imm_minus_one"
-  (match_code "const_vector")
-{
-  return aarch64_const_vec_all_same_int_p (op, -1);
-})
-
 ;; Predicates used by the various SIMD shift operations.  These
 ;; fall in to 3 categories.
 ;;   Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm)
@@ -426,3 +506,156 @@
 (define_predicate "aarch64_constant_pool_symref"
    (and (match_code "symbol_ref")
 	(match_test "CONSTANT_POOL_ADDRESS_P (op)")))
+
+(define_predicate "aarch64_constant_vector_operand"
+  (match_code "const,const_vector"))
+
+(define_predicate "aarch64_sve_ld1r_operand"
+  (and (match_operand 0 "memory_operand")
+       (match_test "aarch64_sve_ld1r_operand_p (op)")))
+
+;; Like memory_operand, but restricted to addresses that are valid for
+;; SVE LDR and STR instructions.
+(define_predicate "aarch64_sve_ldr_operand"
+  (and (match_code "mem")
+       (match_test "aarch64_sve_ldr_operand_p (op)")))
+
+(define_predicate "aarch64_sve_nonimmediate_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_ldr_operand")))
+
+(define_predicate "aarch64_sve_general_operand"
+  (and (match_code "reg,subreg,mem,const,const_vector")
+       (ior (match_operand 0 "register_operand")
+	    (match_operand 0 "aarch64_sve_ldr_operand")
+	    (match_test "aarch64_mov_operand_p (op, mode)"))))
+
+(define_predicate "aarch64_sve_struct_memory_operand"
+  (and (match_code "mem")
+       (match_test "aarch64_sve_struct_memory_operand_p (op)")))
+
+(define_predicate "aarch64_sve_struct_nonimmediate_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_struct_memory_operand")))
+
+;; Doesn't include immediates, since those are handled by the move
+;; patterns instead.
+(define_predicate "aarch64_sve_dup_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_ld1r_operand")))
+
+(define_predicate "aarch64_sve_arith_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_arith_immediate_p (op, false)")))
+
+(define_predicate "aarch64_sve_sub_arith_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_arith_immediate_p (op, true)")))
+
+(define_predicate "aarch64_sve_inc_dec_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_inc_dec_immediate_p (op)")))
+
+(define_predicate "aarch64_sve_logical_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_bitmask_immediate_p (op)")))
+
+(define_predicate "aarch64_sve_mul_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_const_vec_all_same_in_range_p (op, -128, 127)")))
+
+(define_predicate "aarch64_sve_dup_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_dup_immediate_p (op)")))
+
+(define_predicate "aarch64_sve_cmp_vsc_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_cmp_immediate_p (op, true)")))
+
+(define_predicate "aarch64_sve_cmp_vsd_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_cmp_immediate_p (op, false)")))
+
+(define_predicate "aarch64_sve_index_immediate"
+  (and (match_code "const_int")
+       (match_test "aarch64_sve_index_immediate_p (op)")))
+
+(define_predicate "aarch64_sve_float_arith_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_float_arith_immediate_p (op, false)")))
+
+(define_predicate "aarch64_sve_float_arith_with_sub_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_float_arith_immediate_p (op, true)")))
+
+(define_predicate "aarch64_sve_float_mul_immediate"
+  (and (match_code "const,const_vector")
+       (match_test "aarch64_sve_float_mul_immediate_p (op)")))
+
+(define_predicate "aarch64_sve_arith_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_arith_immediate")))
+
+(define_predicate "aarch64_sve_add_operand"
+  (ior (match_operand 0 "aarch64_sve_arith_operand")
+       (match_operand 0 "aarch64_sve_sub_arith_immediate")
+       (match_operand 0 "aarch64_sve_inc_dec_immediate")))
+
+(define_predicate "aarch64_sve_logical_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_logical_immediate")))
+
+(define_predicate "aarch64_sve_lshift_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_simd_lshift_imm")))
+
+(define_predicate "aarch64_sve_rshift_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_simd_rshift_imm")))
+
+(define_predicate "aarch64_sve_mul_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_mul_immediate")))
+
+(define_predicate "aarch64_sve_cmp_vsc_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_cmp_vsc_immediate")))
+
+(define_predicate "aarch64_sve_cmp_vsd_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_cmp_vsd_immediate")))
+
+(define_predicate "aarch64_sve_index_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_index_immediate")))
+
+(define_predicate "aarch64_sve_float_arith_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_float_arith_immediate")))
+
+(define_predicate "aarch64_sve_float_arith_with_sub_operand"
+  (ior (match_operand 0 "aarch64_sve_float_arith_operand")
+       (match_operand 0 "aarch64_sve_float_arith_with_sub_immediate")))
+
+(define_predicate "aarch64_sve_float_mul_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_sve_float_mul_immediate")))
+
+(define_predicate "aarch64_sve_vec_perm_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "aarch64_constant_vector_operand")))
+
+(define_predicate "aarch64_gather_scale_operand_w"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) == 1 || INTVAL (op) == 4")))
+
+(define_predicate "aarch64_gather_scale_operand_d"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) == 1 || INTVAL (op) == 8")))
+
+;; A special predicate that doesn't match a particular mode.
+(define_special_predicate "aarch64_any_register_operand"
+  (match_code "reg"))
+
+(define_predicate "aarch64_sve_any_binary_operator"
+  (match_code "plus,minus,mult,div,udiv,smax,umax,smin,umin,and,ior,xor"))