| 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/compiler/generic-node-inl.h" | 5 #include "src/compiler/generic-node-inl.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 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 g.UseImmediate(right)); | 398 g.UseImmediate(right)); |
| 399 } else { | 399 } else { |
| 400 if (g.CanBeBetterLeftOperand(right)) { | 400 if (g.CanBeBetterLeftOperand(right)) { |
| 401 std::swap(left, right); | 401 std::swap(left, right); |
| 402 } | 402 } |
| 403 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | 403 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), |
| 404 g.Use(right)); | 404 g.Use(right)); |
| 405 } | 405 } |
| 406 } | 406 } |
| 407 | 407 |
| 408 |
| 409 void VisitMulHigh(InstructionSelector* selector, Node* node, |
| 410 ArchOpcode opcode) { |
| 411 X64OperandGenerator g(selector); |
| 412 Node* left = node->InputAt(0); |
| 413 Node* right = node->InputAt(1); |
| 414 if (selector->IsLive(left) && !selector->IsLive(right)) { |
| 415 std::swap(left, right); |
| 416 } |
| 417 selector->Emit(opcode, g.DefineAsFixed(node, rdx), g.UseFixed(left, rax), |
| 418 g.UseUnique(right)); |
| 419 } |
| 420 |
| 421 |
| 422 void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { |
| 423 X64OperandGenerator g(selector); |
| 424 InstructionOperand* temps[] = {g.TempRegister(rdx)}; |
| 425 selector->Emit( |
| 426 opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax), |
| 427 g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); |
| 428 } |
| 429 |
| 430 |
| 431 void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { |
| 432 X64OperandGenerator g(selector); |
| 433 selector->Emit(opcode, g.DefineAsFixed(node, rdx), |
| 434 g.UseFixed(node->InputAt(0), rax), |
| 435 g.UseUniqueRegister(node->InputAt(1))); |
| 436 } |
| 437 |
| 408 } // namespace | 438 } // namespace |
| 409 | 439 |
| 410 | 440 |
| 411 void InstructionSelector::VisitInt32Mul(Node* node) { | 441 void InstructionSelector::VisitInt32Mul(Node* node) { |
| 412 VisitMul(this, node, kX64Imul32); | 442 VisitMul(this, node, kX64Imul32); |
| 413 } | 443 } |
| 414 | 444 |
| 415 | 445 |
| 416 void InstructionSelector::VisitInt64Mul(Node* node) { | 446 void InstructionSelector::VisitInt64Mul(Node* node) { |
| 417 VisitMul(this, node, kX64Imul); | 447 VisitMul(this, node, kX64Imul); |
| 418 } | 448 } |
| 419 | 449 |
| 420 | 450 |
| 421 void InstructionSelector::VisitInt32MulHigh(Node* node) { | 451 void InstructionSelector::VisitInt32MulHigh(Node* node) { |
| 422 X64OperandGenerator g(this); | 452 VisitMulHigh(this, node, kX64ImulHigh32); |
| 423 Emit(kX64ImulHigh32, g.DefineAsFixed(node, rdx), | |
| 424 g.UseFixed(node->InputAt(0), rax), | |
| 425 g.UseUniqueRegister(node->InputAt(1))); | |
| 426 } | 453 } |
| 427 | 454 |
| 428 | 455 |
| 429 static void VisitDiv(InstructionSelector* selector, Node* node, | |
| 430 ArchOpcode opcode) { | |
| 431 X64OperandGenerator g(selector); | |
| 432 InstructionOperand* temps[] = {g.TempRegister(rdx)}; | |
| 433 selector->Emit( | |
| 434 opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax), | |
| 435 g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); | |
| 436 } | |
| 437 | |
| 438 | |
| 439 void InstructionSelector::VisitInt32Div(Node* node) { | 456 void InstructionSelector::VisitInt32Div(Node* node) { |
| 440 VisitDiv(this, node, kX64Idiv32); | 457 VisitDiv(this, node, kX64Idiv32); |
| 441 } | 458 } |
| 442 | 459 |
| 443 | 460 |
| 444 void InstructionSelector::VisitInt64Div(Node* node) { | 461 void InstructionSelector::VisitInt64Div(Node* node) { |
| 445 VisitDiv(this, node, kX64Idiv); | 462 VisitDiv(this, node, kX64Idiv); |
| 446 } | 463 } |
| 447 | 464 |
| 448 | 465 |
| 449 void InstructionSelector::VisitUint32Div(Node* node) { | 466 void InstructionSelector::VisitUint32Div(Node* node) { |
| 450 VisitDiv(this, node, kX64Udiv32); | 467 VisitDiv(this, node, kX64Udiv32); |
| 451 } | 468 } |
| 452 | 469 |
| 453 | 470 |
| 454 void InstructionSelector::VisitUint64Div(Node* node) { | 471 void InstructionSelector::VisitUint64Div(Node* node) { |
| 455 VisitDiv(this, node, kX64Udiv); | 472 VisitDiv(this, node, kX64Udiv); |
| 456 } | 473 } |
| 457 | 474 |
| 458 | 475 |
| 459 static void VisitMod(InstructionSelector* selector, Node* node, | |
| 460 ArchOpcode opcode) { | |
| 461 X64OperandGenerator g(selector); | |
| 462 selector->Emit(opcode, g.DefineAsFixed(node, rdx), | |
| 463 g.UseFixed(node->InputAt(0), rax), | |
| 464 g.UseUniqueRegister(node->InputAt(1))); | |
| 465 } | |
| 466 | |
| 467 | |
| 468 void InstructionSelector::VisitInt32Mod(Node* node) { | 476 void InstructionSelector::VisitInt32Mod(Node* node) { |
| 469 VisitMod(this, node, kX64Idiv32); | 477 VisitMod(this, node, kX64Idiv32); |
| 470 } | 478 } |
| 471 | 479 |
| 472 | 480 |
| 473 void InstructionSelector::VisitInt64Mod(Node* node) { | 481 void InstructionSelector::VisitInt64Mod(Node* node) { |
| 474 VisitMod(this, node, kX64Idiv); | 482 VisitMod(this, node, kX64Idiv); |
| 475 } | 483 } |
| 476 | 484 |
| 477 | 485 |
| 478 void InstructionSelector::VisitUint32Mod(Node* node) { | 486 void InstructionSelector::VisitUint32Mod(Node* node) { |
| 479 VisitMod(this, node, kX64Udiv32); | 487 VisitMod(this, node, kX64Udiv32); |
| 480 } | 488 } |
| 481 | 489 |
| 482 | 490 |
| 483 void InstructionSelector::VisitUint64Mod(Node* node) { | 491 void InstructionSelector::VisitUint64Mod(Node* node) { |
| 484 VisitMod(this, node, kX64Udiv); | 492 VisitMod(this, node, kX64Udiv); |
| 485 } | 493 } |
| 486 | 494 |
| 487 | 495 |
| 496 void InstructionSelector::VisitUint32MulHigh(Node* node) { |
| 497 VisitMulHigh(this, node, kX64UmulHigh32); |
| 498 } |
| 499 |
| 500 |
| 488 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { | 501 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
| 489 X64OperandGenerator g(this); | 502 X64OperandGenerator g(this); |
| 490 Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | 503 Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 491 } | 504 } |
| 492 | 505 |
| 493 | 506 |
| 494 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { | 507 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
| 495 X64OperandGenerator g(this); | 508 X64OperandGenerator g(this); |
| 496 Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); | 509 Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0))); |
| 497 } | 510 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 case IrOpcode::kInt32Sub: | 550 case IrOpcode::kInt32Sub: |
| 538 case IrOpcode::kInt32Mul: | 551 case IrOpcode::kInt32Mul: |
| 539 case IrOpcode::kInt32MulHigh: | 552 case IrOpcode::kInt32MulHigh: |
| 540 case IrOpcode::kInt32Div: | 553 case IrOpcode::kInt32Div: |
| 541 case IrOpcode::kInt32LessThan: | 554 case IrOpcode::kInt32LessThan: |
| 542 case IrOpcode::kInt32LessThanOrEqual: | 555 case IrOpcode::kInt32LessThanOrEqual: |
| 543 case IrOpcode::kInt32Mod: | 556 case IrOpcode::kInt32Mod: |
| 544 case IrOpcode::kUint32Div: | 557 case IrOpcode::kUint32Div: |
| 545 case IrOpcode::kUint32LessThan: | 558 case IrOpcode::kUint32LessThan: |
| 546 case IrOpcode::kUint32LessThanOrEqual: | 559 case IrOpcode::kUint32LessThanOrEqual: |
| 547 case IrOpcode::kUint32Mod: { | 560 case IrOpcode::kUint32Mod: |
| 561 case IrOpcode::kUint32MulHigh: { |
| 548 // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the | 562 // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the |
| 549 // zero-extension is a no-op. | 563 // zero-extension is a no-op. |
| 550 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | 564 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); |
| 551 return; | 565 return; |
| 552 } | 566 } |
| 553 default: | 567 default: |
| 554 break; | 568 break; |
| 555 } | 569 } |
| 556 Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); | 570 Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); |
| 557 } | 571 } |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1056 if (CpuFeatures::IsSupported(SSE4_1)) { | 1070 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 1057 return MachineOperatorBuilder::kFloat64Floor | | 1071 return MachineOperatorBuilder::kFloat64Floor | |
| 1058 MachineOperatorBuilder::kFloat64Ceil | | 1072 MachineOperatorBuilder::kFloat64Ceil | |
| 1059 MachineOperatorBuilder::kFloat64RoundTruncate; | 1073 MachineOperatorBuilder::kFloat64RoundTruncate; |
| 1060 } | 1074 } |
| 1061 return MachineOperatorBuilder::kNoFlags; | 1075 return MachineOperatorBuilder::kNoFlags; |
| 1062 } | 1076 } |
| 1063 } // namespace compiler | 1077 } // namespace compiler |
| 1064 } // namespace internal | 1078 } // namespace internal |
| 1065 } // namespace v8 | 1079 } // namespace v8 |
| OLD | NEW |