diff --git a/include/ircd/simd/rol.h b/include/ircd/simd/rol.h new file mode 100644 index 000000000..918fff5d3 --- /dev/null +++ b/include/ircd/simd/rol.h @@ -0,0 +1,100 @@ +// The Construct +// +// Copyright (C) The Construct Developers, Authors & Contributors +// Copyright (C) 2016-2020 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_ROL_H + +// xmmx rotate-left interface +namespace ircd::simd +{ + template + T _rol(const T) noexcept; + + template + typename std::enable_if::type + rol(const T a) noexcept; + + template + typename std::enable_if::type + rol(const T a) noexcept; + + template + typename std::enable_if::type + rol(const T a) noexcept; +} + +template +[[using gnu: always_inline, gnu_inline, artificial]] +extern inline T +ircd::simd::_rol(const T a) +noexcept +{ + static_assert + ( + sizeof(T) == sizeof(V) + ); + + static_assert + ( + b % 8 == 0, "[emulated] xmmx register only rotates left at bytewise resolution." + ); + + constexpr int B + { + b / 8 + }; + + size_t i(0); + V arg(a), ret; + for(; i < B; ++i) + ret[i] = arg[sizeof(V) - B + i]; + + for(; i < sizeof(V); ++i) + ret[i] = arg[i - B]; + + return T(ret); +} + +template +[[using gnu: always_inline, gnu_inline, artificial]] +extern inline typename std::enable_if::type +ircd::simd::rol(const T a) +noexcept +{ + return _rol(a); +} + +template +[[using gnu: always_inline, gnu_inline, artificial]] +extern inline typename std::enable_if::type +ircd::simd::rol(const T a) +noexcept +{ + return _rol(a); +} + +template +[[using gnu: always_inline, gnu_inline, artificial]] +extern inline typename std::enable_if::type +ircd::simd::rol(const T a) +noexcept +{ + return _rol(a); +} diff --git a/include/ircd/simd/ror.h b/include/ircd/simd/ror.h new file mode 100644 index 000000000..fbed1f386 --- /dev/null +++ b/include/ircd/simd/ror.h @@ -0,0 +1,105 @@ +// The Construct +// +// Copyright (C) The Construct Developers, Authors & Contributors +// Copyright (C) 2016-2020 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_ROR_H + +// xmmx rotate-right interface +namespace ircd::simd +{ + template + T _ror(const T) noexcept; + + template + typename std::enable_if::type + ror(const T a) noexcept; + + template + typename std::enable_if::type + ror(const T a) noexcept; + + template + typename std::enable_if::type + ror(const T a) noexcept; +} + +template +[[using gnu: always_inline, gnu_inline, artificial]] +extern inline T +ircd::simd::_ror(const T a) +noexcept +{ + static_assert + ( + sizeof(T) == sizeof(V) + ); + + static_assert + ( + b % 8 == 0, "[emulated] xmmx register only rotates left at bytewise resolution." + ); + + constexpr int B + { + b / 8 + }; + + constexpr auto S + { + sizeof(V) - B + }; + + size_t i(0); + V arg(a), ret; + for(; i < S; ++i) + ret[i] = arg[i + B]; + + for(; i < sizeof(V); ++i) + ret[i] = arg[i - S]; + + return T(ret); +} + +template +[[using gnu: always_inline, gnu_inline, artificial]] +extern inline typename std::enable_if::type +ircd::simd::ror(const T a) +noexcept +{ + return _ror(a); +} + +template +[[using gnu: always_inline, gnu_inline, artificial]] +extern inline typename std::enable_if::type +ircd::simd::ror(const T a) +noexcept +{ + return _ror(a); +} + +template +[[using gnu: always_inline, gnu_inline, artificial]] +extern inline typename std::enable_if::type +ircd::simd::ror(const T a) +noexcept +{ + return _ror(a); +} diff --git a/include/ircd/simd/simd.h b/include/ircd/simd/simd.h index f859b52ce..b3b6ec790 100644 --- a/include/ircd/simd/simd.h +++ b/include/ircd/simd/simd.h @@ -22,6 +22,8 @@ #include "gather.h" #include "shl.h" #include "shr.h" +#include "rol.h" +#include "ror.h" #include "popcnt.h" #include "lzcnt.h" #include "tzcnt.h" @@ -36,6 +38,9 @@ namespace ircd using simd::shl; using simd::shr; + using simd::rol; + using simd::ror; + using simd::lzcnt; using simd::tzcnt;