| Index: src/compiler/wasm-compiler.cc
|
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
|
| index 64b3089952d32f6b093d42adb24e28c43b5ccc59..b7f04d42ac9991c1ab5016c90b09572613f10c79 100644
|
| --- a/src/compiler/wasm-compiler.cc
|
| +++ b/src/compiler/wasm-compiler.cc
|
| @@ -756,11 +756,10 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
|
| case wasm::kExprF32Trunc: {
|
| if (m->Float32RoundTruncate().IsSupported()) {
|
| op = m->Float32RoundTruncate().op();
|
| - break;
|
| } else {
|
| - op = UnsupportedOpcode(opcode);
|
| - break;
|
| + return BuildF32Trunc(input);
|
| }
|
| + break;
|
| }
|
| case wasm::kExprF32NearestInt: {
|
| if (m->Float32RoundTiesEven().IsSupported()) {
|
| @@ -1365,6 +1364,73 @@ Node* WasmGraphBuilder::BuildI64Popcnt(Node* input) {
|
| }
|
|
|
|
|
| +Node* WasmGraphBuilder::BuildF32Trunc(Node* input) {
|
| + // int32_t int_input = bitftoi(input);
|
| + // int32_t exponent = int_input & 0x7f800000;
|
| + // if (exponent >= ((23 + 127) << 23)) {
|
| + // if (input != input) {
|
| + // return bititof(int_input | (1 << 22));
|
| + // }
|
| + // return input;
|
| + // }
|
| + // int32_t sign = int_input & 0x80000000;
|
| + // if (exponent < (127 << 23)) {
|
| + // return bititof(sign);
|
| + // }
|
| + // int32_t mantissa = int_input & 0x007fffff;
|
| + // int32_t shift = (127 + 23) - (exponent >> 23);
|
| + // int32_t new_mantissa = (mantissa >> shift) << shift;
|
| + // int32_t result = new_mantissa | exponent | sign;
|
| + // return bititof(result);
|
| +
|
| + Node* int_input = Unop(wasm::kExprI32ReinterpretF32, input);
|
| + Node* exponent =
|
| + Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x7f800000));
|
| +
|
| + Node* sign =
|
| + Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x80000000));
|
| +
|
| + Node* result_out_of_range = int_input;
|
| +
|
| + Node* result_nan =
|
| + Binop(wasm::kExprI32Ior, int_input, jsgraph()->Int32Constant(1 << 22));
|
| +
|
| + Node* result_zero = sign;
|
| +
|
| + Node* mantissa =
|
| + Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x007fffff));
|
| + Node* shift =
|
| + Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(23 + 127),
|
| + Binop(wasm::kExprI32ShrU, exponent, jsgraph()->Int32Constant(23)));
|
| + Node* new_mantissa = Binop(wasm::kExprI32Shl,
|
| + Binop(wasm::kExprI32ShrU, mantissa, shift), shift);
|
| + Node* result_truncate =
|
| + Binop(wasm::kExprI32Ior, Binop(wasm::kExprI32Ior, new_mantissa, exponent),
|
| + sign);
|
| +
|
| + Diamond is_zero(
|
| + graph(), jsgraph()->common(),
|
| + Binop(wasm::kExprI32LtU, exponent, jsgraph()->Int32Constant(127 << 23)));
|
| +
|
| + Node* result_within_range =
|
| + is_zero.Phi(wasm::kAstI32, result_zero, result_truncate);
|
| +
|
| + Diamond input_nan(graph(), jsgraph()->common(),
|
| + Binop(wasm::kExprF32Ne, input, input));
|
| + Node* result_exponent_geq_23 =
|
| + input_nan.Phi(wasm::kAstI32, result_nan, result_out_of_range);
|
| +
|
| + Diamond exponent_geq_23(graph(), jsgraph()->common(),
|
| + Binop(wasm::kExprI32GeU, exponent,
|
| + jsgraph()->Int32Constant((23 + 127) << 23)));
|
| +
|
| + Node* result = exponent_geq_23.Phi(wasm::kAstI32, result_exponent_geq_23,
|
| + result_within_range);
|
| +
|
| + return Unop(wasm::kExprF32ReinterpretI32, result);
|
| +}
|
| +
|
| +
|
| Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args) {
|
| const size_t params = sig->parameter_count();
|
| const size_t extra = 2; // effect and control inputs.
|
|
|