2c031db2779eae3c293931dbf04ccbddd88296a3
[reactos.git] / reactos / ntoskrnl / ex / i386 / interlck.c
1 /* $Id$
2 *
3 * reactos/ntoskrnl/ex/i386/interlck.c
4 *
5 */
6 #include <ntoskrnl.h>
7
8 #ifdef LOCK
9 #undef LOCK
10 #endif
11
12 #if defined(__GNUC__)
13
14 #ifdef CONFIG_SMP
15 #define LOCK "lock ; "
16 #else
17 #define LOCK ""
18 #endif
19
20 #elif defined(_MSC_VER)
21
22 #ifdef CONFIG_SMP
23 #define LOCK lock
24 #else
25 #define LOCK
26 #endif
27
28 #endif
29
30 #if defined(__GNUC__)
31
32 /*
33 * @implemented
34 */
35 INTERLOCKED_RESULT FASTCALL
36 Exfi386InterlockedIncrementLong(IN PLONG Addend);
37
38 __asm__("\n\t.global @Exfi386InterlockedIncrementLong@4\n\t"
39 "@Exfi386InterlockedIncrementLong@4:\n\t"
40 LOCK
41 "addl $1,(%ecx)\n\t"
42 "lahf\n\t"
43 "andl $0xC000, %eax\n\t"
44 "ret\n\t");
45
46 #elif defined(_MSC_VER)
47
48 /*
49 * @implemented
50 */
51 __declspec(naked)
52 INTERLOCKED_RESULT FASTCALL
53 Exfi386InterlockedIncrementLong(IN PLONG Addend)
54 {
55 __asm LOCK add dword ptr [ecx], 1
56 __asm lahf
57 __asm and eax, 0xC000
58 __asm ret
59 }
60
61 #else
62 #error Unknown compiler for inline assembler
63 #endif
64
65
66 #if defined(__GNUC__)
67
68 /*
69 * @implemented
70 */
71 INTERLOCKED_RESULT FASTCALL
72 Exfi386InterlockedDecrementLong(IN PLONG Addend);
73
74 __asm__("\n\t.global @Exfi386InterlockedDecrementLong@4\n\t"
75 "@Exfi386InterlockedDecrementLong@4:\n\t"
76 LOCK
77 "subl $1,(%ecx)\n\t"
78 "lahf\n\t"
79 "andl $0xC000, %eax\n\t"
80 "ret\n\t");
81
82 #elif defined(_MSC_VER)
83
84 /*
85 * @implemented
86 */
87 __declspec(naked)
88 INTERLOCKED_RESULT FASTCALL
89 Exfi386InterlockedDecrementLong(IN PLONG Addend)
90 {
91 __asm LOCK sub dword ptr [ecx], 1
92 __asm lahf
93 __asm and eax, 0xC000
94 __asm ret
95 }
96
97 #else
98 #error Unknown compiler for inline assembler
99 #endif
100
101
102 #if defined(__GNUC__)
103
104 /*
105 * @implemented
106 */
107 ULONG FASTCALL
108 Exfi386InterlockedExchangeUlong(IN PULONG Target,
109 IN ULONG Value);
110
111 __asm__("\n\t.global @Exfi386InterlockedExchangeUlong@8\n\t"
112 "@Exfi386InterlockedExchangeUlong@8:\n\t"
113 LOCK
114 "xchgl %edx,(%ecx)\n\t"
115 "movl %edx,%eax\n\t"
116 "ret\n\t");
117
118 #elif defined(_MSC_VER)
119
120 /*
121 * @implemented
122 */
123 __declspec(naked)
124 ULONG FASTCALL
125 Exfi386InterlockedExchangeUlong(IN PULONG Target,
126 IN ULONG Value)
127 {
128 __asm LOCK xchg [ecx], edx
129 __asm mov eax, edx
130 __asm ret
131 }
132
133 #else
134 #error Unknown compiler for inline assembler
135 #endif
136
137
138 #if defined(__GNUC__)
139
140 INTERLOCKED_RESULT STDCALL
141 Exi386InterlockedIncrementLong(IN PLONG Addend);
142
143 __asm__("\n\t.global _Exi386InterlockedIncrementLong@4\n\t"
144 "_Exi386InterlockedIncrementLong@4:\n\t"
145 "movl 4(%esp),%eax\n\t"
146 LOCK
147 "addl $1,(%eax)\n\t"
148 "lahf\n\t"
149 "andl $0xC000, %eax\n\t"
150 "ret $4\n\t");
151
152 #elif defined(_MSC_VER)
153
154 __declspec(naked)
155 INTERLOCKED_RESULT STDCALL
156 Exi386InterlockedIncrementLong(IN PLONG Addend)
157 {
158 __asm mov eax, Addend
159 __asm LOCK add dword ptr [eax], 1
160 __asm lahf
161 __asm and eax, 0xC000
162 __asm ret 4
163 }
164
165 #else
166 #error Unknown compiler for inline assembler
167 #endif
168
169
170 #if defined(__GNUC__)
171
172 INTERLOCKED_RESULT STDCALL
173 Exi386InterlockedDecrementLong(IN PLONG Addend);
174
175 __asm__("\n\t.global _Exi386InterlockedDecrementLong@4\n\t"
176 "_Exi386InterlockedDecrementLong@4:\n\t"
177 "movl 4(%esp),%eax\n\t"
178 LOCK
179 "subl $1,(%eax)\n\t"
180 "lahf\n\t"
181 "andl $0xC000, %eax\n\t"
182 "ret $4\n\t");
183
184 #elif defined(_MSC_VER)
185
186 __declspec(naked)
187 INTERLOCKED_RESULT STDCALL
188 Exi386InterlockedDecrementLong(IN PLONG Addend)
189 {
190 __asm mov eax, Addend
191 __asm LOCK sub dword ptr [eax], 1
192 __asm lahf
193 __asm and eax, 0xC000
194 __asm ret 4
195 }
196
197 #else
198 #error Unknown compiler for inline assembler
199 #endif
200
201
202 #if defined(__GNUC__)
203
204 ULONG STDCALL
205 Exi386InterlockedExchangeUlong(IN PULONG Target,
206 IN ULONG Value);
207
208 __asm__("\n\t.global _Exi386InterlockedExchangeUlong@8\n\t"
209 "_Exi386InterlockedExchangeUlong@8:\n\t"
210 "movl 4(%esp),%edx\n\t"
211 "movl 8(%esp),%eax\n\t"
212 LOCK
213 "xchgl %eax,(%edx)\n\t"
214 "ret $8\n\t");
215
216 #elif defined(_MSC_VER)
217
218 __declspec(naked)
219 ULONG STDCALL
220 Exi386InterlockedExchangeUlong(IN PULONG Target,
221 IN ULONG Value)
222 {
223 __asm mov edx, Value
224 __asm mov eax, Target
225 __asm LOCK xchg [edx], eax
226 __asm ret 8
227 }
228
229 #else
230 #error Unknown compiler for inline assembler
231 #endif
232
233
234
235 /**********************************************************************
236 * FASTCALL: @InterlockedIncrement@4
237 * STDCALL : _InterlockedIncrement@4
238 */
239 #if defined(__GNUC__)
240 /*
241 * @implemented
242 */
243 LONG FASTCALL
244 InterlockedIncrement(PLONG Addend);
245 /*
246 * FUNCTION: Increments a caller supplied variable of type LONG as an
247 * atomic operation
248 * ARGUMENTS:
249 * Addend = Points to a variable whose value is to be increment
250 * RETURNS: The incremented value
251 */
252
253 __asm__("\n\t.global @InterlockedIncrement@4\n\t"
254 "@InterlockedIncrement@4:\n\t"
255 "movl $1,%eax\n\t"
256 LOCK
257 "xaddl %eax,(%ecx)\n\t"
258 "incl %eax\n\t"
259 "ret\n\t");
260
261 #elif defined(_MSC_VER)
262 /*
263 * @implemented
264 */
265 __declspec(naked)
266 LONG FASTCALL
267 InterlockedIncrement(PLONG Addend)
268 {
269 __asm mov eax, 1
270 __asm LOCK xadd [ecx], eax
271 __asm inc eax
272 __asm ret
273 }
274
275 #else
276 #error Unknown compiler for inline assembler
277 #endif
278
279
280 /**********************************************************************
281 * FASTCALL: @InterlockedDecrement@4
282 * STDCALL : _InterlockedDecrement@4
283 */
284 #if defined(__GNUC__)
285 /*
286 * @implemented
287 */
288 LONG FASTCALL
289 InterlockedDecrement(PLONG Addend);
290
291 __asm__("\n\t.global @InterlockedDecrement@4\n\t"
292 "@InterlockedDecrement@4:\n\t"
293 "movl $-1,%eax\n\t"
294 LOCK
295 "xaddl %eax,(%ecx)\n\t"
296 "decl %eax\n\t"
297 "ret\n\t");
298
299 #elif defined(_MSC_VER)
300
301 /*
302 * @implemented
303 */
304 __declspec(naked)
305 LONG FASTCALL
306 InterlockedDecrement(PLONG Addend)
307 {
308 __asm mov eax, -1
309 __asm LOCK xadd [ecx], eax
310 __asm dec eax
311 __asm ret
312 }
313
314 #else
315 #error Unknown compiler for inline assembler
316 #endif
317
318
319 /**********************************************************************
320 * FASTCALL: @InterlockedExchange@8
321 * STDCALL : _InterlockedExchange@8
322 */
323
324 #if defined(__GNUC__)
325 /*
326 * @implemented
327 */
328 LONG FASTCALL
329 InterlockedExchange(PLONG Target,
330 LONG Value);
331
332 __asm__("\n\t.global @InterlockedExchange@8\n\t"
333 "@InterlockedExchange@8:\n\t"
334 LOCK
335 "xchgl %edx,(%ecx)\n\t"
336 "movl %edx,%eax\n\t"
337 "ret\n\t");
338
339 #elif defined(_MSC_VER)
340 /*
341 * @implemented
342 */
343 __declspec(naked)
344 LONG FASTCALL
345 InterlockedExchange(PLONG Target,
346 LONG Value)
347 {
348 __asm LOCK xchg [ecx], edx
349 __asm mov eax, edx
350 __asm ret
351 }
352
353 #else
354 #error Unknown compiler for inline assembler
355 #endif
356
357 /**********************************************************************
358 * FASTCALL: @InterlockedExchangeAdd@8
359 * STDCALL: _InterlockedExchangeAdd@8
360 */
361 #if defined(__GNUC__)
362 /*
363 * @implemented
364 */
365 LONG FASTCALL
366 InterlockedExchangeAdd(PLONG Addend,
367 LONG Value);
368
369 __asm__("\n\t.global @InterlockedExchangeAdd@8\n\t"
370 "@InterlockedExchangeAdd@8:\n\t"
371 LOCK
372 "xaddl %edx,(%ecx)\n\t"
373 "movl %edx,%eax\n\t"
374 "ret\n\t");
375
376 #elif defined(_MSC_VER)
377 /*
378 * @implemented
379 */
380 __declspec(naked)
381 LONG FASTCALL
382 InterlockedExchangeAdd(PLONG Addend,
383 LONG Value)
384 {
385 __asm LOCK xadd [ecx], edx
386 __asm mov eax, edx
387 __asm ret
388 }
389
390 #else
391 #error Unknown compiler for inline assembler
392 #endif
393
394
395 /**********************************************************************
396 * FASTCALL: @InterlockedCompareExchange@12
397 * STDCALL: _InterlockedCompareExchange@12
398 */
399 #if defined(__GNUC__)
400
401 LONG FASTCALL
402 InterlockedCompareExchange(PLONG Destination,
403 LONG Exchange,
404 LONG Comperand);
405
406 __asm__("\n\t.global @InterlockedCompareExchange@12\n\t"
407 "@InterlockedCompareExchange@12:\n\t"
408 "movl 4(%esp),%eax\n\t"
409 LOCK
410 "cmpxchg %edx,(%ecx)\n\t"
411 "ret $4\n\t");
412
413 #elif defined(_MSC_VER)
414
415 __declspec(naked)
416 LONG FASTCALL
417 InterlockedCompareExchange(PLONG Destination,
418 LONG Exchange,
419 LONG Comperand)
420 {
421 __asm mov eax, Comperand
422 __asm LOCK cmpxchg [ecx], edx
423 __asm ret 4
424 }
425
426 #else
427 #error Unknown compiler for inline assembler
428 #endif
429
430 /**********************************************************************
431 * FASTCALL: @InterlockedCompareExchange64@8
432 */
433 #if defined(__GNUC__)
434 LONGLONG FASTCALL
435 ExfpInterlockedExchange64(LONGLONG volatile * Destination,
436 PLONGLONG Exchange);
437
438 __asm__("\n\t.global @ExfpInterlockedExchange64@8\n\t"
439 "@ExfpInterlockedExchange64@8:\n\t"
440 "pushl %ebx\n\t"
441 "pushl %esi\n\t"
442 "movl %ecx,%esi\n\t"
443 "movl (%edx),%ebx\n\t"
444 "movl 4(%edx),%ecx\n\t"
445 "\n1:\t"
446 "movl (%esi),%eax\n\t"
447 "movl 4(%esi),%edx\n\t"
448 LOCK
449 "cmpxchg8b (%esi)\n\t"
450 "jnz 1b\n\t"
451 "popl %esi\n\t"
452 "popl %ebx\n\t"
453 "ret\n\t");
454
455 #else
456 #error Unknown compiler for inline assembler
457 #endif
458
459 /**********************************************************************
460 * FASTCALL: @ExfInterlockedCompareExchange@12
461 */
462 #if defined(__GNUC__)
463 LONGLONG FASTCALL
464 ExfInterlockedCompareExchange64(LONGLONG volatile * Destination,
465 PLONGLONG Exchange,
466 PLONGLONG Comperand);
467
468 __asm__("\n\t.global @ExfInterlockedCompareExchange64@12\n\t"
469 "@ExfInterlockedCompareExchange64@12:\n\t"
470 "pushl %ebx\n\t"
471 "pushl %esi\n\t"
472 "movl %ecx,%esi\n\t"
473 "movl (%edx),%ebx\n\t"
474 "movl 4(%edx),%ecx\n\t"
475 "movl 12(%esp),%edx\n\t"
476 "movl (%edx),%eax\n\t"
477 "movl 4(%edx),%edx\n\t"
478 LOCK
479 "cmpxchg8b (%esi)\n\t"
480 "popl %esi\n\t"
481 "popl %ebx\n\t"
482 "ret $4\n\t");
483
484 #else
485 #error Unknown compiler for inline assembler
486 #endif
487
488 /* EOF */