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