predicates.md (expandable_comparison_operator): New predicate, extracted from...
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 22 Sep 2011 10:33:24 +0000 (10:33 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 22 Sep 2011 10:33:24 +0000 (10:33 +0000)
gcc/
* config/arm/predicates.md (expandable_comparison_operator): New
predicate, extracted from...
(arm_comparison_operator): ...here.
* config/arm/arm.md (cbranchsi4, cbranchsf4, cbranchdf4, cbranchdi4)
(cstoresi4, cstoresf4, cstoredf4, cstoredi4, movsicc, movsfcc)
(movdfcc): Use expandable_comparison_operator.

gcc/testsuite/
* gcc.target/arm/cmp-1.c: New test.
* gcc.target/arm/cmp-2.c: Likewise.

From-SVN: r179082

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/cmp-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/cmp-2.c [new file with mode: 0644]

index 973376c65f3d17065820601b6cde2a3e1444033f..7291c09ef8a91313ab15e540231457315dc9f2ef 100644 (file)
@@ -1,3 +1,12 @@
+2011-09-22  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * config/arm/predicates.md (expandable_comparison_operator): New
+       predicate, extracted from...
+       (arm_comparison_operator): ...here.
+       * config/arm/arm.md (cbranchsi4, cbranchsf4, cbranchdf4, cbranchdi4)
+       (cstoresi4, cstoresf4, cstoredf4, cstoredi4, movsicc, movsfcc)
+       (movdfcc): Use expandable_comparison_operator.
+
 2011-09-22  Georg-Johann Lay  <avr@gjlay.de>
 
        PR target/50447
index bb9e3283fc369287acb11acfa98116eba928761f..3889322fd47a64bc1288fe5a985ad253340210c3 100644 (file)
 
 (define_expand "cbranchsi4"
   [(set (pc) (if_then_else
-             (match_operator 0 "arm_comparison_operator"
+             (match_operator 0 "expandable_comparison_operator"
               [(match_operand:SI 1 "s_register_operand" "")
                (match_operand:SI 2 "nonmemory_operand" "")])
              (label_ref (match_operand 3 "" ""))
 
 (define_expand "cbranchsf4"
   [(set (pc) (if_then_else
-             (match_operator 0 "arm_comparison_operator"
+             (match_operator 0 "expandable_comparison_operator"
               [(match_operand:SF 1 "s_register_operand" "")
                (match_operand:SF 2 "arm_float_compare_operand" "")])
              (label_ref (match_operand 3 "" ""))
 
 (define_expand "cbranchdf4"
   [(set (pc) (if_then_else
-             (match_operator 0 "arm_comparison_operator"
+             (match_operator 0 "expandable_comparison_operator"
               [(match_operand:DF 1 "s_register_operand" "")
                (match_operand:DF 2 "arm_float_compare_operand" "")])
              (label_ref (match_operand 3 "" ""))
 
 (define_expand "cbranchdi4"
   [(set (pc) (if_then_else
-             (match_operator 0 "arm_comparison_operator"
+             (match_operator 0 "expandable_comparison_operator"
               [(match_operand:DI 1 "cmpdi_operand" "")
                (match_operand:DI 2 "cmpdi_operand" "")])
              (label_ref (match_operand 3 "" ""))
 
 (define_expand "cstoresi4"
   [(set (match_operand:SI 0 "s_register_operand" "")
-       (match_operator:SI 1 "arm_comparison_operator"
+       (match_operator:SI 1 "expandable_comparison_operator"
         [(match_operand:SI 2 "s_register_operand" "")
          (match_operand:SI 3 "reg_or_int_operand" "")]))]
   "TARGET_32BIT || TARGET_THUMB1"
 
 (define_expand "cstoresf4"
   [(set (match_operand:SI 0 "s_register_operand" "")
-       (match_operator:SI 1 "arm_comparison_operator"
+       (match_operator:SI 1 "expandable_comparison_operator"
         [(match_operand:SF 2 "s_register_operand" "")
          (match_operand:SF 3 "arm_float_compare_operand" "")]))]
   "TARGET_32BIT && TARGET_HARD_FLOAT"
 
 (define_expand "cstoredf4"
   [(set (match_operand:SI 0 "s_register_operand" "")
-       (match_operator:SI 1 "arm_comparison_operator"
+       (match_operator:SI 1 "expandable_comparison_operator"
         [(match_operand:DF 2 "s_register_operand" "")
          (match_operand:DF 3 "arm_float_compare_operand" "")]))]
   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
 
 (define_expand "cstoredi4"
   [(set (match_operand:SI 0 "s_register_operand" "")
-       (match_operator:SI 1 "arm_comparison_operator"
+       (match_operator:SI 1 "expandable_comparison_operator"
         [(match_operand:DI 2 "cmpdi_operand" "")
          (match_operand:DI 3 "cmpdi_operand" "")]))]
   "TARGET_32BIT"
 
 (define_expand "movsicc"
   [(set (match_operand:SI 0 "s_register_operand" "")
-       (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
+       (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
                         (match_operand:SI 2 "arm_not_operand" "")
                         (match_operand:SI 3 "arm_not_operand" "")))]
   "TARGET_32BIT"
 
 (define_expand "movsfcc"
   [(set (match_operand:SF 0 "s_register_operand" "")
-       (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
+       (if_then_else:SF (match_operand 1 "expandable_comparison_operator" "")
                         (match_operand:SF 2 "s_register_operand" "")
                         (match_operand:SF 3 "nonmemory_operand" "")))]
   "TARGET_32BIT && TARGET_HARD_FLOAT"
 
 (define_expand "movdfcc"
   [(set (match_operand:DF 0 "s_register_operand" "")
-       (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
+       (if_then_else:DF (match_operand 1 "expandable_comparison_operator" "")
                         (match_operand:DF 2 "s_register_operand" "")
                         (match_operand:DF 3 "arm_float_add_operand" "")))]
   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
index df8990ea648b5522e793b0dc0775ec8dd0781119..8b4a6773936b97ede8b2573a84a6c174dcccd39c 100644 (file)
 
 ;; True for integer comparisons and, if FP is active, for comparisons
 ;; other than LTGT or UNEQ.
+(define_special_predicate "expandable_comparison_operator"
+  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
+              unordered,ordered,unlt,unle,unge,ungt"))
+
+;; Likewise, but only accept comparisons that are directly supported
+;; by ARM condition codes.
 (define_special_predicate "arm_comparison_operator"
-  (and (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
-                   unordered,ordered,unlt,unle,unge,ungt")
+  (and (match_operand 0 "expandable_comparison_operator")
        (match_test "maybe_get_arm_condition_code (op) != ARM_NV")))
 
 (define_special_predicate "lt_ge_comparison_operator"
index 10aff8268a2f0010e11267761091624902429572..1942dfc0f45469ec66b207ac0d9a46b8d9b5c8cb 100644 (file)
@@ -1,3 +1,8 @@
+2011-09-22  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * gcc.target/arm/cmp-1.c: New test.
+       * gcc.target/arm/cmp-2.c: Likewise.
+
 2011-09-22  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/41733
diff --git a/gcc/testsuite/gcc.target/arm/cmp-1.c b/gcc/testsuite/gcc.target/arm/cmp-1.c
new file mode 100644 (file)
index 0000000..0d6b7c2
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+/* { dg-final { scan-assembler-not "\tbl\t" } } */
+/* { dg-final { scan-assembler-not "__aeabi" } } */
+int x, y;
+
+#define TEST_EXPR(NAME, ARGS, EXPR)                    \
+  int NAME##1 ARGS { return (EXPR); }                  \
+  int NAME##2 ARGS { return !(EXPR); }                 \
+  int NAME##3 ARGS { return (EXPR) ? x : y; }          \
+  void NAME##4 ARGS { if (EXPR) x++; }                 \
+  void NAME##5 ARGS { if (!(EXPR)) x++; }
+
+#define TEST(NAME, TYPE, OPERATOR) \
+  TEST_EXPR (NAME##_rr, (TYPE a1, TYPE a2), a1 OPERATOR a2)    \
+  TEST_EXPR (NAME##_rm, (TYPE a1, TYPE *a2), a1 OPERATOR *a2)  \
+  TEST_EXPR (NAME##_mr, (TYPE *a1, TYPE a2), *a1 OPERATOR a2)  \
+  TEST_EXPR (NAME##_mm, (TYPE *a1, TYPE *a2), *a1 OPERATOR *a2) \
+  TEST_EXPR (NAME##_rc, (TYPE a1), a1 OPERATOR 100)            \
+  TEST_EXPR (NAME##_cr, (TYPE a1), 100 OPERATOR a1)
+
+#define TEST_OP(NAME, OPERATOR) \
+  TEST (sc_##NAME, signed char, OPERATOR)              \
+  TEST (uc_##NAME, unsigned char, OPERATOR)            \
+  TEST (ss_##NAME, short, OPERATOR)                    \
+  TEST (us_##NAME, unsigned short, OPERATOR)           \
+  TEST (si_##NAME, int, OPERATOR)                      \
+  TEST (ui_##NAME, unsigned int, OPERATOR)             \
+  TEST (sll_##NAME, long long, OPERATOR)               \
+  TEST (ull_##NAME, unsigned long long, OPERATOR)
+
+TEST_OP (eq, ==)
+TEST_OP (ne, !=)
+TEST_OP (lt, <)
+TEST_OP (gt, >)
+TEST_OP (le, <=)
+TEST_OP (ge, >=)
diff --git a/gcc/testsuite/gcc.target/arm/cmp-2.c b/gcc/testsuite/gcc.target/arm/cmp-2.c
new file mode 100644 (file)
index 0000000..ed6b609
--- /dev/null
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=softfp" } */
+/* { dg-final { scan-assembler-not "\tbl\t" } } */
+/* { dg-final { scan-assembler-not "__aeabi" } } */
+int x, y;
+
+#define EQ(X, Y) ((X) == (Y))
+#define NE(X, Y) ((X) != (Y))
+#define LT(X, Y) ((X) < (Y))
+#define GT(X, Y) ((X) > (Y))
+#define LE(X, Y) ((X) <= (Y))
+#define GE(X, Y) ((X) >= (Y))
+
+#define TEST_EXPR(NAME, ARGS, EXPR)                    \
+  int NAME##1 ARGS { return (EXPR); }                  \
+  int NAME##2 ARGS { return !(EXPR); }                 \
+  int NAME##3 ARGS { return (EXPR) ? x : y; }          \
+  void NAME##4 ARGS { if (EXPR) x++; }                 \
+  void NAME##5 ARGS { if (!(EXPR)) x++; }
+
+#define TEST(NAME, TYPE, OPERATOR) \
+  TEST_EXPR (NAME##_rr, (TYPE a1, TYPE a2), OPERATOR (a1, a2))         \
+  TEST_EXPR (NAME##_rm, (TYPE a1, TYPE *a2), OPERATOR (a1, *a2))       \
+  TEST_EXPR (NAME##_mr, (TYPE *a1, TYPE a2), OPERATOR (*a1, a2))       \
+  TEST_EXPR (NAME##_mm, (TYPE *a1, TYPE *a2), OPERATOR (*a1, *a2))     \
+  TEST_EXPR (NAME##_rc, (TYPE a1), OPERATOR (a1, 100))                 \
+  TEST_EXPR (NAME##_cr, (TYPE a1), OPERATOR (100, a1))
+
+#define TEST_OP(NAME, OPERATOR) \
+  TEST (f_##NAME, float, OPERATOR)             \
+  TEST (d_##NAME, double, OPERATOR)            \
+  TEST (ld_##NAME, long double, OPERATOR)
+
+TEST_OP (eq, EQ)
+TEST_OP (ne, NE)
+TEST_OP (lt, LT)
+TEST_OP (gt, GT)
+TEST_OP (le, LE)
+TEST_OP (ge, GE)
+TEST_OP (blt, __builtin_isless)
+TEST_OP (bgt, __builtin_isgreater)
+TEST_OP (ble, __builtin_islessequal)
+TEST_OP (bge, __builtin_isgreaterequal)
+/* This one should be expanded into separate ordered and equality
+   comparisons.  */
+TEST_OP (blg, __builtin_islessgreater)
+TEST_OP (bun, __builtin_isunordered)