Add compiler specific syntax for inline assembly.

This commit is contained in:
Pavel Krajcevski 2012-08-28 15:36:26 -04:00
parent 38e26850fe
commit cff862344f
3 changed files with 89 additions and 11 deletions

View file

@ -5,7 +5,67 @@ INCLUDE(CheckCXXSourceRuns)
SET(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
IF(CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_REQUIRED_FLAGS -msse4.1 -E)
# Test whether or not the compiler allows inline
# assmbly...
CHECK_CXX_SOURCE_RUNS("
\#ifdef _MSC_VER
int main() {
int x = 1, y = 0;
__asm {
mov eax, x
mov y, eax
}
return !y;
}
\#else
int main() {
int x = 1, y = 0;
__asm__ (\"movl %1, %%eax;\"
\"movl %%eax, %0;\"
:\"=r\"(y) /* output */
:\"r\"(x) /* input */
:\"%eax\" /* clobbered register */
);
return !y;
}
\#endif"
HAS_INLINE_ASSEMBLY
)
# If the compiler doesn't allow it, then try with a
# compiler flag...
IF( NOT HAS_INLINE_ASSEMBLY )
SET(CMAKE_REQUIRED_FLAGS -fasm-blocks)
CHECK_CXX_SOURCE_RUNS("
\#ifdef _MSC_VER
int main() {
int x = 1, y = 0;
__asm {
mov eax, x
mov y, eax
}
return !y;
}
\#else
int main() {
int x = 1, y = 0;
__asm__ (\"movl %1, %%eax;\"
\"movl %%eax, %0;\"
:\"=r\"(y) /* output */
:\"r\"(x) /* input */
:\"%eax\" /* clobbered register */
);
return !y;
}
\#endif"
HAS_INLINE_ASSEMBLY_WITH_FLAGS
)
ENDIF()
SET(CMAKE_REQUIRED_FLAGS -msse4.1)
CHECK_CXX_SOURCE_RUNS("
#include <smmintrin.h>
int main() {
@ -36,15 +96,15 @@ ELSEIF(MSVC)
ENDIF()
SET(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
IF( NOT HAS_INLINE_ASSEMBLY AND NOT HAS_INLINE_ASSEMBLY_WITH_FLAGS )
SET( NO_INLINE_ASSEMBLY true )
ENDIF()
CONFIGURE_FILE(
"config/BC7Config.h.in"
"include/BC7Config.h"
)
IF(CMAKE_COMPILER_IS_GNUCC)
ADD_DEFINITIONS(-fasm-blocks)
ENDIF(CMAKE_COMPILER_IS_GNUCC)
SET( HEADERS
src/BC7CompressionMode.h
src/BC7IntTypes.h
@ -86,6 +146,14 @@ IF( HAS_SSE_41 )
)
ENDIF( HAS_SSE_41 )
IF( HAS_INLINE_ASSEMBLY_WITH_FLAGS )
IF( MSVC )
# !FIXME!
ELSE()
ADD_DEFINITIONS( -fasm-blocks )
ENDIF()
ENDIF()
ADD_LIBRARY( BPTCEncoder
${HEADERS}
${SOURCES}

View file

@ -5,4 +5,5 @@
// explicitly by the CMake build process.
// Do we have the proper popcnt instruction defined?
#cmakedefine NO_INLINE_ASSEMBLY
#cmakedefine HAS_SSE_POPCNT

View file

@ -15,6 +15,7 @@
//
//--------------------------------------------------------------------------------------
#include "BC7Config.h"
#include "BC7IntTypes.h"
#include "RGBAEndpoints.h"
#include "BC7Compressor.h"
@ -66,7 +67,7 @@ static const float kFloatConversion[256] = {
///////////////////////////////////////////////////////////////////////////////
static inline uint32 CountBitsInMask(uint8 n) {
#if _WIN64
#if defined(_WIN64) || defined(NO_INLINE_ASSEMBLY)
if(!n) return 0; // no bits set
if(!(n & (n-1))) return 1; // power of two
@ -76,15 +77,23 @@ static inline uint32 CountBitsInMask(uint8 n) {
}
return c;
#else
__asm
{
#ifdef _MSC_VER
__asm {
mov eax, 8
movzx ecx, n
bsf ecx, ecx
sub eax, ecx
}
}
#else
__asm__("mov %%eax, 8;"
"movzbl %0, %%ecx;"
"bsf %%ecx, %%ecx;"
"sub %%eax, %%ecx;"
: // No output registers
: "r"(n)
: "%eax", "%ecx"
);
#endif
#endif
}