bitops.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.bitops.c 1.7 05/17/01 18:14:21 cort
  3.  */
  4. /*
  5.  * Copyright (C) 1996 Paul Mackerras.
  6.  */
  7. #include <linux/kernel.h>
  8. #include <asm/bitops.h>
  9. /*
  10.  * If the bitops are not inlined in bitops.h, they are defined here.
  11.  *  -- paulus
  12.  */
  13. #if !__INLINE_BITOPS
  14. void set_bit(int nr, volatile void * addr)
  15. {
  16. unsigned long old;
  17. unsigned long mask = 1 << (nr & 0x1f);
  18. unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
  19. __asm__ __volatile__(SMP_WMB "n
  20. 1: lwarx %0,0,%3 n
  21. or %0,%0,%2 n
  22. stwcx. %0,0,%3 n
  23. bne 1b"
  24. SMP_MB
  25. : "=&r" (old), "=m" (*p)
  26. : "r" (mask), "r" (p), "m" (*p)
  27. : "cc" );
  28. }
  29. void clear_bit(int nr, volatile void *addr)
  30. {
  31. unsigned long old;
  32. unsigned long mask = 1 << (nr & 0x1f);
  33. unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
  34. __asm__ __volatile__(SMP_WMB "n
  35. 1: lwarx %0,0,%3 n
  36. andc %0,%0,%2 n
  37. stwcx. %0,0,%3 n
  38. bne 1b"
  39. SMP_MB
  40. : "=&r" (old), "=m" (*p)
  41. : "r" (mask), "r" (p), "m" (*p)
  42. : "cc");
  43. }
  44. void change_bit(int nr, volatile void *addr)
  45. {
  46. unsigned long old;
  47. unsigned long mask = 1 << (nr & 0x1f);
  48. unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
  49. __asm__ __volatile__(SMP_WMB "n
  50. 1: lwarx %0,0,%3 n
  51. xor %0,%0,%2 n
  52. stwcx. %0,0,%3 n
  53. bne 1b"
  54. SMP_MB
  55. : "=&r" (old), "=m" (*p)
  56. : "r" (mask), "r" (p), "m" (*p)
  57. : "cc");
  58. }
  59. int test_and_set_bit(int nr, volatile void *addr)
  60. {
  61. unsigned int old, t;
  62. unsigned int mask = 1 << (nr & 0x1f);
  63. volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
  64. __asm__ __volatile__(SMP_WMB "n
  65. 1: lwarx %0,0,%4 n
  66. or %1,%0,%3 n
  67. stwcx. %1,0,%4 n
  68. bne 1b"
  69. SMP_MB
  70. : "=&r" (old), "=&r" (t), "=m" (*p)
  71. : "r" (mask), "r" (p), "m" (*p)
  72. : "cc");
  73. return (old & mask) != 0;
  74. }
  75. int test_and_clear_bit(int nr, volatile void *addr)
  76. {
  77. unsigned int old, t;
  78. unsigned int mask = 1 << (nr & 0x1f);
  79. volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
  80. __asm__ __volatile__(SMP_WMB "n
  81. 1: lwarx %0,0,%4 n
  82. andc %1,%0,%3 n
  83. stwcx. %1,0,%4 n
  84. bne 1b"
  85. SMP_MB
  86. : "=&r" (old), "=&r" (t), "=m" (*p)
  87. : "r" (mask), "r" (p), "m" (*p)
  88. : "cc");
  89. return (old & mask) != 0;
  90. }
  91. int test_and_change_bit(int nr, volatile void *addr)
  92. {
  93. unsigned int old, t;
  94. unsigned int mask = 1 << (nr & 0x1f);
  95. volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
  96. __asm__ __volatile__(SMP_WMB "n
  97. 1: lwarx %0,0,%4 n
  98. xor %1,%0,%3 n
  99. stwcx. %1,0,%4 n
  100. bne 1b"
  101. SMP_MB
  102. : "=&r" (old), "=&r" (t), "=m" (*p)
  103. : "r" (mask), "r" (p), "m" (*p)
  104. : "cc");
  105. return (old & mask) != 0;
  106. }
  107. #endif /* !__INLINE_BITOPS */