commit a70dc696b967196d6662479a44682e3f423377ac
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date: Mon Aug 4 16:49:24 2014 +0100
[AArch64] Generalise condition code usage for csinc pattterns
@@ -174,6 +174,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,
@@ -3589,7 +3589,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));
@@ -3616,7 +3616,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;
@@ -3633,7 +3633,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;
@@ -3652,7 +3652,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;
@@ -3663,7 +3663,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;
@@ -3672,12 +3672,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;
}
}
@@ -3795,39 +3795,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':
@@ -2598,9 +2598,8 @@ (define_insn "aarch64_<crc_variant>"
(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 "*csinc2<mode>_insn"
(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 @@ (define_expand "ffs<mode>2"
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;
}
)
@@ -202,6 +202,18 @@ (define_predicate "aarch64_reg_or_imm"
(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")