| 1 | // Copyright 2009-2021 Intel Corporation | 
| 2 | // SPDX-License-Identifier: Apache-2.0 | 
| 3 |  | 
| 4 | #pragma once | 
| 5 |  | 
| 6 | #include "../sys/platform.h" | 
| 7 |  | 
| 8 | namespace embree | 
| 9 | { | 
| 10 |   /* Varying numeric types */ | 
| 11 |   template<int N> | 
| 12 |   struct vfloat_impl | 
| 13 |   { | 
| 14 |     union { float f[N]; int i[N]; }; | 
| 15 |     __forceinline const float& operator [](size_t index) const { assert(index < N); return f[index]; } | 
| 16 |     __forceinline       float& operator [](size_t index)       { assert(index < N); return f[index]; } | 
| 17 |   }; | 
| 18 |  | 
| 19 |   template<int N> | 
| 20 |   struct vdouble_impl | 
| 21 |   { | 
| 22 |     union { double f[N]; long long i[N]; }; | 
| 23 |     __forceinline const double& operator [](size_t index) const { assert(index < N); return f[index]; } | 
| 24 |     __forceinline       double& operator [](size_t index)       { assert(index < N); return f[index]; } | 
| 25 |   }; | 
| 26 |  | 
| 27 |   template<int N> | 
| 28 |   struct vint_impl | 
| 29 |   { | 
| 30 |     int i[N]; | 
| 31 |     __forceinline const int& operator [](size_t index) const { assert(index < N); return i[index]; } | 
| 32 |     __forceinline       int& operator [](size_t index)       { assert(index < N); return i[index]; } | 
| 33 |   }; | 
| 34 |  | 
| 35 |   template<int N> | 
| 36 |   struct vuint_impl | 
| 37 |   { | 
| 38 |     unsigned int i[N]; | 
| 39 |     __forceinline const unsigned int& operator [](size_t index) const { assert(index < N); return i[index]; } | 
| 40 |     __forceinline       unsigned int& operator [](size_t index)       { assert(index < N); return i[index]; } | 
| 41 |   }; | 
| 42 |  | 
| 43 |   template<int N> | 
| 44 |   struct vllong_impl | 
| 45 |   { | 
| 46 |     long long i[N]; | 
| 47 |     __forceinline const long long& operator [](size_t index) const { assert(index < N); return i[index]; } | 
| 48 |     __forceinline       long long& operator [](size_t index)       { assert(index < N); return i[index]; } | 
| 49 |   }; | 
| 50 |  | 
| 51 |   /* Varying bool types */ | 
| 52 |   template<int N> struct vboolf_impl { int       i[N]; }; // for float/int | 
| 53 |   template<int N> struct vboold_impl { long long i[N]; }; // for double/long long | 
| 54 |   | 
| 55 |   /* Varying size constants */ | 
| 56 | #if defined(__AVX512VL__) // SKX | 
| 57 |   const int VSIZEX = 8;  // default size | 
| 58 |   const int VSIZEL = 16; // large size | 
| 59 | #elif defined(__AVX__) | 
| 60 |   const int VSIZEX = 8; | 
| 61 |   const int VSIZEL = 8; | 
| 62 | #else | 
| 63 |   const int VSIZEX = 4; | 
| 64 |   const int VSIZEL = 4; | 
| 65 | #endif | 
| 66 |  | 
| 67 |   template<int N> | 
| 68 |   struct vtypes { | 
| 69 |     using vbool = vboolf_impl<N>; | 
| 70 |     using vboolf = vboolf_impl<N>; | 
| 71 |     using vboold = vboold_impl<N>; | 
| 72 |     using vint = vint_impl<N>; | 
| 73 |     using vuint = vuint_impl<N>; | 
| 74 |     using vllong = vllong_impl<N>; | 
| 75 |     using vfloat = vfloat_impl<N>; | 
| 76 |     using vdouble = vdouble_impl<N>; | 
| 77 |   }; | 
| 78 |  | 
| 79 |   template<> | 
| 80 |   struct vtypes<1> { | 
| 81 |     using vbool = bool; | 
| 82 |     using vboolf = bool; | 
| 83 |     using vboold = bool; | 
| 84 |     using vint = int; | 
| 85 |     using vuint = unsigned int; | 
| 86 |     using vllong = long long; | 
| 87 |     using vfloat = float; | 
| 88 |     using vdouble = double; | 
| 89 |   }; | 
| 90 |  | 
| 91 |   /* Aliases to default types */ | 
| 92 |   template<int N> using vbool = typename vtypes<N>::vbool; | 
| 93 |   template<int N> using vboolf = typename vtypes<N>::vboolf; | 
| 94 |   template<int N> using vboold = typename vtypes<N>::vboold; | 
| 95 |   template<int N> using vint = typename vtypes<N>::vint; | 
| 96 |   template<int N> using vuint = typename vtypes<N>::vuint; | 
| 97 |   template<int N> using vllong = typename vtypes<N>::vllong; | 
| 98 |   template<int N> using vreal = typename vtypes<N>::vfloat; | 
| 99 |   template<int N> using vfloat = typename vtypes<N>::vfloat; | 
| 100 |   template<int N> using vdouble = typename vtypes<N>::vdouble; | 
| 101 |  | 
| 102 |   /* 4-wide shortcuts */ | 
| 103 |   typedef vfloat<4>  vfloat4; | 
| 104 |   typedef vdouble<4> vdouble4; | 
| 105 |   typedef vreal<4>   vreal4; | 
| 106 |   typedef vint<4>    vint4; | 
| 107 |   typedef vuint<4>  vuint4; | 
| 108 |   typedef vllong<4>  vllong4; | 
| 109 |   typedef vbool<4>   vbool4; | 
| 110 |   typedef vboolf<4>  vboolf4; | 
| 111 |   typedef vboold<4>  vboold4; | 
| 112 |  | 
| 113 |   /* 8-wide shortcuts */ | 
| 114 |   typedef vfloat<8>  vfloat8; | 
| 115 |   typedef vdouble<8> vdouble8; | 
| 116 |   typedef vreal<8>   vreal8; | 
| 117 |   typedef vint<8>    vint8; | 
| 118 |   typedef vuint<8>    vuint8; | 
| 119 |   typedef vllong<8>  vllong8; | 
| 120 |   typedef vbool<8>   vbool8; | 
| 121 |   typedef vboolf<8>  vboolf8; | 
| 122 |   typedef vboold<8>  vboold8; | 
| 123 |  | 
| 124 |   /* 16-wide shortcuts */ | 
| 125 |   typedef vfloat<16>  vfloat16; | 
| 126 |   typedef vdouble<16> vdouble16; | 
| 127 |   typedef vreal<16>   vreal16; | 
| 128 |   typedef vint<16>    vint16; | 
| 129 |   typedef vuint<16>   vuint16; | 
| 130 |   typedef vllong<16>  vllong16; | 
| 131 |   typedef vbool<16>   vbool16; | 
| 132 |   typedef vboolf<16>  vboolf16; | 
| 133 |   typedef vboold<16>  vboold16; | 
| 134 |  | 
| 135 |   /* Default shortcuts */ | 
| 136 |   typedef vfloat<VSIZEX>  vfloatx; | 
| 137 |   typedef vdouble<VSIZEX> vdoublex; | 
| 138 |   typedef vreal<VSIZEX>   vrealx; | 
| 139 |   typedef vint<VSIZEX>    vintx; | 
| 140 |   typedef vuint<VSIZEX>   vuintx; | 
| 141 |   typedef vllong<VSIZEX>  vllongx; | 
| 142 |   typedef vbool<VSIZEX>   vboolx; | 
| 143 |   typedef vboolf<VSIZEX>  vboolfx; | 
| 144 |   typedef vboold<VSIZEX>  vbooldx; | 
| 145 | } | 
| 146 |  |