blob: 9b0ca8fe80fce949d0a6b6825aec99d96946d8de [file] [log] [blame]
Luca Barbieria7e926a2010-02-24 10:54:25 +01001/*
2 * atomic64_t for 386/486
3 *
4 * Copyright © 2010 Luca Barbieri
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/linkage.h>
13#include <asm/alternative-asm.h>
Luca Barbieria7e926a2010-02-24 10:54:25 +010014
15/* if you want SMP support, implement these with real spinlocks */
16.macro LOCK reg
Ingo Molnar131484c2015-05-28 12:21:47 +020017 pushfl
Luca Barbieria7e926a2010-02-24 10:54:25 +010018 cli
19.endm
20
21.macro UNLOCK reg
Ingo Molnar131484c2015-05-28 12:21:47 +020022 popfl
Luca Barbieria7e926a2010-02-24 10:54:25 +010023.endm
24
Luca Barbieri30246552010-08-06 04:04:38 +020025#define BEGIN(op) \
Luca Barbieri417484d2010-08-12 07:00:35 -070026.macro endp; \
Luca Barbieri30246552010-08-06 04:04:38 +020027ENDPROC(atomic64_##op##_386); \
Luca Barbieri417484d2010-08-12 07:00:35 -070028.purgem endp; \
Luca Barbieri30246552010-08-06 04:04:38 +020029.endm; \
30ENTRY(atomic64_##op##_386); \
Luca Barbieri30246552010-08-06 04:04:38 +020031 LOCK v;
Luca Barbieria7e926a2010-02-24 10:54:25 +010032
Luca Barbieri417484d2010-08-12 07:00:35 -070033#define ENDP endp
34
Luca Barbieri30246552010-08-06 04:04:38 +020035#define RET \
36 UNLOCK v; \
Luca Barbieria7e926a2010-02-24 10:54:25 +010037 ret
Luca Barbieria7e926a2010-02-24 10:54:25 +010038
Luca Barbieri417484d2010-08-12 07:00:35 -070039#define RET_ENDP \
Luca Barbieri30246552010-08-06 04:04:38 +020040 RET; \
Luca Barbieri417484d2010-08-12 07:00:35 -070041 ENDP
Luca Barbieria7e926a2010-02-24 10:54:25 +010042
Luca Barbieri30246552010-08-06 04:04:38 +020043#define v %ecx
44BEGIN(read)
45 movl (v), %eax
46 movl 4(v), %edx
Luca Barbieri417484d2010-08-12 07:00:35 -070047RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020048#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010049
Luca Barbieri30246552010-08-06 04:04:38 +020050#define v %esi
51BEGIN(set)
52 movl %ebx, (v)
53 movl %ecx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070054RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020055#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010056
Luca Barbieri30246552010-08-06 04:04:38 +020057#define v %esi
58BEGIN(xchg)
59 movl (v), %eax
60 movl 4(v), %edx
61 movl %ebx, (v)
62 movl %ecx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070063RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020064#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010065
Luca Barbieri30246552010-08-06 04:04:38 +020066#define v %ecx
67BEGIN(add)
68 addl %eax, (v)
69 adcl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070070RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020071#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010072
Luca Barbieri30246552010-08-06 04:04:38 +020073#define v %ecx
74BEGIN(add_return)
75 addl (v), %eax
76 adcl 4(v), %edx
77 movl %eax, (v)
78 movl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070079RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020080#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010081
Luca Barbieri30246552010-08-06 04:04:38 +020082#define v %ecx
83BEGIN(sub)
84 subl %eax, (v)
85 sbbl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070086RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020087#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010088
Luca Barbieri30246552010-08-06 04:04:38 +020089#define v %ecx
90BEGIN(sub_return)
Luca Barbieria7e926a2010-02-24 10:54:25 +010091 negl %edx
92 negl %eax
93 sbbl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +020094 addl (v), %eax
95 adcl 4(v), %edx
96 movl %eax, (v)
97 movl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070098RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020099#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100100
Luca Barbieri30246552010-08-06 04:04:38 +0200101#define v %esi
102BEGIN(inc)
103 addl $1, (v)
104 adcl $0, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700105RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200106#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100107
Luca Barbieri30246552010-08-06 04:04:38 +0200108#define v %esi
109BEGIN(inc_return)
110 movl (v), %eax
111 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100112 addl $1, %eax
113 adcl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200114 movl %eax, (v)
115 movl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700116RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200117#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100118
Luca Barbieri30246552010-08-06 04:04:38 +0200119#define v %esi
120BEGIN(dec)
121 subl $1, (v)
122 sbbl $0, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700123RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200124#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100125
Luca Barbieri30246552010-08-06 04:04:38 +0200126#define v %esi
127BEGIN(dec_return)
128 movl (v), %eax
129 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100130 subl $1, %eax
131 sbbl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200132 movl %eax, (v)
133 movl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700134RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200135#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100136
Jan Beulichcb8095b2012-01-20 16:22:04 +0000137#define v %esi
Luca Barbieri30246552010-08-06 04:04:38 +0200138BEGIN(add_unless)
Jan Beulichcb8095b2012-01-20 16:22:04 +0000139 addl %eax, %ecx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100140 adcl %edx, %edi
Luca Barbieri30246552010-08-06 04:04:38 +0200141 addl (v), %eax
142 adcl 4(v), %edx
Jan Beulichcb8095b2012-01-20 16:22:04 +0000143 cmpl %eax, %ecx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100144 je 3f
1451:
Luca Barbieri30246552010-08-06 04:04:38 +0200146 movl %eax, (v)
147 movl %edx, 4(v)
Luca Barbieri6e6104f2010-03-01 19:55:46 +0100148 movl $1, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +01001492:
Luca Barbieri30246552010-08-06 04:04:38 +0200150 RET
Luca Barbieria7e926a2010-02-24 10:54:25 +01001513:
152 cmpl %edx, %edi
153 jne 1b
Luca Barbieri6e6104f2010-03-01 19:55:46 +0100154 xorl %eax, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +0100155 jmp 2b
Luca Barbieri417484d2010-08-12 07:00:35 -0700156ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200157#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100158
Luca Barbieri30246552010-08-06 04:04:38 +0200159#define v %esi
160BEGIN(inc_not_zero)
161 movl (v), %eax
162 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100163 testl %eax, %eax
164 je 3f
1651:
166 addl $1, %eax
167 adcl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200168 movl %eax, (v)
169 movl %edx, 4(v)
Luca Barbierif3e83132010-03-01 19:55:49 +0100170 movl $1, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +01001712:
Luca Barbieri30246552010-08-06 04:04:38 +0200172 RET
Luca Barbieria7e926a2010-02-24 10:54:25 +01001733:
174 testl %edx, %edx
175 jne 1b
Luca Barbieria7e926a2010-02-24 10:54:25 +0100176 jmp 2b
Luca Barbieri417484d2010-08-12 07:00:35 -0700177ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200178#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100179
Luca Barbieri30246552010-08-06 04:04:38 +0200180#define v %esi
181BEGIN(dec_if_positive)
182 movl (v), %eax
183 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100184 subl $1, %eax
185 sbbl $0, %edx
186 js 1f
Luca Barbieri30246552010-08-06 04:04:38 +0200187 movl %eax, (v)
188 movl %edx, 4(v)
Luca Barbieria7e926a2010-02-24 10:54:25 +01001891:
Luca Barbieri417484d2010-08-12 07:00:35 -0700190RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200191#undef v