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