diff options
Diffstat (limited to 'gcc/config/arm')
-rw-r--r-- | gcc/config/arm/arm.cc | 19 | ||||
-rw-r--r-- | gcc/config/arm/iterators.md | 17 | ||||
-rw-r--r-- | gcc/config/arm/mve.md | 36 | ||||
-rw-r--r-- | gcc/config/arm/unspecs.md | 16 |
4 files changed, 76 insertions, 12 deletions
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index da28d96..6df2fa0 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -5696,6 +5696,22 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, maxval = (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (mode) - 1)) - 1; + /* For floating-point comparisons, prefer >= and > over <= and < since + the former are supported by VSEL on some architectures. Only do this + if both operands are registers. */ + if (GET_MODE_CLASS (mode) == MODE_FLOAT + && (*code == LE + || *code == LT + || *code == UNGT + || *code == UNGE) + && register_operand (*op0, mode) + && register_operand (*op1, mode)) + { + std::swap (*op0, *op1); + *code = (int) swap_condition ((rtx_code)*code); + return; + } + /* For DImode, we have GE/LT/GEU/LTU comparisons (with cmp/sbc). In ARM mode we can also use cmp/cmpeq for GTU/LEU. GT/LE must be either reversed or (for constant OP1) adjusted to GE/LT. @@ -32478,6 +32494,9 @@ arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2) case E_HFmode: if (!TARGET_VFP_FP16INST) break; + if (!arm_vsel_comparison_operator (*comparison, mode)) + return false; + /* FP16 comparisons are done in SF mode. */ mode = SFmode; *op1 = convert_to_mode (mode, *op1, 1); diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 0c163ed..eb519e7 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -3014,3 +3014,20 @@ ;; Define iterators for VCMLA operations as MUL (define_int_iterator VCMUL_OP [UNSPEC_VCMUL UNSPEC_VCMUL_CONJ]) + +(define_int_attr VxCIQ_carry [(VADCIQ_U "VADCIQ_U_carry") + (VADCIQ_S "VADCIQ_S_carry") + (VSBCIQ_U "VSBCIQ_U_carry") + (VSBCIQ_S "VSBCIQ_S_carry")]) +(define_int_attr VxCIQ_M_carry [(VADCIQ_M_U "VADCIQ_M_U_carry") + (VADCIQ_M_S "VADCIQ_M_S_carry") + (VSBCIQ_M_U "VSBCIQ_M_U_carry") + (VSBCIQ_M_S "VSBCIQ_M_S_carry")]) +(define_int_attr VxCQ_carry [(VADCQ_U "VADCQ_U_carry") + (VADCQ_S "VADCQ_S_carry") + (VSBCQ_U "VSBCQ_U_carry") + (VSBCQ_S "VSBCQ_S_carry")]) +(define_int_attr VxCQ_M_carry [(VADCQ_M_U "VADCQ_M_U_carry") + (VADCQ_M_S "VADCQ_M_S_carry") + (VSBCQ_M_U "VSBCQ_M_U_carry") + (VSBCQ_M_S "VSBCQ_M_S_carry")]) diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index bd3db24..87b45b2 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -3965,14 +3965,14 @@ (define_insn "get_fpscr_nzcvqc" [(set (match_operand:SI 0 "register_operand" "=r") - (unspec_volatile:SI [(reg:SI VFPCC_REGNUM)] UNSPEC_GET_FPSCR_NZCVQC))] + (unspec:SI [(reg:SI VFPCC_REGNUM)] UNSPEC_GET_FPSCR_NZCVQC))] "TARGET_HAVE_MVE" "vmrs\\t%0, FPSCR_nzcvqc" [(set_attr "type" "mve_move")]) (define_insn "set_fpscr_nzcvqc" [(set (reg:SI VFPCC_REGNUM) - (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] + (unspec:SI [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FPSCR_NZCVQC))] "TARGET_HAVE_MVE" "vmsr\\tFPSCR_nzcvqc, %0" @@ -3988,8 +3988,9 @@ (match_operand:V4SI 2 "s_register_operand" "w")] VxCIQ)) (set (reg:SI VFPCC_REGNUM) - (unspec:SI [(const_int 0)] - VxCIQ)) + (unspec:SI [(match_dup 1) + (match_dup 2)] + <VxCIQ_carry>)) ] "TARGET_HAVE_MVE" "<mve_insn>.i32\t%q0, %q1, %q2" @@ -4009,8 +4010,11 @@ (match_operand:V4BI 4 "vpr_register_operand" "Up")] VxCIQ_M)) (set (reg:SI VFPCC_REGNUM) - (unspec:SI [(const_int 0)] - VxCIQ_M)) + (unspec:SI [(match_dup 1) + (match_dup 2) + (match_dup 3) + (match_dup 4)] + <VxCIQ_M_carry>)) ] "TARGET_HAVE_MVE" "vpst\;<mve_insn>t.i32\t%q0, %q2, %q3" @@ -4025,11 +4029,14 @@ (define_insn "@mve_<mve_insn>q_<supf>v4si" [(set (match_operand:V4SI 0 "s_register_operand" "=w") (unspec:V4SI [(match_operand:V4SI 1 "s_register_operand" "w") - (match_operand:V4SI 2 "s_register_operand" "w")] + (match_operand:V4SI 2 "s_register_operand" "w") + (reg:SI VFPCC_REGNUM)] VxCQ)) (set (reg:SI VFPCC_REGNUM) - (unspec:SI [(reg:SI VFPCC_REGNUM)] - VxCQ)) + (unspec:SI [(match_dup 1) + (match_dup 2) + (reg:SI VFPCC_REGNUM)] + <VxCQ_carry>)) ] "TARGET_HAVE_MVE" "<mve_insn>.i32\t%q0, %q1, %q2" @@ -4047,11 +4054,16 @@ (unspec:V4SI [(match_operand:V4SI 1 "s_register_operand" "0") (match_operand:V4SI 2 "s_register_operand" "w") (match_operand:V4SI 3 "s_register_operand" "w") - (match_operand:V4BI 4 "vpr_register_operand" "Up")] + (match_operand:V4BI 4 "vpr_register_operand" "Up") + (reg:SI VFPCC_REGNUM)] VxCQ_M)) (set (reg:SI VFPCC_REGNUM) - (unspec:SI [(reg:SI VFPCC_REGNUM)] - VxCQ_M)) + (unspec:SI [(match_dup 1) + (match_dup 2) + (match_dup 3) + (match_dup 4) + (reg:SI VFPCC_REGNUM)] + <VxCQ_M_carry>)) ] "TARGET_HAVE_MVE" "vpst\;<mve_insn>t.i32\t%q0, %q2, %q3" diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index c1ee972..17af152 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -1160,21 +1160,37 @@ VLDRGBWBQ VLDRGBWBQ_Z VADCQ_U + VADCQ_U_carry VADCQ_M_U + VADCQ_M_U_carry VADCQ_S + VADCQ_S_carry VADCQ_M_S + VADCQ_M_S_carry VSBCIQ_U + VSBCIQ_U_carry VSBCIQ_S + VSBCIQ_S_carry VSBCIQ_M_U + VSBCIQ_M_U_carry VSBCIQ_M_S + VSBCIQ_M_S_carry VSBCQ_U + VSBCQ_U_carry VSBCQ_S + VSBCQ_S_carry VSBCQ_M_U + VSBCQ_M_U_carry VSBCQ_M_S + VSBCQ_M_S_carry VADCIQ_U + VADCIQ_U_carry VADCIQ_M_U + VADCIQ_M_U_carry VADCIQ_S + VADCIQ_S_carry VADCIQ_M_S + VADCIQ_M_S_carry VLD2Q VLD4Q VST2Q |