DONE;
})
-(define_expand "aarch64_vcond_internal<mode>"
+(define_expand "aarch64_vcond_internal<mode><mode>"
[(set (match_operand:VDQ 0 "register_operand")
(if_then_else:VDQ
(match_operator 3 "comparison_operator"
DONE;
})
-(define_expand "aarch64_vcond_internal<mode>"
- [(set (match_operand:VDQF 0 "register_operand")
+(define_expand "aarch64_vcond_internal<VDQF_COND:mode><VDQF:mode>"
+ [(set (match_operand:VDQF_COND 0 "register_operand")
(if_then_else:VDQF
(match_operator 3 "comparison_operator"
[(match_operand:VDQF 4 "register_operand")
(match_operand:VDQF 5 "nonmemory_operand")])
- (match_operand:VDQF 1 "nonmemory_operand")
- (match_operand:VDQF 2 "nonmemory_operand")))]
+ (match_operand:VDQF_COND 1 "nonmemory_operand")
+ (match_operand:VDQF_COND 2 "nonmemory_operand")))]
"TARGET_SIMD"
{
int inverse = 0;
int swap_bsl_operands = 0;
rtx op1 = operands[1];
rtx op2 = operands[2];
- rtx mask = gen_reg_rtx (<V_cmp_result>mode);
- rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
+ rtx mask = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
+ rtx tmp = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
rtx (*base_comparison) (rtx, rtx, rtx);
rtx (*complimentary_comparison) (rtx, rtx, rtx);
/* Fall through. */
default:
if (!REG_P (operands[5]))
- operands[5] = force_reg (<MODE>mode, operands[5]);
+ operands[5] = force_reg (<VDQF:MODE>mode, operands[5]);
}
switch (GET_CODE (operands[3]))
case UNGE:
case ORDERED:
case UNORDERED:
- base_comparison = gen_aarch64_cmge<mode>;
- complimentary_comparison = gen_aarch64_cmgt<mode>;
+ base_comparison = gen_aarch64_cmge<VDQF:mode>;
+ complimentary_comparison = gen_aarch64_cmgt<VDQF:mode>;
break;
case LE:
case UNLE:
/* Fall through. */
case GT:
case UNGT:
- base_comparison = gen_aarch64_cmgt<mode>;
- complimentary_comparison = gen_aarch64_cmge<mode>;
+ base_comparison = gen_aarch64_cmgt<VDQF:mode>;
+ complimentary_comparison = gen_aarch64_cmge<VDQF:mode>;
break;
case EQ:
case NE:
case UNEQ:
- base_comparison = gen_aarch64_cmeq<mode>;
- complimentary_comparison = gen_aarch64_cmeq<mode>;
+ base_comparison = gen_aarch64_cmeq<VDQF:mode>;
+ complimentary_comparison = gen_aarch64_cmeq<VDQF:mode>;
break;
default:
gcc_unreachable ();
switch (GET_CODE (operands[3]))
{
case LT:
- base_comparison = gen_aarch64_cmlt<mode>;
+ base_comparison = gen_aarch64_cmlt<VDQF:mode>;
break;
case LE:
- base_comparison = gen_aarch64_cmle<mode>;
+ base_comparison = gen_aarch64_cmle<VDQF:mode>;
break;
default:
/* Do nothing, other zero form cases already have the correct
true iff !(a != b && a ORDERED b), swapping the operands to BSL
will then give us (a == b || a UNORDERED b) as intended. */
- emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
- emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[5], operands[4]));
- emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
+ emit_insn (gen_aarch64_cmgt<VDQF:mode> (mask, operands[4], operands[5]));
+ emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[5], operands[4]));
+ emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
swap_bsl_operands = 1;
break;
case UNORDERED:
swap_bsl_operands = 1;
/* Fall through. */
case ORDERED:
- emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[4], operands[5]));
- emit_insn (gen_aarch64_cmge<mode> (mask, operands[5], operands[4]));
- emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
+ emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[4], operands[5]));
+ emit_insn (gen_aarch64_cmge<VDQF:mode> (mask, operands[5], operands[4]));
+ emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
break;
default:
gcc_unreachable ();
/* If we have (a = (b CMP c) ? -1 : 0);
Then we can simply move the generated mask. */
- if (op1 == CONSTM1_RTX (<V_cmp_result>mode)
- && op2 == CONST0_RTX (<V_cmp_result>mode))
+ if (op1 == CONSTM1_RTX (<VDQF_COND:V_cmp_result>mode)
+ && op2 == CONST0_RTX (<VDQF_COND:V_cmp_result>mode))
emit_move_insn (operands[0], mask);
else
{
if (!REG_P (op1))
- op1 = force_reg (<MODE>mode, op1);
+ op1 = force_reg (<VDQF_COND:MODE>mode, op1);
if (!REG_P (op2))
- op2 = force_reg (<MODE>mode, op2);
- emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask,
+ op2 = force_reg (<VDQF_COND:MODE>mode, op2);
+ emit_insn (gen_aarch64_simd_bsl<VDQF_COND:mode> (operands[0], mask,
op1, op2));
}
(match_operand:VALL 2 "nonmemory_operand")))]
"TARGET_SIMD"
{
- emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
+ emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
operands[2], operands[3],
operands[4], operands[5]));
DONE;
(match_operand:<V_cmp_result> 2 "nonmemory_operand")))]
"TARGET_SIMD"
{
- emit_insn (gen_aarch64_vcond_internal<v_cmp_result> (
+ emit_insn (gen_aarch64_vcond_internal<v_cmp_result><mode> (
operands[0], operands[1],
operands[2], operands[3],
operands[4], operands[5]));
(match_operand:VDQ 2 "nonmemory_operand")))]
"TARGET_SIMD"
{
- emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
+ emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
operands[2], operands[3],
operands[4], operands[5]));
DONE;
2.0, -4.0, 8.0, -16.0,
-2.125, 4.25, -8.5, 17.0};
+/* Float comparisons, float results. */
+
void
foo (FTYPE *in1, FTYPE *in2, FTYPE *output)
{
output[i] = (in1[i] INV_OP 0.0) ? 4.0 : 2.0;
}
+/* Float comparisons, int results. */
+
+void
+foo_int (FTYPE *in1, FTYPE *in2, ITYPE *output)
+{
+ int i = 0;
+ /* Vectorizable. */
+ for (i = 0; i < N; i++)
+ output[i] = (in1[i] OP in2[i]) ? 2 : 4;
+}
+
+void
+bar_int (FTYPE *in1, FTYPE *in2, ITYPE *output)
+{
+ int i = 0;
+ /* Vectorizable. */
+ for (i = 0; i < N; i++)
+ output[i] = (in1[i] INV_OP in2[i]) ? 4 : 2;
+}
+
+void
+foobar_int (FTYPE *in1, FTYPE *in2, ITYPE *output)
+{
+ int i = 0;
+ /* Vectorizable. */
+ for (i = 0; i < N; i++)
+ output[i] = (in1[i] OP 0.0) ? 4 : 2;
+}
+
+void
+foobarbar_int (FTYPE *in1, FTYPE *in2, ITYPE *output)
+{
+ int i = 0;
+ /* Vectorizable. */
+ for (i = 0; i < N; i++)
+ output[i] = (in1[i] INV_OP 0.0) ? 4 : 2;
+}
+
int
main (int argc, char **argv)
{
FTYPE out1[N];
FTYPE out2[N];
+ ITYPE outi1[N];
+ ITYPE outi2[N];
+
int i = 0;
foo (input1, input2, out1);
bar (input1, input2, out2);
for (i = 0; i < N; i++)
if (out1[i] == out2[i])
abort ();
+
+ foo_int (input1, input2, outi1);
+ bar_int (input1, input2, outi2);
+ for (i = 0; i < N; i++)
+ if (outi1[i] != outi2[i])
+ abort ();
+ foobar_int (input1, input2, outi1);
+ foobarbar_int (input1, input2, outi2);
+ for (i = 0; i < N; i++)
+ if (outi1[i] == outi2[i])
+ abort ();
return 0;
}