18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_ATOMIC64_32_H
38c2ecf20Sopenharmony_ci#define _ASM_X86_ATOMIC64_32_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/compiler.h>
68c2ecf20Sopenharmony_ci#include <linux/types.h>
78c2ecf20Sopenharmony_ci//#include <asm/cmpxchg.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/* An 64bit atomic type */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_citypedef struct {
128c2ecf20Sopenharmony_ci	s64 __aligned(8) counter;
138c2ecf20Sopenharmony_ci} atomic64_t;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define ATOMIC64_INIT(val)	{ (val) }
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define __ATOMIC64_DECL(sym) void atomic64_##sym(atomic64_t *, ...)
188c2ecf20Sopenharmony_ci#ifndef ATOMIC64_EXPORT
198c2ecf20Sopenharmony_ci#define ATOMIC64_DECL_ONE __ATOMIC64_DECL
208c2ecf20Sopenharmony_ci#else
218c2ecf20Sopenharmony_ci#define ATOMIC64_DECL_ONE(sym) __ATOMIC64_DECL(sym); \
228c2ecf20Sopenharmony_ci	ATOMIC64_EXPORT(atomic64_##sym)
238c2ecf20Sopenharmony_ci#endif
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_CMPXCHG64
268c2ecf20Sopenharmony_ci#define __alternative_atomic64(f, g, out, in...) \
278c2ecf20Sopenharmony_ci	asm volatile("call %P[func]" \
288c2ecf20Sopenharmony_ci		     : out : [func] "i" (atomic64_##g##_cx8), ## in)
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8)
318c2ecf20Sopenharmony_ci#else
328c2ecf20Sopenharmony_ci#define __alternative_atomic64(f, g, out, in...) \
338c2ecf20Sopenharmony_ci	alternative_call(atomic64_##f##_386, atomic64_##g##_cx8, \
348c2ecf20Sopenharmony_ci			 X86_FEATURE_CX8, ASM_OUTPUT2(out), ## in)
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8); \
378c2ecf20Sopenharmony_ci	ATOMIC64_DECL_ONE(sym##_386)
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ciATOMIC64_DECL_ONE(add_386);
408c2ecf20Sopenharmony_ciATOMIC64_DECL_ONE(sub_386);
418c2ecf20Sopenharmony_ciATOMIC64_DECL_ONE(inc_386);
428c2ecf20Sopenharmony_ciATOMIC64_DECL_ONE(dec_386);
438c2ecf20Sopenharmony_ci#endif
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#define alternative_atomic64(f, out, in...) \
468c2ecf20Sopenharmony_ci	__alternative_atomic64(f, f, ASM_OUTPUT2(out), ## in)
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ciATOMIC64_DECL(read);
498c2ecf20Sopenharmony_ciATOMIC64_DECL(set);
508c2ecf20Sopenharmony_ciATOMIC64_DECL(xchg);
518c2ecf20Sopenharmony_ciATOMIC64_DECL(add_return);
528c2ecf20Sopenharmony_ciATOMIC64_DECL(sub_return);
538c2ecf20Sopenharmony_ciATOMIC64_DECL(inc_return);
548c2ecf20Sopenharmony_ciATOMIC64_DECL(dec_return);
558c2ecf20Sopenharmony_ciATOMIC64_DECL(dec_if_positive);
568c2ecf20Sopenharmony_ciATOMIC64_DECL(inc_not_zero);
578c2ecf20Sopenharmony_ciATOMIC64_DECL(add_unless);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci#undef ATOMIC64_DECL
608c2ecf20Sopenharmony_ci#undef ATOMIC64_DECL_ONE
618c2ecf20Sopenharmony_ci#undef __ATOMIC64_DECL
628c2ecf20Sopenharmony_ci#undef ATOMIC64_EXPORT
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/**
658c2ecf20Sopenharmony_ci * arch_atomic64_cmpxchg - cmpxchg atomic64 variable
668c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
678c2ecf20Sopenharmony_ci * @o: expected value
688c2ecf20Sopenharmony_ci * @n: new value
698c2ecf20Sopenharmony_ci *
708c2ecf20Sopenharmony_ci * Atomically sets @v to @n if it was equal to @o and returns
718c2ecf20Sopenharmony_ci * the old value.
728c2ecf20Sopenharmony_ci */
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_cmpxchg(atomic64_t *v, s64 o, s64 n)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	return arch_cmpxchg64(&v->counter, o, n);
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_ci#define arch_atomic64_cmpxchg arch_atomic64_cmpxchg
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci/**
818c2ecf20Sopenharmony_ci * arch_atomic64_xchg - xchg atomic64 variable
828c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
838c2ecf20Sopenharmony_ci * @n: value to assign
848c2ecf20Sopenharmony_ci *
858c2ecf20Sopenharmony_ci * Atomically xchgs the value of @v to @n and returns
868c2ecf20Sopenharmony_ci * the old value.
878c2ecf20Sopenharmony_ci */
888c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_xchg(atomic64_t *v, s64 n)
898c2ecf20Sopenharmony_ci{
908c2ecf20Sopenharmony_ci	s64 o;
918c2ecf20Sopenharmony_ci	unsigned high = (unsigned)(n >> 32);
928c2ecf20Sopenharmony_ci	unsigned low = (unsigned)n;
938c2ecf20Sopenharmony_ci	alternative_atomic64(xchg, "=&A" (o),
948c2ecf20Sopenharmony_ci			     "S" (v), "b" (low), "c" (high)
958c2ecf20Sopenharmony_ci			     : "memory");
968c2ecf20Sopenharmony_ci	return o;
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci#define arch_atomic64_xchg arch_atomic64_xchg
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci/**
1018c2ecf20Sopenharmony_ci * arch_atomic64_set - set atomic64 variable
1028c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
1038c2ecf20Sopenharmony_ci * @i: value to assign
1048c2ecf20Sopenharmony_ci *
1058c2ecf20Sopenharmony_ci * Atomically sets the value of @v to @n.
1068c2ecf20Sopenharmony_ci */
1078c2ecf20Sopenharmony_cistatic inline void arch_atomic64_set(atomic64_t *v, s64 i)
1088c2ecf20Sopenharmony_ci{
1098c2ecf20Sopenharmony_ci	unsigned high = (unsigned)(i >> 32);
1108c2ecf20Sopenharmony_ci	unsigned low = (unsigned)i;
1118c2ecf20Sopenharmony_ci	alternative_atomic64(set, /* no output */,
1128c2ecf20Sopenharmony_ci			     "S" (v), "b" (low), "c" (high)
1138c2ecf20Sopenharmony_ci			     : "eax", "edx", "memory");
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/**
1178c2ecf20Sopenharmony_ci * arch_atomic64_read - read atomic64 variable
1188c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
1198c2ecf20Sopenharmony_ci *
1208c2ecf20Sopenharmony_ci * Atomically reads the value of @v and returns it.
1218c2ecf20Sopenharmony_ci */
1228c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_read(const atomic64_t *v)
1238c2ecf20Sopenharmony_ci{
1248c2ecf20Sopenharmony_ci	s64 r;
1258c2ecf20Sopenharmony_ci	alternative_atomic64(read, "=&A" (r), "c" (v) : "memory");
1268c2ecf20Sopenharmony_ci	return r;
1278c2ecf20Sopenharmony_ci}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci/**
1308c2ecf20Sopenharmony_ci * arch_atomic64_add_return - add and return
1318c2ecf20Sopenharmony_ci * @i: integer value to add
1328c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
1338c2ecf20Sopenharmony_ci *
1348c2ecf20Sopenharmony_ci * Atomically adds @i to @v and returns @i + *@v
1358c2ecf20Sopenharmony_ci */
1368c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_add_return(s64 i, atomic64_t *v)
1378c2ecf20Sopenharmony_ci{
1388c2ecf20Sopenharmony_ci	alternative_atomic64(add_return,
1398c2ecf20Sopenharmony_ci			     ASM_OUTPUT2("+A" (i), "+c" (v)),
1408c2ecf20Sopenharmony_ci			     ASM_NO_INPUT_CLOBBER("memory"));
1418c2ecf20Sopenharmony_ci	return i;
1428c2ecf20Sopenharmony_ci}
1438c2ecf20Sopenharmony_ci#define arch_atomic64_add_return arch_atomic64_add_return
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci/*
1468c2ecf20Sopenharmony_ci * Other variants with different arithmetic operators:
1478c2ecf20Sopenharmony_ci */
1488c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_sub_return(s64 i, atomic64_t *v)
1498c2ecf20Sopenharmony_ci{
1508c2ecf20Sopenharmony_ci	alternative_atomic64(sub_return,
1518c2ecf20Sopenharmony_ci			     ASM_OUTPUT2("+A" (i), "+c" (v)),
1528c2ecf20Sopenharmony_ci			     ASM_NO_INPUT_CLOBBER("memory"));
1538c2ecf20Sopenharmony_ci	return i;
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci#define arch_atomic64_sub_return arch_atomic64_sub_return
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_inc_return(atomic64_t *v)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	s64 a;
1608c2ecf20Sopenharmony_ci	alternative_atomic64(inc_return, "=&A" (a),
1618c2ecf20Sopenharmony_ci			     "S" (v) : "memory", "ecx");
1628c2ecf20Sopenharmony_ci	return a;
1638c2ecf20Sopenharmony_ci}
1648c2ecf20Sopenharmony_ci#define arch_atomic64_inc_return arch_atomic64_inc_return
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_dec_return(atomic64_t *v)
1678c2ecf20Sopenharmony_ci{
1688c2ecf20Sopenharmony_ci	s64 a;
1698c2ecf20Sopenharmony_ci	alternative_atomic64(dec_return, "=&A" (a),
1708c2ecf20Sopenharmony_ci			     "S" (v) : "memory", "ecx");
1718c2ecf20Sopenharmony_ci	return a;
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci#define arch_atomic64_dec_return arch_atomic64_dec_return
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci/**
1768c2ecf20Sopenharmony_ci * arch_atomic64_add - add integer to atomic64 variable
1778c2ecf20Sopenharmony_ci * @i: integer value to add
1788c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
1798c2ecf20Sopenharmony_ci *
1808c2ecf20Sopenharmony_ci * Atomically adds @i to @v.
1818c2ecf20Sopenharmony_ci */
1828c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_add(s64 i, atomic64_t *v)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	__alternative_atomic64(add, add_return,
1858c2ecf20Sopenharmony_ci			       ASM_OUTPUT2("+A" (i), "+c" (v)),
1868c2ecf20Sopenharmony_ci			       ASM_NO_INPUT_CLOBBER("memory"));
1878c2ecf20Sopenharmony_ci	return i;
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci/**
1918c2ecf20Sopenharmony_ci * arch_atomic64_sub - subtract the atomic64 variable
1928c2ecf20Sopenharmony_ci * @i: integer value to subtract
1938c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
1948c2ecf20Sopenharmony_ci *
1958c2ecf20Sopenharmony_ci * Atomically subtracts @i from @v.
1968c2ecf20Sopenharmony_ci */
1978c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_sub(s64 i, atomic64_t *v)
1988c2ecf20Sopenharmony_ci{
1998c2ecf20Sopenharmony_ci	__alternative_atomic64(sub, sub_return,
2008c2ecf20Sopenharmony_ci			       ASM_OUTPUT2("+A" (i), "+c" (v)),
2018c2ecf20Sopenharmony_ci			       ASM_NO_INPUT_CLOBBER("memory"));
2028c2ecf20Sopenharmony_ci	return i;
2038c2ecf20Sopenharmony_ci}
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci/**
2068c2ecf20Sopenharmony_ci * arch_atomic64_inc - increment atomic64 variable
2078c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
2088c2ecf20Sopenharmony_ci *
2098c2ecf20Sopenharmony_ci * Atomically increments @v by 1.
2108c2ecf20Sopenharmony_ci */
2118c2ecf20Sopenharmony_cistatic inline void arch_atomic64_inc(atomic64_t *v)
2128c2ecf20Sopenharmony_ci{
2138c2ecf20Sopenharmony_ci	__alternative_atomic64(inc, inc_return, /* no output */,
2148c2ecf20Sopenharmony_ci			       "S" (v) : "memory", "eax", "ecx", "edx");
2158c2ecf20Sopenharmony_ci}
2168c2ecf20Sopenharmony_ci#define arch_atomic64_inc arch_atomic64_inc
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci/**
2198c2ecf20Sopenharmony_ci * arch_atomic64_dec - decrement atomic64 variable
2208c2ecf20Sopenharmony_ci * @v: pointer to type atomic64_t
2218c2ecf20Sopenharmony_ci *
2228c2ecf20Sopenharmony_ci * Atomically decrements @v by 1.
2238c2ecf20Sopenharmony_ci */
2248c2ecf20Sopenharmony_cistatic inline void arch_atomic64_dec(atomic64_t *v)
2258c2ecf20Sopenharmony_ci{
2268c2ecf20Sopenharmony_ci	__alternative_atomic64(dec, dec_return, /* no output */,
2278c2ecf20Sopenharmony_ci			       "S" (v) : "memory", "eax", "ecx", "edx");
2288c2ecf20Sopenharmony_ci}
2298c2ecf20Sopenharmony_ci#define arch_atomic64_dec arch_atomic64_dec
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci/**
2328c2ecf20Sopenharmony_ci * arch_atomic64_add_unless - add unless the number is a given value
2338c2ecf20Sopenharmony_ci * @v: pointer of type atomic64_t
2348c2ecf20Sopenharmony_ci * @a: the amount to add to v...
2358c2ecf20Sopenharmony_ci * @u: ...unless v is equal to u.
2368c2ecf20Sopenharmony_ci *
2378c2ecf20Sopenharmony_ci * Atomically adds @a to @v, so long as it was not @u.
2388c2ecf20Sopenharmony_ci * Returns non-zero if the add was done, zero otherwise.
2398c2ecf20Sopenharmony_ci */
2408c2ecf20Sopenharmony_cistatic inline int arch_atomic64_add_unless(atomic64_t *v, s64 a, s64 u)
2418c2ecf20Sopenharmony_ci{
2428c2ecf20Sopenharmony_ci	unsigned low = (unsigned)u;
2438c2ecf20Sopenharmony_ci	unsigned high = (unsigned)(u >> 32);
2448c2ecf20Sopenharmony_ci	alternative_atomic64(add_unless,
2458c2ecf20Sopenharmony_ci			     ASM_OUTPUT2("+A" (a), "+c" (low), "+D" (high)),
2468c2ecf20Sopenharmony_ci			     "S" (v) : "memory");
2478c2ecf20Sopenharmony_ci	return (int)a;
2488c2ecf20Sopenharmony_ci}
2498c2ecf20Sopenharmony_ci#define arch_atomic64_add_unless arch_atomic64_add_unless
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_cistatic inline int arch_atomic64_inc_not_zero(atomic64_t *v)
2528c2ecf20Sopenharmony_ci{
2538c2ecf20Sopenharmony_ci	int r;
2548c2ecf20Sopenharmony_ci	alternative_atomic64(inc_not_zero, "=&a" (r),
2558c2ecf20Sopenharmony_ci			     "S" (v) : "ecx", "edx", "memory");
2568c2ecf20Sopenharmony_ci	return r;
2578c2ecf20Sopenharmony_ci}
2588c2ecf20Sopenharmony_ci#define arch_atomic64_inc_not_zero arch_atomic64_inc_not_zero
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
2618c2ecf20Sopenharmony_ci{
2628c2ecf20Sopenharmony_ci	s64 r;
2638c2ecf20Sopenharmony_ci	alternative_atomic64(dec_if_positive, "=&A" (r),
2648c2ecf20Sopenharmony_ci			     "S" (v) : "ecx", "memory");
2658c2ecf20Sopenharmony_ci	return r;
2668c2ecf20Sopenharmony_ci}
2678c2ecf20Sopenharmony_ci#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci#undef alternative_atomic64
2708c2ecf20Sopenharmony_ci#undef __alternative_atomic64
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_cistatic inline void arch_atomic64_and(s64 i, atomic64_t *v)
2738c2ecf20Sopenharmony_ci{
2748c2ecf20Sopenharmony_ci	s64 old, c = 0;
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	while ((old = arch_atomic64_cmpxchg(v, c, c & i)) != c)
2778c2ecf20Sopenharmony_ci		c = old;
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_fetch_and(s64 i, atomic64_t *v)
2818c2ecf20Sopenharmony_ci{
2828c2ecf20Sopenharmony_ci	s64 old, c = 0;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	while ((old = arch_atomic64_cmpxchg(v, c, c & i)) != c)
2858c2ecf20Sopenharmony_ci		c = old;
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	return old;
2888c2ecf20Sopenharmony_ci}
2898c2ecf20Sopenharmony_ci#define arch_atomic64_fetch_and arch_atomic64_fetch_and
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_cistatic inline void arch_atomic64_or(s64 i, atomic64_t *v)
2928c2ecf20Sopenharmony_ci{
2938c2ecf20Sopenharmony_ci	s64 old, c = 0;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	while ((old = arch_atomic64_cmpxchg(v, c, c | i)) != c)
2968c2ecf20Sopenharmony_ci		c = old;
2978c2ecf20Sopenharmony_ci}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_fetch_or(s64 i, atomic64_t *v)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	s64 old, c = 0;
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	while ((old = arch_atomic64_cmpxchg(v, c, c | i)) != c)
3048c2ecf20Sopenharmony_ci		c = old;
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	return old;
3078c2ecf20Sopenharmony_ci}
3088c2ecf20Sopenharmony_ci#define arch_atomic64_fetch_or arch_atomic64_fetch_or
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_cistatic inline void arch_atomic64_xor(s64 i, atomic64_t *v)
3118c2ecf20Sopenharmony_ci{
3128c2ecf20Sopenharmony_ci	s64 old, c = 0;
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci	while ((old = arch_atomic64_cmpxchg(v, c, c ^ i)) != c)
3158c2ecf20Sopenharmony_ci		c = old;
3168c2ecf20Sopenharmony_ci}
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_fetch_xor(s64 i, atomic64_t *v)
3198c2ecf20Sopenharmony_ci{
3208c2ecf20Sopenharmony_ci	s64 old, c = 0;
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	while ((old = arch_atomic64_cmpxchg(v, c, c ^ i)) != c)
3238c2ecf20Sopenharmony_ci		c = old;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	return old;
3268c2ecf20Sopenharmony_ci}
3278c2ecf20Sopenharmony_ci#define arch_atomic64_fetch_xor arch_atomic64_fetch_xor
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_cistatic inline s64 arch_atomic64_fetch_add(s64 i, atomic64_t *v)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	s64 old, c = 0;
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	while ((old = arch_atomic64_cmpxchg(v, c, c + i)) != c)
3348c2ecf20Sopenharmony_ci		c = old;
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	return old;
3378c2ecf20Sopenharmony_ci}
3388c2ecf20Sopenharmony_ci#define arch_atomic64_fetch_add arch_atomic64_fetch_add
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci#define arch_atomic64_fetch_sub(i, v)	arch_atomic64_fetch_add(-(i), (v))
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci#endif /* _ASM_X86_ATOMIC64_32_H */
343