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

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

Issue 1804513002: [wasm] Int64Lowering of I64Div and I64Rem. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 9 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/serializer-common.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 559f894f8abf9d1c0e24a5c2ead29ed862655758..5b1ff409ad20e0bd9542d6b31ab355226d7bdded 100644
--- a/src/compiler/wasm-compiler.cc
+++ b/src/compiler/wasm-compiler.cc
@@ -500,9 +500,17 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left,
// kExprI64Sub:
// kExprI64Mul:
// kExprI64DivS:
+ case wasm::kExprI64DivS:
+ return BuildI64DivS(left, right);
// kExprI64DivU:
+ case wasm::kExprI64DivU:
+ return BuildI64DivU(left, right);
// kExprI64RemS:
+ case wasm::kExprI64RemS:
+ return BuildI64RemS(left, right);
// kExprI64RemU:
+ case wasm::kExprI64RemU:
+ return BuildI64RemU(left, right);
case wasm::kExprI64Ior:
op = m->Word64Or();
break;
@@ -568,44 +576,6 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left,
case wasm::kExprI64Mul:
op = m->Int64Mul();
break;
- case wasm::kExprI64DivS: {
- trap_->ZeroCheck64(kTrapDivByZero, right);
- Node* before = *control_;
- Node* denom_is_m1;
- Node* denom_is_not_m1;
- Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
- jsgraph()->Int64Constant(-1)),
- &denom_is_m1, &denom_is_not_m1);
- *control_ = denom_is_m1;
- trap_->TrapIfEq64(kTrapDivUnrepresentable, left,
- std::numeric_limits<int64_t>::min());
- if (*control_ != denom_is_m1) {
- *control_ = graph()->NewNode(jsgraph()->common()->Merge(2),
- denom_is_not_m1, *control_);
- } else {
- *control_ = before;
- }
- return graph()->NewNode(m->Int64Div(), left, right, *control_);
- }
- case wasm::kExprI64DivU:
- op = m->Uint64Div();
- return graph()->NewNode(op, left, right,
- trap_->ZeroCheck64(kTrapDivByZero, right));
- case wasm::kExprI64RemS: {
- trap_->ZeroCheck64(kTrapRemByZero, right);
- Diamond d(jsgraph()->graph(), jsgraph()->common(),
- graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
- jsgraph()->Int64Constant(-1)));
-
- Node* rem = graph()->NewNode(m->Int64Mod(), left, right, d.if_false);
-
- return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0),
- rem);
- }
- case wasm::kExprI64RemU:
- op = m->Uint64Mod();
- return graph()->NewNode(op, left, right,
- trap_->ZeroCheck64(kTrapRemByZero, right));
case wasm::kExprI64Ror:
op = m->Word64Ror();
break;
@@ -1774,6 +1744,108 @@ Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction(
return load;
}
+Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) {
+ if (jsgraph()->machine()->Is32()) {
+ return BuildDiv64Call(
+ left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()),
+ MachineType::Int64(), kTrapDivByZero);
+ }
+ trap_->ZeroCheck64(kTrapDivByZero, right);
+ Node* before = *control_;
+ Node* denom_is_m1;
+ Node* denom_is_not_m1;
+ Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
+ jsgraph()->Int64Constant(-1)),
+ &denom_is_m1, &denom_is_not_m1);
+ *control_ = denom_is_m1;
+ trap_->TrapIfEq64(kTrapDivUnrepresentable, left,
+ std::numeric_limits<int64_t>::min());
+ if (*control_ != denom_is_m1) {
+ *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1,
+ *control_);
+ } else {
+ *control_ = before;
+ }
+ return graph()->NewNode(jsgraph()->machine()->Int64Div(), left, right,
+ *control_);
+}
+
+Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) {
+ if (jsgraph()->machine()->Is32()) {
+ return BuildDiv64Call(
+ left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()),
+ MachineType::Int64(), kTrapRemByZero);
+ }
+ trap_->ZeroCheck64(kTrapRemByZero, right);
+ Diamond d(jsgraph()->graph(), jsgraph()->common(),
+ graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
+ jsgraph()->Int64Constant(-1)));
+
+ Node* rem = graph()->NewNode(jsgraph()->machine()->Int64Mod(), left, right,
+ d.if_false);
+
+ return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0),
+ rem);
+}
+
+Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right) {
+ if (jsgraph()->machine()->Is32()) {
+ return BuildDiv64Call(
+ left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()),
+ MachineType::Int64(), kTrapDivByZero);
+ }
+ return graph()->NewNode(jsgraph()->machine()->Uint64Div(), left, right,
+ trap_->ZeroCheck64(kTrapDivByZero, right));
+}
+Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right) {
+ if (jsgraph()->machine()->Is32()) {
+ return BuildDiv64Call(
+ left, right, ExternalReference::wasm_uint64_mod(jsgraph()->isolate()),
+ MachineType::Int64(), kTrapRemByZero);
+ }
+ return graph()->NewNode(jsgraph()->machine()->Uint64Mod(), left, right,
+ trap_->ZeroCheck64(kTrapRemByZero, right));
+}
+
+Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right,
+ ExternalReference ref,
+ MachineType result_type, int trap_zero) {
+ Node* stack_slot_dst = graph()->NewNode(
+ jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
+ Node* stack_slot_src = graph()->NewNode(
+ jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
+
+ const Operator* store_op = jsgraph()->machine()->Store(
+ StoreRepresentation(MachineRepresentation::kWord64, kNoWriteBarrier));
+ *effect_ =
+ graph()->NewNode(store_op, stack_slot_dst, jsgraph()->Int32Constant(0),
+ left, *effect_, *control_);
+ *effect_ =
+ graph()->NewNode(store_op, stack_slot_src, jsgraph()->Int32Constant(0),
+ right, *effect_, *control_);
+
+ MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
+ sig_builder.AddReturn(MachineType::Int32());
+ sig_builder.AddParam(MachineType::Pointer());
+ sig_builder.AddParam(MachineType::Pointer());
+
+ Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
+ Node* args[] = {function, stack_slot_dst, stack_slot_src};
+
+ Node* call = BuildCCall(sig_builder.Build(), args);
+
+ // TODO(wasm): This can get simpler if we have a specialized runtime call to
+ // throw WASM exceptions by trap code instead of by string.
+ trap_->ZeroCheck32(static_cast<TrapReason>(trap_zero), call);
+ trap_->TrapIfEq32(kTrapDivUnrepresentable, call, -1);
+ const Operator* load_op = jsgraph()->machine()->Load(result_type);
+ Node* load =
+ graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0),
+ *effect_, *control_);
+ *effect_ = load;
+ return load;
+}
+
Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
const size_t params = sig->parameter_count();
const size_t extra = 2; // effect and control inputs.
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/snapshot/serializer-common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698