| Index: src/compiler/x87/instruction-selector-x87.cc
|
| diff --git a/src/compiler/x87/instruction-selector-x87.cc b/src/compiler/x87/instruction-selector-x87.cc
|
| index 079d5d202668c4c6a3ee00057245b2208af458a1..90f0f61e170674810501c7bb4e1f808e9226c930 100644
|
| --- a/src/compiler/x87/instruction-selector-x87.cc
|
| +++ b/src/compiler/x87/instruction-selector-x87.cc
|
| @@ -365,10 +365,11 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
|
| }
|
| }
|
|
|
| +namespace {
|
|
|
| // Shared routine for multiple binary operations.
|
| -static void VisitBinop(InstructionSelector* selector, Node* node,
|
| - InstructionCode opcode, FlagsContinuation* cont) {
|
| +void VisitBinop(InstructionSelector* selector, Node* node,
|
| + InstructionCode opcode, FlagsContinuation* cont) {
|
| X87OperandGenerator g(selector);
|
| Int32BinopMatcher m(node);
|
| Node* left = m.left().node();
|
| @@ -417,18 +418,24 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
|
| DCHECK_GE(arraysize(inputs), input_count);
|
| DCHECK_GE(arraysize(outputs), output_count);
|
|
|
| - selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
|
| - inputs);
|
| + opcode = cont->Encode(opcode);
|
| + if (cont->IsDeoptimize()) {
|
| + selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
|
| + cont->frame_state());
|
| + } else {
|
| + selector->Emit(opcode, output_count, outputs, input_count, inputs);
|
| + }
|
| }
|
|
|
|
|
| // Shared routine for multiple binary operations.
|
| -static void VisitBinop(InstructionSelector* selector, Node* node,
|
| - InstructionCode opcode) {
|
| +void VisitBinop(InstructionSelector* selector, Node* node,
|
| + InstructionCode opcode) {
|
| FlagsContinuation cont;
|
| VisitBinop(selector, node, opcode, &cont);
|
| }
|
|
|
| +} // namespace
|
|
|
| void InstructionSelector::VisitWord32And(Node* node) {
|
| VisitBinop(this, node, kX87And);
|
| @@ -1011,6 +1018,9 @@ void VisitCompareWithMemoryOperand(InstructionSelector* selector,
|
| inputs[input_count++] = g.Label(cont->true_block());
|
| inputs[input_count++] = g.Label(cont->false_block());
|
| selector->Emit(opcode, 0, nullptr, input_count, inputs);
|
| + } else if (cont->IsDeoptimize()) {
|
| + selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs,
|
| + cont->frame_state());
|
| } else {
|
| DCHECK(cont->IsSet());
|
| InstructionOperand output = g.DefineAsRegister(cont->result());
|
| @@ -1038,13 +1048,16 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
|
| InstructionOperand left, InstructionOperand right,
|
| FlagsContinuation* cont) {
|
| X87OperandGenerator g(selector);
|
| + opcode = cont->Encode(opcode);
|
| if (cont->IsBranch()) {
|
| - selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right,
|
| + selector->Emit(opcode, g.NoOutput(), left, right,
|
| g.Label(cont->true_block()), g.Label(cont->false_block()));
|
| + } else if (cont->IsDeoptimize()) {
|
| + selector->EmitDeoptimize(opcode, g.NoOutput(), left, right,
|
| + cont->frame_state());
|
| } else {
|
| DCHECK(cont->IsSet());
|
| - selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()),
|
| - left, right);
|
| + selector->Emit(opcode, g.DefineAsByteRegister(cont->result()), left, right);
|
| }
|
| }
|
|
|
| @@ -1070,6 +1083,10 @@ void VisitFloat32Compare(InstructionSelector* selector, Node* node,
|
| if (cont->IsBranch()) {
|
| selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(),
|
| g.Label(cont->true_block()), g.Label(cont->false_block()));
|
| + } else if (cont->IsDeoptimize()) {
|
| + selector->EmitDeoptimize(cont->Encode(kX87Float32Cmp), g.NoOutput(),
|
| + g.Use(node->InputAt(0)), g.Use(node->InputAt(1)),
|
| + cont->frame_state());
|
| } else {
|
| DCHECK(cont->IsSet());
|
| selector->Emit(cont->Encode(kX87Float32Cmp),
|
| @@ -1087,6 +1104,10 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node,
|
| if (cont->IsBranch()) {
|
| selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(),
|
| g.Label(cont->true_block()), g.Label(cont->false_block()));
|
| + } else if (cont->IsDeoptimize()) {
|
| + selector->EmitDeoptimize(cont->Encode(kX87Float64Cmp), g.NoOutput(),
|
| + g.Use(node->InputAt(0)), g.Use(node->InputAt(1)),
|
| + cont->frame_state());
|
| } else {
|
| DCHECK(cont->IsSet());
|
| selector->Emit(cont->Encode(kX87Float64Cmp),
|
| @@ -1145,6 +1166,9 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
|
| if (cont->IsBranch()) {
|
| selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()),
|
| g.Label(cont->false_block()));
|
| + } else if (cont->IsDeoptimize()) {
|
| + selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr,
|
| + cont->frame_state());
|
| } else {
|
| DCHECK(cont->IsSet());
|
| selector->Emit(opcode, g.DefineAsRegister(cont->result()));
|
| @@ -1254,6 +1278,17 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
|
| VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
|
| }
|
|
|
| +void InstructionSelector::VisitDeoptimizeIf(Node* node) {
|
| + FlagsContinuation cont =
|
| + FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1));
|
| + VisitWordCompareZero(this, node, node->InputAt(0), &cont);
|
| +}
|
| +
|
| +void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
|
| + FlagsContinuation cont =
|
| + FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1));
|
| + VisitWordCompareZero(this, node, node->InputAt(0), &cont);
|
| +}
|
|
|
| void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
|
| X87OperandGenerator g(this);
|
| @@ -1284,7 +1319,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
|
|
|
|
|
| void InstructionSelector::VisitWord32Equal(Node* const node) {
|
| - FlagsContinuation cont(kEqual, node);
|
| + FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
|
| Int32BinopMatcher m(node);
|
| if (m.right().Is(0)) {
|
| return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
|
| @@ -1294,32 +1329,34 @@ void InstructionSelector::VisitWord32Equal(Node* const node) {
|
|
|
|
|
| void InstructionSelector::VisitInt32LessThan(Node* node) {
|
| - FlagsContinuation cont(kSignedLessThan, node);
|
| + FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
|
| VisitWordCompare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
|
| - FlagsContinuation cont(kSignedLessThanOrEqual, node);
|
| + FlagsContinuation cont =
|
| + FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
|
| VisitWordCompare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitUint32LessThan(Node* node) {
|
| - FlagsContinuation cont(kUnsignedLessThan, node);
|
| + FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
|
| VisitWordCompare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
|
| - FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
|
| + FlagsContinuation cont =
|
| + FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
|
| VisitWordCompare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
|
| if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
|
| - FlagsContinuation cont(kOverflow, ovf);
|
| + FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
|
| return VisitBinop(this, node, kX87Add, &cont);
|
| }
|
| FlagsContinuation cont;
|
| @@ -1329,7 +1366,7 @@ void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
|
|
|
| void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
|
| if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
|
| - FlagsContinuation cont(kOverflow, ovf);
|
| + FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
|
| return VisitBinop(this, node, kX87Sub, &cont);
|
| }
|
| FlagsContinuation cont;
|
| @@ -1338,37 +1375,41 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
|
|
|
|
|
| void InstructionSelector::VisitFloat32Equal(Node* node) {
|
| - FlagsContinuation cont(kUnorderedEqual, node);
|
| + FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node);
|
| VisitFloat32Compare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitFloat32LessThan(Node* node) {
|
| - FlagsContinuation cont(kUnsignedGreaterThan, node);
|
| + FlagsContinuation cont =
|
| + FlagsContinuation::ForSet(kUnsignedGreaterThan, node);
|
| VisitFloat32Compare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
|
| - FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
|
| + FlagsContinuation cont =
|
| + FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node);
|
| VisitFloat32Compare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitFloat64Equal(Node* node) {
|
| - FlagsContinuation cont(kUnorderedEqual, node);
|
| + FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node);
|
| VisitFloat64Compare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitFloat64LessThan(Node* node) {
|
| - FlagsContinuation cont(kUnsignedGreaterThan, node);
|
| + FlagsContinuation cont =
|
| + FlagsContinuation::ForSet(kUnsignedGreaterThan, node);
|
| VisitFloat64Compare(this, node, &cont);
|
| }
|
|
|
|
|
| void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
|
| - FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
|
| + FlagsContinuation cont =
|
| + FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node);
|
| VisitFloat64Compare(this, node, &cont);
|
| }
|
|
|
|
|