]> git.proxmox.com Git - mirror_zfs-debian.git/blame - lib/libspl/asm-x86_64/atomic.S
Add atomic_sub_* functions to libspl.
[mirror_zfs-debian.git] / lib / libspl / asm-x86_64 / atomic.S
CommitLineData
a26baf28
BB
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 <ia32/sys/asm_linkage.h>
32
33 ENTRY(atomic_inc_8)
34 ALTENTRY(atomic_inc_uchar)
35 lock
36 incb (%rdi)
37 ret
38 SET_SIZE(atomic_inc_uchar)
39 SET_SIZE(atomic_inc_8)
40
41 ENTRY(atomic_inc_16)
42 ALTENTRY(atomic_inc_ushort)
43 lock
44 incw (%rdi)
45 ret
46 SET_SIZE(atomic_inc_ushort)
47 SET_SIZE(atomic_inc_16)
48
49 ENTRY(atomic_inc_32)
50 ALTENTRY(atomic_inc_uint)
51 lock
52 incl (%rdi)
53 ret
54 SET_SIZE(atomic_inc_uint)
55 SET_SIZE(atomic_inc_32)
56
57 ENTRY(atomic_inc_64)
58 ALTENTRY(atomic_inc_ulong)
59 lock
60 incq (%rdi)
61 ret
62 SET_SIZE(atomic_inc_ulong)
63 SET_SIZE(atomic_inc_64)
64
65 ENTRY(atomic_inc_8_nv)
66 ALTENTRY(atomic_inc_uchar_nv)
67 movb (%rdi), %al
681:
69 leaq 1(%rax), %rcx
70 lock
71 cmpxchgb %cl, (%rdi)
72 jne 1b
73 movzbl %cl, %eax
74 ret
75 SET_SIZE(atomic_inc_uchar_nv)
76 SET_SIZE(atomic_inc_8_nv)
77
78 ENTRY(atomic_inc_16_nv)
79 ALTENTRY(atomic_inc_ushort_nv)
80 movw (%rdi), %ax
811:
82 leaq 1(%rax), %rcx
83 lock
84 cmpxchgw %cx, (%rdi)
85 jne 1b
86 movzwl %cx, %eax
87 ret
88 SET_SIZE(atomic_inc_ushort_nv)
89 SET_SIZE(atomic_inc_16_nv)
90
91 ENTRY(atomic_inc_32_nv)
92 ALTENTRY(atomic_inc_uint_nv)
93 movl (%rdi), %eax
941:
95 leaq 1(%rax), %rcx
96 lock
97 cmpxchgl %ecx, (%rdi)
98 jne 1b
99 movl %ecx, %eax
100 ret
101 SET_SIZE(atomic_inc_uint_nv)
102 SET_SIZE(atomic_inc_32_nv)
103
104 ENTRY(atomic_inc_64_nv)
105 ALTENTRY(atomic_inc_ulong_nv)
106 movq (%rdi), %rax
1071:
108 leaq 1(%rax), %rcx
109 lock
110 cmpxchgq %rcx, (%rdi)
111 jne 1b
112 movq %rcx, %rax
113 ret
114 SET_SIZE(atomic_inc_ulong_nv)
115 SET_SIZE(atomic_inc_64_nv)
116
117 ENTRY(atomic_dec_8)
118 ALTENTRY(atomic_dec_uchar)
119 lock
120 decb (%rdi)
121 ret
122 SET_SIZE(atomic_dec_uchar)
123 SET_SIZE(atomic_dec_8)
124
125 ENTRY(atomic_dec_16)
126 ALTENTRY(atomic_dec_ushort)
127 lock
128 decw (%rdi)
129 ret
130 SET_SIZE(atomic_dec_ushort)
131 SET_SIZE(atomic_dec_16)
132
133 ENTRY(atomic_dec_32)
134 ALTENTRY(atomic_dec_uint)
135 lock
136 decl (%rdi)
137 ret
138 SET_SIZE(atomic_dec_uint)
139 SET_SIZE(atomic_dec_32)
140
141 ENTRY(atomic_dec_64)
142 ALTENTRY(atomic_dec_ulong)
143 lock
144 decq (%rdi)
145 ret
146 SET_SIZE(atomic_dec_ulong)
147 SET_SIZE(atomic_dec_64)
148
149 ENTRY(atomic_dec_8_nv)
150 ALTENTRY(atomic_dec_uchar_nv)
151 movb (%rdi), %al
1521:
153 leaq -1(%rax), %rcx
154 lock
155 cmpxchgb %cl, (%rdi)
156 jne 1b
157 movzbl %cl, %eax
158 ret
159 SET_SIZE(atomic_dec_uchar_nv)
160 SET_SIZE(atomic_dec_8_nv)
161
162 ENTRY(atomic_dec_16_nv)
163 ALTENTRY(atomic_dec_ushort_nv)
164 movw (%rdi), %ax
1651:
166 leaq -1(%rax), %rcx
167 lock
168 cmpxchgw %cx, (%rdi)
169 jne 1b
170 movzwl %cx, %eax
171 ret
172 SET_SIZE(atomic_dec_ushort_nv)
173 SET_SIZE(atomic_dec_16_nv)
174
175 ENTRY(atomic_dec_32_nv)
176 ALTENTRY(atomic_dec_uint_nv)
177 movl (%rdi), %eax
1781:
179 leaq -1(%rax), %rcx
180 lock
181 cmpxchgl %ecx, (%rdi)
182 jne 1b
183 movl %ecx, %eax
184 ret
185 SET_SIZE(atomic_dec_uint_nv)
186 SET_SIZE(atomic_dec_32_nv)
187
188 ENTRY(atomic_dec_64_nv)
189 ALTENTRY(atomic_dec_ulong_nv)
190 movq (%rdi), %rax
1911:
192 leaq -1(%rax), %rcx
193 lock
194 cmpxchgq %rcx, (%rdi)
195 jne 1b
196 movq %rcx, %rax
197 ret
198 SET_SIZE(atomic_dec_ulong_nv)
199 SET_SIZE(atomic_dec_64_nv)
200
201 ENTRY(atomic_add_8)
202 ALTENTRY(atomic_add_char)
203 lock
204 addb %sil, (%rdi)
205 ret
206 SET_SIZE(atomic_add_char)
207 SET_SIZE(atomic_add_8)
208
209 ENTRY(atomic_add_16)
210 ALTENTRY(atomic_add_short)
211 lock
212 addw %si, (%rdi)
213 ret
214 SET_SIZE(atomic_add_short)
215 SET_SIZE(atomic_add_16)
216
217 ENTRY(atomic_add_32)
218 ALTENTRY(atomic_add_int)
219 lock
220 addl %esi, (%rdi)
221 ret
222 SET_SIZE(atomic_add_int)
223 SET_SIZE(atomic_add_32)
224
225 ENTRY(atomic_add_64)
226 ALTENTRY(atomic_add_ptr)
227 ALTENTRY(atomic_add_long)
228 lock
229 addq %rsi, (%rdi)
230 ret
231 SET_SIZE(atomic_add_long)
232 SET_SIZE(atomic_add_ptr)
233 SET_SIZE(atomic_add_64)
234
142e6dd1
ED
235 ENTRY(atomic_sub_8)
236 ALTENTRY(atomic_sub_char)
237 lock
238 subb %sil, (%rdi)
239 ret
240 SET_SIZE(atomic_sub_char)
241 SET_SIZE(atomic_sub_8)
242
243 ENTRY(atomic_sub_16)
244 ALTENTRY(atomic_sub_short)
245 lock
246 subw %si, (%rdi)
247 ret
248 SET_SIZE(atomic_sub_short)
249 SET_SIZE(atomic_sub_16)
250
251 ENTRY(atomic_sub_32)
252 ALTENTRY(atomic_sub_int)
253 lock
254 subl %esi, (%rdi)
255 ret
256 SET_SIZE(atomic_sub_int)
257 SET_SIZE(atomic_sub_32)
258
259 ENTRY(atomic_sub_64)
260 ALTENTRY(atomic_sub_ptr)
261 ALTENTRY(atomic_sub_long)
262 lock
263 subq %rsi, (%rdi)
264 ret
265 SET_SIZE(atomic_sub_long)
266 SET_SIZE(atomic_sub_ptr)
267 SET_SIZE(atomic_sub_64)
268
a26baf28
BB
269 ENTRY(atomic_or_8)
270 ALTENTRY(atomic_or_uchar)
271 lock
272 orb %sil, (%rdi)
273 ret
274 SET_SIZE(atomic_or_uchar)
275 SET_SIZE(atomic_or_8)
276
277 ENTRY(atomic_or_16)
278 ALTENTRY(atomic_or_ushort)
279 lock
280 orw %si, (%rdi)
281 ret
282 SET_SIZE(atomic_or_ushort)
283 SET_SIZE(atomic_or_16)
284
285 ENTRY(atomic_or_32)
286 ALTENTRY(atomic_or_uint)
287 lock
288 orl %esi, (%rdi)
289 ret
290 SET_SIZE(atomic_or_uint)
291 SET_SIZE(atomic_or_32)
292
293 ENTRY(atomic_or_64)
294 ALTENTRY(atomic_or_ulong)
295 lock
296 orq %rsi, (%rdi)
297 ret
298 SET_SIZE(atomic_or_ulong)
299 SET_SIZE(atomic_or_64)
300
301 ENTRY(atomic_and_8)
302 ALTENTRY(atomic_and_uchar)
303 lock
304 andb %sil, (%rdi)
305 ret
306 SET_SIZE(atomic_and_uchar)
307 SET_SIZE(atomic_and_8)
308
309 ENTRY(atomic_and_16)
310 ALTENTRY(atomic_and_ushort)
311 lock
312 andw %si, (%rdi)
313 ret
314 SET_SIZE(atomic_and_ushort)
315 SET_SIZE(atomic_and_16)
316
317 ENTRY(atomic_and_32)
318 ALTENTRY(atomic_and_uint)
319 lock
320 andl %esi, (%rdi)
321 ret
322 SET_SIZE(atomic_and_uint)
323 SET_SIZE(atomic_and_32)
324
325 ENTRY(atomic_and_64)
326 ALTENTRY(atomic_and_ulong)
327 lock
328 andq %rsi, (%rdi)
329 ret
330 SET_SIZE(atomic_and_ulong)
331 SET_SIZE(atomic_and_64)
332
333 ENTRY(atomic_add_8_nv)
334 ALTENTRY(atomic_add_char_nv)
335 movb (%rdi), %al
3361:
337 movb %sil, %cl
338 addb %al, %cl
339 lock
340 cmpxchgb %cl, (%rdi)
341 jne 1b
342 movzbl %cl, %eax
343 ret
344 SET_SIZE(atomic_add_char_nv)
345 SET_SIZE(atomic_add_8_nv)
346
347 ENTRY(atomic_add_16_nv)
348 ALTENTRY(atomic_add_short_nv)
349 movw (%rdi), %ax
3501:
351 movw %si, %cx
352 addw %ax, %cx
353 lock
354 cmpxchgw %cx, (%rdi)
355 jne 1b
356 movzwl %cx, %eax
357 ret
358 SET_SIZE(atomic_add_short_nv)
359 SET_SIZE(atomic_add_16_nv)
360
361 ENTRY(atomic_add_32_nv)
362 ALTENTRY(atomic_add_int_nv)
363 movl (%rdi), %eax
3641:
365 movl %esi, %ecx
366 addl %eax, %ecx
367 lock
368 cmpxchgl %ecx, (%rdi)
369 jne 1b
370 movl %ecx, %eax
371 ret
372 SET_SIZE(atomic_add_int_nv)
373 SET_SIZE(atomic_add_32_nv)
374
375 ENTRY(atomic_add_64_nv)
376 ALTENTRY(atomic_add_ptr_nv)
377 ALTENTRY(atomic_add_long_nv)
378 movq (%rdi), %rax
3791:
380 movq %rsi, %rcx
381 addq %rax, %rcx
382 lock
383 cmpxchgq %rcx, (%rdi)
384 jne 1b
385 movq %rcx, %rax
386 ret
387 SET_SIZE(atomic_add_long_nv)
388 SET_SIZE(atomic_add_ptr_nv)
389 SET_SIZE(atomic_add_64_nv)
390
142e6dd1
ED
391 ENTRY(atomic_sub_8_nv)
392 ALTENTRY(atomic_sub_char_nv)
393 movb (%rdi), %al
3941:
395 movb %sil, %cl
396 subb %al, %cl
397 lock
398 cmpxchgb %cl, (%rdi)
399 jne 1b
400 movzbl %cl, %eax
401 ret
402 SET_SIZE(atomic_sub_char_nv)
403 SET_SIZE(atomic_sub_8_nv)
404
405 ENTRY(atomic_sub_16_nv)
406 ALTENTRY(atomic_sub_short_nv)
407 movw (%rdi), %ax
4081:
409 movw %si, %cx
410 subw %ax, %cx
411 lock
412 cmpxchgw %cx, (%rdi)
413 jne 1b
414 movzwl %cx, %eax
415 ret
416 SET_SIZE(atomic_sub_short_nv)
417 SET_SIZE(atomic_sub_16_nv)
418
419 ENTRY(atomic_sub_32_nv)
420 ALTENTRY(atomic_sub_int_nv)
421 movl (%rdi), %eax
4221:
423 movl %esi, %ecx
424 subl %eax, %ecx
425 lock
426 cmpxchgl %ecx, (%rdi)
427 jne 1b
428 movl %ecx, %eax
429 ret
430 SET_SIZE(atomic_sub_int_nv)
431 SET_SIZE(atomic_sub_32_nv)
432
433 ENTRY(atomic_sub_64_nv)
434 ALTENTRY(atomic_sub_ptr_nv)
435 ALTENTRY(atomic_sub_long_nv)
436 movq (%rdi), %rax
4371:
438 movq %rsi, %rcx
439 subq %rax, %rcx
440 lock
441 cmpxchgq %rcx, (%rdi)
442 jne 1b
443 movq %rcx, %rax
444 ret
445 SET_SIZE(atomic_sub_long_nv)
446 SET_SIZE(atomic_sub_ptr_nv)
447 SET_SIZE(atomic_sub_64_nv)
448
a26baf28
BB
449 ENTRY(atomic_and_8_nv)
450 ALTENTRY(atomic_and_uchar_nv)
451 movb (%rdi), %al
4521:
453 movb %sil, %cl
454 andb %al, %cl
455 lock
456 cmpxchgb %cl, (%rdi)
457 jne 1b
458 movzbl %cl, %eax
459 ret
460 SET_SIZE(atomic_and_uchar_nv)
461 SET_SIZE(atomic_and_8_nv)
462
463 ENTRY(atomic_and_16_nv)
464 ALTENTRY(atomic_and_ushort_nv)
465 movw (%rdi), %ax
4661:
467 movw %si, %cx
468 andw %ax, %cx
469 lock
470 cmpxchgw %cx, (%rdi)
471 jne 1b
472 movzwl %cx, %eax
473 ret
474 SET_SIZE(atomic_and_ushort_nv)
475 SET_SIZE(atomic_and_16_nv)
476
477 ENTRY(atomic_and_32_nv)
478 ALTENTRY(atomic_and_uint_nv)
479 movl (%rdi), %eax
4801:
481 movl %esi, %ecx
482 andl %eax, %ecx
483 lock
484 cmpxchgl %ecx, (%rdi)
485 jne 1b
486 movl %ecx, %eax
487 ret
488 SET_SIZE(atomic_and_uint_nv)
489 SET_SIZE(atomic_and_32_nv)
490
491 ENTRY(atomic_and_64_nv)
492 ALTENTRY(atomic_and_ulong_nv)
493 movq (%rdi), %rax
4941:
495 movq %rsi, %rcx
496 andq %rax, %rcx
497 lock
498 cmpxchgq %rcx, (%rdi)
499 jne 1b
500 movq %rcx, %rax
501 ret
502 SET_SIZE(atomic_and_ulong_nv)
503 SET_SIZE(atomic_and_64_nv)
504
505 ENTRY(atomic_or_8_nv)
506 ALTENTRY(atomic_or_uchar_nv)
507 movb (%rdi), %al
5081:
509 movb %sil, %cl
510 orb %al, %cl
511 lock
512 cmpxchgb %cl, (%rdi)
513 jne 1b
514 movzbl %cl, %eax
515 ret
516 SET_SIZE(atomic_and_uchar_nv)
517 SET_SIZE(atomic_and_8_nv)
518
519 ENTRY(atomic_or_16_nv)
520 ALTENTRY(atomic_or_ushort_nv)
521 movw (%rdi), %ax
5221:
523 movw %si, %cx
524 orw %ax, %cx
525 lock
526 cmpxchgw %cx, (%rdi)
527 jne 1b
528 movzwl %cx, %eax
529 ret
530 SET_SIZE(atomic_or_ushort_nv)
531 SET_SIZE(atomic_or_16_nv)
532
533 ENTRY(atomic_or_32_nv)
534 ALTENTRY(atomic_or_uint_nv)
535 movl (%rdi), %eax
5361:
537 movl %esi, %ecx
538 orl %eax, %ecx
539 lock
540 cmpxchgl %ecx, (%rdi)
541 jne 1b
542 movl %ecx, %eax
543 ret
544 SET_SIZE(atomic_or_uint_nv)
545 SET_SIZE(atomic_or_32_nv)
546
547 ENTRY(atomic_or_64_nv)
548 ALTENTRY(atomic_or_ulong_nv)
549 movq (%rdi), %rax
5501:
551 movq %rsi, %rcx
552 orq %rax, %rcx
553 lock
554 cmpxchgq %rcx, (%rdi)
555 jne 1b
556 movq %rcx, %rax
557 ret
558 SET_SIZE(atomic_or_ulong_nv)
559 SET_SIZE(atomic_or_64_nv)
560
561 ENTRY(atomic_cas_8)
562 ALTENTRY(atomic_cas_uchar)
563 movzbl %sil, %eax
564 lock
565 cmpxchgb %dl, (%rdi)
566 ret
567 SET_SIZE(atomic_cas_uchar)
568 SET_SIZE(atomic_cas_8)
569
570 ENTRY(atomic_cas_16)
571 ALTENTRY(atomic_cas_ushort)
572 movzwl %si, %eax
573 lock
574 cmpxchgw %dx, (%rdi)
575 ret
576 SET_SIZE(atomic_cas_ushort)
577 SET_SIZE(atomic_cas_16)
578
579 ENTRY(atomic_cas_32)
580 ALTENTRY(atomic_cas_uint)
581 movl %esi, %eax
582 lock
583 cmpxchgl %edx, (%rdi)
584 ret
585 SET_SIZE(atomic_cas_uint)
586 SET_SIZE(atomic_cas_32)
587
588 ENTRY(atomic_cas_64)
589 ALTENTRY(atomic_cas_ulong)
590 ALTENTRY(atomic_cas_ptr)
591 movq %rsi, %rax
592 lock
593 cmpxchgq %rdx, (%rdi)
594 ret
595 SET_SIZE(atomic_cas_ptr)
596 SET_SIZE(atomic_cas_ulong)
597 SET_SIZE(atomic_cas_64)
598
599 ENTRY(atomic_swap_8)
600 ALTENTRY(atomic_swap_uchar)
601 movzbl %sil, %eax
602 lock
603 xchgb %al, (%rdi)
604 ret
605 SET_SIZE(atomic_swap_uchar)
606 SET_SIZE(atomic_swap_8)
607
608 ENTRY(atomic_swap_16)
609 ALTENTRY(atomic_swap_ushort)
610 movzwl %si, %eax
611 lock
612 xchgw %ax, (%rdi)
613 ret
614 SET_SIZE(atomic_swap_ushort)
615 SET_SIZE(atomic_swap_16)
616
617 ENTRY(atomic_swap_32)
618 ALTENTRY(atomic_swap_uint)
619 movl %esi, %eax
620 lock
621 xchgl %eax, (%rdi)
622 ret
623 SET_SIZE(atomic_swap_uint)
624 SET_SIZE(atomic_swap_32)
625
626 ENTRY(atomic_swap_64)
627 ALTENTRY(atomic_swap_ulong)
628 ALTENTRY(atomic_swap_ptr)
629 movq %rsi, %rax
630 lock
631 xchgq %rax, (%rdi)
632 ret
633 SET_SIZE(atomic_swap_ptr)
634 SET_SIZE(atomic_swap_ulong)
635 SET_SIZE(atomic_swap_64)
636
637 ENTRY(atomic_set_long_excl)
638 xorl %eax, %eax
639 lock
640 btsq %rsi, (%rdi)
641 jnc 1f
642 decl %eax
6431:
644 ret
645 SET_SIZE(atomic_set_long_excl)
646
647 ENTRY(atomic_clear_long_excl)
648 xorl %eax, %eax
649 lock
650 btrq %rsi, (%rdi)
651 jc 1f
652 decl %eax
6531:
654 ret
655 SET_SIZE(atomic_clear_long_excl)
656
657 /*
658 * NOTE: membar_enter, and membar_exit are identical routines.
659 * We define them separately, instead of using an ALTENTRY
660 * definitions to alias them together, so that DTrace and
661 * debuggers will see a unique address for them, allowing
662 * more accurate tracing.
663 */
664
665 ENTRY(membar_enter)
666 mfence
667 ret
668 SET_SIZE(membar_enter)
669
670 ENTRY(membar_exit)
671 mfence
672 ret
673 SET_SIZE(membar_exit)
674
675 ENTRY(membar_producer)
676 sfence
677 ret
678 SET_SIZE(membar_producer)
679
680 ENTRY(membar_consumer)
681 lfence
682 ret
683 SET_SIZE(membar_consumer)
684
685#ifdef __ELF__
686.section .note.GNU-stack,"",%progbits
687#endif