Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1057)

Unified Diff: src/compiler/wasm-compiler.cc

Issue 1661463002: [wasm] Provide backoff implementations for the Fxx rounding instructions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@trunc64-external-reference
Patch Set: rebase. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/snapshot/serialize.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/wasm-compiler.cc
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
index dd0dfe3873bca5de94a28196a0072b44184f0d85..69e51d77e5544ff89e21b1c3a4326a468bc89953 100644
--- a/src/compiler/wasm-compiler.cc
+++ b/src/compiler/wasm-compiler.cc
@@ -742,57 +742,35 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
}
}
case wasm::kExprF32Floor: {
- if (m->Float32RoundDown().IsSupported()) {
- op = m->Float32RoundDown().op();
- break;
- } else {
- op = UnsupportedOpcode(opcode);
- break;
- }
+ if (!m->Float32RoundDown().IsSupported()) return BuildF32Floor(input);
+ op = m->Float32RoundDown().op();
+ break;
}
case wasm::kExprF32Ceil: {
- if (m->Float32RoundUp().IsSupported()) {
- op = m->Float32RoundUp().op();
- break;
- } else {
- op = UnsupportedOpcode(opcode);
- break;
- }
+ if (!m->Float32RoundUp().IsSupported()) return BuildF32Ceil(input);
+ op = m->Float32RoundUp().op();
+ break;
}
case wasm::kExprF32Trunc: {
- if (m->Float32RoundTruncate().IsSupported()) {
- op = m->Float32RoundTruncate().op();
- } else {
- return BuildF32Trunc(input);
- }
+ if (!m->Float32RoundTruncate().IsSupported()) return BuildF32Trunc(input);
+ op = m->Float32RoundTruncate().op();
break;
}
case wasm::kExprF32NearestInt: {
- if (m->Float32RoundTiesEven().IsSupported()) {
- op = m->Float32RoundTiesEven().op();
- break;
- } else {
- op = UnsupportedOpcode(opcode);
- break;
- }
+ if (!m->Float32RoundTiesEven().IsSupported())
+ return BuildF32NearestInt(input);
+ op = m->Float32RoundTiesEven().op();
+ break;
}
case wasm::kExprF64Floor: {
- if (m->Float64RoundDown().IsSupported()) {
- op = m->Float64RoundDown().op();
- break;
- } else {
- op = UnsupportedOpcode(opcode);
- break;
- }
+ if (!m->Float64RoundDown().IsSupported()) return BuildF64Floor(input);
+ op = m->Float64RoundDown().op();
+ break;
}
case wasm::kExprF64Ceil: {
- if (m->Float64RoundUp().IsSupported()) {
- op = m->Float64RoundUp().op();
- break;
- } else {
- op = UnsupportedOpcode(opcode);
- break;
- }
+ if (!m->Float64RoundUp().IsSupported()) return BuildF64Ceil(input);
+ op = m->Float64RoundUp().op();
+ break;
}
case wasm::kExprF64Trunc: {
if (!m->Float64RoundTruncate().IsSupported()) return BuildF64Trunc(input);
@@ -800,13 +778,10 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
break;
}
case wasm::kExprF64NearestInt: {
- if (m->Float64RoundTiesEven().IsSupported()) {
- op = m->Float64RoundTiesEven().op();
- break;
- } else {
- op = UnsupportedOpcode(opcode);
- break;
- }
+ if (!m->Float64RoundTiesEven().IsSupported())
+ return BuildF64NearestInt(input);
+ op = m->Float64RoundTiesEven().op();
+ break;
}
#if WASM_64
@@ -1365,99 +1340,89 @@ Node* WasmGraphBuilder::BuildI64Popcnt(Node* input) {
return result;
}
-
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);
+ MachineType type = MachineType::Float32();
+ ExternalReference ref =
+ ExternalReference::f32_trunc_wrapper_function(jsgraph()->isolate());
+ return BuildRoundingInstruction(input, ref, type);
+}
+
+Node* WasmGraphBuilder::BuildF32Floor(Node* input) {
+ MachineType type = MachineType::Float32();
+ ExternalReference ref =
+ ExternalReference::f32_floor_wrapper_function(jsgraph()->isolate());
+ return BuildRoundingInstruction(input, ref, type);
+}
+
+Node* WasmGraphBuilder::BuildF32Ceil(Node* input) {
+ MachineType type = MachineType::Float32();
+ ExternalReference ref =
+ ExternalReference::f32_ceil_wrapper_function(jsgraph()->isolate());
+ return BuildRoundingInstruction(input, ref, type);
+}
+
+Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) {
+ MachineType type = MachineType::Float32();
+ ExternalReference ref =
+ ExternalReference::f32_nearest_int_wrapper_function(jsgraph()->isolate());
+ return BuildRoundingInstruction(input, ref, type);
}
Node* WasmGraphBuilder::BuildF64Trunc(Node* input) {
+ MachineType type = MachineType::Float64();
+ ExternalReference ref =
+ ExternalReference::f64_trunc_wrapper_function(jsgraph()->isolate());
+ return BuildRoundingInstruction(input, ref, type);
+}
+
+Node* WasmGraphBuilder::BuildF64Floor(Node* input) {
+ MachineType type = MachineType::Float64();
+ ExternalReference ref =
+ ExternalReference::f64_floor_wrapper_function(jsgraph()->isolate());
+ return BuildRoundingInstruction(input, ref, type);
+}
+
+Node* WasmGraphBuilder::BuildF64Ceil(Node* input) {
+ MachineType type = MachineType::Float64();
+ ExternalReference ref =
+ ExternalReference::f64_ceil_wrapper_function(jsgraph()->isolate());
+ return BuildRoundingInstruction(input, ref, type);
+}
+
+Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) {
+ MachineType type = MachineType::Float64();
+ ExternalReference ref =
+ ExternalReference::f64_nearest_int_wrapper_function(jsgraph()->isolate());
+ return BuildRoundingInstruction(input, ref, type);
+}
+
+Node* WasmGraphBuilder::BuildRoundingInstruction(Node* input,
+ ExternalReference ref,
+ MachineType type) {
// We do truncation by calling a C function which calculates the truncation
// for us. The input is passed to the C function as a double* to avoid double
// parameters. For this we reserve a slot on the stack, store the parameter in
// that slot, pass a pointer to the slot to the C function, and after calling
// the C function we collect the return value from the stack slot.
- Node* stack_slot_param = graph()->NewNode(
- jsgraph()->machine()->StackSlot(MachineRepresentation::kFloat64));
+ Node* stack_slot_param =
+ graph()->NewNode(jsgraph()->machine()->StackSlot(type.representation()));
const Operator* store_op = jsgraph()->machine()->Store(
- StoreRepresentation(MachineRepresentation::kFloat64, kNoWriteBarrier));
+ StoreRepresentation(type.representation(), kNoWriteBarrier));
*effect_ =
graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
input, *effect_, *control_);
Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 1);
sig_builder.AddParam(MachineType::Pointer());
- Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(
- ExternalReference::trunc64_wrapper_function(jsgraph()->isolate())));
+ Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
Node* args[] = {function, stack_slot_param};
BuildCCall(sig_builder.Build(), args);
- const Operator* load_op = jsgraph()->machine()->Load(MachineType::Float64());
+ const Operator* load_op = jsgraph()->machine()->Load(type);
Node* load =
graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0),
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/snapshot/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698