• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • Directories
  • File List
  • Globals

bit_test.h

00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2010 iptelorg GmbH
00005  *
00006  * Permission to use, copy, modify, and distribute this software for any
00007  * purpose with or without fee is hereby granted, provided that the above
00008  * copyright notice and this permission notice appear in all copies.
00009  *
00010  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00011  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00012  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00013  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00014  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00015  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00016  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00017  *
00018  * History
00019  * -------
00020  *  2010-04-26  Initial version (Miklos)
00021  *  2011-01-05  bit_test_and_reset added (Miklos)
00022  */
00023 
00024 /* Bit test functions:
00025  *  - int bit_test(int offset, unsigned int *addr)
00026  *      Returns the bit found at offset position 
00027  *      in a bitstring pointed by addr.
00028  *
00029  *  - int bit_test_and_set(int offset, unsigned int *addr)
00030  *      Returns the bit found at offset position 
00031  *      in a bitstring pointed by addr, and sets
00032  *      the bit at the given offset.
00033  *
00034  *  - int bit_test_and_reset(int offset, unsigned int *addr)
00035  *      Returns the bit found at offset position 
00036  *      in a bitstring pointed by addr, and resets
00037  *      the bit at the given offset.
00038  *
00039  * Note that 0 <= offset <= 128, Make sure that addr points to
00040  * a large enough memory area.
00041  */
00042 
00043 #ifndef _BIT_TEST_H
00044 #define _BIT_TEST_H
00045 
00046 /* fix __CPU_i386 -> __CPU_x86 */
00047 #if defined __CPU_i386 && ! defined __CPU_x86
00048 #define __CPU_x86
00049 #endif
00050  
00051 #ifdef CC_GCC_LIKE_ASM
00052 #if defined __CPU_x86 || defined __CPU_x86_64
00053 #define BIT_TEST_ASM
00054 #endif
00055 #endif
00056 
00057 #ifdef BIT_TEST_ASM
00058 
00059 /* Returns the bit found at offset position in the bitstring
00060  * pointed by addr.
00061  * Note that the CPU can access 4 bytes starting from addr,
00062  * hence 0 <= offset < 128 holds. Make sure that addr points
00063  * to a memory area that is large enough.
00064  */
00065 static inline int bit_test(int offset, unsigned int *addr)
00066 {
00067         unsigned char   v;
00068 
00069         asm volatile(
00070                 " bt %2, %1 \n\t"
00071                 " setc %0 \n\t"
00072                 : "=qm" (v) : "m" (*addr), "r" (offset)
00073         );
00074         return (int)v;
00075 }
00076 
00077 /* Returns the bit found at offset position in the bitstring
00078  * pointed by addr and sets it to 1.
00079  * Note that the CPU can access 4 bytes starting from addr,
00080  * hence 0 <= offset < 128 holds. Make sure that addr points
00081  * to a memory area that is large enough.
00082  */
00083 static inline int bit_test_and_set(int offset, unsigned int *addr)
00084 {
00085         unsigned char   v;
00086 
00087         asm volatile(
00088                 " bts %2, %1 \n\t"
00089                 " setc %0 \n\t"
00090                 : "=qm" (v) : "m" (*addr), "r" (offset)
00091         );
00092         return (int)v;
00093 }
00094 
00095 /* Returns the bit found at offset position in the bitstring
00096  * pointed by addr and resets it to 0.
00097  * Note that the CPU can access 4 bytes starting from addr,
00098  * hence 0 <= offset < 128 holds. Make sure that addr points
00099  * to a memory area that is large enough.
00100  */
00101 static inline int bit_test_and_reset(int offset, unsigned int *addr)
00102 {
00103         unsigned char   v;
00104 
00105         asm volatile(
00106                 " btr %2, %1 \n\t"
00107                 " setc %0 \n\t"
00108                 : "=qm" (v) : "m" (*addr), "r" (offset)
00109         );
00110         return (int)v;
00111 }
00112 
00113 #else /* BIT_TEST_ASM */
00114 
00115 /* Returns the bit found at offset position in the bitstring
00116  * pointed by addr.
00117  * Note that offset can be grater than 32, make sure that addr points
00118  * to a memory area that is large enough.
00119  */
00120 static inline int bit_test(int offset, unsigned int *addr)
00121 {
00122         return ((*(addr + offset/32)) & (1U << (offset % 32))) ? 1 : 0;
00123 }
00124 
00125 /* Returns the bit found at offset position in the bitstring
00126  * pointed by addr and sets it to 1.
00127  * Note that offset can be grater than 32, make sure that addr points
00128  * to a memory area that is large enough.
00129  */
00130 static inline int bit_test_and_set(int offset, unsigned int *addr)
00131 {
00132         unsigned int    *i;
00133         int     mask, res;
00134 
00135         i = addr + offset/32;
00136         mask = 1U << (offset % 32);
00137         res = ((*i) & mask) ? 1 : 0;
00138         (*i) |= mask;
00139 
00140         return res;
00141 }
00142 
00143 /* Returns the bit found at offset position in the bitstring
00144  * pointed by addr and resets it to 0.
00145  * Note that offset can be grater than 32, make sure that addr points
00146  * to a memory area that is large enough.
00147  */
00148 static inline int bit_test_and_reset(int offset, unsigned int *addr)
00149 {
00150         unsigned int    *i;
00151         int     mask, res;
00152 
00153         i = addr + offset/32;
00154         mask = 1U << (offset % 32);
00155         res = ((*i) & mask) ? 1 : 0;
00156         (*i) &= ~mask;
00157 
00158         return res;
00159 }
00160 
00161 #endif /* BIT_TEST_ASM */
00162 
00163 #endif /* #ifndef _BIT_TEST_H */

Generated on Tue May 22 2012 13:10:03 for SIP Router by  doxygen 1.7.1