diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-05 20:41:41 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-05 20:41:41 -0800 |
commit | 2298da8a685268e0f4bdf6a7a03e47429c39105a (patch) | |
tree | bb84e02afe023462fcbb17227161dc79238fee73 /src/wasm-interpreter.h | |
parent | 00588550c369ec56feaafe6993e2192d9def72d6 (diff) | |
download | binaryen-2298da8a685268e0f4bdf6a7a03e47429c39105a.tar.gz binaryen-2298da8a685268e0f4bdf6a7a03e47429c39105a.tar.bz2 binaryen-2298da8a685268e0f4bdf6a7a03e47429c39105a.zip |
clz fixes
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r-- | src/wasm-interpreter.h | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index b5eb531bb..2c8a2bacd 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -11,12 +11,24 @@ namespace wasm { using namespace cashew; +// Utilities + +IString WASM("wasm"); + +int32_t safe_clz(int32_t v) { + if (v == 0) return 32; + return __builtin_clz(v); +} + +int32_t safe_ctz(int32_t v) { + if (v == 0) return 32; + return __builtin_ctz(v); +} + // // An instance of a WebAssembly module, which can execute it via AST interpretation // -IString WASM("wasm"); - class ModuleInstance { public: typedef std::vector<Literal> LiteralList; @@ -311,13 +323,10 @@ public: if (value.type == i32) { int32_t v = value.geti32(); switch (curr->op) { - case Clz: { - if (v == 0) return Literal(32); - return Literal((int32_t)__builtin_clz(v)); - } + case Clz: return Literal(safe_clz(v)); case Ctz: { if (v == 0) return Literal(32); - return Literal((int32_t)__builtin_ctz(v)); + return Literal((int32_t)safe_ctz(v)); } case Popcnt: return Literal((int32_t)__builtin_popcount(v)); default: abort(); @@ -328,11 +337,15 @@ public: switch (curr->op) { case Clz: { if (v == 0) return Literal((int64_t)64); - return Literal((int64_t)__builtin_clz(v)); + int32_t high = v >> 32, low = v; + if (high == 0) return Literal(32+(int64_t)safe_clz(low)); + return Literal((int64_t)safe_clz(high)); } case Ctz: { if (v == 0) return Literal((int64_t)64); - return Literal((int64_t)__builtin_ctz(v)); + int32_t high = v >> 32, low = v; + if (low == 0) return Literal(32+(int64_t)safe_ctz(high)); + return Literal((int64_t)safe_ctz(low)); } case Popcnt: return Literal((int64_t)__builtin_popcount(v)); default: abort(); |