From cd5660ab1229ff6b47987f81769d908970ea0950 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Tue, 2 Sep 2014 15:53:08 +0000 Subject: [PATCH] [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_insn): Use aarch64_comparison_operation instead of matching an operator. Update operand numbers. (csinc3_insn): Likewise. (*csinv3_insn): Likewise. (*csneg3_insn): Likewise. (ffs2): Update gen_csinc3_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 --- gcc/ChangeLog | 17 +++++++ gcc/config/aarch64/aarch64-protos.h | 1 + gcc/config/aarch64/aarch64.c | 73 ++++++++++++++++------------- gcc/config/aarch64/aarch64.md | 34 ++++++-------- gcc/config/aarch64/predicates.md | 12 +++++ 5 files changed, 86 insertions(+), 51 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 910c04dba57..35148ffd927 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2014-09-02 Kyrylo Tkachov + + * config/aarch64/predicates.md (aarch64_comparison_operation): + New special predicate. + * config/aarch64/aarch64.md (*csinc2_insn): Use + aarch64_comparison_operation instead of matching an operator. + Update operand numbers. + (csinc3_insn): Likewise. + (*csinv3_insn): Likewise. + (*csneg3_insn): Likewise. + (ffs2): Update gen_csinc3_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 * 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 cca3bc96af9..6878f7d3162 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 3f66b8f0673..c48cdf0a0b1 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 1f7ab9151ba..b5be79ce360 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2598,9 +2598,8 @@ (define_insn "*csinc2_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%0, %1, %1, %M2" [(set_attr "type" "csel")] @@ -2609,37 +2608,34 @@ (define_insn "csinc3_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%0, %4, %3, %M1" + "csinc\\t%0, %3, %2, %M1" [(set_attr "type" "csel")] ) (define_insn "*csinv3_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%0, %4, %3, %M1" + "csinv\\t%0, %3, %2, %M1" [(set_attr "type" "csel")] ) (define_insn "*csneg3_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%0, %4, %3, %M1" + "csneg\\t%0, %3, %2, %M1" [(set_attr "type" "csel")] ) @@ -2896,7 +2892,7 @@ emit_insn (gen_rbit2 (operands[0], operands[1])); emit_insn (gen_clz2 (operands[0], operands[0])); - emit_insn (gen_csinc3_insn (operands[0], x, ccreg, operands[0], const0_rtx)); + emit_insn (gen_csinc3_insn (operands[0], x, operands[0], const0_rtx)); DONE; } ) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 3dd83caf907..c1510cac749 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") -- 2.30.2