Mercurial > vba-linux
comparison src/SFMT/SFMT-sse2.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 /** | |
2 * @file SFMT-sse2.h | |
3 * @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2 | |
4 * | |
5 * @author Mutsuo Saito (Hiroshima University) | |
6 * @author Makoto Matsumoto (Hiroshima University) | |
7 * | |
8 * @note We assume LITTLE ENDIAN in this file | |
9 * | |
10 * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima | |
11 * University. All rights reserved. | |
12 * | |
13 * The new BSD License is applied to this software, see LICENSE.txt | |
14 */ | |
15 | |
16 #ifndef SFMT_SSE2_H | |
17 #define SFMT_SSE2_H | |
18 | |
19 PRE_ALWAYS static __m128i mm_recursion(__m128i *a, __m128i *b, __m128i c, | |
20 __m128i d, __m128i mask) ALWAYSINLINE; | |
21 | |
22 /** | |
23 * This function represents the recursion formula. | |
24 * @param a a 128-bit part of the interal state array | |
25 * @param b a 128-bit part of the interal state array | |
26 * @param c a 128-bit part of the interal state array | |
27 * @param d a 128-bit part of the interal state array | |
28 * @param mask 128-bit mask | |
29 * @return output | |
30 */ | |
31 PRE_ALWAYS static __m128i mm_recursion(__m128i *a, __m128i *b, | |
32 __m128i c, __m128i d, __m128i mask) { | |
33 __m128i v, x, y, z; | |
34 | |
35 x = _mm_load_si128(a); | |
36 y = _mm_srli_epi32(*b, SR1); | |
37 z = _mm_srli_si128(c, SR2); | |
38 v = _mm_slli_epi32(d, SL1); | |
39 z = _mm_xor_si128(z, x); | |
40 z = _mm_xor_si128(z, v); | |
41 x = _mm_slli_si128(x, SL2); | |
42 y = _mm_and_si128(y, mask); | |
43 z = _mm_xor_si128(z, x); | |
44 z = _mm_xor_si128(z, y); | |
45 return z; | |
46 } | |
47 | |
48 /** | |
49 * This function fills the internal state array with pseudorandom | |
50 * integers. | |
51 */ | |
52 inline static void gen_rand_all(void) { | |
53 int i; | |
54 __m128i r, r1, r2, mask; | |
55 mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1); | |
56 | |
57 r1 = _mm_load_si128(&sfmt[N - 2].si); | |
58 r2 = _mm_load_si128(&sfmt[N - 1].si); | |
59 for (i = 0; i < N - POS1; i++) { | |
60 r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1].si, r1, r2, mask); | |
61 _mm_store_si128(&sfmt[i].si, r); | |
62 r1 = r2; | |
63 r2 = r; | |
64 } | |
65 for (; i < N; i++) { | |
66 r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1 - N].si, r1, r2, mask); | |
67 _mm_store_si128(&sfmt[i].si, r); | |
68 r1 = r2; | |
69 r2 = r; | |
70 } | |
71 } | |
72 | |
73 /** | |
74 * This function fills the user-specified array with pseudorandom | |
75 * integers. | |
76 * | |
77 * @param array an 128-bit array to be filled by pseudorandom numbers. | |
78 * @param size number of 128-bit pesudorandom numbers to be generated. | |
79 */ | |
80 inline static void gen_rand_array(w128_t *array, int size) { | |
81 int i, j; | |
82 __m128i r, r1, r2, mask; | |
83 mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1); | |
84 | |
85 r1 = _mm_load_si128(&sfmt[N - 2].si); | |
86 r2 = _mm_load_si128(&sfmt[N - 1].si); | |
87 for (i = 0; i < N - POS1; i++) { | |
88 r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1].si, r1, r2, mask); | |
89 _mm_store_si128(&array[i].si, r); | |
90 r1 = r2; | |
91 r2 = r; | |
92 } | |
93 for (; i < N; i++) { | |
94 r = mm_recursion(&sfmt[i].si, &array[i + POS1 - N].si, r1, r2, mask); | |
95 _mm_store_si128(&array[i].si, r); | |
96 r1 = r2; | |
97 r2 = r; | |
98 } | |
99 /* main loop */ | |
100 for (; i < size - N; i++) { | |
101 r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2, | |
102 mask); | |
103 _mm_store_si128(&array[i].si, r); | |
104 r1 = r2; | |
105 r2 = r; | |
106 } | |
107 for (j = 0; j < 2 * N - size; j++) { | |
108 r = _mm_load_si128(&array[j + size - N].si); | |
109 _mm_store_si128(&sfmt[j].si, r); | |
110 } | |
111 for (; i < size; i++) { | |
112 r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2, | |
113 mask); | |
114 _mm_store_si128(&array[i].si, r); | |
115 _mm_store_si128(&sfmt[j++].si, r); | |
116 r1 = r2; | |
117 r2 = r; | |
118 } | |
119 } | |
120 | |
121 #endif |