#if (defined _WIN32 && !defined _WIN32_WCE) || (defined __WINS__ && defined _SYMBIAN) || defined(_OPENWAVE_SIMULATOR) || defined(WINCE_EMULATOR) /* Symbian emulator for Ix86 */
#pragma warning( disable : 4035 ) /* complains about inline asm not returning a value */
static __inline int MULSHIFT32(int x, int y)
{
__asm {
mov eax, x
imul y
mov eax, edx
}
}
static __inline int FASTABS(int x)
{
int sign;
sign = x >> (sizeof(int) * 8 - 1);
x ^= sign;
x -= sign;
return x;
}
static __inline int CLZ(int x)
{
int numZeros;
if (!x)
return (sizeof(int) * 8);
numZeros = 0;
while (!(x & 0x80000000)) {
numZeros++;
x <<= 1;
}
return numZeros;
}
/* MADD64, SHL64, SAR64:
* write in assembly to avoid dependency on run-time lib for 64-bit shifts, muls
* (sometimes compiler thunks to function calls instead of code generating)
* required for Symbian emulator
*/
#ifdef __CW32__
typedef long long Word64;
#else
typedef __int64 Word64;
#endif
static __inline Word64 MADD64(Word64 sum, int x, int y)
{
unsigned int sumLo = ((unsigned int *)&sum)[0];
int sumHi = ((int *)&sum)[1];
__asm {
mov eax, x
imul y
add eax, sumLo
adc edx, sumHi
}
/* equivalent to return (sum + ((__int64)x * y)); */
}
static __inline Word64 SHL64(Word64 x, int n)
{
unsigned int xLo = ((unsigned int *)&x)[0];
int xHi = ((int *)&x)[1];
unsigned char nb = (unsigned char)n;
if (n < 32) {
__asm {
mov edx, xHi
mov eax, xLo
mov cl, nb
shld edx, eax, cl
shl eax, cl
}
} else if (n < 64) {
/* shl masks cl to 0x1f */
__asm {
mov edx, xLo
mov cl, nb
xor eax, eax
shl edx, cl
}
} else {
__asm {
xor edx, edx
xor eax, eax
}
}
}
static __inline Word64 SAR64(Word64 x, int n)
{
unsigned int xLo = ((unsigned int *)&x)[0];
int xHi = ((int *)&x)[1];
unsigned char nb = (unsigned char)n;
if (n < 32) {
__asm {
mov edx, xHi
mov eax, xLo
mov cl, nb
shrd eax, edx, cl
sar edx, cl
}
} else if (n < 64) {
/* sar masks cl to 0x1f */
__asm {
mov edx, xHi
mov eax, xHi
mov cl, nb
sar edx, 31
sar eax, cl
}
} else {
__asm {
sar xHi, 31
mov eax, xHi
mov edx, xHi
}
}
}
#elif (defined _WIN32) && (defined _WIN32_WCE)
/* use asm function for now (EVC++ 3.0 does horrible job compiling __int64 version) */
#define MULSHIFT32 xmp3_MULSHIFT32
int MULSHIFT32(int x, int y);
static __inline int FASTABS(int x)
{
int sign;
sign = x >> (sizeof(int) * 8 - 1);
x ^= sign;
x -= sign;
return x;
}
static __inline int CLZ(int x)
{
int numZeros;
if (!x)
return (sizeof(int) * 8);
numZeros = 0;
while (!(x & 0x80000000)) {
numZeros++;
x <<= 1;
}
return numZeros;
}
#elif defined ARM_ADS
static __inline int MULSHIFT32(int x, int y)
{
int zlow;
__asm {
smull zlow,y,x,y
}
return y;
}
static __inline int FASTABS(int x)
{
int t=0; /*Really is not necessary to initialiaze only to avoid warning*/
__asm {
eor t, x, x, asr #31 // T:=X XOR (X>>31)
sub t, t, x, asr #31 // T:=T-(X>>31)
}
return t;
}
static __inline int CLZ(int x)
{
int numZeros;
if (!x)
return (sizeof(int) * 8);
numZeros = 0;
while (!(x & 0x80000000)) {
numZeros++;
x <<= 1;
}
return numZeros;
}
#elif defined(__GNUC__) && defined(ARM)
typedef long long Word64;
#define MULSHIFT32 xmp3_MULSHIFT32
extern int MULSHIFT32(int x, int y);
#define FASTABS xmp3_FASTABS
int FASTABS(int x);
static __inline int CLZ(int x)
{
int numZeros;
if (!x)
return (sizeof(int) * 8);
numZeros = 0;
while (!(x & 0x80000000)) {
numZeros++;
x <<= 1;
}
return numZeros;
}
#else
#error Unsupported platform in assembly.h
#endif /* platforms */
#endif /* _ASSEMBLY_H */