// Copyright 2023 Google LLC // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Tuple support. Included by those ops/* that lack native tuple types, after // they define VFromD and before they use the tuples e.g. for LoadInterleaved2. // Assumes we are already in the HWY_NAMESPACE and under an include guard. // If viewing this header standalone, define VFromD to avoid IDE warnings. // This is normally set by set_macros-inl.h before this header is included. #if !defined(HWY_NAMESPACE) #include "hwy/base.h" template using VFromD = int; #endif // On SVE, Vec2..4 are aliases to built-in types. template struct Vec2 { VFromD v0; VFromD v1; }; template struct Vec3 { VFromD v0; VFromD v1; VFromD v2; }; template struct Vec4 { VFromD v0; VFromD v1; VFromD v2; VFromD v3; }; // D arg is unused but allows deducing D. template HWY_API Vec2 Create2(D /* tag */, VFromD v0, VFromD v1) { return Vec2{v0, v1}; } template HWY_API Vec3 Create3(D /* tag */, VFromD v0, VFromD v1, VFromD v2) { return Vec3{v0, v1, v2}; } template HWY_API Vec4 Create4(D /* tag */, VFromD v0, VFromD v1, VFromD v2, VFromD v3) { return Vec4{v0, v1, v2, v3}; } template HWY_API VFromD Get2(Vec2 tuple) { static_assert(kIndex < 2, "Tuple index out of bounds"); return kIndex == 0 ? tuple.v0 : tuple.v1; } template HWY_API VFromD Get3(Vec3 tuple) { static_assert(kIndex < 3, "Tuple index out of bounds"); return kIndex == 0 ? tuple.v0 : kIndex == 1 ? tuple.v1 : tuple.v2; } template HWY_API VFromD Get4(Vec4 tuple) { static_assert(kIndex < 4, "Tuple index out of bounds"); return kIndex == 0 ? tuple.v0 : kIndex == 1 ? tuple.v1 : kIndex == 2 ? tuple.v2 : tuple.v3; } template HWY_API Vec2 Set2(Vec2 tuple, VFromD val) { static_assert(kIndex < 2, "Tuple index out of bounds"); if (kIndex == 0) { tuple.v0 = val; } else { tuple.v1 = val; } return tuple; } template HWY_API Vec3 Set3(Vec3 tuple, VFromD val) { static_assert(kIndex < 3, "Tuple index out of bounds"); if (kIndex == 0) { tuple.v0 = val; } else if (kIndex == 1) { tuple.v1 = val; } else { tuple.v2 = val; } return tuple; } template HWY_API Vec4 Set4(Vec4 tuple, VFromD val) { static_assert(kIndex < 4, "Tuple index out of bounds"); if (kIndex == 0) { tuple.v0 = val; } else if (kIndex == 1) { tuple.v1 = val; } else if (kIndex == 2) { tuple.v2 = val; } else { tuple.v3 = val; } return tuple; }