| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
| 6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
| 8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 } | 474 } |
| 475 | 475 |
| 476 DCHECK_NE(0u, input_count); | 476 DCHECK_NE(0u, input_count); |
| 477 DCHECK_NE(0u, output_count); | 477 DCHECK_NE(0u, output_count); |
| 478 DCHECK_GE(arraysize(inputs), input_count); | 478 DCHECK_GE(arraysize(inputs), input_count); |
| 479 DCHECK_GE(arraysize(outputs), output_count); | 479 DCHECK_GE(arraysize(outputs), output_count); |
| 480 | 480 |
| 481 opcode = cont->Encode(opcode); | 481 opcode = cont->Encode(opcode); |
| 482 if (cont->IsDeoptimize()) { | 482 if (cont->IsDeoptimize()) { |
| 483 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, | 483 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
| 484 cont->kind(), cont->reason(), cont->frame_state()); | 484 cont->reason(), cont->frame_state()); |
| 485 } else { | 485 } else { |
| 486 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 486 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 487 } | 487 } |
| 488 } | 488 } |
| 489 | 489 |
| 490 | 490 |
| 491 // Shared routine for multiple binary operations. | 491 // Shared routine for multiple binary operations. |
| 492 void VisitBinop(InstructionSelector* selector, Node* node, | 492 void VisitBinop(InstructionSelector* selector, Node* node, |
| 493 InstructionCode opcode) { | 493 InstructionCode opcode) { |
| 494 FlagsContinuation cont; | 494 FlagsContinuation cont; |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 opcode |= AddressingModeField::encode(addressing_mode); | 1216 opcode |= AddressingModeField::encode(addressing_mode); |
| 1217 opcode = cont->Encode(opcode); | 1217 opcode = cont->Encode(opcode); |
| 1218 inputs[input_count++] = right; | 1218 inputs[input_count++] = right; |
| 1219 | 1219 |
| 1220 if (cont->IsBranch()) { | 1220 if (cont->IsBranch()) { |
| 1221 inputs[input_count++] = g.Label(cont->true_block()); | 1221 inputs[input_count++] = g.Label(cont->true_block()); |
| 1222 inputs[input_count++] = g.Label(cont->false_block()); | 1222 inputs[input_count++] = g.Label(cont->false_block()); |
| 1223 selector->Emit(opcode, 0, nullptr, input_count, inputs); | 1223 selector->Emit(opcode, 0, nullptr, input_count, inputs); |
| 1224 } else if (cont->IsDeoptimize()) { | 1224 } else if (cont->IsDeoptimize()) { |
| 1225 selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, | 1225 selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, |
| 1226 cont->kind(), cont->reason(), cont->frame_state()); | 1226 cont->reason(), cont->frame_state()); |
| 1227 } else if (cont->IsSet()) { | 1227 } else if (cont->IsSet()) { |
| 1228 InstructionOperand output = g.DefineAsRegister(cont->result()); | 1228 InstructionOperand output = g.DefineAsRegister(cont->result()); |
| 1229 selector->Emit(opcode, 1, &output, input_count, inputs); | 1229 selector->Emit(opcode, 1, &output, input_count, inputs); |
| 1230 } else { | 1230 } else { |
| 1231 DCHECK(cont->IsTrap()); | 1231 DCHECK(cont->IsTrap()); |
| 1232 inputs[input_count++] = g.UseImmediate(cont->trap_id()); | 1232 inputs[input_count++] = g.UseImmediate(cont->trap_id()); |
| 1233 selector->Emit(opcode, 0, nullptr, input_count, inputs); | 1233 selector->Emit(opcode, 0, nullptr, input_count, inputs); |
| 1234 } | 1234 } |
| 1235 } | 1235 } |
| 1236 | 1236 |
| 1237 // Shared routine for multiple compare operations. | 1237 // Shared routine for multiple compare operations. |
| 1238 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1238 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1239 InstructionOperand left, InstructionOperand right, | 1239 InstructionOperand left, InstructionOperand right, |
| 1240 FlagsContinuation* cont) { | 1240 FlagsContinuation* cont) { |
| 1241 X87OperandGenerator g(selector); | 1241 X87OperandGenerator g(selector); |
| 1242 opcode = cont->Encode(opcode); | 1242 opcode = cont->Encode(opcode); |
| 1243 if (cont->IsBranch()) { | 1243 if (cont->IsBranch()) { |
| 1244 selector->Emit(opcode, g.NoOutput(), left, right, | 1244 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1245 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1245 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1246 } else if (cont->IsDeoptimize()) { | 1246 } else if (cont->IsDeoptimize()) { |
| 1247 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), | 1247 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), |
| 1248 cont->reason(), cont->frame_state()); | 1248 cont->frame_state()); |
| 1249 } else if (cont->IsSet()) { | 1249 } else if (cont->IsSet()) { |
| 1250 selector->Emit(opcode, g.DefineAsByteRegister(cont->result()), left, right); | 1250 selector->Emit(opcode, g.DefineAsByteRegister(cont->result()), left, right); |
| 1251 } else { | 1251 } else { |
| 1252 DCHECK(cont->IsTrap()); | 1252 DCHECK(cont->IsTrap()); |
| 1253 selector->Emit(opcode, g.NoOutput(), left, right, | 1253 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1254 g.UseImmediate(cont->trap_id())); | 1254 g.UseImmediate(cont->trap_id())); |
| 1255 } | 1255 } |
| 1256 } | 1256 } |
| 1257 | 1257 |
| 1258 | 1258 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 FlagsContinuation* cont) { | 1353 FlagsContinuation* cont) { |
| 1354 X87OperandGenerator g(selector); | 1354 X87OperandGenerator g(selector); |
| 1355 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); | 1355 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0))); |
| 1356 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); | 1356 selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1))); |
| 1357 if (cont->IsBranch()) { | 1357 if (cont->IsBranch()) { |
| 1358 selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), | 1358 selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
| 1359 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1359 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1360 } else if (cont->IsDeoptimize()) { | 1360 } else if (cont->IsDeoptimize()) { |
| 1361 selector->EmitDeoptimize(cont->Encode(kX87Float32Cmp), g.NoOutput(), | 1361 selector->EmitDeoptimize(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
| 1362 g.Use(node->InputAt(0)), g.Use(node->InputAt(1)), | 1362 g.Use(node->InputAt(0)), g.Use(node->InputAt(1)), |
| 1363 cont->kind(), cont->reason(), cont->frame_state()); | 1363 cont->reason(), cont->frame_state()); |
| 1364 } else if (cont->IsSet()) { | 1364 } else if (cont->IsSet()) { |
| 1365 selector->Emit(cont->Encode(kX87Float32Cmp), | 1365 selector->Emit(cont->Encode(kX87Float32Cmp), |
| 1366 g.DefineAsByteRegister(cont->result())); | 1366 g.DefineAsByteRegister(cont->result())); |
| 1367 } else { | 1367 } else { |
| 1368 DCHECK(cont->IsTrap()); | 1368 DCHECK(cont->IsTrap()); |
| 1369 selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), | 1369 selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
| 1370 g.UseImmediate(cont->trap_id())); | 1370 g.UseImmediate(cont->trap_id())); |
| 1371 } | 1371 } |
| 1372 } | 1372 } |
| 1373 | 1373 |
| 1374 | 1374 |
| 1375 // Shared routine for multiple float64 compare operations (inputs commuted). | 1375 // Shared routine for multiple float64 compare operations (inputs commuted). |
| 1376 void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1376 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
| 1377 FlagsContinuation* cont) { | 1377 FlagsContinuation* cont) { |
| 1378 X87OperandGenerator g(selector); | 1378 X87OperandGenerator g(selector); |
| 1379 selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); | 1379 selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0))); |
| 1380 selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); | 1380 selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1))); |
| 1381 if (cont->IsBranch()) { | 1381 if (cont->IsBranch()) { |
| 1382 selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(), | 1382 selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(), |
| 1383 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1383 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1384 } else if (cont->IsDeoptimize()) { | 1384 } else if (cont->IsDeoptimize()) { |
| 1385 selector->EmitDeoptimize(cont->Encode(kX87Float64Cmp), g.NoOutput(), | 1385 selector->EmitDeoptimize(cont->Encode(kX87Float64Cmp), g.NoOutput(), |
| 1386 g.Use(node->InputAt(0)), g.Use(node->InputAt(1)), | 1386 g.Use(node->InputAt(0)), g.Use(node->InputAt(1)), |
| 1387 cont->kind(), cont->reason(), cont->frame_state()); | 1387 cont->reason(), cont->frame_state()); |
| 1388 } else if (cont->IsSet()) { | 1388 } else if (cont->IsSet()) { |
| 1389 selector->Emit(cont->Encode(kX87Float64Cmp), | 1389 selector->Emit(cont->Encode(kX87Float64Cmp), |
| 1390 g.DefineAsByteRegister(cont->result())); | 1390 g.DefineAsByteRegister(cont->result())); |
| 1391 } else { | 1391 } else { |
| 1392 DCHECK(cont->IsTrap()); | 1392 DCHECK(cont->IsTrap()); |
| 1393 selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(), | 1393 selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(), |
| 1394 g.UseImmediate(cont->trap_id())); | 1394 g.UseImmediate(cont->trap_id())); |
| 1395 } | 1395 } |
| 1396 } | 1396 } |
| 1397 | 1397 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1458 ExternalReference js_stack_limit = | 1458 ExternalReference js_stack_limit = |
| 1459 ExternalReference::address_of_stack_limit(selector->isolate()); | 1459 ExternalReference::address_of_stack_limit(selector->isolate()); |
| 1460 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { | 1460 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { |
| 1461 // Compare(Load(js_stack_limit), LoadStackPointer) | 1461 // Compare(Load(js_stack_limit), LoadStackPointer) |
| 1462 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 1462 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); |
| 1463 InstructionCode opcode = cont->Encode(kX87StackCheck); | 1463 InstructionCode opcode = cont->Encode(kX87StackCheck); |
| 1464 if (cont->IsBranch()) { | 1464 if (cont->IsBranch()) { |
| 1465 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), | 1465 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), |
| 1466 g.Label(cont->false_block())); | 1466 g.Label(cont->false_block())); |
| 1467 } else if (cont->IsDeoptimize()) { | 1467 } else if (cont->IsDeoptimize()) { |
| 1468 selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->kind(), | 1468 selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->reason(), |
| 1469 cont->reason(), cont->frame_state()); | 1469 cont->frame_state()); |
| 1470 } else { | 1470 } else { |
| 1471 DCHECK(cont->IsSet()); | 1471 DCHECK(cont->IsSet()); |
| 1472 selector->Emit(opcode, g.DefineAsRegister(cont->result())); | 1472 selector->Emit(opcode, g.DefineAsRegister(cont->result())); |
| 1473 } | 1473 } |
| 1474 return; | 1474 return; |
| 1475 } | 1475 } |
| 1476 } | 1476 } |
| 1477 VisitWordCompare(selector, node, kX87Cmp, cont); | 1477 VisitWordCompare(selector, node, kX87Cmp, cont); |
| 1478 } | 1478 } |
| 1479 | 1479 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1572 } // namespace | 1572 } // namespace |
| 1573 | 1573 |
| 1574 | 1574 |
| 1575 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1575 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
| 1576 BasicBlock* fbranch) { | 1576 BasicBlock* fbranch) { |
| 1577 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 1577 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
| 1578 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); | 1578 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); |
| 1579 } | 1579 } |
| 1580 | 1580 |
| 1581 void InstructionSelector::VisitDeoptimizeIf(Node* node) { | 1581 void InstructionSelector::VisitDeoptimizeIf(Node* node) { |
| 1582 DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); | |
| 1583 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 1582 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
| 1584 kNotEqual, p.kind(), p.reason(), node->InputAt(1)); | 1583 kNotEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
| 1585 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 1584 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 1586 } | 1585 } |
| 1587 | 1586 |
| 1588 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { | 1587 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { |
| 1589 DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); | |
| 1590 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 1588 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
| 1591 kEqual, p.kind(), p.reason(), node->InputAt(1)); | 1589 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
| 1592 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 1590 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 1593 } | 1591 } |
| 1594 | 1592 |
| 1595 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { | 1593 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { |
| 1596 FlagsContinuation cont = | 1594 FlagsContinuation cont = |
| 1597 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); | 1595 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); |
| 1598 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 1596 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
| 1599 } | 1597 } |
| 1600 | 1598 |
| 1601 void InstructionSelector::VisitTrapUnless(Node* node, | 1599 void InstructionSelector::VisitTrapUnless(Node* node, |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1844 // static | 1842 // static |
| 1845 MachineOperatorBuilder::AlignmentRequirements | 1843 MachineOperatorBuilder::AlignmentRequirements |
| 1846 InstructionSelector::AlignmentRequirements() { | 1844 InstructionSelector::AlignmentRequirements() { |
| 1847 return MachineOperatorBuilder::AlignmentRequirements:: | 1845 return MachineOperatorBuilder::AlignmentRequirements:: |
| 1848 FullUnalignedAccessSupport(); | 1846 FullUnalignedAccessSupport(); |
| 1849 } | 1847 } |
| 1850 | 1848 |
| 1851 } // namespace compiler | 1849 } // namespace compiler |
| 1852 } // namespace internal | 1850 } // namespace internal |
| 1853 } // namespace v8 | 1851 } // namespace v8 |
| OLD | NEW |