home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / include / asm-m68k / bitops.h next >
Encoding:
C/C++ Source or Header  |  1994-11-29  |  2.7 KB  |  121 lines

  1. #ifndef _M68K_BITOPS_H
  2. #define _M68K_BITOPS_H
  3. /*
  4.  * Copyright 1992, Linus Torvalds.
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  */
  10.  
  11. /*
  12.  * Require 68020 or better.
  13.  *
  14.  * They don't use the standard m680x0 bit ordering.
  15.  * Instead, the use the standard m680x0 bitfield ordering.
  16.  *
  17.  * Thus, bit 0 is the MSB of addr; bit 32 is the MSB of (addr+1).
  18.  */
  19.  
  20. extern __inline__ int set_bit(int nr,void * vaddr)
  21. {
  22.     char retval;
  23.  
  24.     __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
  25.          : "=d" (retval) : "d" (nr), "a" (vaddr));
  26.  
  27.     return retval;
  28. }
  29.  
  30. extern __inline__ int clear_bit(int nr, void * vaddr)
  31. {
  32.     char retval;
  33.  
  34.     __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
  35.          : "=d" (retval) : "d" (nr), "a" (vaddr));
  36.  
  37.     return retval;
  38. }
  39.  
  40. extern __inline__ int change_bit(int nr, void * vaddr)
  41. {
  42.     char retval;
  43.  
  44.     __asm__ __volatile__ ("bfchg %2@{%1:#1}; sne %0"
  45.          : "=d" (retval) : "d" (nr), "a" (vaddr));
  46.  
  47.     return retval;
  48. }
  49.  
  50. extern __inline__ int test_bit(int nr, const void * vaddr)
  51. {
  52.     char retval;
  53.  
  54.     __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
  55.          : "=d" (retval) : "d" (nr), "a" (vaddr));
  56.  
  57.     return retval;
  58. }
  59.  
  60. extern inline int find_first_zero_bit(void * vaddr, unsigned size)
  61. {
  62.     unsigned long res;
  63.     unsigned long *p;
  64.     unsigned long *addr = vaddr;
  65.  
  66.     if (!size)
  67.         return 0;
  68.     __asm__ __volatile__ ("    moveq #-1,d0\n\t"
  69.                   "1:"
  70.                   "    cmpl  %1@+,d0\n\t"
  71.                   "    bne   2f\n\t"
  72.                   "    subql #1,%0\n\t"
  73.                   "    bne   1b\n\t"
  74.                   "    bra   5f\n\t"
  75.                   "2:"
  76.                   "    movel %1@-,d0\n\t"
  77.                   "    notl  d0\n\t"
  78.                   "    bfffo d0{#0,#0},%0\n\t"
  79.                   "5:"
  80.                   : "=d" (res), "=a" (p)
  81.                   : "0" ((size + 31) >> 5), "1" (addr)
  82.                   : "d0");
  83.     return ((p - addr) << 5) + res;
  84. }
  85.  
  86. static inline int find_next_zero_bit (void *vaddr, int size,
  87.                       int offset)
  88. {
  89.     unsigned long *addr = vaddr;
  90.     unsigned long *p = addr + (offset >> 5);
  91.     int set = 0, bit = offset & 31, res;
  92.  
  93.     if (bit) {
  94.         /* Look for zero in first longword */
  95.         __asm__("bfffo %1{#0,#0},%0"
  96.             : "=d" (set)
  97.             : "d" (~*p << bit));
  98.         if (set < (32 - bit))
  99.             return set + offset;
  100.                 set = 32 - bit;
  101.         p++;
  102.     }
  103.     /* No zero yet, search remaining full bytes for a zero */
  104.     res = find_first_zero_bit (p, size - 32 * (p - addr));
  105.     return (offset + set + res);
  106. }
  107.  
  108. /*
  109.  * ffz = Find First Zero in word. Undefined if no zero exists,
  110.  * so code should check against ~0UL first..
  111.  */
  112. extern inline unsigned long ffz(unsigned long word)
  113. {
  114.     __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
  115.                   : "=d" (word)
  116.                   : "d" (~(word)));
  117.     return word;
  118. }
  119.  
  120. #endif /* _M68K_BITOPS_H */
  121.