| 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 { |
| 11 namespace compiler { | 11 namespace compiler { |
| 12 | 12 |
| 13 // Adds X64-specific methods for generating operands. | 13 // Adds X64-specific methods for generating operands. |
| 14 class X64OperandGenerator FINAL : public OperandGenerator { | 14 class X64OperandGenerator FINAL : public OperandGenerator { |
| 15 public: | 15 public: |
| 16 explicit X64OperandGenerator(InstructionSelector* selector) | 16 explicit X64OperandGenerator(InstructionSelector* selector) |
| 17 : OperandGenerator(selector) {} | 17 : OperandGenerator(selector) {} |
| 18 | 18 |
| 19 InstructionOperand* TempRegister(Register reg) { | 19 InstructionOperand* TempRegister(Register reg) { |
| 20 return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, | 20 return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, |
| 21 Register::ToAllocationIndex(reg)); | 21 Register::ToAllocationIndex(reg)); |
| 22 } | 22 } |
| 23 | 23 |
| 24 InstructionOperand* UseImmediate64(Node* node) { return UseImmediate(node); } | |
| 25 | |
| 26 bool CanBeImmediate(Node* node) { | 24 bool CanBeImmediate(Node* node) { |
| 27 switch (node->opcode()) { | 25 switch (node->opcode()) { |
| 28 case IrOpcode::kInt32Constant: | 26 case IrOpcode::kInt32Constant: |
| 29 return true; | 27 return true; |
| 30 default: | 28 default: |
| 31 return false; | 29 return false; |
| 32 } | 30 } |
| 33 } | 31 } |
| 34 | 32 |
| 35 bool CanBeImmediate64(Node* node) { | |
| 36 switch (node->opcode()) { | |
| 37 case IrOpcode::kInt32Constant: | |
| 38 return true; | |
| 39 case IrOpcode::kNumberConstant: | |
| 40 return true; | |
| 41 case IrOpcode::kHeapConstant: { | |
| 42 // Constants in new space cannot be used as immediates in V8 because | |
| 43 // the GC does not scan code objects when collecting the new generation. | |
| 44 Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node); | |
| 45 return !isolate()->heap()->InNewSpace(*value.handle()); | |
| 46 } | |
| 47 default: | |
| 48 return false; | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 bool CanBeBetterLeftOperand(Node* node) const { | 33 bool CanBeBetterLeftOperand(Node* node) const { |
| 53 return !selector()->IsLive(node); | 34 return !selector()->IsLive(node); |
| 54 } | 35 } |
| 55 }; | 36 }; |
| 56 | 37 |
| 57 | 38 |
| 58 // Get the AddressingMode of scale factor N from the AddressingMode of scale | 39 // Get the AddressingMode of scale factor N from the AddressingMode of scale |
| 59 // factor 1. | 40 // factor 1. |
| 60 static AddressingMode AdjustAddressingMode(AddressingMode base_mode, | 41 static AddressingMode AdjustAddressingMode(AddressingMode base_mode, |
| 61 int power) { | 42 int power) { |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 // Shared routine for multiple 32-bit shift operations. | 326 // Shared routine for multiple 32-bit shift operations. |
| 346 // TODO(bmeurer): Merge this with VisitWord64Shift using template magic? | 327 // TODO(bmeurer): Merge this with VisitWord64Shift using template magic? |
| 347 static void VisitWord32Shift(InstructionSelector* selector, Node* node, | 328 static void VisitWord32Shift(InstructionSelector* selector, Node* node, |
| 348 ArchOpcode opcode) { | 329 ArchOpcode opcode) { |
| 349 X64OperandGenerator g(selector); | 330 X64OperandGenerator g(selector); |
| 350 Node* left = node->InputAt(0); | 331 Node* left = node->InputAt(0); |
| 351 Node* right = node->InputAt(1); | 332 Node* right = node->InputAt(1); |
| 352 | 333 |
| 353 // TODO(turbofan): assembler only supports some addressing modes for shifts. | 334 // TODO(turbofan): assembler only supports some addressing modes for shifts. |
| 354 if (g.CanBeImmediate(right)) { | 335 if (g.CanBeImmediate(right)) { |
| 355 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | 336 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), |
| 356 g.UseImmediate(right)); | 337 g.UseImmediate(right)); |
| 357 } else { | 338 } else { |
| 358 Int32BinopMatcher m(node); | 339 Int32BinopMatcher m(node); |
| 359 if (m.right().IsWord32And()) { | 340 if (m.right().IsWord32And()) { |
| 360 Int32BinopMatcher mright(right); | 341 Int32BinopMatcher mright(right); |
| 361 if (mright.right().Is(0x1F)) { | 342 if (mright.right().Is(0x1F)) { |
| 362 right = mright.left().node(); | 343 right = mright.left().node(); |
| 363 } | 344 } |
| 364 } | 345 } |
| 365 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | 346 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), |
| 366 g.UseFixed(right, rcx)); | 347 g.UseFixed(right, rcx)); |
| 367 } | 348 } |
| 368 } | 349 } |
| 369 | 350 |
| 370 | 351 |
| 371 // Shared routine for multiple 64-bit shift operations. | 352 // Shared routine for multiple 64-bit shift operations. |
| 372 // TODO(bmeurer): Merge this with VisitWord32Shift using template magic? | 353 // TODO(bmeurer): Merge this with VisitWord32Shift using template magic? |
| 373 static void VisitWord64Shift(InstructionSelector* selector, Node* node, | 354 static void VisitWord64Shift(InstructionSelector* selector, Node* node, |
| 374 ArchOpcode opcode) { | 355 ArchOpcode opcode) { |
| 375 X64OperandGenerator g(selector); | 356 X64OperandGenerator g(selector); |
| 376 Node* left = node->InputAt(0); | 357 Node* left = node->InputAt(0); |
| 377 Node* right = node->InputAt(1); | 358 Node* right = node->InputAt(1); |
| 378 | 359 |
| 379 // TODO(turbofan): assembler only supports some addressing modes for shifts. | 360 // TODO(turbofan): assembler only supports some addressing modes for shifts. |
| 380 if (g.CanBeImmediate(right)) { | 361 if (g.CanBeImmediate(right)) { |
| 381 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | 362 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), |
| 382 g.UseImmediate(right)); | 363 g.UseImmediate(right)); |
| 383 } else { | 364 } else { |
| 384 Int64BinopMatcher m(node); | 365 Int64BinopMatcher m(node); |
| 385 if (m.right().IsWord64And()) { | 366 if (m.right().IsWord64And()) { |
| 386 Int64BinopMatcher mright(right); | 367 Int64BinopMatcher mright(right); |
| 387 if (mright.right().Is(0x3F)) { | 368 if (mright.right().Is(0x3F)) { |
| 388 right = mright.left().node(); | 369 right = mright.left().node(); |
| 389 } | 370 } |
| 390 } | 371 } |
| 391 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | 372 selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), |
| 392 g.UseFixed(right, rcx)); | 373 g.UseFixed(right, rcx)); |
| 393 } | 374 } |
| 394 } | 375 } |
| 395 | 376 |
| 396 | 377 |
| 397 void InstructionSelector::VisitWord32Shl(Node* node) { | 378 void InstructionSelector::VisitWord32Shl(Node* node) { |
| 398 VisitWord32Shift(this, node, kX64Shl32); | 379 VisitWord32Shift(this, node, kX64Shl32); |
| 399 } | 380 } |
| 400 | 381 |
| 401 | 382 |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 call_instr->MarkAsCall(); | 854 call_instr->MarkAsCall(); |
| 874 if (deoptimization != NULL) { | 855 if (deoptimization != NULL) { |
| 875 DCHECK(continuation != NULL); | 856 DCHECK(continuation != NULL); |
| 876 call_instr->MarkAsControl(); | 857 call_instr->MarkAsControl(); |
| 877 } | 858 } |
| 878 } | 859 } |
| 879 | 860 |
| 880 } // namespace compiler | 861 } // namespace compiler |
| 881 } // namespace internal | 862 } // namespace internal |
| 882 } // namespace v8 | 863 } // namespace v8 |
| OLD | NEW |