# SFBMath.h

    00001 /*                                              -*- mode:C++; fill-column:100 -*-
    00002   SFBMath.h - Misc bit twiddling and mathy routines, just in case
    00003   Copyright (C) 2009 The Regents of the University of New Mexico.  All rights reserved.
    00004
    00005   This library is free software; you can redistribute it and/or
    00006   modify it under the terms of the GNU Lesser General Public
    00007   License as published by the Free Software Foundation; either
    00008   version 2.1 of the License, or (at your option) any later version.
    00009
    00010   This library is distributed in the hope that it will be useful,
    00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013   Lesser General Public License for more details.
    00014
    00015   You should have received a copy of the GNU General Public License
    00016   along with this library; if not, write to the Free Software
    00017   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
    00018   USA
    00019
    00020   $Id$
    00021 */
    00022
    00023 #ifndef SFBMATH_H
    00024 #define SFBMATH_H
    00025
    00026 #include "SFBTypes.h"
    00027
    00028 #ifdef __cplusplus
    00029 extern "C" {
    00030 #endif
    00031
    00032 #if defined(HOST_MODE) || defined(__thumb__)
    00033
    00037 #define COUNT_LEADING_ZEROS(u32InputVal, u32OutputCount)              \
    00038  do {                                                                 \
    00039   (u32InputVal) |= (u32InputVal)>>1;                                  \
    00040   (u32InputVal) |= (u32InputVal)>>2;                                  \
    00041   (u32InputVal) |= (u32InputVal)>>2;                                  \
    00042   (u32InputVal) |= (u32InputVal)>>4;                                  \
    00043   (u32InputVal) |= (u32InputVal)>>8;                                  \
    00044   (u32InputVal) |= (u32InputVal)>>16;                                 \
    00045   (u32OutputCount) = 32-countOnes(u32InputVal);                       \
    00046  } while (0)
    00047
    00048 #else
    00049
    00054 #define COUNT_LEADING_ZEROS(u32InputVal, u32OutputCount)              \
    00055  /* 16 cycle leading zero count algorithm */                          \
    00056   __asm__ __volatile__ ("movs   %[count],%[val],lsr #16\n\t"          \
    00057                         "mov    %[count],#0\n\t"                      \
    00058                         "addeq  %[count],%[count],#16\n\t"            \
    00059                         "moveqs %[val],%[val],lsl #16\n\t"            \
    00060                         "addeq  %[count],%[count],#1\n\t"             \
    00061                         "tst    %[val],#0xff000000\n\t"               \
    00062                         "addeq  %[count],%[count],#8\n\t"             \
    00063                         "moveq  %[val],%[val],lsl #8\n\t"             \
    00064                         "tst    %[val],#0xf0000000\n\t"               \
    00065                         "addeq  %[count],%[count],#4\n\t"             \
    00066                         "moveq  %[val],%[val],lsl #4\n\t"             \
    00067                         "tst    %[val],#0xc0000000\n\t"               \
    00068                         "addeq  %[count],%[count],#2\n\t"             \
    00069                         "moveq  %[val],%[val],lsl #2\n\t"             \
    00070                         "tst    %[val],#0x80000000\n\t"               \
    00071                         "addeq  %[count],%[count],#1"                 \
    00072                         : [count] "=r" (u32OutputCount),              \
    00073                           [val] "+r" (u32InputVal)                    \
    00074                         : )
    00075 #endif
    00076
    00077 extern int countLeadingZeros(u32 x) ;
    00078
    00079 extern int countOnes(u32 x) ;
    00080
    00081 extern int countTrailingZeros(int x) ;
    00082
    00083 #ifdef __cplusplus
    00084 }
    00085 #endif
    00086
    00087
    00088 #endif /* SFBMATH_H */
    00089