| 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 #ifndef V8_COMPILER_INSTRUCTION_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
| 6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
| 7 | 7 |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <iosfwd> | 9 #include <iosfwd> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 value_ = KindField::encode(kind); | 65 value_ = KindField::encode(kind); |
| 66 value_ |= bit_cast<unsigned>(index << KindField::kSize); | 66 value_ |= bit_cast<unsigned>(index << KindField::kSize); |
| 67 DCHECK(this->index() == index); | 67 DCHECK(this->index() == index); |
| 68 } | 68 } |
| 69 | 69 |
| 70 // Calls SetUpCache()/TearDownCache() for each subclass. | 70 // Calls SetUpCache()/TearDownCache() for each subclass. |
| 71 static void SetUpCaches(); | 71 static void SetUpCaches(); |
| 72 static void TearDownCaches(); | 72 static void TearDownCaches(); |
| 73 | 73 |
| 74 protected: | 74 protected: |
| 75 // TODO(dcarney): remove. used to construct the Instruction operand array. |
| 76 InstructionOperand() : value_(0xffffffff) {} |
| 75 typedef BitField<Kind, 0, 3> KindField; | 77 typedef BitField<Kind, 0, 3> KindField; |
| 76 | 78 |
| 77 uint32_t value_; | 79 uint32_t value_; |
| 78 }; | 80 }; |
| 79 | 81 |
| 80 typedef ZoneVector<InstructionOperand*> InstructionOperandVector; | 82 typedef ZoneVector<InstructionOperand*> InstructionOperandVector; |
| 81 | 83 |
| 82 struct PrintableInstructionOperand { | 84 struct PrintableInstructionOperand { |
| 83 const RegisterConfiguration* register_configuration_; | 85 const RegisterConfiguration* register_configuration_; |
| 84 const InstructionOperand* op_; | 86 const InstructionOperand* op_; |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 int32_t virtual_register() const { return virtual_register_; } | 258 int32_t virtual_register() const { return virtual_register_; } |
| 257 void set_virtual_register(int32_t id) { virtual_register_ = id; } | 259 void set_virtual_register(int32_t id) { virtual_register_ = id; } |
| 258 | 260 |
| 259 // [lifetime]: Only for non-FIXED_SLOT. | 261 // [lifetime]: Only for non-FIXED_SLOT. |
| 260 bool IsUsedAtStart() const { | 262 bool IsUsedAtStart() const { |
| 261 DCHECK(basic_policy() == EXTENDED_POLICY); | 263 DCHECK(basic_policy() == EXTENDED_POLICY); |
| 262 return LifetimeField::decode(value_) == USED_AT_START; | 264 return LifetimeField::decode(value_) == USED_AT_START; |
| 263 } | 265 } |
| 264 | 266 |
| 265 private: | 267 private: |
| 268 friend class Instruction; |
| 269 UnallocatedOperand() |
| 270 : InstructionOperand(), virtual_register_(kInvalidVirtualRegister) {} |
| 271 |
| 266 // TODO(dcarney): this should really be unsigned. | 272 // TODO(dcarney): this should really be unsigned. |
| 267 int32_t virtual_register_; | 273 int32_t virtual_register_; |
| 268 }; | 274 }; |
| 269 | 275 |
| 270 | 276 |
| 271 class MoveOperands FINAL { | 277 class MoveOperands FINAL { |
| 272 public: | 278 public: |
| 273 MoveOperands(InstructionOperand* source, InstructionOperand* destination) | 279 MoveOperands(InstructionOperand* source, InstructionOperand* destination) |
| 274 : source_(source), destination_(destination) {} | 280 : source_(source), destination_(destination) {} |
| 275 | 281 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 ZoneList<InstructionOperand*> untagged_operands_; | 421 ZoneList<InstructionOperand*> untagged_operands_; |
| 416 int instruction_position_; | 422 int instruction_position_; |
| 417 }; | 423 }; |
| 418 | 424 |
| 419 std::ostream& operator<<(std::ostream& os, const PointerMap& pm); | 425 std::ostream& operator<<(std::ostream& os, const PointerMap& pm); |
| 420 | 426 |
| 421 // TODO(titzer): s/PointerMap/ReferenceMap/ | 427 // TODO(titzer): s/PointerMap/ReferenceMap/ |
| 422 class Instruction : public ZoneObject { | 428 class Instruction : public ZoneObject { |
| 423 public: | 429 public: |
| 424 size_t OutputCount() const { return OutputCountField::decode(bit_field_); } | 430 size_t OutputCount() const { return OutputCountField::decode(bit_field_); } |
| 425 InstructionOperand* OutputAt(size_t i) const { | 431 const InstructionOperand* OutputAt(size_t i) const { |
| 426 DCHECK(i < OutputCount()); | 432 DCHECK(i < OutputCount()); |
| 427 return operands_[i]; | 433 return &operands_[i]; |
| 434 } |
| 435 InstructionOperand* OutputAt(size_t i) { |
| 436 DCHECK(i < OutputCount()); |
| 437 return &operands_[i]; |
| 428 } | 438 } |
| 429 | 439 |
| 430 bool HasOutput() const { return OutputCount() == 1; } | 440 bool HasOutput() const { return OutputCount() == 1; } |
| 431 InstructionOperand* Output() const { return OutputAt(0); } | 441 const InstructionOperand* Output() const { return OutputAt(0); } |
| 442 InstructionOperand* Output() { return OutputAt(0); } |
| 432 | 443 |
| 433 size_t InputCount() const { return InputCountField::decode(bit_field_); } | 444 size_t InputCount() const { return InputCountField::decode(bit_field_); } |
| 434 InstructionOperand* InputAt(size_t i) const { | 445 const InstructionOperand* InputAt(size_t i) const { |
| 435 DCHECK(i < InputCount()); | 446 DCHECK(i < InputCount()); |
| 436 return operands_[OutputCount() + i]; | 447 return &operands_[OutputCount() + i]; |
| 437 } | 448 } |
| 438 void SetInputAt(size_t i, InstructionOperand* operand) { | 449 InstructionOperand* InputAt(size_t i) { |
| 439 DCHECK(i < InputCount()); | 450 DCHECK(i < InputCount()); |
| 440 operands_[OutputCount() + i] = operand; | 451 return &operands_[OutputCount() + i]; |
| 441 } | 452 } |
| 442 | 453 |
| 443 size_t TempCount() const { return TempCountField::decode(bit_field_); } | 454 size_t TempCount() const { return TempCountField::decode(bit_field_); } |
| 444 InstructionOperand* TempAt(size_t i) const { | 455 const InstructionOperand* TempAt(size_t i) const { |
| 445 DCHECK(i < TempCount()); | 456 DCHECK(i < TempCount()); |
| 446 return operands_[OutputCount() + InputCount() + i]; | 457 return &operands_[OutputCount() + InputCount() + i]; |
| 458 } |
| 459 InstructionOperand* TempAt(size_t i) { |
| 460 DCHECK(i < TempCount()); |
| 461 return &operands_[OutputCount() + InputCount() + i]; |
| 447 } | 462 } |
| 448 | 463 |
| 449 InstructionCode opcode() const { return opcode_; } | 464 InstructionCode opcode() const { return opcode_; } |
| 450 ArchOpcode arch_opcode() const { return ArchOpcodeField::decode(opcode()); } | 465 ArchOpcode arch_opcode() const { return ArchOpcodeField::decode(opcode()); } |
| 451 AddressingMode addressing_mode() const { | 466 AddressingMode addressing_mode() const { |
| 452 return AddressingModeField::decode(opcode()); | 467 return AddressingModeField::decode(opcode()); |
| 453 } | 468 } |
| 454 FlagsMode flags_mode() const { return FlagsModeField::decode(opcode()); } | 469 FlagsMode flags_mode() const { return FlagsModeField::decode(opcode()); } |
| 455 FlagsCondition flags_condition() const { | 470 FlagsCondition flags_condition() const { |
| 456 return FlagsConditionField::decode(opcode()); | 471 return FlagsConditionField::decode(opcode()); |
| 457 } | 472 } |
| 458 | 473 |
| 459 // TODO(titzer): make control and call into flags. | 474 // TODO(titzer): make control and call into flags. |
| 460 static Instruction* New(Zone* zone, InstructionCode opcode) { | 475 static Instruction* New(Zone* zone, InstructionCode opcode) { |
| 461 return New(zone, opcode, 0, NULL, 0, NULL, 0, NULL); | 476 return New(zone, opcode, 0, NULL, 0, NULL, 0, NULL); |
| 462 } | 477 } |
| 463 | 478 |
| 464 static Instruction* New(Zone* zone, InstructionCode opcode, | 479 static Instruction* New(Zone* zone, InstructionCode opcode, |
| 465 size_t output_count, InstructionOperand** outputs, | 480 size_t output_count, InstructionOperand** outputs, |
| 466 size_t input_count, InstructionOperand** inputs, | 481 size_t input_count, InstructionOperand** inputs, |
| 467 size_t temp_count, InstructionOperand** temps) { | 482 size_t temp_count, InstructionOperand** temps) { |
| 468 DCHECK(opcode >= 0); | 483 DCHECK(opcode >= 0); |
| 469 DCHECK(output_count == 0 || outputs != NULL); | 484 DCHECK(output_count == 0 || outputs != NULL); |
| 470 DCHECK(input_count == 0 || inputs != NULL); | 485 DCHECK(input_count == 0 || inputs != NULL); |
| 471 DCHECK(temp_count == 0 || temps != NULL); | 486 DCHECK(temp_count == 0 || temps != NULL); |
| 472 InstructionOperand* none = NULL; | 487 size_t total_extra_ops = output_count + input_count + temp_count; |
| 473 USE(none); | 488 if (total_extra_ops != 0) total_extra_ops--; |
| 474 int size = static_cast<int>(RoundUp(sizeof(Instruction), kPointerSize) + | 489 int size = static_cast<int>( |
| 475 (output_count + input_count + temp_count - 1) * | 490 RoundUp(sizeof(Instruction), sizeof(UnallocatedOperand)) + |
| 476 sizeof(none)); | 491 total_extra_ops * sizeof(UnallocatedOperand)); |
| 477 return new (zone->New(size)) Instruction( | 492 return new (zone->New(size)) Instruction( |
| 478 opcode, output_count, outputs, input_count, inputs, temp_count, temps); | 493 opcode, output_count, outputs, input_count, inputs, temp_count, temps); |
| 479 } | 494 } |
| 480 | 495 |
| 481 // TODO(titzer): another holdover from lithium days; register allocator | 496 // TODO(titzer): another holdover from lithium days; register allocator |
| 482 // should not need to know about control instructions. | 497 // should not need to know about control instructions. |
| 483 Instruction* MarkAsControl() { | 498 Instruction* MarkAsControl() { |
| 484 bit_field_ = IsControlField::update(bit_field_, true); | 499 bit_field_ = IsControlField::update(bit_field_, true); |
| 485 return this; | 500 return this; |
| 486 } | 501 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 bit_field_ = 0; | 535 bit_field_ = 0; |
| 521 pointer_map_ = NULL; | 536 pointer_map_ = NULL; |
| 522 } | 537 } |
| 523 | 538 |
| 524 bool IsNop() const { | 539 bool IsNop() const { |
| 525 return arch_opcode() == kArchNop && InputCount() == 0 && | 540 return arch_opcode() == kArchNop && InputCount() == 0 && |
| 526 OutputCount() == 0 && TempCount() == 0; | 541 OutputCount() == 0 && TempCount() == 0; |
| 527 } | 542 } |
| 528 | 543 |
| 529 protected: | 544 protected: |
| 530 explicit Instruction(InstructionCode opcode) | 545 explicit Instruction(InstructionCode opcode); |
| 531 : opcode_(opcode), | |
| 532 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | | |
| 533 TempCountField::encode(0) | IsCallField::encode(false) | | |
| 534 IsControlField::encode(false)), | |
| 535 pointer_map_(NULL) {} | |
| 536 | |
| 537 Instruction(InstructionCode opcode, size_t output_count, | 546 Instruction(InstructionCode opcode, size_t output_count, |
| 538 InstructionOperand** outputs, size_t input_count, | 547 InstructionOperand** outputs, size_t input_count, |
| 539 InstructionOperand** inputs, size_t temp_count, | 548 InstructionOperand** inputs, size_t temp_count, |
| 540 InstructionOperand** temps) | 549 InstructionOperand** temps); |
| 541 : opcode_(opcode), | |
| 542 bit_field_(OutputCountField::encode(output_count) | | |
| 543 InputCountField::encode(input_count) | | |
| 544 TempCountField::encode(temp_count) | | |
| 545 IsCallField::encode(false) | IsControlField::encode(false)), | |
| 546 pointer_map_(NULL) { | |
| 547 for (size_t i = 0; i < output_count; ++i) { | |
| 548 operands_[i] = outputs[i]; | |
| 549 } | |
| 550 for (size_t i = 0; i < input_count; ++i) { | |
| 551 operands_[output_count + i] = inputs[i]; | |
| 552 } | |
| 553 for (size_t i = 0; i < temp_count; ++i) { | |
| 554 operands_[output_count + input_count + i] = temps[i]; | |
| 555 } | |
| 556 } | |
| 557 | 550 |
| 558 protected: | 551 protected: |
| 559 typedef BitField<size_t, 0, 8> OutputCountField; | 552 typedef BitField<size_t, 0, 8> OutputCountField; |
| 560 typedef BitField<size_t, 8, 16> InputCountField; | 553 typedef BitField<size_t, 8, 16> InputCountField; |
| 561 typedef BitField<size_t, 24, 6> TempCountField; | 554 typedef BitField<size_t, 24, 6> TempCountField; |
| 562 typedef BitField<bool, 30, 1> IsCallField; | 555 typedef BitField<bool, 30, 1> IsCallField; |
| 563 typedef BitField<bool, 31, 1> IsControlField; | 556 typedef BitField<bool, 31, 1> IsControlField; |
| 564 | 557 |
| 565 InstructionCode opcode_; | 558 InstructionCode opcode_; |
| 566 uint32_t bit_field_; | 559 uint32_t bit_field_; |
| 567 PointerMap* pointer_map_; | 560 PointerMap* pointer_map_; |
| 568 InstructionOperand* operands_[1]; | 561 UnallocatedOperand operands_[1]; |
| 569 }; | 562 }; |
| 570 | 563 |
| 571 | 564 |
| 572 struct PrintableInstruction { | 565 struct PrintableInstruction { |
| 573 const RegisterConfiguration* register_configuration_; | 566 const RegisterConfiguration* register_configuration_; |
| 574 const Instruction* instr_; | 567 const Instruction* instr_; |
| 575 }; | 568 }; |
| 576 std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr); | 569 std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr); |
| 577 | 570 |
| 578 | 571 |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 | 1055 |
| 1063 | 1056 |
| 1064 std::ostream& operator<<(std::ostream& os, | 1057 std::ostream& operator<<(std::ostream& os, |
| 1065 const PrintableInstructionSequence& code); | 1058 const PrintableInstructionSequence& code); |
| 1066 | 1059 |
| 1067 } // namespace compiler | 1060 } // namespace compiler |
| 1068 } // namespace internal | 1061 } // namespace internal |
| 1069 } // namespace v8 | 1062 } // namespace v8 |
| 1070 | 1063 |
| 1071 #endif // V8_COMPILER_INSTRUCTION_H_ | 1064 #endif // V8_COMPILER_INSTRUCTION_H_ |
| OLD | NEW |