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. |