Sync to Wine-0_9:
[reactos.git] / reactos / lib / rtl / i386 / random_asm.S
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ranom.asm
5 * PURPOSE: Random number generator functions
6 * PROGRAMMER: Magnus Olsen (magnusolsen@greatlord.com)
7 * UPDATE HISTORY:
8 * Created 27/07/2005
9 */
10
11 .intel_syntax noprefix
12
13 /* GLOBALS ****************************************************************/
14
15 .globl _RtlRandom@4 // [1] (no bug) (max optimze code)
16 .globl _RtlUniform@4 // [2] (no bug) (max optimze code)
17 .globl _SavedValue // [3] (no bug) (max optimze code)
18
19 /* FUNCTIONS ***************************************************************/
20
21 _RtlRandom@4:
22 // load pointer
23 mov ecx,[esp+4]
24 mov eax,[ecx]
25
26 // Result = *Seed * 0xffffffed + 0x7fffffc3 // take now 3 cycles
27 lea edx,[eax + eax * 8]
28
29 lea eax,[eax + edx * 2 + 2147483709 ] // + 2147483709
30 neg eax
31
32 cmp eax,-1
33 je .RtlRandom_Rand1
34 cmp eax, 2147483646
35 je .RtlRandom_Rand1
36
37 cmp eax, 2147483647
38 je .RtlRandom_Rand2
39
40 test eax,eax
41 jns .RtlRandom_Rand3
42
43 // else {
44 mov edx,eax
45 and edx,1
46 add eax,edx
47 and eax,2147483647
48 mov [ecx],eax
49 jmp .RtlRandom_Seed
50
51 .RtlRandom_Rand1:
52 // if (Result == 0xffffffff || Result == 0x7ffffffe)
53 add eax, 2
54 and eax, 2147483647
55 mov [ecx],eax
56 jmp .RtlRandom_Seed
57
58 .RtlRandom_Rand2:
59 // else if (Result == 0x7fffffff)
60 xor eax,eax
61 mov [ecx],eax
62 jmp .RtlRandom_Seed
63
64 .RtlRandom_Rand3:
65 // else if ((Result & 0x80000000) == 0)
66 mov edx,eax
67 xor edx,-1 // not edx lock all clock until it finsish, but xor does not do that
68 and edx,1
69 add eax,edx
70 mov [ecx],eax
71
72 .RtlRandom_Seed:
73 mov eax,[ecx]
74
75 // Result = *Seed * 0xffffffed + 0x7fffffc3 // take now 3 cycles
76 lea edx,[eax + eax * 8]
77
78 lea eax,[eax + edx * 2 + 2147483709 ] // + 2147483709 09-18
79 neg eax
80
81 cmp eax,-1
82 je .RtlRandom_Seed1
83 cmp eax, 2147483646
84 je .RtlRandom_Seed1
85
86 cmp eax, 2147483647
87 je .RtlRandom_Seed2
88
89 test eax,eax
90 jns .RtlRandom_Seed3
91
92 // else {
93 mov edx,eax
94 and edx,1
95 add eax,edx
96 and eax,2147483647
97
98 // end
99 mov edx,[ecx]
100 mov [ecx],eax
101
102 mov ecx,eax // pos
103 and ecx, 0x7f // pos = seed & 0x7f
104 mov eax,ecx//
105 mov eax, [_SavedValue + ecx*4]
106 mov [_SavedValue + ecx*4], edx
107 ret 4
108
109 .RtlRandom_Seed1:
110 // if (Result == 0xffffffff || Result == 0x7ffffffe)
111 add eax, 2
112 and eax, 2147483647
113
114 // end
115 mov edx,[ecx]
116 mov [ecx],eax
117
118 mov ecx,eax // pos
119 and ecx, 0x7f // pos = seed & 0x7f
120 mov eax,ecx//
121 mov eax, [_SavedValue + ecx*4]
122 mov [_SavedValue + ecx*4], edx
123 ret 4
124
125 .RtlRandom_Seed2:
126 // else if (Result == 0x7fffffff)
127 xor eax,eax
128
129 // end
130 mov edx,[ecx]
131 mov [ecx],eax
132
133 mov ecx,eax // pos
134 and ecx, 0x7f // pos = seed & 0x7f
135 mov eax,ecx//
136 mov eax, [_SavedValue + ecx*4]
137 mov [_SavedValue + ecx*4], edx
138 ret 4
139
140 .RtlRandom_Seed3:
141 // else if ((Result & 0x80000000) == 0)
142 mov edx,eax
143 xor edx,-1 // not edx lock all clock until it finsish, but xor does not do that
144 and edx,1
145 add eax,edx
146
147 // end
148 mov edx,[ecx]
149 mov [ecx],eax
150
151 mov ecx,eax // pos
152 and ecx, 0x7f // pos = seed & 0x7f
153 mov eax,ecx//
154 mov eax, [_SavedValue + ecx*4]
155 mov [_SavedValue + ecx*4], edx
156 ret 4
157
158 // prototype: ULONG STDCALL RtlUniform (PULONG Seed)
159 _RtlUniform@4:
160 // load pointer
161 mov ecx,[esp+4]
162 mov eax,[ecx]
163
164 // Result = *Seed * 0xffffffed + 0x7fffffc3 // take now 3 cycles
165 lea edx,[eax + eax * 8]
166
167 lea eax,[eax + edx * 2 + 2147483709 ] // + 2147483709 09-18
168 neg eax
169
170 cmp eax,-1
171 je .RtlUniform_jump1
172 cmp eax, 2147483646
173 je .RtlUniform_jump1
174
175 cmp eax, 2147483647
176 je .RtlUniform_jump2
177
178 test eax,eax
179 jns .RtlUniform_jump3
180
181 // else {
182 mov edx,eax
183 and edx,1
184 add eax,edx
185 and eax,2147483647
186 mov [ecx],eax
187 ret 4
188
189 .RtlUniform_jump1:
190 // if (Result == 0xffffffff || Result == 0x7ffffffe)
191 add eax, 2
192 and eax, 2147483647
193 mov [ecx],eax
194 ret 4
195
196 .RtlUniform_jump2:
197 // else if (Result == 0x7fffffff)
198 xor eax,eax
199 mov [ecx],eax
200 ret 4
201
202 .RtlUniform_jump3:
203 // else if ((Result & 0x80000000) == 0)
204 mov edx,eax
205 xor edx,-1 // not edx lock all clock until it finsish, but xor does not do that
206 and edx,1
207 add eax,edx
208 mov [ecx],eax
209 ret 4
210
211 .data
212 // SavedValue[128]
213 _SavedValue:
214 .long 0x4c8bc0aa, 0x4c022957, 0x2232827a, 0x2f1e7626
215 .long 0x7f8bdafb, 0x5c37d02a, 0x0ab48f72, 0x2f0c4ffa
216 .long 0x290e1954, 0x6b635f23, 0x5d3885c0, 0x74b49ff8
217 .long 0x5155fa54, 0x6214ad3f, 0x111e9c29, 0x242a3a09
218 .long 0x75932ae1, 0x40ac432e, 0x54f7ba7a, 0x585ccbd5
219 .long 0x6df5c727, 0x0374dad1, 0x7112b3f1, 0x735fc311
220 .long 0x404331a9, 0x74d97781, 0x64495118, 0x323e04be
221 .long 0x5974b425, 0x4862e393, 0x62389c1d, 0x28a68b82
222 .long 0x0f95da37, 0x7a50bbc6, 0x09b0091c, 0x22cdb7b4
223 .long 0x4faaed26, 0x66417ccd, 0x189e4bfa, 0x1ce4e8dd
224 .long 0x5274c742, 0x3bdcf4dc, 0x2d94e907, 0x32eac016
225 .long 0x26d33ca3, 0x60415a8a, 0x31f57880, 0x68c8aa52
226 .long 0x23eb16da, 0x6204f4a1, 0x373927c1, 0x0d24eb7c
227 .long 0x06dd7379, 0x2b3be507, 0x0f9c55b1, 0x2c7925eb
228 .long 0x36d67c9a, 0x42f831d9, 0x5e3961cb, 0x65d637a8
229 .long 0x24bb3820, 0x4d08e33d, 0x2188754f, 0x147e409e
230 .long 0x6a9620a0, 0x62e26657, 0x7bd8ce81, 0x11da0abb
231 .long 0x5f9e7b50, 0x23e444b6, 0x25920c78, 0x5fc894f0
232 .long 0x5e338cbb, 0x404237fd, 0x1d60f80f, 0x320a1743
233 .long 0x76013d2b, 0x070294ee, 0x695e243b, 0x56b177fd
234 .long 0x752492e1, 0x6decd52f, 0x125f5219, 0x139d2e78
235 .long 0x1898d11e, 0x2f7ee785, 0x4db405d8, 0x1a028a35
236 .long 0x63f6f323, 0x1f6d0078, 0x307cfd67, 0x3f32a78a
237 .long 0x6980796c, 0x462b3d83, 0x34b639f2, 0x53fce379
238 .long 0x74ba50f4, 0x1abc2c4b, 0x5eeaeb8d, 0x335a7a0d
239 .long 0x3973dd20, 0x0462d66b, 0x159813ff, 0x1e4643fd
240 .long 0x06bc5c62, 0x3115e3fc, 0x09101613, 0x47af2515
241 .long 0x4f11ec54, 0x78b99911, 0x3db8dd44, 0x1ec10b9b
242 .long 0x5b5506ca, 0x773ce092, 0x567be81a, 0x5475b975
243 .long 0x7a2cde1a, 0x494536f5, 0x34737bb4, 0x76d9750b
244 .long 0x2a1f6232, 0x2e49644d, 0x7dddcbe7, 0x500cebdb
245 .long 0x619dab9e, 0x48c626fe, 0x1cda3193, 0x52dabe9d