// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2021 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_SIMD_SHUF_H namespace ircd::simd { template T shuf(const T in, const U dst = lane_id(), const U src = lane_id()) noexcept; } /// Move values between lanes in a vector. The destination lane number and /// source lane number are indexed by respective argument. Each argument is /// a vector with the same number of lanes as the input value vector. By /// default each argument vector is lane_id(), which means no-op. /// template inline T ircd::simd::shuf(const T in, const U dst, const U src) noexcept { static_assert ( lanes() == lanes() ); static_assert ( std::is_integral>() ); lane_type out alignas(alignof(T)) [lanes()] { 0 }; for(uint i(0); i < lanes(); ++i) out[dst[i]] = in[src[i]]; return *reinterpret_cast(out); }