diff options
author | Alon Zakai (kripken) <alonzakai@gmail.com> | 2017-04-18 11:55:02 -0700 |
---|---|---|
committer | Alon Zakai (kripken) <alonzakai@gmail.com> | 2017-04-18 16:58:58 -0700 |
commit | 12e8c5c20bf9f7d1e5fd85a56c722adf786b5bab (patch) | |
tree | ad3377744b5a0065a5333f0b4be35263cd062f53 /src/asm2wasm.h | |
parent | e1bfd0c5851122762d54d0f578f049e7005bde86 (diff) | |
download | binaryen-12e8c5c20bf9f7d1e5fd85a56c722adf786b5bab.tar.gz binaryen-12e8c5c20bf9f7d1e5fd85a56c722adf786b5bab.tar.bz2 binaryen-12e8c5c20bf9f7d1e5fd85a56c722adf786b5bab.zip |
handle unsigned float-to-int properly in asm2wasm
Diffstat (limited to 'src/asm2wasm.h')
-rw-r--r-- | src/asm2wasm.h | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index ada026176..ed8c75e56 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -485,6 +485,14 @@ private: return detectSign(ast, Math_fround) == ASM_UNSIGNED; } + bool isParentUnsignedCoercion(Ref parent) { + // parent may not exist, or may be a non-relevant node + if (!!parent && parent->isArray() && parent[0] == BINARY && isUnsignedCoercion(parent)) { + return true; + } + return false; + } + BinaryOp parseAsmBinaryOp(IString op, Ref left, Ref right, Expression* leftWasm, Expression* rightWasm) { WasmType leftType = leftWasm->type; bool isInteger = leftType == WasmType::i32; @@ -735,11 +743,16 @@ private: } // Some conversions might trap, so emit them safely if necessary - Expression* makeTrappingFloatToInt(Expression* value) { + Expression* makeTrappingFloatToInt(bool signed_, Expression* value) { if (trapMode == TrapMode::Allow) { auto ret = allocator.alloc<Unary>(); ret->value = value; - ret->op = ret->value->type == f64 ? TruncSFloat64ToInt32 : TruncSFloat32ToInt32; + bool isF64 = ret->value->type == f64; + if (signed_) { + ret->op = isF64 ? TruncSFloat64ToInt32 : TruncSFloat32ToInt32; + } else { + ret->op = isF64 ? TruncUFloat64ToInt32 : TruncUFloat32ToInt32; + } ret->type = WasmType::i32; return ret; } @@ -1752,7 +1765,8 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } else if (ast[1] == B_NOT) { // ~, might be ~~ as a coercion or just a not if (ast[2]->isArray(UNARY_PREFIX) && ast[2][1] == B_NOT) { - return makeTrappingFloatToInt(process(ast[2][2])); + // if we have an unsigned coercion on us, it is an unsigned op + return makeTrappingFloatToInt(!isParentUnsignedCoercion(astStackHelper.getParent()), process(ast[2][2])); } // no bitwise unary not, so do xor with -1 auto ret = allocator.alloc<Binary>(); |