From 7c19979f0fed0f2a52e51cdbb592654c3e7b8245 Mon Sep 17 00:00:00 2001 From: James Greenhalgh Date: Wed, 1 May 2013 10:40:23 +0000 Subject: [PATCH] [AArch64] Add special case when expanding vcond with arms {-1, -1}, {0, 0}. gcc/ * config/aarch64/aarch64-simd.md (vcond_internal): Handle special cases for constant masks. (vcond): Allow nonmemory_operands for outcome vectors. (vcondu): Likewise. (vcond): New. From-SVN: r198492 --- gcc/ChangeLog | 8 ++++ gcc/config/aarch64/aarch64-simd.md | 87 ++++++++++++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 94959e0..d0392c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2013-05-01 James Greenhalgh + * config/aarch64/aarch64-simd.md + (vcond_internal): Handle special cases for constant masks. + (vcond): Allow nonmemory_operands for outcome vectors. + (vcondu): Likewise. + (vcond): New. + +2013-05-01 James Greenhalgh + * config/aarch64/aarch64-builtins.c (BUILTIN_VALLDI): Define. (aarch64_fold_builtin): Add folding for cm. * config/aarch64/aarch64-simd-builtins.def diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 3893444..dfe4acb 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1683,11 +1683,13 @@ (match_operator 3 "comparison_operator" [(match_operand:VDQ 4 "register_operand") (match_operand:VDQ 5 "nonmemory_operand")]) - (match_operand:VDQ 1 "register_operand") - (match_operand:VDQ 2 "register_operand")))] + (match_operand:VDQ 1 "nonmemory_operand") + (match_operand:VDQ 2 "nonmemory_operand")))] "TARGET_SIMD" { int inverse = 0, has_zero_imm_form = 0; + rtx op1 = operands[1]; + rtx op2 = operands[2]; rtx mask = gen_reg_rtx (mode); switch (GET_CODE (operands[3])) @@ -1746,11 +1748,26 @@ } if (inverse) - emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[2], - operands[1])); - else - emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[1], - operands[2])); + { + op1 = operands[2]; + op2 = operands[1]; + } + + /* If we have (a = (b CMP c) ? -1 : 0); + Then we can simply move the generated mask. */ + + if (op1 == CONSTM1_RTX (mode) + && op2 == CONST0_RTX (mode)) + emit_move_insn (operands[0], mask); + else + { + if (!REG_P (op1)) + op1 = force_reg (mode, op1); + if (!REG_P (op2)) + op2 = force_reg (mode, op2); + emit_insn (gen_aarch64_simd_bsl (operands[0], mask, + op1, op2)); + } DONE; }) @@ -1761,13 +1778,15 @@ (match_operator 3 "comparison_operator" [(match_operand:VDQF 4 "register_operand") (match_operand:VDQF 5 "nonmemory_operand")]) - (match_operand:VDQF 1 "register_operand") - (match_operand:VDQF 2 "register_operand")))] + (match_operand:VDQF 1 "nonmemory_operand") + (match_operand:VDQF 2 "nonmemory_operand")))] "TARGET_SIMD" { int inverse = 0; int use_zero_form = 0; int swap_bsl_operands = 0; + rtx op1 = operands[1]; + rtx op2 = operands[2]; rtx mask = gen_reg_rtx (mode); rtx tmp = gen_reg_rtx (mode); @@ -1912,11 +1931,27 @@ } if (swap_bsl_operands) - emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[2], - operands[1])); - else - emit_insn (gen_aarch64_simd_bsl (operands[0], mask, operands[1], - operands[2])); + { + op1 = operands[2]; + op2 = operands[1]; + } + + /* If we have (a = (b CMP c) ? -1 : 0); + Then we can simply move the generated mask. */ + + if (op1 == CONSTM1_RTX (mode) + && op2 == CONST0_RTX (mode)) + emit_move_insn (operands[0], mask); + else + { + if (!REG_P (op1)) + op1 = force_reg (mode, op1); + if (!REG_P (op2)) + op2 = force_reg (mode, op2); + emit_insn (gen_aarch64_simd_bsl (operands[0], mask, + op1, op2)); + } + DONE; }) @@ -1926,8 +1961,8 @@ (match_operator 3 "comparison_operator" [(match_operand:VALL 4 "register_operand") (match_operand:VALL 5 "nonmemory_operand")]) - (match_operand:VALL 1 "register_operand") - (match_operand:VALL 2 "register_operand")))] + (match_operand:VALL 1 "nonmemory_operand") + (match_operand:VALL 2 "nonmemory_operand")))] "TARGET_SIMD" { emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], @@ -1936,6 +1971,22 @@ DONE; }) +(define_expand "vcond" + [(set (match_operand: 0 "register_operand") + (if_then_else: + (match_operator 3 "comparison_operator" + [(match_operand:VDQF 4 "register_operand") + (match_operand:VDQF 5 "nonmemory_operand")]) + (match_operand: 1 "nonmemory_operand") + (match_operand: 2 "nonmemory_operand")))] + "TARGET_SIMD" +{ + emit_insn (gen_aarch64_vcond_internal ( + operands[0], operands[1], + operands[2], operands[3], + operands[4], operands[5])); + DONE; +}) (define_expand "vcondu" [(set (match_operand:VDQ 0 "register_operand") @@ -1943,8 +1994,8 @@ (match_operator 3 "comparison_operator" [(match_operand:VDQ 4 "register_operand") (match_operand:VDQ 5 "nonmemory_operand")]) - (match_operand:VDQ 1 "register_operand") - (match_operand:VDQ 2 "register_operand")))] + (match_operand:VDQ 1 "nonmemory_operand") + (match_operand:VDQ 2 "nonmemory_operand")))] "TARGET_SIMD" { emit_insn (gen_aarch64_vcond_internal (operands[0], operands[1], -- 2.7.4