Saturday, April 19, 2008

how to unstuff bits of given memory

there is a macro to get unstuff bits of given memory. given memory should be the type of unsigned int * and the size shall not greater than 32 and the result is stored in result variable . this macro is originally from mmc/sd driver source code of linux kernel.

1. for the case of given memory is address increasing

#define UNSTUFF_BITS(resp, start, size, result)             \
  {                      \
     const int __size = size;            \
     const unsigned int __mask = (__size < 32 ? 1 << __size : 0) - 1;   \
     const int __off = ((start) / 32);        \
     const int __shft = (start) & 31;       \
     unsigned int __res;                 \
                                                                    \
     __res = resp[__off] >> __shft;            \
     if (__size + __shft > 32)           \
        __res |= resp[__off+1] << ((32 - __shft) % 32); \
     result = __res & __mask;                  \
  }

2. address decreasing (not tested)
#define UNSTUFF_BITS(resp, start, size, result)             \
  {                      \
     const int __size = size;            \
     const unsigned int __mask = (__size < 32 ? 1 << __size : 0) - 1;   \
     const int __off = 3 - ((start) / 32);        \
     const int __shft = (start) & 31;       \
     unsigned int __res;                 \
                                                                    \
     __res = resp[__off] >> __shft;            \
     if (__size + __shft > 32)           \
        __res |= resp[__off-1] << ((32 - __shft) % 32); \
     result = __res & __mask;                  \
  }

3 testing code:
int main(void)
{
        unsigned temp = 0;
        unsigned int test[2];
        test[0] = 0x76543210;
        test[1] = 0xfedcba98;
        UNSTUFF_BITS(test, 24, 16, temp);
        printf("test 24,16 : %x\r\n", temp);
        return 0;
}
result:
harry@harry-ubuntu:~/workspace/c$ ./a.out
test 24,16 : 9876

No comments: