MCKL
Monte Carlo Kernel Library
threefry_sse2_64.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/threefry_sse2_64.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_64_HPP
33 #define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_64_HPP
34 
44 
45 MCKL_PUSH_GCC_WARNING("-Wignored-attributes")
46 
47 namespace mckl {
48 
49 namespace internal {
50 
51 template <typename T, std::size_t K, std::size_t Rounds, typename Constants>
53 {
54  public:
55  static void eval(
56  const void *plain, void *cipher, const std::array<T, K + 4> &par)
57  {
59  plain, cipher, par);
60  }
61 
62  template <typename ResultType>
63  static void eval(
64  Counter<T, K> &ctr, ResultType *r, const std::array<T, K + 4> &par)
65  {
67  ctr, r, par);
68  }
69 
70  template <typename ResultType>
71  static void eval(Counter<T, K> &ctr, std::size_t n, ResultType *r,
72  const std::array<T, K + 4> &par)
73  {
74  constexpr std::size_t S = K <= 8 ? 8 : K;
75  constexpr std::size_t N = sizeof(__m128i) * S / (sizeof(T) * K);
76  constexpr std::size_t R = sizeof(T) * K / sizeof(ResultType);
77 
78  while (n >= N) {
79  std::array<__m128i, S> s;
81  MCKL_INLINE_CALL transpose2x64_load_si128(s);
83  MCKL_INLINE_CALL transpose2x64_store_si128(s);
84  std::memcpy(r, s.data(), sizeof(T) * K * N);
85  n -= N;
86  r += N * R;
87  }
88 
89  alignas(MCKL_ALIGNMENT) std::array<ResultType, N * R> t;
91  ctr, n, t.data(), par);
92  std::memcpy(r, t.data(), sizeof(T) * K * n);
93  }
94 
95  private:
96  template <std::size_t, std::size_t S>
97  static void round(std::array<__m128i, S> &, const std::array<T, K + 4> &,
98  std::false_type)
99  {
100  }
101 
102  template <std::size_t N, std::size_t S>
103  static void round(std::array<__m128i, S> &s,
104  const std::array<T, K + 4> &par, std::true_type)
105  {
107  }
108 
109  template <std::size_t N, std::size_t S>
110  MCKL_INLINE static void kbox(
111  std::array<__m128i, S> &s, const std::array<T, K + 4> &par)
112  {
113  kbox<N>(s, par,
114  std::integral_constant<bool, (N % 4 == 0 && N <= Rounds)>());
115  }
116 
117  template <std::size_t, std::size_t S>
118  static void kbox(std::array<__m128i, S> &, const std::array<T, K + 4> &,
119  std::false_type)
120  {
121  }
122 
123  template <std::size_t N>
124  static void kbox(std::array<__m128i, 8> &s,
125  const std::array<T, K + 4> &par, std::true_type)
126  {
127  std::array<__m128i, K> k;
128  set_key<N>(k, par);
129 
130  std::get<0>(s) = _mm_add_epi64(std::get<0>(s), std::get<0 % K>(k));
131  std::get<1>(s) = _mm_add_epi64(std::get<1>(s), std::get<1 % K>(k));
132  std::get<2>(s) = _mm_add_epi64(std::get<2>(s), std::get<2 % K>(k));
133  std::get<3>(s) = _mm_add_epi64(std::get<3>(s), std::get<3 % K>(k));
134  std::get<4>(s) = _mm_add_epi64(std::get<4>(s), std::get<4 % K>(k));
135  std::get<5>(s) = _mm_add_epi64(std::get<5>(s), std::get<5 % K>(k));
136  std::get<6>(s) = _mm_add_epi64(std::get<6>(s), std::get<6 % K>(k));
137  std::get<7>(s) = _mm_add_epi64(std::get<7>(s), std::get<7 % K>(k));
138  }
139 
140  template <std::size_t N>
141  static void kbox(std::array<__m128i, 16> &s,
142  const std::array<T, K + 4> &par, std::true_type)
143  {
144  std::array<__m128i, K> k;
145  set_key<N>(k, par);
146 
147  std::get<0x0>(s) =
148  _mm_add_epi64(std::get<0x0>(s), std::get<0x0 % K>(k));
149  std::get<0x1>(s) =
150  _mm_add_epi64(std::get<0x1>(s), std::get<0x1 % K>(k));
151  std::get<0x2>(s) =
152  _mm_add_epi64(std::get<0x2>(s), std::get<0x2 % K>(k));
153  std::get<0x3>(s) =
154  _mm_add_epi64(std::get<0x3>(s), std::get<0x3 % K>(k));
155  std::get<0x4>(s) =
156  _mm_add_epi64(std::get<0x4>(s), std::get<0x4 % K>(k));
157  std::get<0x5>(s) =
158  _mm_add_epi64(std::get<0x5>(s), std::get<0x5 % K>(k));
159  std::get<0x6>(s) =
160  _mm_add_epi64(std::get<0x6>(s), std::get<0x6 % K>(k));
161  std::get<0x7>(s) =
162  _mm_add_epi64(std::get<0x7>(s), std::get<0x7 % K>(k));
163  std::get<0x8>(s) =
164  _mm_add_epi64(std::get<0x8>(s), std::get<0x8 % K>(k));
165  std::get<0x9>(s) =
166  _mm_add_epi64(std::get<0x9>(s), std::get<0x9 % K>(k));
167  std::get<0xA>(s) =
168  _mm_add_epi64(std::get<0xA>(s), std::get<0xA % K>(k));
169  std::get<0xB>(s) =
170  _mm_add_epi64(std::get<0xB>(s), std::get<0xB % K>(k));
171  std::get<0xC>(s) =
172  _mm_add_epi64(std::get<0xC>(s), std::get<0xC % K>(k));
173  std::get<0xD>(s) =
174  _mm_add_epi64(std::get<0xD>(s), std::get<0xD % K>(k));
175  std::get<0xE>(s) =
176  _mm_add_epi64(std::get<0xE>(s), std::get<0xE % K>(k));
177  std::get<0xF>(s) =
178  _mm_add_epi64(std::get<0xF>(s), std::get<0xF % K>(k));
179  }
180 
181  template <std::size_t N, std::size_t S>
182  MCKL_INLINE static void rbox(std::array<__m128i, S> &s)
183  {
184  rbox<N>(s, std::integral_constant<bool, (N > 0 && N <= Rounds)>());
185  }
186 
187  template <std::size_t, std::size_t S>
188  static void rbox(std::array<__m128i, S> &, std::false_type)
189  {
190  }
191 
192  template <std::size_t N>
193  static void rbox(std::array<__m128i, 8> &s, std::true_type)
194  {
195  constexpr int L0 = Constants::rotate::value[0 % (K / 2)][(N - 1) % 8];
196  constexpr int L1 = Constants::rotate::value[1 % (K / 2)][(N - 1) % 8];
197  constexpr int L2 = Constants::rotate::value[2 % (K / 2)][(N - 1) % 8];
198  constexpr int L3 = Constants::rotate::value[3 % (K / 2)][(N - 1) % 8];
199  constexpr int R0 = 64 - L0;
200  constexpr int R1 = 64 - L1;
201  constexpr int R2 = 64 - L2;
202  constexpr int R3 = 64 - L3;
203 
204  std::get<0>(s) = _mm_add_epi64(std::get<0>(s), std::get<1>(s));
205  std::get<2>(s) = _mm_add_epi64(std::get<2>(s), std::get<3>(s));
206  std::get<4>(s) = _mm_add_epi64(std::get<4>(s), std::get<5>(s));
207  std::get<6>(s) = _mm_add_epi64(std::get<6>(s), std::get<7>(s));
208 
209  __m128i l0 = _mm_slli_epi64(std::get<1>(s), L0);
210  __m128i l1 = _mm_slli_epi64(std::get<3>(s), L1);
211  __m128i l2 = _mm_slli_epi64(std::get<5>(s), L2);
212  __m128i l3 = _mm_slli_epi64(std::get<7>(s), L3);
213 
214  __m128i r0 = _mm_srli_epi64(std::get<1>(s), R0);
215  __m128i r1 = _mm_srli_epi64(std::get<3>(s), R1);
216  __m128i r2 = _mm_srli_epi64(std::get<5>(s), R2);
217  __m128i r3 = _mm_srli_epi64(std::get<7>(s), R3);
218 
219  std::get<1>(s) = _mm_or_si128(l0, r0);
220  std::get<3>(s) = _mm_or_si128(l1, r1);
221  std::get<5>(s) = _mm_or_si128(l2, r2);
222  std::get<7>(s) = _mm_or_si128(l3, r3);
223 
224  std::get<1>(s) = _mm_xor_si128(std::get<0>(s), std::get<1>(s));
225  std::get<3>(s) = _mm_xor_si128(std::get<2>(s), std::get<3>(s));
226  std::get<5>(s) = _mm_xor_si128(std::get<4>(s), std::get<5>(s));
227  std::get<7>(s) = _mm_xor_si128(std::get<6>(s), std::get<7>(s));
228 
229  permute(s);
230  }
231 
232  template <std::size_t N>
233  static void rbox(std::array<__m128i, 16> &s, std::true_type)
234  {
235  constexpr int L0 = Constants::rotate::value[0 % (K / 2)][(N - 1) % 8];
236  constexpr int L1 = Constants::rotate::value[1 % (K / 2)][(N - 1) % 8];
237  constexpr int L2 = Constants::rotate::value[2 % (K / 2)][(N - 1) % 8];
238  constexpr int L3 = Constants::rotate::value[3 % (K / 2)][(N - 1) % 8];
239  constexpr int L4 = Constants::rotate::value[4 % (K / 2)][(N - 1) % 8];
240  constexpr int L5 = Constants::rotate::value[5 % (K / 2)][(N - 1) % 8];
241  constexpr int L6 = Constants::rotate::value[6 % (K / 2)][(N - 1) % 8];
242  constexpr int L7 = Constants::rotate::value[7 % (K / 2)][(N - 1) % 8];
243  constexpr int R0 = 64 - L0;
244  constexpr int R1 = 64 - L1;
245  constexpr int R2 = 64 - L2;
246  constexpr int R3 = 64 - L3;
247  constexpr int R4 = 64 - L4;
248  constexpr int R5 = 64 - L5;
249  constexpr int R6 = 64 - L6;
250  constexpr int R7 = 64 - L7;
251 
252  std::get<0x0>(s) = _mm_add_epi64(std::get<0x0>(s), std::get<0x1>(s));
253  std::get<0x2>(s) = _mm_add_epi64(std::get<0x2>(s), std::get<0x3>(s));
254  std::get<0x4>(s) = _mm_add_epi64(std::get<0x4>(s), std::get<0x5>(s));
255  std::get<0x6>(s) = _mm_add_epi64(std::get<0x6>(s), std::get<0x7>(s));
256  std::get<0x8>(s) = _mm_add_epi64(std::get<0x8>(s), std::get<0x9>(s));
257  std::get<0xA>(s) = _mm_add_epi64(std::get<0xA>(s), std::get<0xB>(s));
258  std::get<0xC>(s) = _mm_add_epi64(std::get<0xC>(s), std::get<0xD>(s));
259  std::get<0xE>(s) = _mm_add_epi64(std::get<0xE>(s), std::get<0xF>(s));
260 
261  __m128i l0 = _mm_slli_epi64(std::get<0x1>(s), L0);
262  __m128i l1 = _mm_slli_epi64(std::get<0x3>(s), L1);
263  __m128i l2 = _mm_slli_epi64(std::get<0x5>(s), L2);
264  __m128i l3 = _mm_slli_epi64(std::get<0x7>(s), L3);
265  __m128i l4 = _mm_slli_epi64(std::get<0x9>(s), L4);
266  __m128i l5 = _mm_slli_epi64(std::get<0xB>(s), L5);
267  __m128i l6 = _mm_slli_epi64(std::get<0xD>(s), L6);
268  __m128i l7 = _mm_slli_epi64(std::get<0xF>(s), L7);
269 
270  std::get<0x1>(s) = _mm_srli_epi64(std::get<0x1>(s), R0);
271  std::get<0x3>(s) = _mm_srli_epi64(std::get<0x3>(s), R1);
272  std::get<0x5>(s) = _mm_srli_epi64(std::get<0x5>(s), R2);
273  std::get<0x7>(s) = _mm_srli_epi64(std::get<0x7>(s), R3);
274  std::get<0x9>(s) = _mm_srli_epi64(std::get<0x9>(s), R4);
275  std::get<0xB>(s) = _mm_srli_epi64(std::get<0xB>(s), R5);
276  std::get<0xD>(s) = _mm_srli_epi64(std::get<0xD>(s), R6);
277  std::get<0xF>(s) = _mm_srli_epi64(std::get<0xF>(s), R7);
278 
279  std::get<0x1>(s) = _mm_or_si128(l0, std::get<0x1>(s));
280  std::get<0x3>(s) = _mm_or_si128(l1, std::get<0x3>(s));
281  std::get<0x5>(s) = _mm_or_si128(l2, std::get<0x5>(s));
282  std::get<0x7>(s) = _mm_or_si128(l3, std::get<0x7>(s));
283  std::get<0x9>(s) = _mm_or_si128(l4, std::get<0x9>(s));
284  std::get<0xB>(s) = _mm_or_si128(l5, std::get<0xB>(s));
285  std::get<0xD>(s) = _mm_or_si128(l6, std::get<0xD>(s));
286  std::get<0xF>(s) = _mm_or_si128(l7, std::get<0xF>(s));
287 
288  std::get<0x1>(s) = _mm_xor_si128(std::get<0x0>(s), std::get<0x1>(s));
289  std::get<0x3>(s) = _mm_xor_si128(std::get<0x2>(s), std::get<0x3>(s));
290  std::get<0x5>(s) = _mm_xor_si128(std::get<0x4>(s), std::get<0x5>(s));
291  std::get<0x7>(s) = _mm_xor_si128(std::get<0x6>(s), std::get<0x7>(s));
292  std::get<0x9>(s) = _mm_xor_si128(std::get<0x8>(s), std::get<0x9>(s));
293  std::get<0xB>(s) = _mm_xor_si128(std::get<0xA>(s), std::get<0xB>(s));
294  std::get<0xD>(s) = _mm_xor_si128(std::get<0xC>(s), std::get<0xD>(s));
295  std::get<0xF>(s) = _mm_xor_si128(std::get<0xE>(s), std::get<0xF>(s));
296 
297  permute(s);
298  }
299 
300  template <std::size_t N>
301  static void set_key(std::array<__m128i, 2> &k, const std::array<T, 6> &par)
302  {
303  std::get<0>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
304  ThreefryKBox<T, 2, N>::template key<0>(par)));
305  std::get<1>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
306  ThreefryKBox<T, 2, N>::template key<1>(par)));
307  }
308 
309  template <std::size_t N>
310  static void set_key(std::array<__m128i, 4> &k, const std::array<T, 8> &par)
311  {
312  std::get<0>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
313  ThreefryKBox<T, 4, N>::template key<0>(par)));
314  std::get<1>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
315  ThreefryKBox<T, 4, N>::template key<1>(par)));
316  std::get<2>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
317  ThreefryKBox<T, 4, N>::template key<2>(par)));
318  std::get<3>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
319  ThreefryKBox<T, 4, N>::template key<3>(par)));
320  }
321 
322  template <std::size_t N>
323  static void set_key(
324  std::array<__m128i, 8> &k, const std::array<T, 12> &par)
325  {
326  std::get<0>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
327  ThreefryKBox<T, 8, N>::template key<0>(par)));
328  std::get<1>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
329  ThreefryKBox<T, 8, N>::template key<1>(par)));
330  std::get<2>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
331  ThreefryKBox<T, 8, N>::template key<2>(par)));
332  std::get<3>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
333  ThreefryKBox<T, 8, N>::template key<3>(par)));
334  std::get<4>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
335  ThreefryKBox<T, 8, N>::template key<4>(par)));
336  std::get<5>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
337  ThreefryKBox<T, 8, N>::template key<5>(par)));
338  std::get<6>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
339  ThreefryKBox<T, 8, N>::template key<6>(par)));
340  std::get<7>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
341  ThreefryKBox<T, 8, N>::template key<7>(par)));
342  }
343 
344  template <std::size_t N>
345  static void set_key(
346  std::array<__m128i, 16> &k, const std::array<T, 20> &par)
347  {
348  std::get<0x0>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
349  ThreefryKBox<T, 16, N>::template key<0x0>(par)));
350  std::get<0x1>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
351  ThreefryKBox<T, 16, N>::template key<0x1>(par)));
352  std::get<0x2>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
353  ThreefryKBox<T, 16, N>::template key<0x2>(par)));
354  std::get<0x3>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
355  ThreefryKBox<T, 16, N>::template key<0x3>(par)));
356  std::get<0x4>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
357  ThreefryKBox<T, 16, N>::template key<0x4>(par)));
358  std::get<0x5>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
359  ThreefryKBox<T, 16, N>::template key<0x5>(par)));
360  std::get<0x6>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
361  ThreefryKBox<T, 16, N>::template key<0x6>(par)));
362  std::get<0x7>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
363  ThreefryKBox<T, 16, N>::template key<0x7>(par)));
364  std::get<0x8>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
365  ThreefryKBox<T, 16, N>::template key<0x8>(par)));
366  std::get<0x9>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
367  ThreefryKBox<T, 16, N>::template key<0x9>(par)));
368  std::get<0xA>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
369  ThreefryKBox<T, 16, N>::template key<0xA>(par)));
370  std::get<0xB>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
371  ThreefryKBox<T, 16, N>::template key<0xB>(par)));
372  std::get<0xC>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
373  ThreefryKBox<T, 16, N>::template key<0xC>(par)));
374  std::get<0xD>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
375  ThreefryKBox<T, 16, N>::template key<0xD>(par)));
376  std::get<0xE>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
377  ThreefryKBox<T, 16, N>::template key<0xE>(par)));
378  std::get<0xF>(k) = _mm_set1_epi64x(static_cast<MCKL_INT64>(
379  ThreefryKBox<T, 16, N>::template key<0xF>(par)));
380  }
381 
382  template <std::size_t S>
383  static void permute(std::array<__m128i, S> &s)
384  {
385  permute<0>(s, std::integral_constant<bool, 0 < S / K>());
386  }
387 
388  template <std::size_t, std::size_t S>
389  static void permute(std::array<__m128i, S> &, std::false_type)
390  {
391  }
392 
393  template <std::size_t I, std::size_t S>
394  static void permute(std::array<__m128i, S> &s, std::true_type)
395  {
397  permute<I + 1>(s, std::integral_constant<bool, I + 1 < S / K>());
398  }
399 }; // class ThreefryGeneratorSSE2Impl64
400 
401 template <typename T>
404 {
405 }; // class ThreefryGeneratorSSE2Impl64
406 
407 template <typename T>
410 {
411 }; // class ThreefryGeneratorSSE2Impl64
412 
413 template <typename T>
416 {
417 }; // class ThreefryGeneratorSSE2Impl64
418 
419 template <typename T>
422 {
423 }; // class ThreefryGeneratorSSE2Impl64
424 
425 template <typename T>
428 {
429 }; // class ThreefryGeneratorSSE2Impl64
430 
431 template <typename T>
434 {
435 }; // class ThreefryGeneratorSSE2Impl64
436 
437 template <typename T>
440 {
441 }; // class ThreefryGeneratorSSE2Impl64
442 
443 } // namespace internal
444 
445 } // namespace mckl
446 
448 
449 #endif // MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_64_HPP
#define MCKL_PUSH_GCC_WARNING(warning)
Definition: compiler.h:78
void increment_si128(std::array< T, K > &ctr, std::array< __m128i, S > &s, std::false_type)
static void eval(Counter< T, K > &ctr, ResultType *r, const std::array< T, K+4 > &par)
void round(std::size_t n, const float *a, float *y)
Definition: vmf.hpp:310
#define MCKL_INLINE_CALL
Definition: intel.h:142
typename internal::CounterImpl< T, K >::type Counter
A counter type with the same width as std::array<T, K> but with possibly fewer elements.
Definition: increment.hpp:104
#define MCKL_RANDOM_INTERNAL_THREEFRY_UNROLL_ROUND(N, s, par)
static void eval(Counter< T, K > &ctr, std::size_t n, ResultType *r, const std::array< T, K+4 > &par)
Default Threefry constants.
Definition: mcmc.hpp:40
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
#define MCKL_ALIGNMENT
The default alignment for scalar type.
Definition: config.h:187
#define MCKL_INLINE
Definition: clang.h:147
#define MCKL_POP_GCC_WARNING
Definition: compiler.h:79