Backport from trunk r214824.
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@215977
138bc75d-0d04-0410-961f-
82ee72b054a4
+2014-10-07 Yvan Roux <yvan.roux@linaro.org>
+
+ Backport from trunk r214824.
+ 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-10-07 Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
Backport from trunk r209643, r211881.
};
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,
return CCmode;
}
-static unsigned
+int
aarch64_get_condition_code (rtx x)
{
enum machine_mode mode = GET_MODE (XEXP (x, 0));
case UNLE: return AARCH64_LE;
case UNGT: return AARCH64_HI;
case UNGE: return AARCH64_PL;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
case GTU: return AARCH64_HI;
case LEU: return AARCH64_LS;
case LTU: return AARCH64_CC;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
case GTU: return AARCH64_CC;
case LEU: return AARCH64_CS;
case LTU: return AARCH64_HI;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
case EQ: return AARCH64_EQ;
case GE: return AARCH64_PL;
case LT: return AARCH64_MI;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
{
case NE: return AARCH64_NE;
case EQ: return AARCH64_EQ;
- default: gcc_unreachable ();
+ default: return -1;
}
break;
default:
- gcc_unreachable ();
+ return -1;
break;
}
}
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':
(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")]
(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")]
)
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;
}
)
(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")