diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config.h.in | 155 | ||||
-rw-r--r-- | src/interp.cc | 32 | ||||
-rw-r--r-- | src/literal.cc | 8 |
3 files changed, 100 insertions, 95 deletions
diff --git a/src/config.h.in b/src/config.h.in index cb6af598..c4e4cbbf 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -47,9 +47,6 @@ #cmakedefine01 WITH_EXCEPTIONS #define SIZEOF_SIZE_T @SIZEOF_SIZE_T@ -#define SIZEOF_INT @SIZEOF_INT@ -#define SIZEOF_LONG @SIZEOF_LONG@ -#define SIZEOF_LONG_LONG @SIZEOF_LONG_LONG@ #if HAVE_ALLOCA_H #include <alloca.h> @@ -96,30 +93,6 @@ #define WABT_STATIC_ASSERT(x) _Static_assert((x), #x) #endif -#if SIZEOF_INT == 4 -#define wabt_clz_u32(x) __builtin_clz(x) -#define wabt_ctz_u32(x) __builtin_ctz(x) -#define wabt_popcount_u32(x) __builtin_popcount(x) -#elif SIZEOF_LONG == 4 -#define wabt_clz_u32(x) __builtin_clzl(x) -#define wabt_ctz_u32(x) __builtin_ctzl(x) -#define wabt_popcount_u32(x) __builtin_popcountl(x) -#else -#error "don't know how to define 32-bit builtins" -#endif - -#if SIZEOF_LONG == 8 -#define wabt_clz_u64(x) __builtin_clzl(x) -#define wabt_ctz_u64(x) __builtin_ctzl(x) -#define wabt_popcount_u64(x) __builtin_popcountl(x) -#elif SIZEOF_LONG_LONG == 8 -#define wabt_clz_u64(x) __builtin_clzll(x) -#define wabt_ctz_u64(x) __builtin_ctzll(x) -#define wabt_popcount_u64(x) __builtin_popcountll(x) -#else -#error "don't know how to define 64-bit builtins" -#endif - #define WABT_UNREACHABLE __builtin_unreachable() #elif COMPILER_IS_MSVC @@ -137,76 +110,124 @@ #define WABT_UNREACHABLE __assume(0) -__inline unsigned long wabt_clz_u32(unsigned long mask) { +#else + +#error unknown compiler + +#endif + + +namespace wabt { + +#if COMPILER_IS_CLANG || COMPILER_IS_GNU + +inline int Clz(unsigned x) { return x ? __builtin_clz(x) : sizeof(x) * 8; } +inline int Clz(unsigned long x) { return x ? __builtin_clzl(x) : sizeof(x) * 8; } +inline int Clz(unsigned long long x) { return x ? __builtin_clzll(x) : sizeof(x) * 8; } + +inline int Ctz(unsigned x) { return x ? __builtin_ctz(x) : sizeof(x) * 8; } +inline int Ctz(unsigned long x) { return x ? __builtin_ctzl(x) : sizeof(x) * 8; } +inline int Ctz(unsigned long long x) { return x ? __builtin_ctzll(x) : sizeof(x) * 8; } + +inline int Popcount(unsigned x) { return __builtin_popcount(x); } +inline int Popcount(unsigned long x) { return __builtin_popcountl(x); } +inline int Popcount(unsigned long long x) { return __builtin_popcountll(x); } + +#elif COMPILER_IS_MSVC + +#if _M_IX86 +inline unsigned long LowDword(unsigned __int64 value) { + return (unsigned long)value; +} + +inline unsigned long HighDword(unsigned __int64 value) { + unsigned long high; + memcpy(&high, (unsigned char*)&value + sizeof(high), sizeof(high)); + return high; +} +#endif + +inline int Clz(unsigned long mask) { + if (mask == 0) + return 32; + unsigned long index; _BitScanReverse(&index, mask); return sizeof(unsigned long) * 8 - (index + 1); } -__inline unsigned long wabt_clz_u64(unsigned __int64 mask) { +inline int Clz(unsigned int mask) { + return Clz((unsigned long)mask); +} + +inline int Clz(unsigned __int64 mask) { #if _M_X64 + if (mask == 0) + return 64; + unsigned long index; _BitScanReverse64(&index, mask); return sizeof(unsigned __int64) * 8 - (index + 1); #elif _M_IX86 - unsigned long index; - unsigned long high_mask; - memcpy(&high_mask, (unsigned char*)&mask + sizeof(unsigned long), - sizeof(unsigned long)); - if (_BitScanReverse(&index, high_mask)) { - return sizeof(unsigned long) * 8 - (index + 1); - } + int result = Clz(HighDword(mask)); + if (result == 32) + result += Clz(LowDword(mask)); - unsigned long low_mask; - memcpy(&low_mask, &mask, sizeof(unsigned long)); - _BitScanReverse(&index, low_mask); - return sizeof(unsigned __int64) * 8 - (index + 1); + return result; #else #error unexpected architecture #endif } -__inline unsigned long wabt_ctz_u32(unsigned long mask) { - unsigned long index; - _BitScanForward(&index, mask); - return index; +inline int Ctz(unsigned long mask) { + if (mask == 0) + return 32; + + unsigned long index; + _BitScanForward(&index, mask); + return index; } -__inline unsigned long wabt_ctz_u64(unsigned __int64 mask) { +inline int Ctz(unsigned int mask) { + return Ctz((unsigned long)mask); +} + +inline int Ctz(unsigned __int64 mask) { #if _M_X64 - unsigned long index; - _BitScanForward64(&index, mask); - return index; + if (mask == 0) + return 64; + + unsigned long index; + _BitScanForward64(&index, mask); + return index; #elif _M_IX86 - unsigned long low_mask = (unsigned long)mask; - if (low_mask) { - return wabt_ctz_u32(low_mask); - } - unsigned long high_mask; - memcpy(&high_mask, (unsigned char*)&mask + sizeof(unsigned long), - sizeof(unsigned long)); - return sizeof(unsigned long) * 8 + wabt_ctz_u32(high_mask); + int result = Ctz(LowDword(mask)); + if (result == 32) + result += Ctz(HighDword(mask)); + + return result; #else #error unexpected architecture #endif } +inline int Popcount(unsigned long value) { + return __popcnt(value); +} -#define wabt_popcount_u32 __popcnt +inline int Popcount(unsigned int value) { + return Popcount((unsigned long)value); +} + +inline int Popcount(unsigned __int64 value) { #if _M_X64 + return __popcnt64(value); #elif _M_IX86 -__inline unsigned __int64 __popcnt64(unsigned __int64 value) { - unsigned long high_value; - unsigned long low_value; - memcpy(&high_value, (unsigned char*)&value + sizeof(unsigned long), - sizeof(unsigned long)); - memcpy(&low_value, &value, sizeof(unsigned long)); - return wabt_popcount_u32(high_value) + wabt_popcount_u32(low_value); -} + return Popcount(HighDword(value)) + Popcount(LowDword(value)); #else #error unexpected architecture #endif -#define wabt_popcount_u64 __popcnt64 +} #else @@ -214,6 +235,8 @@ __inline unsigned __int64 __popcnt64(unsigned __int64 value) { #endif +} // namespace wabt + #if COMPILER_IS_MSVC diff --git a/src/interp.cc b/src/interp.cc index dfe2a983..ea464957 100644 --- a/src/interp.cc +++ b/src/interp.cc @@ -1677,23 +1677,17 @@ Result Thread::Run(int num_instructions) { CHECK_TRAP(Binop(Ge<uint32_t>)); break; - case Opcode::I32Clz: { - uint32_t value = Pop<uint32_t>(); - CHECK_TRAP(Push<uint32_t>(value != 0 ? wabt_clz_u32(value) : 32)); + case Opcode::I32Clz: + CHECK_TRAP(Push<uint32_t>(Clz(Pop<uint32_t>()))); break; - } - case Opcode::I32Ctz: { - uint32_t value = Pop<uint32_t>(); - CHECK_TRAP(Push<uint32_t>(value != 0 ? wabt_ctz_u32(value) : 32)); + case Opcode::I32Ctz: + CHECK_TRAP(Push<uint32_t>(Ctz(Pop<uint32_t>()))); break; - } - case Opcode::I32Popcnt: { - uint32_t value = Pop<uint32_t>(); - CHECK_TRAP(Push<uint32_t>(wabt_popcount_u32(value))); + case Opcode::I32Popcnt: + CHECK_TRAP(Push<uint32_t>(Popcount(Pop<uint32_t>()))); break; - } case Opcode::I32Eqz: CHECK_TRAP(Unop(IntEqz<uint32_t, uint32_t>)); @@ -1791,20 +1785,16 @@ Result Thread::Run(int num_instructions) { CHECK_TRAP(Binop(Ge<uint64_t>)); break; - case Opcode::I64Clz: { - uint64_t value = Pop<uint64_t>(); - CHECK_TRAP(Push<uint64_t>(value != 0 ? wabt_clz_u64(value) : 64)); + case Opcode::I64Clz: + CHECK_TRAP(Push<uint64_t>(Clz(Pop<uint64_t>()))); break; - } - case Opcode::I64Ctz: { - uint64_t value = Pop<uint64_t>(); - CHECK_TRAP(Push<uint64_t>(value != 0 ? wabt_ctz_u64(value) : 64)); + case Opcode::I64Ctz: + CHECK_TRAP(Push<uint64_t>(Ctz(Pop<uint64_t>()))); break; - } case Opcode::I64Popcnt: - CHECK_TRAP(Push<uint64_t>(wabt_popcount_u64(Pop<uint64_t>()))); + CHECK_TRAP(Push<uint64_t>(Popcount(Pop<uint64_t>()))); break; case Opcode::F32Add: diff --git a/src/literal.cc b/src/literal.cc index 7476abef..f63c358f 100644 --- a/src/literal.cc +++ b/src/literal.cc @@ -26,14 +26,6 @@ namespace wabt { namespace { -int Clz(uint32_t value) { - return value == 0 ? 32 : wabt_clz_u32(value); -} - -int Clz(uint64_t value) { - return value == 0 ? 64 : wabt_clz_u64(value); -} - template <typename T> struct FloatTraitsBase {}; |