diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-16 17:55:42 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-16 18:13:49 -0800 |
commit | df2d946238e80e2b3ef6b198301b3947e28646dd (patch) | |
tree | cb14736ec0f905d365815a0c8ddafda4cab3152d | |
parent | 797dd8d4119e0b02abd3ddd4d99557d8dfe591e9 (diff) | |
download | binaryen-df2d946238e80e2b3ef6b198301b3947e28646dd.tar.gz binaryen-df2d946238e80e2b3ef6b198301b3947e28646dd.tar.bz2 binaryen-df2d946238e80e2b3ef6b198301b3947e28646dd.zip |
emit a special call to a special import to handle floating-point remainder, which exists in asm.js but not in wasm
-rw-r--r-- | src/asm2wasm.h | 30 | ||||
-rw-r--r-- | src/js/post.js | 5 |
2 files changed, 32 insertions, 3 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index d50e72fea..68c5132f6 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -29,7 +29,9 @@ IString GLOBAL("global"), NAN_("NaN"), INFINITY_("Infinity"), IMPOSSIBLE_CONTINUE("impossible-continue"), MATH("Math"), IMUL("imul"), - CLZ32("clz32"); + CLZ32("clz32"), + ASM2WASM("asm2wasm"), + F64_REM("f64-rem"); static void abort_on(std::string why) { @@ -280,7 +282,7 @@ private: if (isInteger) { { binary = isUnsigned ? BinaryOp::RemU : BinaryOp::RemS; return true; } } - abort_on("non-integer rem"); + { binary = BinaryOp::RemS; return true; } // XXX no floating-point remainder op, this must be handled by the caller } if (op == GE) { if (isInteger) { @@ -508,7 +510,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { Import& import = *pair.second; if (importedFunctionTypes.find(name) != importedFunctionTypes.end()) { import.type = importedFunctionTypes[name]; - } else { + } else if (import.module != ASM2WASM) { // special-case the special module // never actually used toErase.push_back(name); } @@ -652,6 +654,28 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { ret->left = process(ast[2]); ret->right = process(ast[3]); ret->type = ret->left->type; + if (binary == BinaryOp::RemS && isWasmTypeFloat(ret->type)) { + // WebAssembly does not have floating-point remainder, we have to emit a call to a special import of ours + CallImport *call = allocator.alloc<CallImport>(); + call->target = F64_REM; + call->operands.push_back(ret->left); + call->operands.push_back(ret->right); + call->type = f64; + static bool addedImport = false; + if (!addedImport) { + addedImport = true; + auto import = allocator.alloc<Import>(); // f64-rem = asm2wasm.f64-rem; + import->name = F64_REM; + import->module = ASM2WASM; + import->base = F64_REM; + import->type.name = F64_REM; + import->type.result = f64; + import->type.params.push_back(f64); + import->type.params.push_back(f64); + wasm.addImport(import); + } + return call; + } return ret; } else { auto ret = allocator.alloc<Compare>(); diff --git a/src/js/post.js b/src/js/post.js index 45d850f10..6406674ba 100644 --- a/src/js/post.js +++ b/src/js/post.js @@ -28,6 +28,11 @@ var info = wasmJS['info'] = { global: null, env: null, + asm2wasm: { // special asm2wasm imports + "f64-rem": function(x, y) { + return x % y; + }, + }, parent: Module // Module inside wasm-js.cpp refers to wasm-js.cpp; this allows access to the outside program. }; |