18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * atomic64_t for 386/486 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright © 2010 Luca Barbieri 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/linkage.h> 98c2ecf20Sopenharmony_ci#include <asm/alternative.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* if you want SMP support, implement these with real spinlocks */ 128c2ecf20Sopenharmony_ci.macro IRQ_SAVE reg 138c2ecf20Sopenharmony_ci pushfl 148c2ecf20Sopenharmony_ci cli 158c2ecf20Sopenharmony_ci.endm 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci.macro IRQ_RESTORE reg 188c2ecf20Sopenharmony_ci popfl 198c2ecf20Sopenharmony_ci.endm 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define BEGIN_IRQ_SAVE(op) \ 228c2ecf20Sopenharmony_ci.macro endp; \ 238c2ecf20Sopenharmony_ciSYM_FUNC_END(atomic64_##op##_386); \ 248c2ecf20Sopenharmony_ci.purgem endp; \ 258c2ecf20Sopenharmony_ci.endm; \ 268c2ecf20Sopenharmony_ciSYM_FUNC_START(atomic64_##op##_386); \ 278c2ecf20Sopenharmony_ci IRQ_SAVE v; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define ENDP endp 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define RET_IRQ_RESTORE \ 328c2ecf20Sopenharmony_ci IRQ_RESTORE v; \ 338c2ecf20Sopenharmony_ci RET 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define v %ecx 368c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(read) 378c2ecf20Sopenharmony_ci movl (v), %eax 388c2ecf20Sopenharmony_ci movl 4(v), %edx 398c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 408c2ecf20Sopenharmony_ciENDP 418c2ecf20Sopenharmony_ci#undef v 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define v %esi 448c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(set) 458c2ecf20Sopenharmony_ci movl %ebx, (v) 468c2ecf20Sopenharmony_ci movl %ecx, 4(v) 478c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 488c2ecf20Sopenharmony_ciENDP 498c2ecf20Sopenharmony_ci#undef v 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define v %esi 528c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(xchg) 538c2ecf20Sopenharmony_ci movl (v), %eax 548c2ecf20Sopenharmony_ci movl 4(v), %edx 558c2ecf20Sopenharmony_ci movl %ebx, (v) 568c2ecf20Sopenharmony_ci movl %ecx, 4(v) 578c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 588c2ecf20Sopenharmony_ciENDP 598c2ecf20Sopenharmony_ci#undef v 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#define v %ecx 628c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(add) 638c2ecf20Sopenharmony_ci addl %eax, (v) 648c2ecf20Sopenharmony_ci adcl %edx, 4(v) 658c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 668c2ecf20Sopenharmony_ciENDP 678c2ecf20Sopenharmony_ci#undef v 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci#define v %ecx 708c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(add_return) 718c2ecf20Sopenharmony_ci addl (v), %eax 728c2ecf20Sopenharmony_ci adcl 4(v), %edx 738c2ecf20Sopenharmony_ci movl %eax, (v) 748c2ecf20Sopenharmony_ci movl %edx, 4(v) 758c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 768c2ecf20Sopenharmony_ciENDP 778c2ecf20Sopenharmony_ci#undef v 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci#define v %ecx 808c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(sub) 818c2ecf20Sopenharmony_ci subl %eax, (v) 828c2ecf20Sopenharmony_ci sbbl %edx, 4(v) 838c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 848c2ecf20Sopenharmony_ciENDP 858c2ecf20Sopenharmony_ci#undef v 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#define v %ecx 888c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(sub_return) 898c2ecf20Sopenharmony_ci negl %edx 908c2ecf20Sopenharmony_ci negl %eax 918c2ecf20Sopenharmony_ci sbbl $0, %edx 928c2ecf20Sopenharmony_ci addl (v), %eax 938c2ecf20Sopenharmony_ci adcl 4(v), %edx 948c2ecf20Sopenharmony_ci movl %eax, (v) 958c2ecf20Sopenharmony_ci movl %edx, 4(v) 968c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 978c2ecf20Sopenharmony_ciENDP 988c2ecf20Sopenharmony_ci#undef v 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci#define v %esi 1018c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(inc) 1028c2ecf20Sopenharmony_ci addl $1, (v) 1038c2ecf20Sopenharmony_ci adcl $0, 4(v) 1048c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 1058c2ecf20Sopenharmony_ciENDP 1068c2ecf20Sopenharmony_ci#undef v 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci#define v %esi 1098c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(inc_return) 1108c2ecf20Sopenharmony_ci movl (v), %eax 1118c2ecf20Sopenharmony_ci movl 4(v), %edx 1128c2ecf20Sopenharmony_ci addl $1, %eax 1138c2ecf20Sopenharmony_ci adcl $0, %edx 1148c2ecf20Sopenharmony_ci movl %eax, (v) 1158c2ecf20Sopenharmony_ci movl %edx, 4(v) 1168c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 1178c2ecf20Sopenharmony_ciENDP 1188c2ecf20Sopenharmony_ci#undef v 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define v %esi 1218c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(dec) 1228c2ecf20Sopenharmony_ci subl $1, (v) 1238c2ecf20Sopenharmony_ci sbbl $0, 4(v) 1248c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 1258c2ecf20Sopenharmony_ciENDP 1268c2ecf20Sopenharmony_ci#undef v 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci#define v %esi 1298c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(dec_return) 1308c2ecf20Sopenharmony_ci movl (v), %eax 1318c2ecf20Sopenharmony_ci movl 4(v), %edx 1328c2ecf20Sopenharmony_ci subl $1, %eax 1338c2ecf20Sopenharmony_ci sbbl $0, %edx 1348c2ecf20Sopenharmony_ci movl %eax, (v) 1358c2ecf20Sopenharmony_ci movl %edx, 4(v) 1368c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 1378c2ecf20Sopenharmony_ciENDP 1388c2ecf20Sopenharmony_ci#undef v 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci#define v %esi 1418c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(add_unless) 1428c2ecf20Sopenharmony_ci addl %eax, %ecx 1438c2ecf20Sopenharmony_ci adcl %edx, %edi 1448c2ecf20Sopenharmony_ci addl (v), %eax 1458c2ecf20Sopenharmony_ci adcl 4(v), %edx 1468c2ecf20Sopenharmony_ci cmpl %eax, %ecx 1478c2ecf20Sopenharmony_ci je 3f 1488c2ecf20Sopenharmony_ci1: 1498c2ecf20Sopenharmony_ci movl %eax, (v) 1508c2ecf20Sopenharmony_ci movl %edx, 4(v) 1518c2ecf20Sopenharmony_ci movl $1, %eax 1528c2ecf20Sopenharmony_ci2: 1538c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 1548c2ecf20Sopenharmony_ci3: 1558c2ecf20Sopenharmony_ci cmpl %edx, %edi 1568c2ecf20Sopenharmony_ci jne 1b 1578c2ecf20Sopenharmony_ci xorl %eax, %eax 1588c2ecf20Sopenharmony_ci jmp 2b 1598c2ecf20Sopenharmony_ciENDP 1608c2ecf20Sopenharmony_ci#undef v 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci#define v %esi 1638c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(inc_not_zero) 1648c2ecf20Sopenharmony_ci movl (v), %eax 1658c2ecf20Sopenharmony_ci movl 4(v), %edx 1668c2ecf20Sopenharmony_ci testl %eax, %eax 1678c2ecf20Sopenharmony_ci je 3f 1688c2ecf20Sopenharmony_ci1: 1698c2ecf20Sopenharmony_ci addl $1, %eax 1708c2ecf20Sopenharmony_ci adcl $0, %edx 1718c2ecf20Sopenharmony_ci movl %eax, (v) 1728c2ecf20Sopenharmony_ci movl %edx, 4(v) 1738c2ecf20Sopenharmony_ci movl $1, %eax 1748c2ecf20Sopenharmony_ci2: 1758c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 1768c2ecf20Sopenharmony_ci3: 1778c2ecf20Sopenharmony_ci testl %edx, %edx 1788c2ecf20Sopenharmony_ci jne 1b 1798c2ecf20Sopenharmony_ci jmp 2b 1808c2ecf20Sopenharmony_ciENDP 1818c2ecf20Sopenharmony_ci#undef v 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci#define v %esi 1848c2ecf20Sopenharmony_ciBEGIN_IRQ_SAVE(dec_if_positive) 1858c2ecf20Sopenharmony_ci movl (v), %eax 1868c2ecf20Sopenharmony_ci movl 4(v), %edx 1878c2ecf20Sopenharmony_ci subl $1, %eax 1888c2ecf20Sopenharmony_ci sbbl $0, %edx 1898c2ecf20Sopenharmony_ci js 1f 1908c2ecf20Sopenharmony_ci movl %eax, (v) 1918c2ecf20Sopenharmony_ci movl %edx, 4(v) 1928c2ecf20Sopenharmony_ci1: 1938c2ecf20Sopenharmony_ci RET_IRQ_RESTORE 1948c2ecf20Sopenharmony_ciENDP 1958c2ecf20Sopenharmony_ci#undef v 196