[AArch64] Improve description of <F>CM instructions in RTL
authorjgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 May 2013 10:33:57 +0000 (10:33 +0000)
committerjgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 May 2013 10:33:57 +0000 (10:33 +0000)
gcc/
* config/aarch64/aarch64-simd-builtins.def (cmhs): Rename to...
(cmgeu): ...This.
(cmhi): Rename to...
(cmgtu): ...This.
* config/aarch64/aarch64-simd.md
(simd_mode): Add SF.
(aarch64_vcond_internal): Use new names for unsigned comparison insns.
(aarch64_cm<optab><mode>): Rewrite to not use UNSPECs.
* config/aarch64/aarch64.md (*cstore<mode>_neg): Rename to...
(cstore<mode>_neg): ...This.
* config/aarch64/iterators.md
(VALLF): new.
(unspec): Remove UNSPEC_CM<EQ, LE, LT, GE, GT, HS, HI, TST>.
(COMPARISONS): New.
(UCOMPARISONS): Likewise.
(optab): Add missing comparisons.
(n_optab): New.
(cmp_1): Likewise.
(cmp_2): Likewise.
(CMP): Likewise.
(cmp): Remove.
(VCMP_S): Likewise.
(VCMP_U): Likewise.
(V_cmp_result): Add DF, SF modes.
(v_cmp_result): Likewise.
(v): Likewise.
(vmtype): Likewise.
* config/aarch64/predicates.md (aarch64_reg_or_fp_zero): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198490 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/aarch64/aarch64-simd-builtins.def
gcc/config/aarch64/aarch64-simd.md
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/iterators.md
gcc/config/aarch64/predicates.md

index aa78c38..6c26738 100644 (file)
@@ -1,3 +1,34 @@
+2013-05-01  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       * config/aarch64/aarch64-simd-builtins.def (cmhs): Rename to...
+       (cmgeu): ...This.
+       (cmhi): Rename to...
+       (cmgtu): ...This.
+       * config/aarch64/aarch64-simd.md
+       (simd_mode): Add SF.
+       (aarch64_vcond_internal): Use new names for unsigned comparison insns.
+       (aarch64_cm<optab><mode>): Rewrite to not use UNSPECs.
+       * config/aarch64/aarch64.md (*cstore<mode>_neg): Rename to...
+       (cstore<mode>_neg): ...This.
+       * config/aarch64/iterators.md
+       (VALLF): new.
+       (unspec): Remove UNSPEC_CM<EQ, LE, LT, GE, GT, HS, HI, TST>.
+       (COMPARISONS): New.
+       (UCOMPARISONS): Likewise.
+       (optab): Add missing comparisons.
+       (n_optab): New.
+       (cmp_1): Likewise.
+       (cmp_2): Likewise.
+       (CMP): Likewise.
+       (cmp): Remove.
+       (VCMP_S): Likewise.
+       (VCMP_U): Likewise.
+       (V_cmp_result): Add DF, SF modes.
+       (v_cmp_result): Likewise.
+       (v): Likewise.
+       (vmtype): Likewise.
+       * config/aarch64/predicates.md (aarch64_reg_or_fp_zero): New.
+
 2013-05-01  Greta Yorsh  <Greta.Yorsh@arm.com>
 
        * config/arm/thumb2.md (thumb2_smaxsi3,thumb2_sminsi3): Convert
index 6093341..2ae2881 100644 (file)
   BUILTIN_VSDQ_I_DI (BINOP, cmle, 0)
   BUILTIN_VSDQ_I_DI (BINOP, cmlt, 0)
   /* Implemented by aarch64_cm<cmp><mode>.  */
-  BUILTIN_VSDQ_I_DI (BINOP, cmhs, 0)
-  BUILTIN_VSDQ_I_DI (BINOP, cmhi, 0)
+  BUILTIN_VSDQ_I_DI (BINOP, cmgeu, 0)
+  BUILTIN_VSDQ_I_DI (BINOP, cmgtu, 0)
   BUILTIN_VSDQ_I_DI (BINOP, cmtst, 0)
 
   /* Implemented by aarch64_<fmaxmin><mode>.  */
index 32ea587..3893444 100644 (file)
@@ -21,7 +21,7 @@
 
 ; Main data types used by the insntructions
 
-(define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,DI,DF,SI,HI,QI"
+(define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,DI,DF,SI,SF,HI,QI"
   (const_string "unknown"))
 
 
 
     case LTU:
     case GEU:
-      emit_insn (gen_aarch64_cmhs<mode> (mask, operands[4], operands[5]));
+      emit_insn (gen_aarch64_cmgeu<mode> (mask, operands[4], operands[5]));
       break;
 
     case LEU:
     case GTU:
-      emit_insn (gen_aarch64_cmhi<mode> (mask, operands[4], operands[5]));
+      emit_insn (gen_aarch64_cmgtu<mode> (mask, operands[4], operands[5]));
       break;
 
     case NE:
 )
 
 
-;; cm(eq|ge|le|lt|gt)
+;; cm(eq|ge|gt|lt|le)
+;; Note, we have constraints for Dz and Z as different expanders
+;; have different ideas of what should be passed to this pattern.
 
-(define_insn "aarch64_cm<cmp><mode>"
+(define_insn "aarch64_cm<optab><mode>"
   [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
-        (unspec:<V_cmp_result>
-         [(match_operand:VSDQ_I_DI 1 "register_operand" "w,w")
-          (match_operand:VSDQ_I_DI 2 "aarch64_simd_reg_or_zero" "w,Z")]
-          VCMP_S))]
+       (neg:<V_cmp_result>
+         (COMPARISONS:<V_cmp_result>
+           (match_operand:VDQ 1 "register_operand" "w,w")
+           (match_operand:VDQ 2 "aarch64_simd_reg_or_zero" "w,ZDz")
+         )))]
   "TARGET_SIMD"
   "@
-  cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>
-  cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #0"
+  cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
+  cm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #0"
   [(set_attr "simd_type" "simd_cmp")
    (set_attr "simd_mode" "<MODE>")]
 )
 
-;; cm(hs|hi|tst)
+(define_insn_and_split "aarch64_cm<optab>di"
+  [(set (match_operand:DI 0 "register_operand" "=w,w,r")
+       (neg:DI
+         (COMPARISONS:DI
+           (match_operand:DI 1 "register_operand" "w,w,r")
+           (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz,r")
+         )))]
+  "TARGET_SIMD"
+  "@
+  cm<n_optab>\t%d0, %d<cmp_1>, %d<cmp_2>
+  cm<optab>\t%d0, %d1, #0
+  #"
+  "reload_completed
+   /* We need to prevent the split from
+      happening in the 'w' constraint cases.  */
+   && GP_REGNUM_P (REGNO (operands[0]))
+   && GP_REGNUM_P (REGNO (operands[1]))"
+  [(set (reg:CC CC_REGNUM)
+    (compare:CC
+      (match_dup 1)
+      (match_dup 2)))
+  (set (match_dup 0)
+    (neg:DI
+      (COMPARISONS:DI
+       (match_operand 3 "cc_register" "")
+       (const_int 0))))]
+  {
+    enum machine_mode mode = SELECT_CC_MODE (<CMP>, operands[1], operands[2]);
+    rtx cc_reg = aarch64_gen_compare_reg (<CMP>, operands[1], operands[2]);
+    rtx comparison = gen_rtx_<CMP> (mode, operands[1], operands[2]);
+    emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
+    DONE;
+  }
+  [(set_attr "simd_type" "simd_cmp")
+   (set_attr "simd_mode" "DI")]
+)
 
-(define_insn "aarch64_cm<cmp><mode>"
+;; cm(hs|hi)
+
+(define_insn "aarch64_cm<optab><mode>"
   [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
-        (unspec:<V_cmp_result>
-         [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
-          (match_operand:VSDQ_I_DI 2 "register_operand" "w")]
-          VCMP_U))]
+       (neg:<V_cmp_result>
+         (UCOMPARISONS:<V_cmp_result>
+           (match_operand:VDQ 1 "register_operand" "w")
+           (match_operand:VDQ 2 "register_operand" "w")
+         )))]
   "TARGET_SIMD"
-  "cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
+  "cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
+  [(set_attr "simd_type" "simd_cmp")
+   (set_attr "simd_mode" "<MODE>")]
+)
+
+(define_insn_and_split "aarch64_cm<optab>di"
+  [(set (match_operand:DI 0 "register_operand" "=w,r")
+       (neg:DI
+         (UCOMPARISONS:DI
+           (match_operand:DI 1 "register_operand" "w,r")
+           (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,r")
+         )))]
+  "TARGET_SIMD"
+  "@
+  cm<n_optab>\t%d0, %d<cmp_1>, %d<cmp_2>
+  #"
+  "reload_completed
+   /* We need to prevent the split from
+      happening in the 'w' constraint cases.  */
+   && GP_REGNUM_P (REGNO (operands[0]))
+   && GP_REGNUM_P (REGNO (operands[1]))"
+  [(set (reg:CC CC_REGNUM)
+    (compare:CC
+      (match_dup 1)
+      (match_dup 2)))
+  (set (match_dup 0)
+    (neg:DI
+      (UCOMPARISONS:DI
+       (match_operand 3 "cc_register" "")
+       (const_int 0))))]
+  {
+    enum machine_mode mode = SELECT_CC_MODE (<CMP>, operands[1], operands[2]);
+    rtx cc_reg = aarch64_gen_compare_reg (<CMP>, operands[1], operands[2]);
+    rtx comparison = gen_rtx_<CMP> (mode, operands[1], operands[2]);
+    emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
+    DONE;
+  }
+  [(set_attr "simd_type" "simd_cmp")
+   (set_attr "simd_mode" "DI")]
+)
+
+;; cmtst
+
+(define_insn "aarch64_cmtst<mode>"
+  [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
+       (neg:<V_cmp_result>
+         (ne:<V_cmp_result>
+           (and:VDQ
+             (match_operand:VDQ 1 "register_operand" "w")
+             (match_operand:VDQ 2 "register_operand" "w"))
+           (vec_duplicate:<V_cmp_result> (const_int 0)))))]
+  "TARGET_SIMD"
+  "cmtst\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
   [(set_attr "simd_type" "simd_cmp")
    (set_attr "simd_mode" "<MODE>")]
 )
 
-;; fcm(eq|ge|le|lt|gt)
+(define_insn_and_split "aarch64_cmtstdi"
+  [(set (match_operand:DI 0 "register_operand" "=w,r")
+       (neg:DI
+         (ne:DI
+           (and:DI
+             (match_operand:DI 1 "register_operand" "w,r")
+             (match_operand:DI 2 "register_operand" "w,r"))
+           (const_int 0))))]
+  "TARGET_SIMD"
+  "@
+  cmtst\t%d0, %d1, %d2
+  #"
+  "reload_completed
+   /* We need to prevent the split from
+      happening in the 'w' constraint cases.  */
+   && GP_REGNUM_P (REGNO (operands[0]))
+   && GP_REGNUM_P (REGNO (operands[1]))"
+   [(set (reg:CC_NZ CC_REGNUM)
+       (compare:CC_NZ
+        (and:DI (match_dup 1)
+                 (match_dup 2))
+        (const_int 0)))
+  (set (match_dup 0)
+    (neg:DI
+      (ne:DI
+       (match_operand 3 "cc_register" "")
+       (const_int 0))))]
+  {
+    rtx and_tree = gen_rtx_AND (DImode, operands[1], operands[2]);
+    enum machine_mode mode = SELECT_CC_MODE (NE, and_tree, const0_rtx);
+    rtx cc_reg = aarch64_gen_compare_reg (NE, and_tree, const0_rtx);
+    rtx comparison = gen_rtx_NE (mode, and_tree, const0_rtx);
+    emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
+    DONE;
+  }
+  [(set_attr "simd_type" "simd_cmp")
+   (set_attr "simd_mode" "DI")]
+)
 
-(define_insn "aarch64_cm<cmp><mode>"
+;; fcm(eq|ge|gt|le|lt)
+
+(define_insn "aarch64_cm<optab><mode>"
   [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
-       (unspec:<V_cmp_result>
-         [(match_operand:VDQF 1 "register_operand" "w,w")
-          (match_operand:VDQF 2 "aarch64_simd_reg_or_zero" "w,Dz")]
-          VCMP_S))]
+       (neg:<V_cmp_result>
+         (COMPARISONS:<V_cmp_result>
+           (match_operand:VALLF 1 "register_operand" "w,w")
+           (match_operand:VALLF 2 "aarch64_simd_reg_or_zero" "w,YDz")
+         )))]
   "TARGET_SIMD"
   "@
-  fcm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>
-  fcm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
+  fcm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
+  fcm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
   [(set_attr "simd_type" "simd_fcmp")
    (set_attr "simd_mode" "<MODE>")]
 )
index 87e68fa..96be7a1 100644 (file)
    (set_attr "mode" "SI")]
 )
 
-(define_insn "*cstore<mode>_neg"
+(define_insn "cstore<mode>_neg"
   [(set (match_operand:ALLI 0 "register_operand" "=r")
        (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
index d774c4c..0b9f9e8 100644 (file)
@@ -83,6 +83,9 @@
 ;; Vector Float modes.
 (define_mode_iterator VDQF [V2SF V4SF V2DF])
 
+;; All Float modes.
+(define_mode_iterator VALLF [V2SF V4SF V2DF SF DF])
+
 ;; Vector Float modes with 2 elements.
 (define_mode_iterator V2F [V2SF V2DF])
 
     UNSPEC_URSHL       ; Used in aarch64-simd.md.
     UNSPEC_SQRSHL      ; Used in aarch64-simd.md.
     UNSPEC_UQRSHL      ; Used in aarch64-simd.md.
-    UNSPEC_CMEQ                ; Used in aarch64-simd.md.
-    UNSPEC_CMLE                ; Used in aarch64-simd.md.
-    UNSPEC_CMLT                ; Used in aarch64-simd.md.
-    UNSPEC_CMGE                ; Used in aarch64-simd.md.
-    UNSPEC_CMGT                ; Used in aarch64-simd.md.
-    UNSPEC_CMHS                ; Used in aarch64-simd.md.
-    UNSPEC_CMHI                ; Used in aarch64-simd.md.
     UNSPEC_SSLI                ; Used in aarch64-simd.md.
     UNSPEC_USLI                ; Used in aarch64-simd.md.
     UNSPEC_SSRI                ; Used in aarch64-simd.md.
     UNSPEC_SSHLL       ; Used in aarch64-simd.md.
     UNSPEC_USHLL       ; Used in aarch64-simd.md.
     UNSPEC_ADDP                ; Used in aarch64-simd.md.
-    UNSPEC_CMTST       ; Used in aarch64-simd.md.
     UNSPEC_FMAX                ; Used in aarch64-simd.md.
     UNSPEC_FMIN                ; Used in aarch64-simd.md.
     UNSPEC_TBL         ; Used in vector permute patterns.
 
 ;; For scalar usage of vector/FP registers
 (define_mode_attr v [(QI "b") (HI "h") (SI "s") (DI "d")
+                   (SF "s") (DF "d")
                    (V8QI "") (V16QI "")
                    (V4HI "") (V8HI "")
                    (V2SI "") (V4SI  "")
                         (V4SF ".4s") (V2DF ".2d")
                         (DI   "")    (SI   "")
                         (HI   "")    (QI   "")
-                        (TI   "")])
+                        (TI   "")    (SF   "")
+                        (DF   "")])
 
 ;; Register suffix narrowed modes for VQN.
 (define_mode_attr Vmntype [(V8HI ".8b") (V4SI ".4h")
                                (V2SI "V2SI") (V4SI  "V4SI")
                                (DI   "DI")   (V2DI  "V2DI")
                                (V2SF "V2SI") (V4SF  "V4SI")
-                               (V2DF "V2DI")])
+                               (V2DF "V2DI") (DF    "DI")
+                               (SF   "SI")])
 
 ;; Lower case mode of results of comparison operations.
 (define_mode_attr v_cmp_result [(V8QI "v8qi") (V16QI "v16qi")
                                (V2SI "v2si") (V4SI  "v4si")
                                (DI   "di")   (V2DI  "v2di")
                                (V2SF "v2si") (V4SF  "v4si")
-                               (V2DF "v2di")])
+                               (V2DF "v2di") (DF    "di")
+                               (SF   "si")])
 
 ;; Vm for lane instructions is restricted to FP_LO_REGS.
 (define_mode_attr vwx [(V4HI "x") (V8HI "x") (HI "x")
 ;; Code iterator for signed variants of vector saturating binary ops.
 (define_code_iterator SBINQOPS [ss_plus ss_minus])
 
+;; Comparison operators for <F>CM.
+(define_code_iterator COMPARISONS [lt le eq ge gt])
+
+;; Unsigned comparison operators.
+(define_code_iterator UCOMPARISONS [ltu leu geu gtu])
+
 ;; -------------------------------------------------------------------
 ;; Code Attributes
 ;; -------------------------------------------------------------------
                         (eq "eq")
                         (ne "ne")
                         (lt "lt")
-                        (ge "ge")])
+                        (ge "ge")
+                        (le "le")
+                        (gt "gt")
+                        (ltu "ltu")
+                        (leu "leu")
+                        (geu "geu")
+                        (gtu "gtu")])
+
+;; For comparison operators we use the FCM* and CM* instructions.
+;; As there are no CMLE or CMLT instructions which act on 3 vector
+;; operands, we must use CMGE or CMGT and swap the order of the
+;; source operands.
+
+(define_code_attr n_optab [(lt "gt") (le "ge") (eq "eq") (ge "ge") (gt "gt")
+                          (ltu "hi") (leu "hs") (geu "hs") (gtu "hi")])
+(define_code_attr cmp_1   [(lt "2") (le "2") (eq "1") (ge "1") (gt "1")
+                          (ltu "2") (leu "2") (geu "1") (gtu "1")])
+(define_code_attr cmp_2   [(lt "1") (le "1") (eq "2") (ge "2") (gt "2")
+                          (ltu "1") (leu "1") (geu "2") (gtu "2")])
+
+(define_code_attr CMP [(lt "LT") (le "LE") (eq "EQ") (ge "GE") (gt "GT")
+                          (ltu "LTU") (leu "LEU") (geu "GEU") (gtu "GTU")])
 
 (define_code_attr fix_trunc_optab [(fix "fix_trunc")
                                   (unsigned_fix "fixuns_trunc")])
                                UNSPEC_SQSHRN UNSPEC_UQSHRN
                                UNSPEC_SQRSHRN UNSPEC_UQRSHRN])
 
-(define_int_iterator VCMP_S [UNSPEC_CMEQ UNSPEC_CMGE UNSPEC_CMGT
-                            UNSPEC_CMLE UNSPEC_CMLT])
-
-(define_int_iterator VCMP_U [UNSPEC_CMHS UNSPEC_CMHI UNSPEC_CMTST])
-
 (define_int_iterator PERMUTE [UNSPEC_ZIP1 UNSPEC_ZIP2
                              UNSPEC_TRN1 UNSPEC_TRN2
                              UNSPEC_UZP1 UNSPEC_UZP2])
                         (UNSPEC_RADDHN2 "add")
                         (UNSPEC_RSUBHN2 "sub")])
 
-(define_int_attr cmp [(UNSPEC_CMGE "ge") (UNSPEC_CMGT "gt")
-                     (UNSPEC_CMLE "le") (UNSPEC_CMLT "lt")
-                      (UNSPEC_CMEQ "eq")
-                     (UNSPEC_CMHS "hs") (UNSPEC_CMHI "hi")
-                     (UNSPEC_CMTST "tst")])
-
 (define_int_attr offsetlr [(UNSPEC_SSLI        "1") (UNSPEC_USLI "1")
                           (UNSPEC_SSRI "0") (UNSPEC_USRI "0")])
 
index 8f80b20..8514e8f 100644 (file)
        (ior (match_operand 0 "register_operand")
            (match_test "op == const0_rtx"))))
 
+(define_predicate "aarch64_reg_or_fp_zero"
+  (and (match_code "reg,subreg,const_double")
+       (ior (match_operand 0 "register_operand")
+           (match_test "aarch64_float_const_zero_rtx_p (op)"))))
+
 (define_predicate "aarch64_reg_zero_or_m1_or_1"
   (and (match_code "reg,subreg,const_int")
        (ior (match_operand 0 "register_operand")