From: jgreenhalgh Date: Wed, 1 May 2013 10:33:57 +0000 (+0000) Subject: [AArch64] Improve description of CM instructions in RTL X-Git-Tag: upstream/4.9.2~6293 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6ba1316bfa533059bb392db2ecfbaede1605b169;p=platform%2Fupstream%2Flinaro-gcc.git [AArch64] Improve description of CM instructions in RTL 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): Rewrite to not use UNSPECs. * config/aarch64/aarch64.md (*cstore_neg): Rename to... (cstore_neg): ...This. * config/aarch64/iterators.md (VALLF): new. (unspec): Remove UNSPEC_CM. (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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aa78c38..6c26738 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2013-05-01 James Greenhalgh + + * 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): Rewrite to not use UNSPECs. + * config/aarch64/aarch64.md (*cstore_neg): Rename to... + (cstore_neg): ...This. + * config/aarch64/iterators.md + (VALLF): new. + (unspec): Remove UNSPEC_CM. + (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 * config/arm/thumb2.md (thumb2_smaxsi3,thumb2_sminsi3): Convert diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index 6093341..2ae2881 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -230,8 +230,8 @@ BUILTIN_VSDQ_I_DI (BINOP, cmle, 0) BUILTIN_VSDQ_I_DI (BINOP, cmlt, 0) /* Implemented by aarch64_cm. */ - 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_. */ diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 32ea587..3893444 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -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")) @@ -1728,12 +1728,12 @@ case LTU: case GEU: - emit_insn (gen_aarch64_cmhs (mask, operands[4], operands[5])); + emit_insn (gen_aarch64_cmgeu (mask, operands[4], operands[5])); break; case LEU: case GTU: - emit_insn (gen_aarch64_cmhi (mask, operands[4], operands[5])); + emit_insn (gen_aarch64_cmgtu (mask, operands[4], operands[5])); break; case NE: @@ -3170,48 +3170,181 @@ ) -;; 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" +(define_insn "aarch64_cm" [(set (match_operand: 0 "register_operand" "=w,w") - (unspec: - [(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: + (COMPARISONS: + (match_operand:VDQ 1 "register_operand" "w,w") + (match_operand:VDQ 2 "aarch64_simd_reg_or_zero" "w,ZDz") + )))] "TARGET_SIMD" "@ - cm\t%0, %1, %2 - cm\t%0, %1, #0" + cm\t%0, %, % + cm\t%0, %1, #0" [(set_attr "simd_type" "simd_cmp") (set_attr "simd_mode" "")] ) -;; cm(hs|hi|tst) +(define_insn_and_split "aarch64_cmdi" + [(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\t%d0, %d, %d + cm\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 (, operands[1], operands[2]); + rtx cc_reg = aarch64_gen_compare_reg (, operands[1], operands[2]); + rtx comparison = gen_rtx_ (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" +;; cm(hs|hi) + +(define_insn "aarch64_cm" [(set (match_operand: 0 "register_operand" "=w") - (unspec: - [(match_operand:VSDQ_I_DI 1 "register_operand" "w") - (match_operand:VSDQ_I_DI 2 "register_operand" "w")] - VCMP_U))] + (neg: + (UCOMPARISONS: + (match_operand:VDQ 1 "register_operand" "w") + (match_operand:VDQ 2 "register_operand" "w") + )))] "TARGET_SIMD" - "cm\t%0, %1, %2" + "cm\t%0, %, %" + [(set_attr "simd_type" "simd_cmp") + (set_attr "simd_mode" "")] +) + +(define_insn_and_split "aarch64_cmdi" + [(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\t%d0, %d, %d + #" + "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 (, operands[1], operands[2]); + rtx cc_reg = aarch64_gen_compare_reg (, operands[1], operands[2]); + rtx comparison = gen_rtx_ (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" + [(set (match_operand: 0 "register_operand" "=w") + (neg: + (ne: + (and:VDQ + (match_operand:VDQ 1 "register_operand" "w") + (match_operand:VDQ 2 "register_operand" "w")) + (vec_duplicate: (const_int 0)))))] + "TARGET_SIMD" + "cmtst\t%0, %1, %2" [(set_attr "simd_type" "simd_cmp") (set_attr "simd_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" +;; fcm(eq|ge|gt|le|lt) + +(define_insn "aarch64_cm" [(set (match_operand: 0 "register_operand" "=w,w") - (unspec: - [(match_operand:VDQF 1 "register_operand" "w,w") - (match_operand:VDQF 2 "aarch64_simd_reg_or_zero" "w,Dz")] - VCMP_S))] + (neg: + (COMPARISONS: + (match_operand:VALLF 1 "register_operand" "w,w") + (match_operand:VALLF 2 "aarch64_simd_reg_or_zero" "w,YDz") + )))] "TARGET_SIMD" "@ - fcm\t%0, %1, %2 - fcm\t%0, %1, 0" + fcm\t%0, %, % + fcm\t%0, %1, 0" [(set_attr "simd_type" "simd_fcmp") (set_attr "simd_mode" "")] ) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 87e68fa..96be7a1 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2409,7 +2409,7 @@ (set_attr "mode" "SI")] ) -(define_insn "*cstore_neg" +(define_insn "cstore_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)])))] diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index d774c4c..0b9f9e8 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -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]) @@ -213,13 +216,6 @@ 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. @@ -227,7 +223,6 @@ 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. @@ -253,6 +248,7 @@ ;; 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 "") @@ -307,7 +303,8 @@ (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") @@ -446,7 +443,8 @@ (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") @@ -454,7 +452,8 @@ (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") @@ -548,6 +547,12 @@ ;; Code iterator for signed variants of vector saturating binary ops. (define_code_iterator SBINQOPS [ss_plus ss_minus]) +;; Comparison operators for CM. +(define_code_iterator COMPARISONS [lt le eq ge gt]) + +;; Unsigned comparison operators. +(define_code_iterator UCOMPARISONS [ltu leu geu gtu]) + ;; ------------------------------------------------------------------- ;; Code Attributes ;; ------------------------------------------------------------------- @@ -580,7 +585,28 @@ (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")]) @@ -693,11 +719,6 @@ 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]) @@ -784,12 +805,6 @@ (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")]) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 8f80b20..8514e8f 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -31,6 +31,11 @@ (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")