aarch64-protos.h (aarch64_ccmp_mode_to_code): New.
authorZhenqiang Chen <zhenqiang.chen@linaro.org>
Mon, 17 Nov 2014 06:19:08 +0000 (06:19 +0000)
committerZhenqiang Chen <zqchen@gcc.gnu.org>
Mon, 17 Nov 2014 06:19:08 +0000 (06:19 +0000)
2014-11-17  Zhenqiang Chen  <zhenqiang.chen@linaro.org>

* config/aarch64/aarch64-protos.h (aarch64_ccmp_mode_to_code): New.
* aarch64.c (aarch64_nzcv_codes): New data.
(aarch64_ccmp_mode_to_code): New.
(aarch64_print_operand): Output nzcv.
config/aarch64/aarch64.md (cbranchcc4, *ccmp_and, *ccmp_ior, cstorecc4):
New patterns.
(cstore<mode>4): Handle ccmp_cc_register.
* config/aarch64/predicates.md (const0_operand): New.

From-SVN: r217644

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/predicates.md

index c7f353e8b9d3597d1184472c4115d1c537ad2708..6af355b2e7620e60a3fb7381b2e236c40394ae5e 100644 (file)
@@ -1,3 +1,14 @@
+2014-11-17  Zhenqiang Chen  <zhenqiang.chen@linaro.org>
+
+       * config/aarch64/aarch64-protos.h (aarch64_ccmp_mode_to_code): New.
+       * aarch64.c (aarch64_nzcv_codes): New data.
+       (aarch64_ccmp_mode_to_code): New.
+       (aarch64_print_operand): Output nzcv.
+       config/aarch64/aarch64.md (cbranchcc4, *ccmp_and, *ccmp_ior, cstorecc4):
+       New patterns.
+       (cstore<mode>4): Handle ccmp_cc_register.
+       * config/aarch64/predicates.md (const0_operand): New.
+
 2014-11-17  Zhenqiang Chen  <zhenqiang.chen@linaro.org>
 
        * config/aarch64/aarch64-modes.def: Define ccmp CC mode.
index 470b9ebbec09fced64fd6544d0e796567a5e45bf..a9985b5ab76ec1823271adddea6805a9ad78490b 100644 (file)
@@ -314,4 +314,5 @@ extern void aarch64_final_prescan_insn (rtx_insn *);
 extern bool
 aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
 void aarch64_atomic_assign_expand_fenv (tree *, tree *, tree *);
+int aarch64_ccmp_mode_to_code (enum machine_mode mode);
 #endif /* GCC_AARCH64_PROTOS_H */
index 86549979773ecec29f6a49f795fde02cab464a98..b9383a4e110e07af94add8aaab4ae21c88a14a6a 100644 (file)
@@ -3829,6 +3829,75 @@ bit_count (unsigned HOST_WIDE_INT value)
   return count;
 }
 
+/* N Z C V.  */
+#define AARCH64_CC_V 1
+#define AARCH64_CC_C (1 << 1)
+#define AARCH64_CC_Z (1 << 2)
+#define AARCH64_CC_N (1 << 3)
+
+/* N Z C V flags for ccmp.  The first code is for AND op and the other
+   is for IOR op.  Indexed by AARCH64_COND_CODE.  */
+static const int aarch64_nzcv_codes[][2] =
+{
+  {AARCH64_CC_Z, 0}, /* EQ, Z == 1.  */
+  {0, AARCH64_CC_Z}, /* NE, Z == 0.  */
+  {AARCH64_CC_C, 0}, /* CS, C == 1.  */
+  {0, AARCH64_CC_C}, /* CC, C == 0.  */
+  {AARCH64_CC_N, 0}, /* MI, N == 1.  */
+  {0, AARCH64_CC_N}, /* PL, N == 0.  */
+  {AARCH64_CC_V, 0}, /* VS, V == 1.  */
+  {0, AARCH64_CC_V}, /* VC, V == 0.  */
+  {AARCH64_CC_C, 0}, /* HI, C ==1 && Z == 0.  */
+  {0, AARCH64_CC_C}, /* LS, !(C == 1 && Z == 0).  */
+  {0, AARCH64_CC_V}, /* GE, N == V.  */
+  {AARCH64_CC_V, 0}, /* LT, N != V.  */
+  {0, AARCH64_CC_Z}, /* GT, Z == 0 && N == V.  */
+  {AARCH64_CC_Z, 0}, /* LE, !(Z == 0 && N == V).  */
+  {0, 0}, /* AL, Any.  */
+  {0, 0}, /* NV, Any.  */
+};
+
+int
+aarch64_ccmp_mode_to_code (enum machine_mode mode)
+{
+  switch (mode)
+    {
+    case CC_DNEmode:
+      return NE;
+
+    case CC_DEQmode:
+      return EQ;
+
+    case CC_DLEmode:
+      return LE;
+
+    case CC_DGTmode:
+      return GT;
+
+    case CC_DLTmode:
+      return LT;
+
+    case CC_DGEmode:
+      return GE;
+
+    case CC_DLEUmode:
+      return LEU;
+
+    case CC_DGTUmode:
+      return GTU;
+
+    case CC_DLTUmode:
+      return LTU;
+
+    case CC_DGEUmode:
+      return GEU;
+
+    default:
+      gcc_unreachable ();
+    }
+}
+
+
 void
 aarch64_print_operand (FILE *f, rtx x, char code)
 {
@@ -4193,6 +4262,40 @@ aarch64_print_operand (FILE *f, rtx x, char code)
       output_addr_const (asm_out_file, x);
       break;
 
+    case 'K':
+      {
+       int cond_code;
+       /* Print nzcv.  */
+
+       if (!COMPARISON_P (x))
+         {
+           output_operand_lossage ("invalid operand for '%%%c'", code);
+           return;
+         }
+
+       cond_code = aarch64_get_condition_code_1 (CCmode, GET_CODE (x));
+       gcc_assert (cond_code >= 0);
+       asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code][0]);
+      }
+      break;
+
+    case 'k':
+      {
+       int cond_code;
+       /* Print nzcv.  */
+
+       if (!COMPARISON_P (x))
+         {
+           output_operand_lossage ("invalid operand for '%%%c'", code);
+           return;
+         }
+
+       cond_code = aarch64_get_condition_code_1 (CCmode, GET_CODE (x));
+       gcc_assert (cond_code >= 0);
+       asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code][1]);
+      }
+      break;
+
     default:
       output_operand_lossage ("invalid operand prefix '%%%c'", code);
       return;
index 5e1a2756de6639c198cec267a51ac8dce9713e76..b9f9a9d20954858c389ca8fa8888ca19d223de9a 100644 (file)
   "
 )
 
+(define_expand "cbranchcc4"
+  [(set (pc) (if_then_else
+             (match_operator 0 "aarch64_comparison_operator"
+              [(match_operand 1 "cc_register" "")
+               (match_operand 2 "const0_operand")])
+             (label_ref (match_operand 3 "" ""))
+             (pc)))]
+  ""
+  "")
+
+(define_insn "*ccmp_and"
+  [(set (match_operand 1 "ccmp_cc_register" "")
+       (compare
+        (and:SI
+         (match_operator 4 "aarch64_comparison_operator"
+          [(match_operand 0 "ccmp_cc_register" "")
+           (const_int 0)])
+         (match_operator 5 "aarch64_comparison_operator"
+          [(match_operand:GPI 2 "register_operand" "r,r,r")
+           (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
+        (const_int 0)))]
+  "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
+  "@
+   ccmp\\t%<w>2, %<w>3, %k5, %m4
+   ccmp\\t%<w>2, %<w>3, %k5, %m4
+   ccmn\\t%<w>2, #%n3, %k5, %m4"
+  [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
+)
+
+(define_insn "*ccmp_ior"
+  [(set (match_operand 1 "ccmp_cc_register" "")
+       (compare
+        (ior:SI
+         (match_operator 4 "aarch64_comparison_operator"
+          [(match_operand 0 "ccmp_cc_register" "")
+           (const_int 0)])
+         (match_operator 5 "aarch64_comparison_operator"
+          [(match_operand:GPI 2 "register_operand" "r,r,r")
+           (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
+        (const_int 0)))]
+  "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
+  "@
+   ccmp\\t%<w>2, %<w>3, %K5, %M4
+   ccmp\\t%<w>2, %<w>3, %K5, %M4
+   ccmn\\t%<w>2, #%n3, %K5, %M4"
+  [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
+)
+
 (define_insn "*condjump"
   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
                            [(match_operand 1 "cc_register" "") (const_int 0)])
   "
 )
 
+(define_expand "cstorecc4"
+  [(set (match_operand:SI 0 "register_operand")
+       (match_operator 1 "aarch64_comparison_operator"
+        [(match_operand 2 "ccmp_cc_register")
+         (match_operand 3 "const0_operand")]))]
+  ""
+"{
+  emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
+  DONE;
+}")
+
+
 (define_expand "cstore<mode>4"
   [(set (match_operand:SI 0 "register_operand" "")
        (match_operator:SI 1 "aarch64_comparison_operator"
                           (match_operand:ALLI 3 "register_operand" "")))]
   ""
   {
-    rtx ccreg;
     enum rtx_code code = GET_CODE (operands[1]);
 
     if (code == UNEQ || code == LTGT)
       FAIL;
 
-    ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
-                                 XEXP (operands[1], 1));
-    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+    if (!ccmp_cc_register (XEXP (operands[1], 0),
+                          GET_MODE (XEXP (operands[1], 0))))
+      {
+       rtx ccreg;
+       ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
+                                        XEXP (operands[1], 1));
+       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+      }
   }
 )
 
index f6fe58c5edb9da9807baa3bab9fc9d6b97f51fa6..712920346e5551233bccd4cb83a1ebb8bdb6e5cf 100644 (file)
   (ior (match_code "symbol_ref")
        (match_operand 0 "register_operand")))
 
+;; Return true if OP a (const_int 0) operand.
+(define_predicate "const0_operand"
+  (and (match_code "const_int, const_double")
+       (match_test "op == CONST0_RTX (mode)")))
+
 (define_predicate "aarch64_ccmp_immediate"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), -31, 31)")))