11a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst#ifndef _ASM_X86_ATOMIC64_32_H
21a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst#define _ASM_X86_ATOMIC64_32_H
31a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
41a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst#include <linux/compiler.h>
51a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst#include <linux/types.h>
61a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst#include <asm/processor.h>
71a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst//#include <asm/cmpxchg.h>
81a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
91a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/* An 64bit atomic type */
101a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
111a3b1d89eded68d64e5ea409ad37827310059441Brian Gersttypedef struct {
121a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst	u64 __aligned(8) counter;
131a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst} atomic64_t;
141a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
151a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst#define ATOMIC64_INIT(val)	{ (val) }
161a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
17819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#define __ATOMIC64_DECL(sym) void atomic64_##sym(atomic64_t *, ...)
18819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#ifndef ATOMIC64_EXPORT
19819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#define ATOMIC64_DECL_ONE __ATOMIC64_DECL
20819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#else
21819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#define ATOMIC64_DECL_ONE(sym) __ATOMIC64_DECL(sym); \
22819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	ATOMIC64_EXPORT(atomic64_##sym)
23819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#endif
24819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich
25a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri#ifdef CONFIG_X86_CMPXCHG64
26819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#define __alternative_atomic64(f, g, out, in...) \
27819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	asm volatile("call %P[func]" \
28819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich		     : out : [func] "i" (atomic64_##g##_cx8), ## in)
29819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich
30819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8)
31a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri#else
32819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#define __alternative_atomic64(f, g, out, in...) \
33819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_call(atomic64_##f##_386, atomic64_##g##_cx8, \
34819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			 X86_FEATURE_CX8, ASM_OUTPUT2(out), ## in)
35819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich
36819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8); \
37819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	ATOMIC64_DECL_ONE(sym##_386)
38819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich
39819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL_ONE(add_386);
40819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL_ONE(sub_386);
41819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL_ONE(inc_386);
42819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL_ONE(dec_386);
43a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri#endif
44a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
45819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#define alternative_atomic64(f, out, in...) \
46819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	__alternative_atomic64(f, f, ASM_OUTPUT2(out), ## in)
47819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich
48819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(read);
49819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(set);
50819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(xchg);
51819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(add_return);
52819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(sub_return);
53819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(inc_return);
54819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(dec_return);
55819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(dec_if_positive);
56819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(inc_not_zero);
57819165fb34b9777f852429f2c6d6f79fbb71b9ebJan BeulichATOMIC64_DECL(add_unless);
58819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich
59819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#undef ATOMIC64_DECL
60819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#undef ATOMIC64_DECL_ONE
61819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#undef __ATOMIC64_DECL
62819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#undef ATOMIC64_EXPORT
63a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
64a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri/**
65a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * atomic64_cmpxchg - cmpxchg atomic64 variable
661f0459780c28491c480f7098f3ece79334ccae0aPhilipp Hahn * @v: pointer to type atomic64_t
67a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @o: expected value
68a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @n: new value
69a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri *
70a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically sets @v to @n if it was equal to @o and returns
71a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * the old value.
72a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri */
73a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
74a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n)
75a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
76a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return cmpxchg64(&v->counter, o, n);
77a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
781a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
791a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
801a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_xchg - xchg atomic64 variable
81a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
82a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @n: value to assign
831a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
84a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically xchgs the value of @v to @n and returns
851a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * the old value.
861a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
87a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_xchg(atomic64_t *v, long long n)
88a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
89a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	long long o;
90a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	unsigned high = (unsigned)(n >> 32);
91a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	unsigned low = (unsigned)n;
92819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(xchg, "=&A" (o),
93819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     "S" (v), "b" (low), "c" (high)
94819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     : "memory");
95a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return o;
96a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
971a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
981a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
991a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_set - set atomic64 variable
100a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
1011f0459780c28491c480f7098f3ece79334ccae0aPhilipp Hahn * @i: value to assign
1021a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
103a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically sets the value of @v to @n.
1041a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
105a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline void atomic64_set(atomic64_t *v, long long i)
106a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
107a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	unsigned high = (unsigned)(i >> 32);
108a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	unsigned low = (unsigned)i;
109819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(set, /* no output */,
110819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     "S" (v), "b" (low), "c" (high)
111819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     : "eax", "edx", "memory");
112a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
1131a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
1141a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
1151a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_read - read atomic64 variable
116a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
1171a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
118a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically reads the value of @v and returns it.
1191a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
1208030c36d13f030103356709e63638678fdc66fdcH. Peter Anvinstatic inline long long atomic64_read(const atomic64_t *v)
1211a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst{
122a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	long long r;
123819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(read, "=&A" (r), "c" (v) : "memory");
124a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return r;
125a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri }
1261a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
1271a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
1281a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_add_return - add and return
129a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @i: integer value to add
130a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
1311a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
132a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically adds @i to @v and returns @i + *@v
1331a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
134a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_add_return(long long i, atomic64_t *v)
135a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
136819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(add_return,
137819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     ASM_OUTPUT2("+A" (i), "+c" (v)),
138819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     ASM_NO_INPUT_CLOBBER("memory"));
139a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return i;
140a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
1411a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
1421a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/*
1431a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * Other variants with different arithmetic operators:
1441a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
145a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_sub_return(long long i, atomic64_t *v)
146a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
147819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(sub_return,
148819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     ASM_OUTPUT2("+A" (i), "+c" (v)),
149819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     ASM_NO_INPUT_CLOBBER("memory"));
150a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return i;
151a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
152a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
153a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_inc_return(atomic64_t *v)
154a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
155a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	long long a;
156819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(inc_return, "=&A" (a),
157819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     "S" (v) : "memory", "ecx");
158a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return a;
159a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
160a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
161a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_dec_return(atomic64_t *v)
162a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
163a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	long long a;
164819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(dec_return, "=&A" (a),
165819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     "S" (v) : "memory", "ecx");
166a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return a;
167a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
1681a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
1691a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
1701a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_add - add integer to atomic64 variable
171a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @i: integer value to add
172a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
1731a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
174a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically adds @i to @v.
1751a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
176a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_add(long long i, atomic64_t *v)
177a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
178819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	__alternative_atomic64(add, add_return,
179819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			       ASM_OUTPUT2("+A" (i), "+c" (v)),
180819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			       ASM_NO_INPUT_CLOBBER("memory"));
181a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return i;
182a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
1831a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
1841a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
1851a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_sub - subtract the atomic64 variable
186a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @i: integer value to subtract
187a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
1881a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
189a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically subtracts @i from @v.
1901a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
191a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_sub(long long i, atomic64_t *v)
192a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
193819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	__alternative_atomic64(sub, sub_return,
194819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			       ASM_OUTPUT2("+A" (i), "+c" (v)),
195819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			       ASM_NO_INPUT_CLOBBER("memory"));
196a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return i;
197a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
1981a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
1991a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
2001a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_sub_and_test - subtract value from variable and test result
201a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @i: integer value to subtract
202a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
2031f0459780c28491c480f7098f3ece79334ccae0aPhilipp Hahn *
204a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically subtracts @i from @v and returns
2051a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * true if the result is zero, or false for all
2061a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * other cases.
2071a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
208a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline int atomic64_sub_and_test(long long i, atomic64_t *v)
209a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
210a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return atomic64_sub_return(i, v) == 0;
211a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
2121a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
2131a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
2141a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_inc - increment atomic64 variable
215a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
2161a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
217a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically increments @v by 1.
2181a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
219a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline void atomic64_inc(atomic64_t *v)
220a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
221819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	__alternative_atomic64(inc, inc_return, /* no output */,
222819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			       "S" (v) : "memory", "eax", "ecx", "edx");
223a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
2241a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
2251a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
2261a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_dec - decrement atomic64 variable
2271f0459780c28491c480f7098f3ece79334ccae0aPhilipp Hahn * @v: pointer to type atomic64_t
2281a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
2291f0459780c28491c480f7098f3ece79334ccae0aPhilipp Hahn * Atomically decrements @v by 1.
2301a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
231a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline void atomic64_dec(atomic64_t *v)
232a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
233819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	__alternative_atomic64(dec, dec_return, /* no output */,
234819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			       "S" (v) : "memory", "eax", "ecx", "edx");
235a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
2361a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
2371a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
2381a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_dec_and_test - decrement and test
239a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
2401a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
241a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically decrements @v by 1 and
2421a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * returns true if the result is 0, or false for all other
2431a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * cases.
2441a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
245a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline int atomic64_dec_and_test(atomic64_t *v)
246a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
247a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return atomic64_dec_return(v) == 0;
248a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
2491a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
2501a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
2511a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_inc_and_test - increment and test
252a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
2531a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
254a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically increments @v by 1
2551a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * and returns true if the result is zero, or false for all
2561a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * other cases.
2571a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
258a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline int atomic64_inc_and_test(atomic64_t *v)
259a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
260a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return atomic64_inc_return(v) == 0;
261a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
2621a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
2631a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst/**
2641a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * atomic64_add_negative - add and test if negative
265a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @i: integer value to add
266a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer to type atomic64_t
2671a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst *
268a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically adds @i to @v and returns true
2691a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * if the result is negative, or false when
2701a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst * result is greater than or equal to zero.
2711a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst */
272a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline int atomic64_add_negative(long long i, atomic64_t *v)
273a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
274a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return atomic64_add_return(i, v) < 0;
275a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
276a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
277a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri/**
278a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * atomic64_add_unless - add unless the number is a given value
279a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @v: pointer of type atomic64_t
280a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @a: the amount to add to v...
281a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * @u: ...unless v is equal to u.
282a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri *
283a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri * Atomically adds @a to @v, so long as it was not @u.
284819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich * Returns non-zero if the add was done, zero otherwise.
285a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri */
286a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
287a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
288a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	unsigned low = (unsigned)u;
289a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	unsigned high = (unsigned)(u >> 32);
290819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(add_unless,
291cb8095bba6d24118135a5683a956f4f4fb5f17bbJan Beulich			     ASM_OUTPUT2("+A" (a), "+c" (low), "+D" (high)),
292cb8095bba6d24118135a5683a956f4f4fb5f17bbJan Beulich			     "S" (v) : "memory");
293a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return (int)a;
294a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
295a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
296a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
297a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline int atomic64_inc_not_zero(atomic64_t *v)
298a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
299a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	int r;
300819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(inc_not_zero, "=&a" (r),
301819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     "S" (v) : "ecx", "edx", "memory");
302a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return r;
303a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
304a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
305a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieristatic inline long long atomic64_dec_if_positive(atomic64_t *v)
306a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri{
307a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	long long r;
308819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich	alternative_atomic64(dec_if_positive, "=&A" (r),
309819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich			     "S" (v) : "ecx", "memory");
310a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri	return r;
311a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri}
312a7e926abc3adfbd2e5e20d2b46177adb4e313915Luca Barbieri
313819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#undef alternative_atomic64
314819165fb34b9777f852429f2c6d6f79fbb71b9ebJan Beulich#undef __alternative_atomic64
3151a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst
3161a3b1d89eded68d64e5ea409ad37827310059441Brian Gerst#endif /* _ASM_X86_ATOMIC64_32_H */
317