atomic_arch.h raw

   1  #if __mips_isa_rev < 6
   2  #define LLSC_M "m"
   3  #else
   4  #define LLSC_M "ZC"
   5  #endif
   6  
   7  #define a_ll a_ll
   8  static inline int a_ll(volatile int *p)
   9  {
  10  	int v;
  11  #if __mips < 2
  12  	__asm__ __volatile__ (
  13  		".set push ; .set mips2\n\t"
  14  		"ll %0, %1"
  15  		"\n\t.set pop"
  16  		: "=r"(v) : "m"(*p));
  17  #else
  18  	__asm__ __volatile__ (
  19  		"ll %0, %1"
  20  		: "=r"(v) : LLSC_M(*p));
  21  #endif
  22  	return v;
  23  }
  24  
  25  #define a_sc a_sc
  26  static inline int a_sc(volatile int *p, int v)
  27  {
  28  	int r;
  29  #if __mips < 2
  30  	__asm__ __volatile__ (
  31  		".set push ; .set mips2\n\t"
  32  		"sc %0, %1"
  33  		"\n\t.set pop"
  34  		: "=r"(r), "=m"(*p) : "0"(v) : "memory");
  35  #else
  36  	__asm__ __volatile__ (
  37  		"sc %0, %1"
  38  		: "=r"(r), "="LLSC_M(*p) : "0"(v) : "memory");
  39  #endif
  40  	return r;
  41  }
  42  
  43  #define a_barrier a_barrier
  44  static inline void a_barrier()
  45  {
  46  #if __mips < 2
  47  	/* mips2 sync, but using too many directives causes
  48  	 * gcc not to inline it, so encode with .long instead. */
  49  	__asm__ __volatile__ (".long 0xf" : : : "memory");
  50  #else
  51  	__asm__ __volatile__ ("sync" : : : "memory");
  52  #endif
  53  }
  54  
  55  #define a_pre_llsc a_barrier
  56  #define a_post_llsc a_barrier
  57  
  58  #undef LLSC_M
  59