Commit cd5660ab by Kyrylo Tkachov Committed by Kyrylo Tkachov

[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
parent cec362c9
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> 2014-09-02 Aldy Hernandez <aldyh@redhat.com>
* Makefile.in (TAGS): Handle constructs in common.opt, rtl.def, * Makefile.in (TAGS): Handle constructs in common.opt, rtl.def,
...@@ -173,6 +173,7 @@ struct tune_params ...@@ -173,6 +173,7 @@ struct tune_params
}; };
HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned); 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_bitmask_imm (HOST_WIDE_INT val, enum machine_mode);
bool aarch64_cannot_change_mode_class (enum machine_mode, bool aarch64_cannot_change_mode_class (enum machine_mode,
enum machine_mode, enum machine_mode,
......
...@@ -3587,7 +3587,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y) ...@@ -3587,7 +3587,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
return CCmode; return CCmode;
} }
static unsigned int
aarch64_get_condition_code (rtx x) aarch64_get_condition_code (rtx x)
{ {
enum machine_mode mode = GET_MODE (XEXP (x, 0)); enum machine_mode mode = GET_MODE (XEXP (x, 0));
...@@ -3614,7 +3614,7 @@ aarch64_get_condition_code (rtx x) ...@@ -3614,7 +3614,7 @@ aarch64_get_condition_code (rtx x)
case UNLE: return AARCH64_LE; case UNLE: return AARCH64_LE;
case UNGT: return AARCH64_HI; case UNGT: return AARCH64_HI;
case UNGE: return AARCH64_PL; case UNGE: return AARCH64_PL;
default: gcc_unreachable (); default: return -1;
} }
break; break;
...@@ -3631,7 +3631,7 @@ aarch64_get_condition_code (rtx x) ...@@ -3631,7 +3631,7 @@ aarch64_get_condition_code (rtx x)
case GTU: return AARCH64_HI; case GTU: return AARCH64_HI;
case LEU: return AARCH64_LS; case LEU: return AARCH64_LS;
case LTU: return AARCH64_CC; case LTU: return AARCH64_CC;
default: gcc_unreachable (); default: return -1;
} }
break; break;
...@@ -3650,7 +3650,7 @@ aarch64_get_condition_code (rtx x) ...@@ -3650,7 +3650,7 @@ aarch64_get_condition_code (rtx x)
case GTU: return AARCH64_CC; case GTU: return AARCH64_CC;
case LEU: return AARCH64_CS; case LEU: return AARCH64_CS;
case LTU: return AARCH64_HI; case LTU: return AARCH64_HI;
default: gcc_unreachable (); default: return -1;
} }
break; break;
...@@ -3661,7 +3661,7 @@ aarch64_get_condition_code (rtx x) ...@@ -3661,7 +3661,7 @@ aarch64_get_condition_code (rtx x)
case EQ: return AARCH64_EQ; case EQ: return AARCH64_EQ;
case GE: return AARCH64_PL; case GE: return AARCH64_PL;
case LT: return AARCH64_MI; case LT: return AARCH64_MI;
default: gcc_unreachable (); default: return -1;
} }
break; break;
...@@ -3670,12 +3670,12 @@ aarch64_get_condition_code (rtx x) ...@@ -3670,12 +3670,12 @@ aarch64_get_condition_code (rtx x)
{ {
case NE: return AARCH64_NE; case NE: return AARCH64_NE;
case EQ: return AARCH64_EQ; case EQ: return AARCH64_EQ;
default: gcc_unreachable (); default: return -1;
} }
break; break;
default: default:
gcc_unreachable (); return -1;
break; break;
} }
} }
...@@ -3793,39 +3793,48 @@ aarch64_print_operand (FILE *f, rtx x, char code) ...@@ -3793,39 +3793,48 @@ aarch64_print_operand (FILE *f, rtx x, char code)
break; break;
case 'm': case 'm':
/* Print a condition (eq, ne, etc). */ {
int cond_code;
/* CONST_TRUE_RTX means always -- that's the default. */ /* Print a condition (eq, ne, etc). */
if (x == const_true_rtx)
return;
if (!COMPARISON_P (x)) /* CONST_TRUE_RTX means always -- that's the default. */
{ if (x == const_true_rtx)
output_operand_lossage ("invalid operand for '%%%c'", code);
return; 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; break;
case 'M': case 'M':
/* Print the inverse of a condition (eq <-> ne, etc). */ {
int cond_code;
/* CONST_TRUE_RTX means never -- that's the default. */ /* Print the inverse of a condition (eq <-> ne, etc). */
if (x == const_true_rtx)
{
fputs ("nv", f);
return;
}
if (!COMPARISON_P (x)) /* CONST_TRUE_RTX means never -- that's the default. */
{ if (x == const_true_rtx)
output_operand_lossage ("invalid operand for '%%%c'", code); {
return; fputs ("nv", f);
} return;
}
fputs (aarch64_condition_codes[AARCH64_INVERSE_CONDITION_CODE if (!COMPARISON_P (x))
(aarch64_get_condition_code (x))], f); {
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; break;
case 'b': case 'b':
......
...@@ -2598,9 +2598,8 @@ ...@@ -2598,9 +2598,8 @@
(define_insn "*csinc2<mode>_insn" (define_insn "*csinc2<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r") [(set (match_operand:GPI 0 "register_operand" "=r")
(plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator" (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
[(match_operand:CC 3 "cc_register" "") (const_int 0)]) (match_operand:GPI 1 "register_operand" "r")))]
(match_operand:GPI 1 "register_operand" "r")))]
"" ""
"csinc\\t%<w>0, %<w>1, %<w>1, %M2" "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
[(set_attr "type" "csel")] [(set_attr "type" "csel")]
...@@ -2609,37 +2608,34 @@ ...@@ -2609,37 +2608,34 @@
(define_insn "csinc3<mode>_insn" (define_insn "csinc3<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r") [(set (match_operand:GPI 0 "register_operand" "=r")
(if_then_else:GPI (if_then_else:GPI
(match_operator:GPI 1 "aarch64_comparison_operator" (match_operand 1 "aarch64_comparison_operation" "")
[(match_operand:CC 2 "cc_register" "") (const_int 0)]) (plus:GPI (match_operand:GPI 2 "register_operand" "r")
(plus:GPI (match_operand:GPI 3 "register_operand" "r")
(const_int 1)) (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")] [(set_attr "type" "csel")]
) )
(define_insn "*csinv3<mode>_insn" (define_insn "*csinv3<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r") [(set (match_operand:GPI 0 "register_operand" "=r")
(if_then_else:GPI (if_then_else:GPI
(match_operator:GPI 1 "aarch64_comparison_operator" (match_operand 1 "aarch64_comparison_operation" "")
[(match_operand:CC 2 "cc_register" "") (const_int 0)]) (not:GPI (match_operand:GPI 2 "register_operand" "r"))
(not:GPI (match_operand:GPI 3 "register_operand" "r")) (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
(match_operand:GPI 4 "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")] [(set_attr "type" "csel")]
) )
(define_insn "*csneg3<mode>_insn" (define_insn "*csneg3<mode>_insn"
[(set (match_operand:GPI 0 "register_operand" "=r") [(set (match_operand:GPI 0 "register_operand" "=r")
(if_then_else:GPI (if_then_else:GPI
(match_operator:GPI 1 "aarch64_comparison_operator" (match_operand 1 "aarch64_comparison_operation" "")
[(match_operand:CC 2 "cc_register" "") (const_int 0)]) (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
(neg:GPI (match_operand:GPI 3 "register_operand" "r")) (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
(match_operand:GPI 4 "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")] [(set_attr "type" "csel")]
) )
...@@ -2896,7 +2892,7 @@ ...@@ -2896,7 +2892,7 @@
emit_insn (gen_rbit<mode>2 (operands[0], operands[1])); emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
emit_insn (gen_clz<mode>2 (operands[0], operands[0])); 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; DONE;
} }
) )
......
...@@ -202,6 +202,18 @@ ...@@ -202,6 +202,18 @@
(define_special_predicate "aarch64_comparison_operator" (define_special_predicate "aarch64_comparison_operator"
(match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt")) (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. ;; True if the operand is memory reference suitable for a load/store exclusive.
(define_predicate "aarch64_sync_memory_operand" (define_predicate "aarch64_sync_memory_operand"
(and (match_operand 0 "memory_operand") (and (match_operand 0 "memory_operand")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment