blob: 2cda60a06e654ae6e66c5f8f4dadb1f85c5b7b1d [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>
14#include <asm/dwarf2.h>
15
16/* if you want SMP support, implement these with real spinlocks */
17.macro LOCK reg
18 pushfl
19 CFI_ADJUST_CFA_OFFSET 4
20 cli
21.endm
22
23.macro UNLOCK reg
24 popfl
25 CFI_ADJUST_CFA_OFFSET -4
26.endm
27
Luca Barbieri30246552010-08-06 04:04:38 +020028#define BEGIN(op) \
Luca Barbieri417484d2010-08-12 07:00:35 -070029.macro endp; \
Luca Barbieri30246552010-08-06 04:04:38 +020030 CFI_ENDPROC; \
31ENDPROC(atomic64_##op##_386); \
Luca Barbieri417484d2010-08-12 07:00:35 -070032.purgem endp; \
Luca Barbieri30246552010-08-06 04:04:38 +020033.endm; \
34ENTRY(atomic64_##op##_386); \
35 CFI_STARTPROC; \
36 LOCK v;
Luca Barbieria7e926a2010-02-24 10:54:25 +010037
Luca Barbieri417484d2010-08-12 07:00:35 -070038#define ENDP endp
39
Luca Barbieri30246552010-08-06 04:04:38 +020040#define RET \
41 UNLOCK v; \
Luca Barbieria7e926a2010-02-24 10:54:25 +010042 ret
Luca Barbieria7e926a2010-02-24 10:54:25 +010043
Luca Barbieri417484d2010-08-12 07:00:35 -070044#define RET_ENDP \
Luca Barbieri30246552010-08-06 04:04:38 +020045 RET; \
Luca Barbieri417484d2010-08-12 07:00:35 -070046 ENDP
Luca Barbieria7e926a2010-02-24 10:54:25 +010047
Luca Barbieri30246552010-08-06 04:04:38 +020048#define v %ecx
49BEGIN(read)
50 movl (v), %eax
51 movl 4(v), %edx
Luca Barbieri417484d2010-08-12 07:00:35 -070052RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020053#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010054
Luca Barbieri30246552010-08-06 04:04:38 +020055#define v %esi
56BEGIN(set)
57 movl %ebx, (v)
58 movl %ecx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070059RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020060#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010061
Luca Barbieri30246552010-08-06 04:04:38 +020062#define v %esi
63BEGIN(xchg)
64 movl (v), %eax
65 movl 4(v), %edx
66 movl %ebx, (v)
67 movl %ecx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070068RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020069#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010070
Luca Barbieri30246552010-08-06 04:04:38 +020071#define v %ecx
72BEGIN(add)
73 addl %eax, (v)
74 adcl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070075RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020076#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010077
Luca Barbieri30246552010-08-06 04:04:38 +020078#define v %ecx
79BEGIN(add_return)
80 addl (v), %eax
81 adcl 4(v), %edx
82 movl %eax, (v)
83 movl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070084RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020085#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010086
Luca Barbieri30246552010-08-06 04:04:38 +020087#define v %ecx
88BEGIN(sub)
89 subl %eax, (v)
90 sbbl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -070091RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +020092#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +010093
Luca Barbieri30246552010-08-06 04:04:38 +020094#define v %ecx
95BEGIN(sub_return)
Luca Barbieria7e926a2010-02-24 10:54:25 +010096 negl %edx
97 negl %eax
98 sbbl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +020099 addl (v), %eax
100 adcl 4(v), %edx
101 movl %eax, (v)
102 movl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700103RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200104#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100105
Luca Barbieri30246552010-08-06 04:04:38 +0200106#define v %esi
107BEGIN(inc)
108 addl $1, (v)
109 adcl $0, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700110RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200111#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100112
Luca Barbieri30246552010-08-06 04:04:38 +0200113#define v %esi
114BEGIN(inc_return)
115 movl (v), %eax
116 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100117 addl $1, %eax
118 adcl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200119 movl %eax, (v)
120 movl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700121RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200122#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100123
Luca Barbieri30246552010-08-06 04:04:38 +0200124#define v %esi
125BEGIN(dec)
126 subl $1, (v)
127 sbbl $0, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700128RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200129#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100130
Luca Barbieri30246552010-08-06 04:04:38 +0200131#define v %esi
132BEGIN(dec_return)
133 movl (v), %eax
134 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100135 subl $1, %eax
136 sbbl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200137 movl %eax, (v)
138 movl %edx, 4(v)
Luca Barbieri417484d2010-08-12 07:00:35 -0700139RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200140#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100141
Luca Barbieri30246552010-08-06 04:04:38 +0200142#define v %ecx
143BEGIN(add_unless)
Luca Barbieria7e926a2010-02-24 10:54:25 +0100144 addl %eax, %esi
145 adcl %edx, %edi
Luca Barbieri30246552010-08-06 04:04:38 +0200146 addl (v), %eax
147 adcl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100148 cmpl %eax, %esi
149 je 3f
1501:
Luca Barbieri30246552010-08-06 04:04:38 +0200151 movl %eax, (v)
152 movl %edx, 4(v)
Luca Barbieri6e6104f2010-03-01 19:55:46 +0100153 movl $1, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +01001542:
Luca Barbieri30246552010-08-06 04:04:38 +0200155 RET
Luca Barbieria7e926a2010-02-24 10:54:25 +01001563:
157 cmpl %edx, %edi
158 jne 1b
Luca Barbieri6e6104f2010-03-01 19:55:46 +0100159 xorl %eax, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +0100160 jmp 2b
Luca Barbieri417484d2010-08-12 07:00:35 -0700161ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200162#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100163
Luca Barbieri30246552010-08-06 04:04:38 +0200164#define v %esi
165BEGIN(inc_not_zero)
166 movl (v), %eax
167 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100168 testl %eax, %eax
169 je 3f
1701:
171 addl $1, %eax
172 adcl $0, %edx
Luca Barbieri30246552010-08-06 04:04:38 +0200173 movl %eax, (v)
174 movl %edx, 4(v)
Luca Barbierif3e83132010-03-01 19:55:49 +0100175 movl $1, %eax
Luca Barbieria7e926a2010-02-24 10:54:25 +01001762:
Luca Barbieri30246552010-08-06 04:04:38 +0200177 RET
Luca Barbieria7e926a2010-02-24 10:54:25 +01001783:
179 testl %edx, %edx
180 jne 1b
Luca Barbieria7e926a2010-02-24 10:54:25 +0100181 jmp 2b
Luca Barbieri417484d2010-08-12 07:00:35 -0700182ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200183#undef v
Luca Barbieria7e926a2010-02-24 10:54:25 +0100184
Luca Barbieri30246552010-08-06 04:04:38 +0200185#define v %esi
186BEGIN(dec_if_positive)
187 movl (v), %eax
188 movl 4(v), %edx
Luca Barbieria7e926a2010-02-24 10:54:25 +0100189 subl $1, %eax
190 sbbl $0, %edx
191 js 1f
Luca Barbieri30246552010-08-06 04:04:38 +0200192 movl %eax, (v)
193 movl %edx, 4(v)
Luca Barbieria7e926a2010-02-24 10:54:25 +01001941:
Luca Barbieri417484d2010-08-12 07:00:35 -0700195RET_ENDP
Luca Barbieri30246552010-08-06 04:04:38 +0200196#undef v