1/* 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_cfi 19 cli 20.endm 21 22.macro UNLOCK reg 23 popfl_cfi 24.endm 25 26#define BEGIN(op) \ 27.macro endp; \ 28 CFI_ENDPROC; \ 29ENDPROC(atomic64_##op##_386); \ 30.purgem endp; \ 31.endm; \ 32ENTRY(atomic64_##op##_386); \ 33 CFI_STARTPROC; \ 34 LOCK v; 35 36#define ENDP endp 37 38#define RET \ 39 UNLOCK v; \ 40 ret 41 42#define RET_ENDP \ 43 RET; \ 44 ENDP 45 46#define v %ecx 47BEGIN(read) 48 movl (v), %eax 49 movl 4(v), %edx 50RET_ENDP 51#undef v 52 53#define v %esi 54BEGIN(set) 55 movl %ebx, (v) 56 movl %ecx, 4(v) 57RET_ENDP 58#undef v 59 60#define v %esi 61BEGIN(xchg) 62 movl (v), %eax 63 movl 4(v), %edx 64 movl %ebx, (v) 65 movl %ecx, 4(v) 66RET_ENDP 67#undef v 68 69#define v %ecx 70BEGIN(add) 71 addl %eax, (v) 72 adcl %edx, 4(v) 73RET_ENDP 74#undef v 75 76#define v %ecx 77BEGIN(add_return) 78 addl (v), %eax 79 adcl 4(v), %edx 80 movl %eax, (v) 81 movl %edx, 4(v) 82RET_ENDP 83#undef v 84 85#define v %ecx 86BEGIN(sub) 87 subl %eax, (v) 88 sbbl %edx, 4(v) 89RET_ENDP 90#undef v 91 92#define v %ecx 93BEGIN(sub_return) 94 negl %edx 95 negl %eax 96 sbbl $0, %edx 97 addl (v), %eax 98 adcl 4(v), %edx 99 movl %eax, (v) 100 movl %edx, 4(v) 101RET_ENDP 102#undef v 103 104#define v %esi 105BEGIN(inc) 106 addl $1, (v) 107 adcl $0, 4(v) 108RET_ENDP 109#undef v 110 111#define v %esi 112BEGIN(inc_return) 113 movl (v), %eax 114 movl 4(v), %edx 115 addl $1, %eax 116 adcl $0, %edx 117 movl %eax, (v) 118 movl %edx, 4(v) 119RET_ENDP 120#undef v 121 122#define v %esi 123BEGIN(dec) 124 subl $1, (v) 125 sbbl $0, 4(v) 126RET_ENDP 127#undef v 128 129#define v %esi 130BEGIN(dec_return) 131 movl (v), %eax 132 movl 4(v), %edx 133 subl $1, %eax 134 sbbl $0, %edx 135 movl %eax, (v) 136 movl %edx, 4(v) 137RET_ENDP 138#undef v 139 140#define v %esi 141BEGIN(add_unless) 142 addl %eax, %ecx 143 adcl %edx, %edi 144 addl (v), %eax 145 adcl 4(v), %edx 146 cmpl %eax, %ecx 147 je 3f 1481: 149 movl %eax, (v) 150 movl %edx, 4(v) 151 movl $1, %eax 1522: 153 RET 1543: 155 cmpl %edx, %edi 156 jne 1b 157 xorl %eax, %eax 158 jmp 2b 159ENDP 160#undef v 161 162#define v %esi 163BEGIN(inc_not_zero) 164 movl (v), %eax 165 movl 4(v), %edx 166 testl %eax, %eax 167 je 3f 1681: 169 addl $1, %eax 170 adcl $0, %edx 171 movl %eax, (v) 172 movl %edx, 4(v) 173 movl $1, %eax 1742: 175 RET 1763: 177 testl %edx, %edx 178 jne 1b 179 jmp 2b 180ENDP 181#undef v 182 183#define v %esi 184BEGIN(dec_if_positive) 185 movl (v), %eax 186 movl 4(v), %edx 187 subl $1, %eax 188 sbbl $0, %edx 189 js 1f 190 movl %eax, (v) 191 movl %edx, 4(v) 1921: 193RET_ENDP 194#undef v 195