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