aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arm
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arm')
-rw-r--r--gcc/config/arm/arm.cc19
-rw-r--r--gcc/config/arm/iterators.md17
-rw-r--r--gcc/config/arm/mve.md36
-rw-r--r--gcc/config/arm/unspecs.md16
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