Mercurial > hg > CbC > CbC_gcc
diff gcc/config/arm/predicates.md @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/config/arm/predicates.md Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/config/arm/predicates.md Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ ;; Predicate definitions for ARM and Thumb -;; Copyright (C) 2004-2018 Free Software Foundation, Inc. +;; Copyright (C) 2004-2020 Free Software Foundation, Inc. ;; Contributed by ARM Ltd. ;; This file is part of GCC. @@ -31,6 +31,23 @@ || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); }) +; Predicate for stack protector guard's address in +; stack_protect_combined_set_insn and stack_protect_combined_test_insn patterns +(define_predicate "guard_addr_operand" + (match_test "true") +{ + return (CONSTANT_ADDRESS_P (op) + || !targetm.cannot_force_const_mem (mode, op)); +}) + +; Predicate for stack protector guard in stack_protect_combined_set and +; stack_protect_combined_test patterns +(define_predicate "guard_operand" + (match_code "mem") +{ + return guard_addr_operand (XEXP (op, 0), mode); +}) + (define_predicate "imm_for_neon_inv_logic_operand" (match_code "const_vector") { @@ -176,6 +193,14 @@ (and (match_code "const_int") (match_test "IN_RANGE (UINTVAL (op), 1, GET_MODE_BITSIZE (mode))"))) +(define_predicate "ssat16_imm" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 1, 16)"))) + +(define_predicate "usat16_imm" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 0, 15)"))) + (define_predicate "ldrd_strd_offset_operand" (and (match_operand 0 "const_int_operand") (match_test "TARGET_LDRD && offset_ok_for_ldrd_strd (INTVAL (op))"))) @@ -184,28 +209,26 @@ (ior (match_operand 0 "arm_rhs_operand") (match_operand 0 "arm_neg_immediate_operand"))) -(define_predicate "arm_anddi_operand_neon" +(define_predicate "arm_adddi_operand" (ior (match_operand 0 "s_register_operand") (and (match_code "const_int") - (match_test "const_ok_for_dimode_op (INTVAL (op), AND)")) - (match_operand 0 "neon_inv_logic_op2"))) + (match_test "const_ok_for_dimode_op (INTVAL (op), PLUS)")))) -(define_predicate "arm_iordi_operand_neon" +(define_predicate "arm_anddi_operand" (ior (match_operand 0 "s_register_operand") (and (match_code "const_int") - (match_test "const_ok_for_dimode_op (INTVAL (op), IOR)")) - (match_operand 0 "neon_logic_op2"))) + (match_test "const_ok_for_dimode_op (INTVAL (op), AND)")))) + +(define_predicate "arm_iordi_operand" + (ior (match_operand 0 "s_register_operand") + (and (match_code "const_int") + (match_test "const_ok_for_dimode_op (INTVAL (op), IOR)")))) (define_predicate "arm_xordi_operand" (ior (match_operand 0 "s_register_operand") (and (match_code "const_int") (match_test "const_ok_for_dimode_op (INTVAL (op), XOR)")))) -(define_predicate "arm_adddi_operand" - (ior (match_operand 0 "s_register_operand") - (and (match_code "const_int") - (match_test "const_ok_for_dimode_op (INTVAL (op), PLUS)")))) - (define_predicate "arm_addimm_operand" (ior (match_operand 0 "arm_immediate_operand") (match_operand 0 "arm_neg_immediate_operand"))) @@ -214,6 +237,12 @@ (ior (match_operand 0 "arm_rhs_operand") (match_operand 0 "arm_not_immediate_operand"))) +;; A constant that can be used with ADC(SBC) or SBC(ADC) when bit-wise +;; inverted. Similar to arm_not_operand, but excludes registers. +(define_predicate "arm_adcimm_operand" + (ior (match_operand 0 "arm_immediate_operand") + (match_operand 0 "arm_not_immediate_operand"))) + (define_predicate "arm_di_operand" (ior (match_operand 0 "s_register_operand") (match_operand 0 "arm_immediate_di_operand"))) @@ -307,6 +336,15 @@ && (UINTVAL (XEXP (op, 1)) < 32)"))) (match_test "mode == GET_MODE (op)"))) +;; True for Armv8.1-M Mainline long shift instructions. +(define_predicate "long_shift_imm" + (match_test "satisfies_constraint_Pg (op)")) + +(define_predicate "arm_reg_or_long_shift_imm" + (ior (match_test "TARGET_THUMB2 + && arm_general_register_operand (op, GET_MODE (op))") + (match_test "satisfies_constraint_Pg (op)"))) + ;; True for MULT, to identify which variant of shift_operator is in use. (define_special_predicate "mult_operator" (match_code "mult")) @@ -341,6 +379,48 @@ (define_special_predicate "lt_ge_comparison_operator" (match_code "lt,ge")) +(define_special_predicate "arm_carry_operation" + (match_code "geu,ltu") + { + if (XEXP (op, 1) != const0_rtx) + return false; + + rtx op0 = XEXP (op, 0); + + if (!REG_P (op0) || REGNO (op0) != CC_REGNUM) + return false; + + machine_mode ccmode = GET_MODE (op0); + if (ccmode == CC_Cmode) + return GET_CODE (op) == LTU; + else if (ccmode == CCmode || ccmode == CC_RSBmode || ccmode == CC_ADCmode) + return GET_CODE (op) == GEU; + + return false; + } +) + +;; Match a "borrow" operation for use with SBC. The precise code will +;; depend on the form of the comparison. This is generally the inverse of +;; a carry operation, since the logic of SBC uses "not borrow" in it's +;; calculation. +(define_special_predicate "arm_borrow_operation" + (match_code "geu,ltu") + { + if (XEXP (op, 1) != const0_rtx) + return false; + rtx op0 = XEXP (op, 0); + if (!REG_P (op0) || REGNO (op0) != CC_REGNUM) + return false; + machine_mode ccmode = GET_MODE (op0); + if (ccmode == CC_Cmode) + return GET_CODE (op) == GEU; + else if (ccmode == CCmode || ccmode == CC_RSBmode || ccmode == CC_ADCmode) + return GET_CODE (op) == LTU; + return false; + } +) + ;; The vsel instruction only accepts the ARM condition codes listed below. (define_special_predicate "arm_vsel_comparison_operator" (and (match_operand 0 "expandable_comparison_operator") @@ -359,7 +439,7 @@ (match_operand 0 "arm_vsel_comparison_operator")) (match_operand 0 "expandable_comparison_operator"))) -(define_special_predicate "noov_comparison_operator" +(define_special_predicate "nz_comparison_operator" (match_code "lt,ge,eq,ne")) (define_special_predicate "minmax_operator" @@ -456,6 +536,36 @@ (and (match_code "reg,subreg,mem") (match_operand 0 "nonimmediate_soft_df_operand")))) +;; Predicate for thumb2_movsf_vfp. Compared to general_operand, this +;; forbids constant loaded via literal pool iff literal pools are disabled. +(define_predicate "hard_sf_operand" + (and (match_operand 0 "general_operand") + (ior (not (match_code "const_double")) + (not (match_test "arm_disable_literal_pool")) + (match_test "satisfies_constraint_Dv (op)")))) + +;; Predicate for thumb2_movdf_vfp. Compared to soft_df_operand used in +;; movdf_soft_insn, this forbids constant loaded via literal pool iff +;; literal pools are disabled. +(define_predicate "hard_df_operand" + (and (match_operand 0 "soft_df_operand") + (ior (not (match_code "const_double")) + (not (match_test "arm_disable_literal_pool")) + (match_test "satisfies_constraint_Dy (op)") + (match_test "satisfies_constraint_G (op)")))) + +(define_special_predicate "clear_multiple_operation" + (match_code "parallel") +{ + return clear_operation_p (op, /*vfp*/false); +}) + +(define_special_predicate "clear_vfp_multiple_operation" + (match_code "parallel") +{ + return clear_operation_p (op, /*vfp*/true); +}) + (define_special_predicate "load_multiple_operation" (match_code "parallel") { @@ -658,3 +768,7 @@ (ior (and (match_code "symbol_ref") (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))")) (match_operand 0 "s_register_operand"))) + +(define_special_predicate "aligned_operand" + (ior (not (match_code "mem")) + (match_test "MEM_ALIGN (op) >= GET_MODE_ALIGNMENT (mode)")))