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