summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-11-05 20:41:41 -0800
committerAlon Zakai <alonzakai@gmail.com>2015-11-05 20:41:41 -0800
commit2298da8a685268e0f4bdf6a7a03e47429c39105a (patch)
treebb84e02afe023462fcbb17227161dc79238fee73 /src/wasm-interpreter.h
parent00588550c369ec56feaafe6993e2192d9def72d6 (diff)
downloadbinaryen-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.h31
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();