atomic64_386_32.S 2.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * atomic64_t for 386/486
 *
 * Copyright © 2010  Luca Barbieri
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/linkage.h>
#include <asm/alternative-asm.h>
#include <asm/dwarf2.h>

/* if you want SMP support, implement these with real spinlocks */
.macro LOCK reg
	pushfl
	CFI_ADJUST_CFA_OFFSET 4
	cli
.endm

.macro UNLOCK reg
	popfl
	CFI_ADJUST_CFA_OFFSET -4
.endm

28
#define BEGIN(op) \
29
.macro endp; \
30 31
	CFI_ENDPROC; \
ENDPROC(atomic64_##op##_386); \
32
.purgem endp; \
33 34 35 36 37
.endm; \
ENTRY(atomic64_##op##_386); \
	CFI_STARTPROC; \
	LOCK v;

38 39
#define ENDP endp

40 41
#define RET \
	UNLOCK v; \
42 43
	ret

44
#define RET_ENDP \
45
	RET; \
46
	ENDP
47 48 49 50 51

#define v %ecx
BEGIN(read)
	movl  (v), %eax
	movl 4(v), %edx
52
RET_ENDP
53 54 55 56 57 58
#undef v

#define v %esi
BEGIN(set)
	movl %ebx,  (v)
	movl %ecx, 4(v)
59
RET_ENDP
60 61 62 63 64 65 66 67
#undef v

#define v  %esi
BEGIN(xchg)
	movl  (v), %eax
	movl 4(v), %edx
	movl %ebx,  (v)
	movl %ecx, 4(v)
68
RET_ENDP
69 70 71 72 73 74
#undef v

#define v %ecx
BEGIN(add)
	addl %eax,  (v)
	adcl %edx, 4(v)
75
RET_ENDP
76 77 78 79 80 81 82 83
#undef v

#define v %ecx
BEGIN(add_return)
	addl  (v), %eax
	adcl 4(v), %edx
	movl %eax,  (v)
	movl %edx, 4(v)
84
RET_ENDP
85 86 87 88 89 90
#undef v

#define v %ecx
BEGIN(sub)
	subl %eax,  (v)
	sbbl %edx, 4(v)
91
RET_ENDP
92 93 94 95
#undef v

#define v %ecx
BEGIN(sub_return)
96 97 98
	negl %edx
	negl %eax
	sbbl $0, %edx
99 100 101 102
	addl  (v), %eax
	adcl 4(v), %edx
	movl %eax,  (v)
	movl %edx, 4(v)
103
RET_ENDP
104 105 106 107 108 109
#undef v

#define v %esi
BEGIN(inc)
	addl $1,  (v)
	adcl $0, 4(v)
110
RET_ENDP
111 112 113 114 115 116
#undef v

#define v %esi
BEGIN(inc_return)
	movl  (v), %eax
	movl 4(v), %edx
117 118
	addl $1, %eax
	adcl $0, %edx
119 120
	movl %eax,  (v)
	movl %edx, 4(v)
121
RET_ENDP
122 123 124 125 126 127
#undef v

#define v %esi
BEGIN(dec)
	subl $1,  (v)
	sbbl $0, 4(v)
128
RET_ENDP
129 130 131 132 133 134
#undef v

#define v %esi
BEGIN(dec_return)
	movl  (v), %eax
	movl 4(v), %edx
135 136
	subl $1, %eax
	sbbl $0, %edx
137 138
	movl %eax,  (v)
	movl %edx, 4(v)
139
RET_ENDP
140
#undef v
141

142 143
#define v %ecx
BEGIN(add_unless)
144 145
	addl %eax, %esi
	adcl %edx, %edi
146 147
	addl  (v), %eax
	adcl 4(v), %edx
148 149 150
	cmpl %eax, %esi
	je 3f
1:
151 152
	movl %eax,  (v)
	movl %edx, 4(v)
153
	movl $1, %eax
154
2:
155
	RET
156 157 158
3:
	cmpl %edx, %edi
	jne 1b
159
	xorl %eax, %eax
160
	jmp 2b
161
ENDP
162
#undef v
163

164 165 166 167
#define v %esi
BEGIN(inc_not_zero)
	movl  (v), %eax
	movl 4(v), %edx
168 169 170 171 172
	testl %eax, %eax
	je 3f
1:
	addl $1, %eax
	adcl $0, %edx
173 174
	movl %eax,  (v)
	movl %edx, 4(v)
175
	movl $1, %eax
176
2:
177
	RET
178 179 180 181
3:
	testl %edx, %edx
	jne 1b
	jmp 2b
182
ENDP
183
#undef v
184

185 186 187 188
#define v %esi
BEGIN(dec_if_positive)
	movl  (v), %eax
	movl 4(v), %edx
189 190 191
	subl $1, %eax
	sbbl $0, %edx
	js 1f
192 193
	movl %eax,  (v)
	movl %edx, 4(v)
194
1:
195
RET_ENDP
196
#undef v