#ifndef _X86_64_BITOPS_H
#define _X86_64_BITOPS_H

/*
 * Copyright 1992, Linus Torvalds.
 */

#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
/* Technically wrong, but this avoids compilation errors on some gcc
   versions. */
#define ADDR "=m" (*(volatile long *) addr)
#else
#define ADDR "+m" (*(volatile long *) addr)
#endif

/**
 * __change_bit - Toggle a bit in memory
 * @nr: the bit to change
 * @addr: the address to start counting from
 *
 * Unlike change_bit(), this function is non-atomic and may be reordered.
 * If it's called on the same region of memory simultaneously, the effect
 * may be that only one operation succeeds.
 */
static __inline__ void
__change_bit(int nr, volatile void *addr)
{
    __asm__ __volatile__("btcl %1,%0":ADDR:"dIr"(nr));
}

/* WARNING: non atomic and it can be reordered! */
static __inline__ int
__test_and_change_bit(int nr, volatile void *addr)
{
    int oldbit;

    __asm__ __volatile__("btcl %2,%1\n\tsbbl %0,%0":"=r"(oldbit),
			 ADDR:"dIr"(nr):"memory");
    return oldbit;
}
#endif /* _X86_64_BITOPS_H */
