@@ -2903,15 +2903,15 @@ HWY_API Vec128<T, N> And(const Vec128<T, N> a, const Vec128<T, N> b) {
29032903// ------------------------------ AndNot
29042904
29052905namespace detail {
2906- // reversed_andnot returns a & ~b.
2907- HWY_NEON_DEF_FUNCTION_INTS_UINTS (reversed_andnot , vbic, _, 2 )
2906+ // AndNotSwap returns a & ~b, whereas AndNot is defined as ~a & b.
2907+ HWY_NEON_DEF_FUNCTION_INTS_UINTS (AndNotSwap , vbic, _, 2 )
29082908} // namespace detail
29092909
29102910// Returns ~not_mask & mask.
29112911template <typename T, size_t N, HWY_IF_NOT_FLOAT (T)>
29122912HWY_API Vec128<T, N> AndNot (const Vec128<T, N> not_mask,
29132913 const Vec128<T, N> mask) {
2914- return detail::reversed_andnot (mask, not_mask);
2914+ return detail::AndNotSwap (mask, not_mask);
29152915}
29162916
29172917// Uses the u32/64 defined above.
@@ -2921,7 +2921,7 @@ HWY_API Vec128<T, N> AndNot(const Vec128<T, N> not_mask,
29212921 const DFromV<decltype (mask)> d;
29222922 const RebindToUnsigned<decltype (d)> du;
29232923 VFromD<decltype (du)> ret =
2924- detail::reversed_andnot (BitCast (du, mask), BitCast (du, not_mask));
2924+ detail::AndNotSwap (BitCast (du, mask), BitCast (du, not_mask));
29252925 return BitCast (d, ret);
29262926}
29272927
@@ -2951,6 +2951,13 @@ HWY_API Vec128<T, N> Xor(const Vec128<T, N> a, const Vec128<T, N> b) {
29512951
29522952// ------------------------------ Xor3
29532953#if HWY_ARCH_ARM_A64 && defined(__ARM_FEATURE_SHA3)
2954+
2955+ #ifdef HWY_NATIVE_XOR3
2956+ #undef HWY_NATIVE_XOR3
2957+ #else
2958+ #define HWY_NATIVE_XOR3
2959+ #endif
2960+
29542961HWY_NEON_DEF_FUNCTION_FULL_UI (Xor3, veor3, _, 3 )
29552962
29562963// Half vectors are not natively supported. Two Xor are likely more efficient
@@ -2968,11 +2975,6 @@ HWY_API Vec128<T, N> Xor3(const Vec128<T, N> x1, const Vec128<T, N> x2,
29682975 return BitCast (d, Xor3 (BitCast (du, x1), BitCast (du, x2), BitCast (du, x3)));
29692976}
29702977
2971- #else
2972- template <typename T, size_t N>
2973- HWY_API Vec128<T, N> Xor3 (Vec128<T, N> x1, Vec128<T, N> x2, Vec128<T, N> x3) {
2974- return Xor (x1, Xor (x2, x3));
2975- }
29762978#endif
29772979
29782980// ------------------------------ Or3
@@ -2987,6 +2989,45 @@ HWY_API Vec128<T, N> OrAnd(Vec128<T, N> o, Vec128<T, N> a1, Vec128<T, N> a2) {
29872989 return Or (o, And (a1, a2));
29882990}
29892991
2992+ // ------------------------------ XorAndNot
2993+ #if HWY_ARCH_ARM_A64 && defined(__ARM_FEATURE_SHA3)
2994+
2995+ #ifdef HWY_NATIVE_BCAX
2996+ #undef HWY_NATIVE_BCAX
2997+ #else
2998+ #define HWY_NATIVE_BCAX
2999+ #endif
3000+
3001+ namespace detail {
3002+ HWY_NEON_DEF_FUNCTION_FULL_UI (XorAndNotSwap, vbcax, _, 3 )
3003+ } // namespace detail
3004+
3005+ // As with AndNot, swap the last two arguments because our "negated first"
3006+ // convention mismatches the intrinsics, which have the negated arg last.
3007+ template <class V , HWY_IF_V_SIZE_V (V, 16 ), HWY_IF_NOT_FLOAT_V (V)>
3008+ HWY_API V XorAndNot (V x, V a1, V a2) {
3009+ return detail::XorAndNotSwap (x, a2, a1);
3010+ }
3011+
3012+ // Half vectors are not natively supported. Two ops are likely more efficient
3013+ // than Combine to 128-bit.
3014+ template <typename T, size_t N, HWY_IF_V_SIZE_LE (T, N, 8 ), HWY_IF_NOT_FLOAT (T)>
3015+ HWY_API Vec128<T, N> XorAndNot (Vec128<T, N> x, Vec128<T, N> a1,
3016+ Vec128<T, N> a2) {
3017+ return Xor (x, AndNot (a1, a2));
3018+ }
3019+
3020+ template <typename T, size_t N, HWY_IF_FLOAT (T)>
3021+ HWY_API Vec128<T, N> XorAndNot (const Vec128<T, N> x, const Vec128<T, N> a1,
3022+ const Vec128<T, N> a2) {
3023+ const DFromV<decltype (x)> d;
3024+ const RebindToUnsigned<decltype (d)> du;
3025+ return BitCast (d,
3026+ XorAndNot (BitCast (du, x), BitCast (du, a1), BitCast (du, a2)));
3027+ }
3028+
3029+ #endif
3030+
29903031// ------------------------------ Operator overloads (internal-only if float)
29913032
29923033template <typename T, size_t N>
@@ -7699,7 +7740,7 @@ HWY_API VFromD<DI32> SumOfMulQuadAccumulate(
76997740 return BitCast (di32, Sub (result_sum0, result_sum1));
77007741}
77017742
7702- #endif // __ARM_FEATURE_MATMUL_INT8
7743+ #endif // __ARM_FEATURE_MATMUL_INT8
77037744
77047745#endif // HWY_TARGET == HWY_NEON_BF16
77057746
0 commit comments