odin-blend2d

Odin bindings to Blend2D
Log | Files | Refs | README | LICENSE

vecconsttable.h (15110B)


      1 // This file is part of AsmJit project <https://asmjit.com>
      2 //
      3 // See <asmjit/core.h> or LICENSE.md for license and copyright information
      4 // SPDX-License-Identifier: Zlib
      5 
      6 #ifndef ASMJIT_UJIT_VECCONSTTABLE_H_INCLUDED
      7 #define ASMJIT_UJIT_VECCONSTTABLE_H_INCLUDED
      8 
      9 #include "../core/globals.h"
     10 
     11 #if !defined(ASMJIT_NO_UJIT)
     12 
     13 ASMJIT_BEGIN_SUB_NAMESPACE(ujit)
     14 
     15 //! \addtogroup asmjit_ujit
     16 //! \{
     17 
     18 template<typename T, size_t W>
     19 struct VecConst;
     20 
     21 //! \cond
     22 
     23 //! A 64-bit vector constant of type `T` aligned to 64 bits.
     24 template<typename T>
     25 struct ASMJIT_MAY_ALIAS ASMJIT_ALIGNAS(8) VecConst<T, 8> {
     26   using ElementType = T;
     27 
     28   static inline constexpr size_t kVectorWidth = 8;
     29   static inline constexpr size_t kElementSize = sizeof(ElementType);
     30   static inline constexpr size_t kElementCount = kVectorWidth / kElementSize;
     31 
     32   static_assert(kElementCount > 0u, "Vector constant must have at least one element");
     33 
     34   ElementType data[kElementCount];
     35 
     36   template<typename DstT>
     37   ASMJIT_INLINE_NODEBUG const DstT& as() const noexcept {
     38     static_assert(sizeof(DstT) <= sizeof(*this), "Size of the destination type DstT must be <= 8");
     39     return *static_cast<const DstT*>(static_cast<const void*>(this));
     40   }
     41 };
     42 
     43 //! A 128-bit vector constant of type `T` aligned to 128 bits.
     44 template<typename T>
     45 struct ASMJIT_MAY_ALIAS ASMJIT_ALIGNAS(16) VecConst<T, 16> {
     46   using ElementType = T;
     47 
     48   static inline constexpr size_t kVectorWidth = 16;
     49   static inline constexpr size_t kElementSize = sizeof(ElementType);
     50   static inline constexpr size_t kElementCount = kVectorWidth / kElementSize;
     51 
     52   static_assert(kElementCount > 0u, "Vector constant must have at least one element");
     53 
     54   ElementType data[kElementCount];
     55 
     56   template<typename DstT>
     57   ASMJIT_INLINE_NODEBUG const DstT& as() const noexcept {
     58     static_assert(sizeof(DstT) <= sizeof(*this), "Size of the destination type DstT must be <= 16");
     59     return *static_cast<const DstT*>(static_cast<const void*>(this));
     60   }
     61 };
     62 
     63 //! A 256-bit vector constant of type `T` aligned to 256 bits.
     64 template<typename T>
     65 struct ASMJIT_MAY_ALIAS ASMJIT_ALIGNAS(32) VecConst<T, 32> {
     66   using ElementType = T;
     67 
     68   static inline constexpr size_t kVectorWidth = 32;
     69   static inline constexpr size_t kElementSize = sizeof(ElementType);
     70   static inline constexpr size_t kElementCount = kVectorWidth / kElementSize;
     71 
     72   static_assert(kElementCount > 0u, "Vector constant must have at least one element");
     73 
     74   ElementType data[kElementCount];
     75 
     76   template<typename DstT>
     77   ASMJIT_INLINE_NODEBUG const DstT& as() const noexcept {
     78     static_assert(sizeof(DstT) <= sizeof(*this), "Size of the destination type DstT must be <= 32");
     79     return *static_cast<const DstT*>(static_cast<const void*>(this));
     80   }
     81 };
     82 
     83 //! A 512-bit vector constant of type `T` aligned to 512 bits.
     84 template<typename T>
     85 struct ASMJIT_MAY_ALIAS ASMJIT_ALIGNAS(64) VecConst<T, 64> {
     86   using ElementType = T;
     87 
     88   static inline constexpr size_t kVectorWidth = 64;
     89   static inline constexpr size_t kElementSize = sizeof(ElementType);
     90   static inline constexpr size_t kElementCount = kVectorWidth / kElementSize;
     91 
     92   static_assert(kElementCount > 0u, "Vector constant must have at least one element");
     93 
     94   ElementType data[kElementCount];
     95 
     96   template<typename DstT>
     97   ASMJIT_INLINE_NODEBUG const DstT& as() const noexcept {
     98     static_assert(sizeof(DstT) <= sizeof(*this), "Size of the destination type DstT must be <= 64");
     99     return *static_cast<const DstT*>(static_cast<const void*>(this));
    100   }
    101 };
    102 
    103 //! \endcond
    104 
    105 template<typename T> using VecConst64 = VecConst<T, 8>;
    106 template<typename T> using VecConst128 = VecConst<T, 16>;
    107 template<typename T> using VecConst256 = VecConst<T, 32>;
    108 template<typename T> using VecConst512 = VecConst<T, 64>;
    109 
    110 #if ASMJIT_ARCH_X86
    111 // The maximum native constants we want to use in X86 case is 256-bit ones, because in AVX-512 case
    112 // we want to just broadcast the constant to all lanes. The reason is to not end up with a huge table.
    113 template<typename T> using VecConstNative = VecConst256<T>;
    114 #else
    115 // At the moment all non-x86 platforms support at most 128-bit vectors, thus the maximum width of each
    116 // constant is limited to 128 bits as well. Future additions could include LoongArch, which supports
    117 // 256-bit SIMD vectors natively.
    118 template<typename T> using VecConstNative = VecConst128<T>;
    119 #endif
    120 
    121 template<typename V, typename T = typename V::ElementType>
    122 static ASMJIT_INLINE_CONSTEXPR V make_const(T v) noexcept {
    123   static_assert(V::kElementCount == 1u  ||
    124                 V::kElementCount == 2u  ||
    125                 V::kElementCount == 4u  ||
    126                 V::kElementCount == 8u  ||
    127                 V::kElementCount == 16u ||
    128                 V::kElementCount == 32u ||
    129                 V::kElementCount == 64u);
    130 
    131   if constexpr (V::kElementCount == 1u) {
    132     return V{{
    133       v
    134     }};
    135   }
    136   else if constexpr (V::kElementCount == 2u) {
    137     return V{{
    138       v, v
    139     }};
    140   }
    141   else if constexpr (V::kElementCount == 4u) {
    142     return V{{
    143       v, v, v, v
    144     }};
    145   }
    146   else if constexpr (V::kElementCount == 8u) {
    147     return V{{
    148       v, v, v, v, v, v, v, v
    149     }};
    150   }
    151   else if constexpr (V::kElementCount == 16u) {
    152     return V{{
    153       v, v, v, v, v, v, v, v,
    154       v, v, v, v, v, v, v, v
    155     }};
    156   }
    157   else if constexpr (V::kElementCount == 32u) {
    158     return V{{
    159       v, v, v, v, v, v, v, v,
    160       v, v, v, v, v, v, v, v,
    161       v, v, v, v, v, v, v, v,
    162       v, v, v, v, v, v, v, v
    163     }};
    164   }
    165   else {
    166     return V{{
    167       v, v, v, v, v, v, v, v,
    168       v, v, v, v, v, v, v, v,
    169       v, v, v, v, v, v, v, v,
    170       v, v, v, v, v, v, v, v,
    171       v, v, v, v, v, v, v, v,
    172       v, v, v, v, v, v, v, v,
    173       v, v, v, v, v, v, v, v,
    174       v, v, v, v, v, v, v, v
    175     }};
    176   }
    177 }
    178 
    179 template<typename V, typename T = typename V::ElementType>
    180 static ASMJIT_INLINE_CONSTEXPR V make_const(T h, T l) noexcept {
    181   static_assert(V::kElementCount == 2u  ||
    182                 V::kElementCount == 4u  ||
    183                 V::kElementCount == 8u  ||
    184                 V::kElementCount == 16u ||
    185                 V::kElementCount == 32u ||
    186                 V::kElementCount == 64u);
    187 
    188   if constexpr (V::kElementCount == 2u) {
    189     return V{{
    190       l, h
    191     }};
    192   }
    193   else if constexpr (V::kElementCount == 4u) {
    194     return V{{
    195       l, h, l, h
    196     }};
    197   }
    198   else if constexpr (V::kElementCount == 8u) {
    199     return V{{
    200       l, h, l, h, l, h, l, h
    201     }};
    202   }
    203   else if constexpr (V::kElementCount == 16u) {
    204     return V{{
    205       l, h, l, h, l, h, l, h,
    206       l, h, l, h, l, h, l, h
    207     }};
    208   }
    209   else if constexpr (V::kElementCount == 32u) {
    210     return V{{
    211       l, h, l, h, l, h, l, h,
    212       l, h, l, h, l, h, l, h,
    213       l, h, l, h, l, h, l, h,
    214       l, h, l, h, l, h, l, h
    215     }};
    216   }
    217   else {
    218     return V{{
    219       l, h, l, h, l, h, l, h,
    220       l, h, l, h, l, h, l, h,
    221       l, h, l, h, l, h, l, h,
    222       l, h, l, h, l, h, l, h,
    223       l, h, l, h, l, h, l, h,
    224       l, h, l, h, l, h, l, h,
    225       l, h, l, h, l, h, l, h,
    226       l, h, l, h, l, h, l, h
    227     }};
    228   }
    229 }
    230 
    231 template<typename V, typename T = typename V::ElementType>
    232 static ASMJIT_INLINE_CONSTEXPR V make_const(T d, T c, T b, T a) noexcept {
    233   static_assert(V::kElementCount == 4u  ||
    234                 V::kElementCount == 8u  ||
    235                 V::kElementCount == 16u ||
    236                 V::kElementCount == 32u ||
    237                 V::kElementCount == 64u);
    238 
    239   if constexpr (V::kElementCount == 4u) {
    240     return V{{
    241       a, b, c, d
    242     }};
    243   }
    244   else if constexpr (V::kElementCount == 8u) {
    245     return V{{
    246       a, b, c, d, a, b, c, d
    247     }};
    248   }
    249   else if constexpr (V::kElementCount == 16u) {
    250     return V{{
    251       a, b, c, d, a, b, c, d,
    252       a, b, c, d, a, b, c, d
    253     }};
    254   }
    255   else if constexpr (V::kElementCount == 32u) {
    256     return V{{
    257       a, b, c, d, a, b, c, d,
    258       a, b, c, d, a, b, c, d,
    259       a, b, c, d, a, b, c, d,
    260       a, b, c, d, a, b, c, d
    261     }};
    262   }
    263   else {
    264     return V{{
    265       a, b, c, d, a, b, c, d,
    266       a, b, c, d, a, b, c, d,
    267       a, b, c, d, a, b, c, d,
    268       a, b, c, d, a, b, c, d,
    269       a, b, c, d, a, b, c, d,
    270       a, b, c, d, a, b, c, d,
    271       a, b, c, d, a, b, c, d,
    272       a, b, c, d, a, b, c, d
    273     }};
    274   }
    275 }
    276 
    277 template<typename V, typename T = typename V::ElementType>
    278 static ASMJIT_INLINE_CONSTEXPR V make_const(T h, T g, T f, T e, T d, T c, T b, T a) noexcept {
    279   static_assert(V::kElementCount == 8u  ||
    280                 V::kElementCount == 16u ||
    281                 V::kElementCount == 32u ||
    282                 V::kElementCount == 64u);
    283 
    284   if constexpr (V::kElementCount == 8u) {
    285     return V{{
    286       a, b, c, d, e, f, g, h
    287     }};
    288   }
    289   else if constexpr (V::kElementCount == 16u) {
    290     return V{{
    291       a, b, c, d, e, f, g, h,
    292       a, b, c, d, e, f, g, h
    293     }};
    294   }
    295   else if constexpr (V::kElementCount == 32u) {
    296     return V{{
    297       a, b, c, d, e, f, g, h,
    298       a, b, c, d, e, f, g, h,
    299       a, b, c, d, e, f, g, h,
    300       a, b, c, d, e, f, g, h
    301     }};
    302   }
    303   else {
    304     return V{{
    305       a, b, c, d, e, f, g, h,
    306       a, b, c, d, e, f, g, h,
    307       a, b, c, d, e, f, g, h,
    308       a, b, c, d, e, f, g, h,
    309       a, b, c, d, e, f, g, h,
    310       a, b, c, d, e, f, g, h,
    311       a, b, c, d, e, f, g, h,
    312       a, b, c, d, e, f, g, h
    313     }};
    314   }
    315 }
    316 
    317 template<typename V, typename T = typename V::ElementType>
    318 static ASMJIT_INLINE_CONSTEXPR V make_const(
    319   T p, T o, T n, T m, T l, T k, T j, T i, T h, T g, T f, T e, T d, T c, T b, T a
    320 ) noexcept {
    321   static_assert(V::kElementCount == 16u ||
    322                 V::kElementCount == 32u ||
    323                 V::kElementCount == 64u);
    324 
    325   if constexpr (V::kElementCount == 16u) {
    326     return V{{
    327       a, b, c, d, e, f, g, h,
    328       i, j, k, l, m, n, o, p
    329     }};
    330   }
    331   else if constexpr (V::kElementCount == 32u) {
    332     return V{{
    333       a, b, c, d, e, f, g, h,
    334       i, j, k, l, m, n, o, p,
    335       a, b, c, d, e, f, g, h,
    336       i, j, k, l, m, n, o, p
    337     }};
    338   }
    339   else {
    340     return V{{
    341       a, b, c, d, e, f, g, h,
    342       i, j, k, l, m, n, o, p,
    343       a, b, c, d, e, f, g, h,
    344       i, j, k, l, m, n, o, p,
    345       a, b, c, d, e, f, g, h,
    346       i, j, k, l, m, n, o, p,
    347       a, b, c, d, e, f, g, h,
    348       i, j, k, l, m, n, o, p
    349     }};
    350   }
    351 }
    352 
    353 template<typename V, typename T = typename V::ElementType>
    354 static ASMJIT_INLINE_CONSTEXPR V make_const(
    355   T p1, T o1, T n1, T m1, T l1, T k1, T j1, T i1, T h1, T g1, T f1, T e1, T d1, T c1, T b1, T a1,
    356   T p0, T o0, T n0, T m0, T l0, T k0, T j0, T i0, T h0, T g0, T f0, T e0, T d0, T c0, T b0, T a0
    357 ) noexcept {
    358   static_assert(V::kElementCount == 32u ||
    359                 V::kElementCount == 64u);
    360 
    361   if constexpr (V::kElementCount == 32u) {
    362     return V{{
    363       a0, b0, c0, d0, e0, f0, g0, h0,
    364       i0, j0, k0, l0, m0, n0, o0, p0,
    365       a1, b1, c1, d1, e1, f1, g1, h1,
    366       i1, j1, k1, l1, m1, n1, o1, p1
    367     }};
    368   }
    369   else {
    370     return V{{
    371       a0, b0, c0, d0, e0, f0, g0, h0,
    372       i0, j0, k0, l0, m0, n0, o0, p0,
    373       a1, b1, c1, d1, e1, f1, g1, h1,
    374       i1, j1, k1, l1, m1, n1, o1, p1,
    375       a0, b0, c0, d0, e0, f0, g0, h0,
    376       i0, j0, k0, l0, m0, n0, o0, p0,
    377       a1, b1, c1, d1, e1, f1, g1, h1,
    378       i1, j1, k1, l1, m1, n1, o1, p1
    379     }};
    380   }
    381 }
    382 
    383 template<typename V, typename T = typename V::ElementType>
    384 static ASMJIT_INLINE_CONSTEXPR V make_const(
    385   T p3, T o3, T n3, T m3, T l3, T k3, T j3, T i3, T h3, T g3, T f3, T e3, T d3, T c3, T b3, T a3,
    386   T p2, T o2, T n2, T m2, T l2, T k2, T j2, T i2, T h2, T g2, T f2, T e2, T d2, T c2, T b2, T a2,
    387   T p1, T o1, T n1, T m1, T l1, T k1, T j1, T i1, T h1, T g1, T f1, T e1, T d1, T c1, T b1, T a1,
    388   T p0, T o0, T n0, T m0, T l0, T k0, T j0, T i0, T h0, T g0, T f0, T e0, T d0, T c0, T b0, T a0
    389 ) noexcept {
    390   static_assert(V::kElementCount == 64u);
    391 
    392   return V{{
    393     a0, b0, c0, d0, e0, f0, g0, h0,
    394     i0, j0, k0, l0, m0, n0, o0, p0,
    395     a1, b1, c1, d1, e1, f1, g1, h1,
    396     i1, j1, k1, l1, m1, n1, o1, p1,
    397     a2, b2, c2, d2, e2, f2, g2, h2,
    398     i2, j2, k2, l2, m2, n2, o2, p2,
    399     a3, b3, c3, d3, e3, f3, g3, h3,
    400     i3, j3, k3, l3, m3, n3, o3, p3
    401   }};
    402 }
    403 
    404 struct VecConstTable {
    405   VecConstNative<uint64_t> p_0000000000000000 = make_const<VecConstNative<uint64_t>>(uint64_t(0x0000000000000000u));
    406   VecConstNative<uint64_t> p_FFFFFFFFFFFFFFFF = make_const<VecConstNative<uint64_t>>(uint64_t(0xFFFFFFFFFFFFFFFFu));
    407 
    408   VecConstNative<uint64_t> p_8080808080808080 = make_const<VecConstNative<uint64_t>>(uint64_t(0x8080808080808080u));
    409   VecConstNative<uint64_t> p_8000800080008000 = make_const<VecConstNative<uint64_t>>(uint64_t(0x8000800080008000u));
    410   VecConstNative<uint64_t> p_8000000080000000 = make_const<VecConstNative<uint64_t>>(uint64_t(0x8000000080000000u));
    411   VecConstNative<uint64_t> p_8000000000000000 = make_const<VecConstNative<uint64_t>>(uint64_t(0x8000000000000000u));
    412 
    413   VecConstNative<uint64_t> p_7F7F7F7F7F7F7F7F = make_const<VecConstNative<uint64_t>>(uint64_t(0x7F7F7F7F7F7F7F7Fu));
    414   VecConstNative<uint64_t> p_7FFF7FFF7FFF7FFF = make_const<VecConstNative<uint64_t>>(uint64_t(0x7FFF7FFF7FFF7FFFu));
    415   VecConstNative<uint64_t> p_7FFFFFFF7FFFFFFF = make_const<VecConstNative<uint64_t>>(uint64_t(0x7FFFFFFF7FFFFFFFu));
    416   VecConstNative<uint64_t> p_7FFFFFFFFFFFFFFF = make_const<VecConstNative<uint64_t>>(uint64_t(0x7FFFFFFFFFFFFFFFu));
    417 
    418   VecConstNative<uint64_t> p_0100010001000100 = make_const<VecConstNative<uint64_t>>(uint64_t(0x0100010001000100u));
    419   VecConstNative<uint64_t> p_00FF00FF00FF00FF = make_const<VecConstNative<uint64_t>>(uint64_t(0x00FF00FF00FF00FFu));
    420   VecConstNative<uint64_t> p_0F0F0F0F0F0F0F0F = make_const<VecConstNative<uint64_t>>(uint64_t(0x0F0F0F0F0F0F0F0Fu));
    421 
    422   VecConstNative<uint64_t> p_1010101010101010 = make_const<VecConstNative<uint64_t>>(uint64_t(0x1010101010101010u));
    423 
    424   VecConstNative<uint64_t> p_FFFFFFFF00000000 = make_const<VecConstNative<uint64_t>>(uint64_t(0xFFFFFFFF00000000u));
    425 
    426   VecConstNative<uint64_t> p_0000800000008000 = make_const<VecConstNative<uint64_t>>(uint64_t(0x0000800000008000u));
    427 
    428   VecConst128<uint32_t> sign32_scalar         = make_const<VecConst128<uint32_t>>(0u, 0u, 0u, uint32_t(0x80000000u));
    429   VecConst128<uint64_t> sign64_scalar         = make_const<VecConst128<uint64_t>>(uint64_t(0u), uint64_t(0x8000000000000000u));
    430 
    431   VecConstNative<uint64_t> f32_0_5_minus_1ulp  = make_const<VecConstNative<uint64_t>>(0x3EFFFFFF3EFFFFFFu); // 0.49999997 (0.5f - 1ulp)
    432   VecConstNative<float> f32_0_5               = make_const<VecConstNative<float>>(0.5f);
    433   VecConstNative<float> f32_1                 = make_const<VecConstNative<float>>(1.0f);
    434   VecConstNative<float> f32_round_magic       = make_const<VecConstNative<float>>(8388608.0f);
    435 
    436   VecConstNative<uint64_t> f64_0_5_minus_1ulp  = make_const<VecConstNative<uint64_t>>(0x3FDFFFFFFFFFFFFFu); // 0.49999999999999994 (0.5 - 1ulp).
    437   VecConstNative<double> f64_0_5              = make_const<VecConstNative<double>>(0.5);
    438   VecConstNative<double> f64_1                = make_const<VecConstNative<double>>(1.0);
    439   VecConstNative<double> f64_round_magic      = make_const<VecConstNative<double>>(4503599627370496.0);
    440 };
    441 
    442 ASMJIT_VARAPI const VecConstTable vec_const_table;
    443 
    444 struct VecConstTableRef {
    445   const VecConstTable& table;
    446   size_t size;
    447 };
    448 
    449 //! \}
    450 
    451 ASMJIT_END_SUB_NAMESPACE
    452 
    453 #endif // !ASMJIT_NO_UJIT
    454 #endif // ASMJIT_UJIT_VECCONSTTABLE_H_INCLUDED