diff options
Diffstat (limited to 'src/asm2wasm.h')
-rw-r--r-- | src/asm2wasm.h | 73 |
1 files changed, 34 insertions, 39 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 74b1aa8c4..d1959b918 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -307,63 +307,58 @@ private: } BinaryOp parseAsmBinaryOp(IString op, Ref left, Ref right, AsmData *asmData) { - if (op == PLUS) return BinaryOp::Add; - if (op == MINUS) return BinaryOp::Sub; - if (op == MUL) return BinaryOp::Mul; - if (op == AND) return BinaryOp::And; - if (op == OR) return BinaryOp::Or; - if (op == XOR) return BinaryOp::Xor; - if (op == LSHIFT) return BinaryOp::Shl; - if (op == RSHIFT) return BinaryOp::ShrS; - if (op == TRSHIFT) return BinaryOp::ShrU; - if (op == EQ) return BinaryOp::Eq; - if (op == NE) return BinaryOp::Ne; WasmType leftType = detectWasmType(left, asmData); -#if 0 - std::cout << "CHECK\n"; - left->stringify(std::cout); - std::cout << " => " << printWasmType(leftType); - std::cout << '\n'; - right->stringify(std::cout); - std::cout << " => " << printWasmType(detectWasmType(right, asmData)) << "\n"; -#endif bool isInteger = leftType == WasmType::i32; + + if (op == PLUS) return isInteger ? BinaryOp::AddInt32 : (leftType == f32 ? BinaryOp::AddFloat32 : BinaryOp::AddFloat64); + if (op == MINUS) return isInteger ? BinaryOp::SubInt32 : (leftType == f32 ? BinaryOp::SubFloat32 : BinaryOp::SubFloat64); + if (op == MUL) return isInteger ? BinaryOp::MulInt32 : (leftType == f32 ? BinaryOp::MulFloat32 : BinaryOp::MulFloat64); + if (op == AND) return BinaryOp::AndInt32; + if (op == OR) return BinaryOp::OrInt32; + if (op == XOR) return BinaryOp::XorInt32; + if (op == LSHIFT) return BinaryOp::ShlInt32; + if (op == RSHIFT) return BinaryOp::ShrSInt32; + if (op == TRSHIFT) return BinaryOp::ShrUInt32; + if (op == EQ) return isInteger ? BinaryOp::EqInt32 : (leftType == f32 ? BinaryOp::EqFloat32 : BinaryOp::EqFloat64); + if (op == NE) return isInteger ? BinaryOp::NeInt32 : (leftType == f32 ? BinaryOp::NeFloat32 : BinaryOp::NeFloat64); + bool isUnsigned = isUnsignedCoercion(left) || isUnsignedCoercion(right); + if (op == DIV) { if (isInteger) { - return isUnsigned ? BinaryOp::DivU : BinaryOp::DivS; + return isUnsigned ? BinaryOp::DivUInt32 : BinaryOp::DivSInt32; } - return BinaryOp::Div; + return leftType == f32 ? BinaryOp::DivFloat32 : BinaryOp::DivFloat64; } if (op == MOD) { if (isInteger) { - return isUnsigned ? BinaryOp::RemU : BinaryOp::RemS; + return isUnsigned ? BinaryOp::RemUInt32 : BinaryOp::RemSInt32; } - return BinaryOp::RemS; // XXX no floating-point remainder op, this must be handled by the caller + return BinaryOp::RemSInt32; // XXX no floating-point remainder op, this must be handled by the caller } if (op == GE) { if (isInteger) { - return isUnsigned ? BinaryOp::GeU : BinaryOp::GeS; + return isUnsigned ? BinaryOp::GeUInt32 : BinaryOp::GeSInt32; } - return BinaryOp::Ge; + return leftType == f32 ? BinaryOp::GeFloat32 : BinaryOp::GeFloat64; } if (op == GT) { if (isInteger) { - return isUnsigned ? BinaryOp::GtU : BinaryOp::GtS; + return isUnsigned ? BinaryOp::GtUInt32 : BinaryOp::GtSInt32; } - return BinaryOp::Gt; + return leftType == f32 ? BinaryOp::GtFloat32 : BinaryOp::GtFloat64; } if (op == LE) { if (isInteger) { - return isUnsigned ? BinaryOp::LeU : BinaryOp::LeS; + return isUnsigned ? BinaryOp::LeUInt32 : BinaryOp::LeSInt32; } - return BinaryOp::Le; + return leftType == f32 ? BinaryOp::LeFloat32 : BinaryOp::LeFloat64; } if (op == LT) { if (isInteger) { - return isUnsigned ? BinaryOp::LtU : BinaryOp::LtS; + return isUnsigned ? BinaryOp::LtUInt32 : BinaryOp::LtSInt32; } - return BinaryOp::Lt; + return leftType == f32 ? BinaryOp::LtFloat32 : BinaryOp::LtFloat64; } abort_on("bad wasm binary op", op); abort(); // avoid warning @@ -733,7 +728,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { assert(functionTableStarts.find(tableName) != functionTableStarts.end()); auto sub = allocator.alloc<Binary>(); // note that the target is already masked, so we just offset it, we don't need to guard against overflow (which would be an error anyhow) - sub->op = Add; + sub->op = AddInt32; sub->left = call->target; sub->right = allocator.alloc<Const>()->set(Literal((int32_t)functionTableStarts[tableName])); sub->type = WasmType::i32; @@ -1008,7 +1003,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { ret->left = process(ast[2]); ret->right = process(ast[3]); ret->finalize(); - if (binary == BinaryOp::RemS && isWasmTypeFloat(ret->type)) { + if (binary == BinaryOp::RemSInt32 && 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; @@ -1126,7 +1121,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { if (asmType == ASM_INT) { // wasm has no unary negation for int, so do 0- auto ret = allocator.alloc<Binary>(); - ret->op = Sub; + ret->op = SubInt32; ret->left = allocator.alloc<Const>()->set(Literal((int32_t)0)); ret->right = process(ast[2]); ret->type = WasmType::i32; @@ -1182,7 +1177,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } // no bitwise unary not, so do xor with -1 auto ret = allocator.alloc<Binary>(); - ret->op = Xor; + ret->op = XorInt32; ret->left = process(ast[2]); ret->right = allocator.alloc<Const>()->set(Literal(int32_t(-1))); ret->type = WasmType::i32; @@ -1207,7 +1202,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { if (name == Math_imul) { assert(ast[2]->size() == 2); auto ret = allocator.alloc<Binary>(); - ret->op = Mul; + ret->op = MulInt32; ret->left = process(ast[2][0]); ret->right = process(ast[2][1]); ret->type = WasmType::i32; @@ -1263,14 +1258,14 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { return ret; }; auto isNegative = allocator.alloc<Binary>(); - isNegative->op = LtS; + isNegative->op = LtSInt32; isNegative->left = get(); isNegative->right = allocator.alloc<Const>()->set(Literal(0)); isNegative->finalize(); auto block = allocator.alloc<Block>(); block->list.push_back(set); auto flip = allocator.alloc<Binary>(); - flip->op = Sub; + flip->op = SubInt32; flip->left = allocator.alloc<Const>()->set(Literal(0)); flip->right = get(); flip->type = i32; @@ -1631,7 +1626,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } } Binary* offsetor = allocator.alloc<Binary>(); - offsetor->op = BinaryOp::Sub; + offsetor->op = BinaryOp::SubInt32; offsetor->left = br->condition; offsetor->right = allocator.alloc<Const>()->set(Literal(min)); offsetor->type = i32; |