aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2014-09-02 15:53:08 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2014-09-02 15:53:08 +0000
commitcd5660ab1229ff6b47987f81769d908970ea0950 (patch)
tree4a49b13722470fe0ae6029e3f651362067132e2a
parentcec362c90b53bec41a0571220216401978b3a6ad (diff)
downloadgcc-cd5660ab1229ff6b47987f81769d908970ea0950.zip
gcc-cd5660ab1229ff6b47987f81769d908970ea0950.tar.gz
gcc-cd5660ab1229ff6b47987f81769d908970ea0950.tar.bz2
[AArch64] Use CC_Z and CC_NZ with csinc and similar instructions.
* config/aarch64/predicates.md (aarch64_comparison_operation): New special predicate. * config/aarch64/aarch64.md (*csinc2<mode>_insn): Use aarch64_comparison_operation instead of matching an operator. Update operand numbers. (csinc3<mode>_insn): Likewise. (*csinv3<mode>_insn): Likewise. (*csneg3<mode>_insn): Likewise. (ffs<mode>2): Update gen_csinc3<mode>_insn callsite. * config/aarch64/aarch64.c (aarch64_get_condition_code): Return -1 instead of aborting on invalid condition codes. (aarch64_print_operand): Update aarch64_get_condition_code callsites to assert that the returned condition code is valid. * config/aarch64/aarch64-protos.h (aarch64_get_condition_code): Export. From-SVN: r214824
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64.c73
-rw-r--r--gcc/config/aarch64/aarch64.md34
-rw-r--r--gcc/config/aarch64/predicates.md12
5 files changed, 86 insertions, 51 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 910c04d..35148ff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+2014-09-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/predicates.md (aarch64_comparison_operation):
+ New special predicate.
+ * config/aarch64/aarch64.md (*csinc2<mode>_insn): Use
+ aarch64_comparison_operation instead of matching an operator.
+ Update operand numbers.
+ (csinc3<mode>_insn): Likewise.
+ (*csinv3<mode>_insn): Likewise.
+ (*csneg3<mode>_insn): Likewise.
+ (ffs<mode>2): Update gen_csinc3<mode>_insn callsite.
+ * config/aarch64/aarch64.c (aarch64_get_condition_code):
+ Return -1 instead of aborting on invalid condition codes.
+ (aarch64_print_operand): Update aarch64_get_condition_code callsites
+ to assert that the returned condition code is valid.
+ * config/aarch64/aarch64-protos.h (aarch64_get_condition_code): Export.
+
2014-09-02 Aldy Hernandez <aldyh@redhat.com>
* Makefile.in (TAGS): Handle constructs in common.opt, rtl.def,
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index cca3bc9..6878f7d 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -173,6 +173,7 @@ struct tune_params
};
HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
+int aarch64_get_condition_code (rtx);
bool aarch64_bitmask_imm (HOST_WIDE_INT val, enum machine_mode);
bool aarch64_cannot_change_mode_class (enum machine_mode,
enum machine_mode,
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 3f66b8f..c48cdf0 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3587,7 +3587,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
return CCmode;
}
-static unsigned
+int
aarch64_get_condition_code (rtx x)
{
enum machine_mode mode = GET_MODE (XEXP (x, 0));
@@ -3614,7 +3614,7 @@ aarch64_get_condition_code (rtx x)
case UNLE: return AARCH64_LE;
case UNGT: return AARCH64_HI;
case UNGE: return AARCH64_PL;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
@@ -3631,7 +3631,7 @@ aarch64_get_condition_code (rtx x)
case GTU: return AARCH64_HI;
case LEU: return AARCH64_LS;
case LTU: return AARCH64_CC;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
@@ -3650,7 +3650,7 @@ aarch64_get_condition_code (rtx x)
case GTU: return AARCH64_CC;
case LEU: return AARCH64_CS;
case LTU: return AARCH64_HI;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
@@ -3661,7 +3661,7 @@ aarch64_get_condition_code (rtx x)
case EQ: return AARCH64_EQ;
case GE: return AARCH64_PL;
case LT: return AARCH64_MI;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
@@ -3670,12 +3670,12 @@ aarch64_get_condition_code (rtx x)
{
case NE: return AARCH64_NE;
case EQ: return AARCH64_EQ;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
default:
- gcc_unreachable ();
+ return -1;
break;
}
}
@@ -3793,39 +3793,48 @@ aarch64_print_operand (FILE *f, rtx x, char code)
break;
case 'm':
- /* Print a condition (eq, ne, etc). */
-
- /* CONST_TRUE_RTX means always -- that's the default. */
- if (x == const_true_rtx)
- return;
+ {
+ int cond_code;
+ /* Print a condition (eq, ne, etc). */
- if (!COMPARISON_P (x))
- {
- output_operand_lossage ("invalid operand for '%%%c'", code);
+ /* CONST_TRUE_RTX means always -- that's the default. */
+ if (x == const_true_rtx)
return;
- }
- fputs (aarch64_condition_codes[aarch64_get_condition_code (x)], f);
+ if (!COMPARISON_P (x))
+ {
+ output_operand_lossage ("invalid operand for '%%%c'", code);
+ return;
+ }
+
+ cond_code = aarch64_get_condition_code (x);
+ gcc_assert (cond_code >= 0);
+ fputs (aarch64_condition_codes[cond_code], f);
+ }
break;
case 'M':
- /* Print the inverse of a condition (eq <-> ne, etc). */
-
- /* CONST_TRUE_RTX means never -- that's the default. */
- if (x == const_true_rtx)
- {
- fputs ("nv", f);
- return;
- }
+ {
+ int cond_code;
+ /* Print the inverse of a condition (eq <-> ne, etc). */
- if (!COMPARISON_P (x))
- {
- output_operand_lossage ("invalid operand for '%%%c'", code);
- return;
- }
+ /* CONST_TRUE_RTX means never -- that's the default. */
+ if (x == const_true_rtx)
+ {
+ fputs ("nv", f);
+ return;
+ }
- fputs (aarch64_condition_codes[AARCH64_INVERSE_CONDITION_CODE
- (aarch64_get_condition_code (x))], f);
+ if (!COMPARISON_P (x))
+ {
+ output_operand_lossage ("invalid operand for '%%%c'", code);
+ return;
+ }
+ cond_code = aarch64_get_condition_code (x);
+ gcc_assert (cond_code >= 0);
+ fputs (aarch64_condition_codes[AARCH64_INVERSE_CONDITION_CODE
+ (cond_code)], f);
+ }
break;
case 'b':
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 1f7ab91..b5be79c 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -2598,9 +2598,8 @@
(define_insn "*csinc2<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r")
- (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
- [(match_operand:CC 3 "cc_register" "") (const_int 0)])
- (match_operand:GPI 1 "register_operand" "r")))]
+ (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
+ (match_operand:GPI 1 "register_operand" "r")))]
""
"csinc\\t%<w>0, %<w>1, %<w>1, %M2"
[(set_attr "type" "csel")]
@@ -2609,37 +2608,34 @@
(define_insn "csinc3<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r")
(if_then_else:GPI
- (match_operator:GPI 1 "aarch64_comparison_operator"
- [(match_operand:CC 2 "cc_register" "") (const_int 0)])
- (plus:GPI (match_operand:GPI 3 "register_operand" "r")
+ (match_operand 1 "aarch64_comparison_operation" "")
+ (plus:GPI (match_operand:GPI 2 "register_operand" "r")
(const_int 1))
- (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
+ (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
""
- "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
+ "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
[(set_attr "type" "csel")]
)
(define_insn "*csinv3<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r")
(if_then_else:GPI
- (match_operator:GPI 1 "aarch64_comparison_operator"
- [(match_operand:CC 2 "cc_register" "") (const_int 0)])
- (not:GPI (match_operand:GPI 3 "register_operand" "r"))
- (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
+ (match_operand 1 "aarch64_comparison_operation" "")
+ (not:GPI (match_operand:GPI 2 "register_operand" "r"))
+ (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
""
- "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
+ "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
[(set_attr "type" "csel")]
)
(define_insn "*csneg3<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r")
(if_then_else:GPI
- (match_operator:GPI 1 "aarch64_comparison_operator"
- [(match_operand:CC 2 "cc_register" "") (const_int 0)])
- (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
- (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
+ (match_operand 1 "aarch64_comparison_operation" "")
+ (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
+ (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
""
- "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
+ "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
[(set_attr "type" "csel")]
)
@@ -2896,7 +2892,7 @@
emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
- emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
+ emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
DONE;
}
)
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 3dd83ca..c1510ca 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -202,6 +202,18 @@
(define_special_predicate "aarch64_comparison_operator"
(match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
+(define_special_predicate "aarch64_comparison_operation"
+ (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt")
+{
+ if (XEXP (op, 1) != const0_rtx)
+ return false;
+ rtx op0 = XEXP (op, 0);
+ if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
+ return false;
+ return aarch64_get_condition_code (op) >= 0;
+})
+
+
;; True if the operand is memory reference suitable for a load/store exclusive.
(define_predicate "aarch64_sync_memory_operand"
(and (match_operand 0 "memory_operand")