]> git.proxmox.com Git - mirror_zfs-debian.git/blob - zfs/lib/libsolcompat/amd64/atomic.S
Initial Linux ZFS GIT Repo
[mirror_zfs-debian.git] / zfs / lib / libsolcompat / amd64 / atomic.S
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 .ident "%Z%%M% %I% %E% SMI"
27
28 .file "%M%"
29
30 #define _ASM
31 #include <sys/asm_linkage.h>
32
33 #if defined(_KERNEL)
34 /*
35 * Legacy kernel interfaces; they will go away (eventually).
36 */
37 ANSI_PRAGMA_WEAK2(cas8,atomic_cas_8,function)
38 ANSI_PRAGMA_WEAK2(cas32,atomic_cas_32,function)
39 ANSI_PRAGMA_WEAK2(cas64,atomic_cas_64,function)
40 ANSI_PRAGMA_WEAK2(caslong,atomic_cas_ulong,function)
41 ANSI_PRAGMA_WEAK2(casptr,atomic_cas_ptr,function)
42 ANSI_PRAGMA_WEAK2(atomic_and_long,atomic_and_ulong,function)
43 ANSI_PRAGMA_WEAK2(atomic_or_long,atomic_or_ulong,function)
44 #else
45 /*
46 * Include the definitions for the libc weak aliases.
47 */
48 #include "../atomic_asm_weak.h"
49 #endif
50
51 ENTRY(atomic_inc_8)
52 ALTENTRY(atomic_inc_uchar)
53 lock
54 incb (%rdi)
55 ret
56 SET_SIZE(atomic_inc_uchar)
57 SET_SIZE(atomic_inc_8)
58
59 ENTRY(atomic_inc_16)
60 ALTENTRY(atomic_inc_ushort)
61 lock
62 incw (%rdi)
63 ret
64 SET_SIZE(atomic_inc_ushort)
65 SET_SIZE(atomic_inc_16)
66
67 ENTRY(atomic_inc_32)
68 ALTENTRY(atomic_inc_uint)
69 lock
70 incl (%rdi)
71 ret
72 SET_SIZE(atomic_inc_uint)
73 SET_SIZE(atomic_inc_32)
74
75 ENTRY(atomic_inc_64)
76 ALTENTRY(atomic_inc_ulong)
77 lock
78 incq (%rdi)
79 ret
80 SET_SIZE(atomic_inc_ulong)
81 SET_SIZE(atomic_inc_64)
82
83 ENTRY(atomic_inc_8_nv)
84 ALTENTRY(atomic_inc_uchar_nv)
85 movb (%rdi), %al
86 1:
87 leaq 1(%rax), %rcx
88 lock
89 cmpxchgb %cl, (%rdi)
90 jne 1b
91 movzbl %cl, %eax
92 ret
93 SET_SIZE(atomic_inc_uchar_nv)
94 SET_SIZE(atomic_inc_8_nv)
95
96 ENTRY(atomic_inc_16_nv)
97 ALTENTRY(atomic_inc_ushort_nv)
98 movw (%rdi), %ax
99 1:
100 leaq 1(%rax), %rcx
101 lock
102 cmpxchgw %cx, (%rdi)
103 jne 1b
104 movzwl %cx, %eax
105 ret
106 SET_SIZE(atomic_inc_ushort_nv)
107 SET_SIZE(atomic_inc_16_nv)
108
109 ENTRY(atomic_inc_32_nv)
110 ALTENTRY(atomic_inc_uint_nv)
111 movl (%rdi), %eax
112 1:
113 leaq 1(%rax), %rcx
114 lock
115 cmpxchgl %ecx, (%rdi)
116 jne 1b
117 movl %ecx, %eax
118 ret
119 SET_SIZE(atomic_inc_uint_nv)
120 SET_SIZE(atomic_inc_32_nv)
121
122 ENTRY(atomic_inc_64_nv)
123 ALTENTRY(atomic_inc_ulong_nv)
124 movq (%rdi), %rax
125 1:
126 leaq 1(%rax), %rcx
127 lock
128 cmpxchgq %rcx, (%rdi)
129 jne 1b
130 movq %rcx, %rax
131 ret
132 SET_SIZE(atomic_inc_ulong_nv)
133 SET_SIZE(atomic_inc_64_nv)
134
135 ENTRY(atomic_dec_8)
136 ALTENTRY(atomic_dec_uchar)
137 lock
138 decb (%rdi)
139 ret
140 SET_SIZE(atomic_dec_uchar)
141 SET_SIZE(atomic_dec_8)
142
143 ENTRY(atomic_dec_16)
144 ALTENTRY(atomic_dec_ushort)
145 lock
146 decw (%rdi)
147 ret
148 SET_SIZE(atomic_dec_ushort)
149 SET_SIZE(atomic_dec_16)
150
151 ENTRY(atomic_dec_32)
152 ALTENTRY(atomic_dec_uint)
153 lock
154 decl (%rdi)
155 ret
156 SET_SIZE(atomic_dec_uint)
157 SET_SIZE(atomic_dec_32)
158
159 ENTRY(atomic_dec_64)
160 ALTENTRY(atomic_dec_ulong)
161 lock
162 decq (%rdi)
163 ret
164 SET_SIZE(atomic_dec_ulong)
165 SET_SIZE(atomic_dec_64)
166
167 ENTRY(atomic_dec_8_nv)
168 ALTENTRY(atomic_dec_uchar_nv)
169 movb (%rdi), %al
170 1:
171 leaq -1(%rax), %rcx
172 lock
173 cmpxchgb %cl, (%rdi)
174 jne 1b
175 movzbl %cl, %eax
176 ret
177 SET_SIZE(atomic_dec_uchar_nv)
178 SET_SIZE(atomic_dec_8_nv)
179
180 ENTRY(atomic_dec_16_nv)
181 ALTENTRY(atomic_dec_ushort_nv)
182 movw (%rdi), %ax
183 1:
184 leaq -1(%rax), %rcx
185 lock
186 cmpxchgw %cx, (%rdi)
187 jne 1b
188 movzwl %cx, %eax
189 ret
190 SET_SIZE(atomic_dec_ushort_nv)
191 SET_SIZE(atomic_dec_16_nv)
192
193 ENTRY(atomic_dec_32_nv)
194 ALTENTRY(atomic_dec_uint_nv)
195 movl (%rdi), %eax
196 1:
197 leaq -1(%rax), %rcx
198 lock
199 cmpxchgl %ecx, (%rdi)
200 jne 1b
201 movl %ecx, %eax
202 ret
203 SET_SIZE(atomic_dec_uint_nv)
204 SET_SIZE(atomic_dec_32_nv)
205
206 ENTRY(atomic_dec_64_nv)
207 ALTENTRY(atomic_dec_ulong_nv)
208 movq (%rdi), %rax
209 1:
210 leaq -1(%rax), %rcx
211 lock
212 cmpxchgq %rcx, (%rdi)
213 jne 1b
214 movq %rcx, %rax
215 ret
216 SET_SIZE(atomic_dec_ulong_nv)
217 SET_SIZE(atomic_dec_64_nv)
218
219 ENTRY(atomic_add_8)
220 ALTENTRY(atomic_add_char)
221 lock
222 addb %sil, (%rdi)
223 ret
224 SET_SIZE(atomic_add_char)
225 SET_SIZE(atomic_add_8)
226
227 ENTRY(atomic_add_16)
228 ALTENTRY(atomic_add_short)
229 lock
230 addw %si, (%rdi)
231 ret
232 SET_SIZE(atomic_add_short)
233 SET_SIZE(atomic_add_16)
234
235 ENTRY(atomic_add_32)
236 ALTENTRY(atomic_add_int)
237 lock
238 addl %esi, (%rdi)
239 ret
240 SET_SIZE(atomic_add_int)
241 SET_SIZE(atomic_add_32)
242
243 ENTRY(atomic_add_64)
244 ALTENTRY(atomic_add_ptr)
245 ALTENTRY(atomic_add_long)
246 lock
247 addq %rsi, (%rdi)
248 ret
249 SET_SIZE(atomic_add_long)
250 SET_SIZE(atomic_add_ptr)
251 SET_SIZE(atomic_add_64)
252
253 ENTRY(atomic_or_8)
254 ALTENTRY(atomic_or_uchar)
255 lock
256 orb %sil, (%rdi)
257 ret
258 SET_SIZE(atomic_or_uchar)
259 SET_SIZE(atomic_or_8)
260
261 ENTRY(atomic_or_16)
262 ALTENTRY(atomic_or_ushort)
263 lock
264 orw %si, (%rdi)
265 ret
266 SET_SIZE(atomic_or_ushort)
267 SET_SIZE(atomic_or_16)
268
269 ENTRY(atomic_or_32)
270 ALTENTRY(atomic_or_uint)
271 lock
272 orl %esi, (%rdi)
273 ret
274 SET_SIZE(atomic_or_uint)
275 SET_SIZE(atomic_or_32)
276
277 ENTRY(atomic_or_64)
278 ALTENTRY(atomic_or_ulong)
279 lock
280 orq %rsi, (%rdi)
281 ret
282 SET_SIZE(atomic_or_ulong)
283 SET_SIZE(atomic_or_64)
284
285 ENTRY(atomic_and_8)
286 ALTENTRY(atomic_and_uchar)
287 lock
288 andb %sil, (%rdi)
289 ret
290 SET_SIZE(atomic_and_uchar)
291 SET_SIZE(atomic_and_8)
292
293 ENTRY(atomic_and_16)
294 ALTENTRY(atomic_and_ushort)
295 lock
296 andw %si, (%rdi)
297 ret
298 SET_SIZE(atomic_and_ushort)
299 SET_SIZE(atomic_and_16)
300
301 ENTRY(atomic_and_32)
302 ALTENTRY(atomic_and_uint)
303 lock
304 andl %esi, (%rdi)
305 ret
306 SET_SIZE(atomic_and_uint)
307 SET_SIZE(atomic_and_32)
308
309 ENTRY(atomic_and_64)
310 ALTENTRY(atomic_and_ulong)
311 lock
312 andq %rsi, (%rdi)
313 ret
314 SET_SIZE(atomic_and_ulong)
315 SET_SIZE(atomic_and_64)
316
317 ENTRY(atomic_add_8_nv)
318 ALTENTRY(atomic_add_char_nv)
319 movb (%rdi), %al
320 1:
321 movb %sil, %cl
322 addb %al, %cl
323 lock
324 cmpxchgb %cl, (%rdi)
325 jne 1b
326 movzbl %cl, %eax
327 ret
328 SET_SIZE(atomic_add_char_nv)
329 SET_SIZE(atomic_add_8_nv)
330
331 ENTRY(atomic_add_16_nv)
332 ALTENTRY(atomic_add_short_nv)
333 movw (%rdi), %ax
334 1:
335 movw %si, %cx
336 addw %ax, %cx
337 lock
338 cmpxchgw %cx, (%rdi)
339 jne 1b
340 movzwl %cx, %eax
341 ret
342 SET_SIZE(atomic_add_short_nv)
343 SET_SIZE(atomic_add_16_nv)
344
345 ENTRY(atomic_add_32_nv)
346 ALTENTRY(atomic_add_int_nv)
347 movl (%rdi), %eax
348 1:
349 movl %esi, %ecx
350 addl %eax, %ecx
351 lock
352 cmpxchgl %ecx, (%rdi)
353 jne 1b
354 movl %ecx, %eax
355 ret
356 SET_SIZE(atomic_add_int_nv)
357 SET_SIZE(atomic_add_32_nv)
358
359 ENTRY(atomic_add_64_nv)
360 ALTENTRY(atomic_add_ptr_nv)
361 ALTENTRY(atomic_add_long_nv)
362 movq (%rdi), %rax
363 1:
364 movq %rsi, %rcx
365 addq %rax, %rcx
366 lock
367 cmpxchgq %rcx, (%rdi)
368 jne 1b
369 movq %rcx, %rax
370 ret
371 SET_SIZE(atomic_add_long_nv)
372 SET_SIZE(atomic_add_ptr_nv)
373 SET_SIZE(atomic_add_64_nv)
374
375 ENTRY(atomic_and_8_nv)
376 ALTENTRY(atomic_and_uchar_nv)
377 movb (%rdi), %al
378 1:
379 movb %sil, %cl
380 andb %al, %cl
381 lock
382 cmpxchgb %cl, (%rdi)
383 jne 1b
384 movzbl %cl, %eax
385 ret
386 SET_SIZE(atomic_and_uchar_nv)
387 SET_SIZE(atomic_and_8_nv)
388
389 ENTRY(atomic_and_16_nv)
390 ALTENTRY(atomic_and_ushort_nv)
391 movw (%rdi), %ax
392 1:
393 movw %si, %cx
394 andw %ax, %cx
395 lock
396 cmpxchgw %cx, (%rdi)
397 jne 1b
398 movzwl %cx, %eax
399 ret
400 SET_SIZE(atomic_and_ushort_nv)
401 SET_SIZE(atomic_and_16_nv)
402
403 ENTRY(atomic_and_32_nv)
404 ALTENTRY(atomic_and_uint_nv)
405 movl (%rdi), %eax
406 1:
407 movl %esi, %ecx
408 andl %eax, %ecx
409 lock
410 cmpxchgl %ecx, (%rdi)
411 jne 1b
412 movl %ecx, %eax
413 ret
414 SET_SIZE(atomic_and_uint_nv)
415 SET_SIZE(atomic_and_32_nv)
416
417 ENTRY(atomic_and_64_nv)
418 ALTENTRY(atomic_and_ulong_nv)
419 movq (%rdi), %rax
420 1:
421 movq %rsi, %rcx
422 andq %rax, %rcx
423 lock
424 cmpxchgq %rcx, (%rdi)
425 jne 1b
426 movq %rcx, %rax
427 ret
428 SET_SIZE(atomic_and_ulong_nv)
429 SET_SIZE(atomic_and_64_nv)
430
431 ENTRY(atomic_or_8_nv)
432 ALTENTRY(atomic_or_uchar_nv)
433 movb (%rdi), %al
434 1:
435 movb %sil, %cl
436 orb %al, %cl
437 lock
438 cmpxchgb %cl, (%rdi)
439 jne 1b
440 movzbl %cl, %eax
441 ret
442 SET_SIZE(atomic_and_uchar_nv)
443 SET_SIZE(atomic_and_8_nv)
444
445 ENTRY(atomic_or_16_nv)
446 ALTENTRY(atomic_or_ushort_nv)
447 movw (%rdi), %ax
448 1:
449 movw %si, %cx
450 orw %ax, %cx
451 lock
452 cmpxchgw %cx, (%rdi)
453 jne 1b
454 movzwl %cx, %eax
455 ret
456 SET_SIZE(atomic_or_ushort_nv)
457 SET_SIZE(atomic_or_16_nv)
458
459 ENTRY(atomic_or_32_nv)
460 ALTENTRY(atomic_or_uint_nv)
461 movl (%rdi), %eax
462 1:
463 movl %esi, %ecx
464 orl %eax, %ecx
465 lock
466 cmpxchgl %ecx, (%rdi)
467 jne 1b
468 movl %ecx, %eax
469 ret
470 SET_SIZE(atomic_or_uint_nv)
471 SET_SIZE(atomic_or_32_nv)
472
473 ENTRY(atomic_or_64_nv)
474 ALTENTRY(atomic_or_ulong_nv)
475 movq (%rdi), %rax
476 1:
477 movq %rsi, %rcx
478 orq %rax, %rcx
479 lock
480 cmpxchgq %rcx, (%rdi)
481 jne 1b
482 movq %rcx, %rax
483 ret
484 SET_SIZE(atomic_or_ulong_nv)
485 SET_SIZE(atomic_or_64_nv)
486
487 ENTRY(atomic_cas_8)
488 ALTENTRY(atomic_cas_uchar)
489 movzbl %sil, %eax
490 lock
491 cmpxchgb %dl, (%rdi)
492 ret
493 SET_SIZE(atomic_cas_uchar)
494 SET_SIZE(atomic_cas_8)
495
496 ENTRY(atomic_cas_16)
497 ALTENTRY(atomic_cas_ushort)
498 movzwl %si, %eax
499 lock
500 cmpxchgw %dx, (%rdi)
501 ret
502 SET_SIZE(atomic_cas_ushort)
503 SET_SIZE(atomic_cas_16)
504
505 ENTRY(atomic_cas_32)
506 ALTENTRY(atomic_cas_uint)
507 movl %esi, %eax
508 lock
509 cmpxchgl %edx, (%rdi)
510 ret
511 SET_SIZE(atomic_cas_uint)
512 SET_SIZE(atomic_cas_32)
513
514 ENTRY(atomic_cas_64)
515 ALTENTRY(atomic_cas_ulong)
516 ALTENTRY(atomic_cas_ptr)
517 movq %rsi, %rax
518 lock
519 cmpxchgq %rdx, (%rdi)
520 ret
521 SET_SIZE(atomic_cas_ptr)
522 SET_SIZE(atomic_cas_ulong)
523 SET_SIZE(atomic_cas_64)
524
525 ENTRY(atomic_swap_8)
526 ALTENTRY(atomic_swap_uchar)
527 movzbl %sil, %eax
528 lock
529 xchgb %al, (%rdi)
530 ret
531 SET_SIZE(atomic_swap_uchar)
532 SET_SIZE(atomic_swap_8)
533
534 ENTRY(atomic_swap_16)
535 ALTENTRY(atomic_swap_ushort)
536 movzwl %si, %eax
537 lock
538 xchgw %ax, (%rdi)
539 ret
540 SET_SIZE(atomic_swap_ushort)
541 SET_SIZE(atomic_swap_16)
542
543 ENTRY(atomic_swap_32)
544 ALTENTRY(atomic_swap_uint)
545 movl %esi, %eax
546 lock
547 xchgl %eax, (%rdi)
548 ret
549 SET_SIZE(atomic_swap_uint)
550 SET_SIZE(atomic_swap_32)
551
552 ENTRY(atomic_swap_64)
553 ALTENTRY(atomic_swap_ulong)
554 ALTENTRY(atomic_swap_ptr)
555 movq %rsi, %rax
556 lock
557 xchgq %rax, (%rdi)
558 ret
559 SET_SIZE(atomic_swap_ptr)
560 SET_SIZE(atomic_swap_ulong)
561 SET_SIZE(atomic_swap_64)
562
563 ENTRY(atomic_set_long_excl)
564 xorl %eax, %eax
565 lock
566 btsq %rsi, (%rdi)
567 jnc 1f
568 decl %eax
569 1:
570 ret
571 SET_SIZE(atomic_set_long_excl)
572
573 ENTRY(atomic_clear_long_excl)
574 xorl %eax, %eax
575 lock
576 btrq %rsi, (%rdi)
577 jc 1f
578 decl %eax
579 1:
580 ret
581 SET_SIZE(atomic_clear_long_excl)
582
583 #if !defined(_KERNEL)
584
585 /*
586 * NOTE: membar_enter, and membar_exit are identical routines.
587 * We define them separately, instead of using an ALTENTRY
588 * definitions to alias them together, so that DTrace and
589 * debuggers will see a unique address for them, allowing
590 * more accurate tracing.
591 */
592
593 ENTRY(membar_enter)
594 mfence
595 ret
596 SET_SIZE(membar_enter)
597
598 ENTRY(membar_exit)
599 mfence
600 ret
601 SET_SIZE(membar_exit)
602
603 ENTRY(membar_producer)
604 sfence
605 ret
606 SET_SIZE(membar_producer)
607
608 ENTRY(membar_consumer)
609 lfence
610 ret
611 SET_SIZE(membar_consumer)
612
613 #endif /* !_KERNEL */
614
615 #ifdef __ELF__
616 .section .note.GNU-stack,"",%progbits
617 #endif