diff options
Diffstat (limited to 'src/passes/RemoveNonJSOps.cpp')
-rw-r--r-- | src/passes/RemoveNonJSOps.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/src/passes/RemoveNonJSOps.cpp b/src/passes/RemoveNonJSOps.cpp index 7c0a0e2ce..5bbb9f701 100644 --- a/src/passes/RemoveNonJSOps.cpp +++ b/src/passes/RemoveNonJSOps.cpp @@ -252,17 +252,29 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> { } void rewriteCopysign(Binary* curr) { + + // i32.copysign(x, y) => f32.reinterpret( + // (i32.reinterpret(x) & ~(1 << 31)) | + // (i32.reinterpret(y) & (1 << 31) + // ) + // + // i64.copysign(x, y) => f64.reinterpret( + // (i64.reinterpret(x) & ~(1 << 63)) | + // (i64.reinterpret(y) & (1 << 63) + // ) + Literal signBit, otherBits; UnaryOp int2float, float2int; BinaryOp bitAnd, bitOr; + switch (curr->op) { case CopySignFloat32: float2int = ReinterpretFloat32; int2float = ReinterpretInt32; bitAnd = AndInt32; bitOr = OrInt32; - signBit = Literal(uint32_t(1 << 31)); - otherBits = Literal(uint32_t(1 << 31) - 1); + signBit = Literal(uint32_t(1U << 31)); + otherBits = Literal(~uint32_t(1U << 31)); break; case CopySignFloat64: @@ -270,8 +282,8 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> { int2float = ReinterpretInt64; bitAnd = AndInt64; bitOr = OrInt64; - signBit = Literal(uint64_t(1) << 63); - otherBits = Literal((uint64_t(1) << 63) - 1); + signBit = Literal(uint64_t(1ULL << 63)); + otherBits = Literal(~uint64_t(1ULL << 63)); break; default: |