OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 static const int kMantissaOffset = 0; | 102 static const int kMantissaOffset = 0; |
103 static const int kExponentOffset = 4; | 103 static const int kExponentOffset = 4; |
104 #else | 104 #else |
105 static const int kMantissaOffset = 4; | 105 static const int kMantissaOffset = 4; |
106 static const int kExponentOffset = 0; | 106 static const int kExponentOffset = 0; |
107 #endif | 107 #endif |
108 | 108 |
109 static const int kAllocatableLowRangeBegin = 3; | 109 static const int kAllocatableLowRangeBegin = 3; |
110 static const int kAllocatableLowRangeEnd = 10; | 110 static const int kAllocatableLowRangeEnd = 10; |
111 static const int kAllocatableHighRangeBegin = 14; | 111 static const int kAllocatableHighRangeBegin = 14; |
112 #if V8_OOL_CONSTANT_POOL | |
113 static const int kAllocatableHighRangeEnd = 27; | |
114 #else | |
115 static const int kAllocatableHighRangeEnd = 28; | 112 static const int kAllocatableHighRangeEnd = 28; |
116 #endif | |
117 static const int kAllocatableContext = 30; | 113 static const int kAllocatableContext = 30; |
118 | 114 |
119 static const int kNumAllocatableLow = | 115 static const int kNumAllocatableLow = |
120 kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; | 116 kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; |
121 static const int kNumAllocatableHigh = | 117 static const int kNumAllocatableHigh = |
122 kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; | 118 kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; |
123 static const int kMaxNumAllocatableRegisters = | 119 static const int kMaxNumAllocatableRegisters = |
124 kNumAllocatableLow + kNumAllocatableHigh + 1; // cp | 120 kNumAllocatableLow + kNumAllocatableHigh + 1; // cp |
125 | 121 |
126 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } | 122 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 "r18", | 168 "r18", |
173 "r19", | 169 "r19", |
174 "r20", | 170 "r20", |
175 "r21", | 171 "r21", |
176 "r22", | 172 "r22", |
177 "r23", | 173 "r23", |
178 "r24", | 174 "r24", |
179 "r25", | 175 "r25", |
180 "r26", | 176 "r26", |
181 "r27", | 177 "r27", |
182 #if !V8_OOL_CONSTANT_POOL | |
183 "r28", | 178 "r28", |
184 #endif | |
185 "cp", | 179 "cp", |
186 }; | 180 }; |
187 return names[index]; | 181 return names[index]; |
188 } | 182 } |
189 | 183 |
| 184 static const RegList kAllocatable = |
| 185 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 | |
| 186 1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 | |
| 187 1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 | |
| 188 1 << 28 | 1 << 30; |
| 189 |
190 static Register from_code(int code) { | 190 static Register from_code(int code) { |
191 Register r = {code}; | 191 Register r = {code}; |
192 return r; | 192 return r; |
193 } | 193 } |
194 | 194 |
195 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | 195 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
196 bool is(Register reg) const { return code_ == reg.code_; } | 196 bool is(Register reg) const { return code_ == reg.code_; } |
197 int code() const { | 197 int code() const { |
198 DCHECK(is_valid()); | 198 DCHECK(is_valid()); |
199 return code_; | 199 return code_; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 const int kRegister_r18_Code = 18; | 236 const int kRegister_r18_Code = 18; |
237 const int kRegister_r19_Code = 19; | 237 const int kRegister_r19_Code = 19; |
238 const int kRegister_r20_Code = 20; | 238 const int kRegister_r20_Code = 20; |
239 const int kRegister_r21_Code = 21; | 239 const int kRegister_r21_Code = 21; |
240 const int kRegister_r22_Code = 22; | 240 const int kRegister_r22_Code = 22; |
241 const int kRegister_r23_Code = 23; | 241 const int kRegister_r23_Code = 23; |
242 const int kRegister_r24_Code = 24; | 242 const int kRegister_r24_Code = 24; |
243 const int kRegister_r25_Code = 25; | 243 const int kRegister_r25_Code = 25; |
244 const int kRegister_r26_Code = 26; | 244 const int kRegister_r26_Code = 26; |
245 const int kRegister_r27_Code = 27; | 245 const int kRegister_r27_Code = 27; |
246 const int kRegister_r28_Code = 28; // constant pool pointer | 246 const int kRegister_r28_Code = 28; |
247 const int kRegister_r29_Code = 29; // roots array pointer | 247 const int kRegister_r29_Code = 29; // roots array pointer |
248 const int kRegister_r30_Code = 30; // context pointer | 248 const int kRegister_r30_Code = 30; // context pointer |
249 const int kRegister_fp_Code = 31; // frame pointer | 249 const int kRegister_fp_Code = 31; // frame pointer |
250 | 250 |
251 const Register no_reg = {kRegister_no_reg_Code}; | 251 const Register no_reg = {kRegister_no_reg_Code}; |
252 | 252 |
253 const Register r0 = {kRegister_r0_Code}; | 253 const Register r0 = {kRegister_r0_Code}; |
254 const Register sp = {kRegister_sp_Code}; | 254 const Register sp = {kRegister_sp_Code}; |
255 const Register r2 = {kRegister_r2_Code}; | 255 const Register r2 = {kRegister_r2_Code}; |
256 const Register r3 = {kRegister_r3_Code}; | 256 const Register r3 = {kRegister_r3_Code}; |
(...skipping 23 matching lines...) Expand all Loading... |
280 const Register r26 = {kRegister_r26_Code}; | 280 const Register r26 = {kRegister_r26_Code}; |
281 const Register r27 = {kRegister_r27_Code}; | 281 const Register r27 = {kRegister_r27_Code}; |
282 const Register r28 = {kRegister_r28_Code}; | 282 const Register r28 = {kRegister_r28_Code}; |
283 const Register r29 = {kRegister_r29_Code}; | 283 const Register r29 = {kRegister_r29_Code}; |
284 const Register r30 = {kRegister_r30_Code}; | 284 const Register r30 = {kRegister_r30_Code}; |
285 const Register fp = {kRegister_fp_Code}; | 285 const Register fp = {kRegister_fp_Code}; |
286 | 286 |
287 // Give alias names to registers | 287 // Give alias names to registers |
288 const Register cp = {kRegister_r30_Code}; // JavaScript context pointer | 288 const Register cp = {kRegister_r30_Code}; // JavaScript context pointer |
289 const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer. | 289 const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer. |
290 #if V8_OOL_CONSTANT_POOL | |
291 const Register kConstantPoolRegister = {kRegister_r28_Code}; // Constant pool | |
292 #endif | |
293 | 290 |
294 // Double word FP register. | 291 // Double word FP register. |
295 struct DoubleRegister { | 292 struct DoubleRegister { |
296 static const int kNumRegisters = 32; | 293 static const int kNumRegisters = 32; |
297 static const int kMaxNumRegisters = kNumRegisters; | 294 static const int kMaxNumRegisters = kNumRegisters; |
298 static const int kNumVolatileRegisters = 14; // d0-d13 | 295 static const int kNumVolatileRegisters = 14; // d0-d13 |
299 static const int kSizeInBytes = 8; | 296 static const int kSizeInBytes = 8; |
300 | 297 |
301 static const int kAllocatableLowRangeBegin = 1; | 298 static const int kAllocatableLowRangeBegin = 1; |
302 static const int kAllocatableLowRangeEnd = 12; | 299 static const int kAllocatableLowRangeEnd = 12; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 INLINE(explicit Operand(const ExternalReference& f)); | 458 INLINE(explicit Operand(const ExternalReference& f)); |
462 explicit Operand(Handle<Object> handle); | 459 explicit Operand(Handle<Object> handle); |
463 INLINE(explicit Operand(Smi* value)); | 460 INLINE(explicit Operand(Smi* value)); |
464 | 461 |
465 // rm | 462 // rm |
466 INLINE(explicit Operand(Register rm)); | 463 INLINE(explicit Operand(Register rm)); |
467 | 464 |
468 // Return true if this is a register operand. | 465 // Return true if this is a register operand. |
469 INLINE(bool is_reg() const); | 466 INLINE(bool is_reg() const); |
470 | 467 |
471 // For mov. Return the number of actual instructions required to | |
472 // load the operand into a register. This can be anywhere from | |
473 // one (constant pool small section) to five instructions (full | |
474 // 64-bit sequence). | |
475 // | |
476 // The value returned is only valid as long as no entries are added to the | |
477 // constant pool between this call and the actual instruction being emitted. | |
478 bool must_output_reloc_info(const Assembler* assembler) const; | 468 bool must_output_reloc_info(const Assembler* assembler) const; |
479 | 469 |
480 inline intptr_t immediate() const { | 470 inline intptr_t immediate() const { |
481 DCHECK(!rm_.is_valid()); | 471 DCHECK(!rm_.is_valid()); |
482 return imm_; | 472 return imm_; |
483 } | 473 } |
484 | 474 |
485 Register rm() const { return rm_; } | 475 Register rm() const { return rm_; } |
486 | 476 |
487 private: | 477 private: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 | 511 |
522 private: | 512 private: |
523 Register ra_; // base | 513 Register ra_; // base |
524 int32_t offset_; // offset | 514 int32_t offset_; // offset |
525 Register rb_; // index | 515 Register rb_; // index |
526 | 516 |
527 friend class Assembler; | 517 friend class Assembler; |
528 }; | 518 }; |
529 | 519 |
530 | 520 |
531 #if V8_OOL_CONSTANT_POOL | |
532 // Class used to build a constant pool. | |
533 class ConstantPoolBuilder BASE_EMBEDDED { | |
534 public: | |
535 ConstantPoolBuilder(); | |
536 ConstantPoolArray::LayoutSection AddEntry(Assembler* assm, | |
537 const RelocInfo& rinfo); | |
538 void Relocate(intptr_t pc_delta); | |
539 bool IsEmpty(); | |
540 Handle<ConstantPoolArray> New(Isolate* isolate); | |
541 void Populate(Assembler* assm, ConstantPoolArray* constant_pool); | |
542 | |
543 inline ConstantPoolArray::LayoutSection current_section() const { | |
544 return current_section_; | |
545 } | |
546 | |
547 // Rather than increasing the capacity of the ConstantPoolArray's | |
548 // small section to match the longer (16-bit) reach of PPC's load | |
549 // instruction (at the expense of a larger header to describe the | |
550 // layout), the PPC implementation utilizes the extended section to | |
551 // satisfy that reach. I.e. all entries (regardless of their | |
552 // section) are reachable with a single load instruction. | |
553 // | |
554 // This implementation does not support an unlimited constant pool | |
555 // size (which would require a multi-instruction sequence). [See | |
556 // ARM commit e27ab337 for a reference on the changes required to | |
557 // support the longer instruction sequence.] Note, however, that | |
558 // going down that path will necessarily generate that longer | |
559 // sequence for all extended section accesses since the placement of | |
560 // a given entry within the section is not known at the time of | |
561 // code generation. | |
562 // | |
563 // TODO(mbrandy): Determine whether there is a benefit to supporting | |
564 // the longer sequence given that nops could be used for those | |
565 // entries which are reachable with a single instruction. | |
566 inline bool is_full() const { return !is_int16(size_); } | |
567 | |
568 inline ConstantPoolArray::NumberOfEntries* number_of_entries( | |
569 ConstantPoolArray::LayoutSection section) { | |
570 return &number_of_entries_[section]; | |
571 } | |
572 | |
573 inline ConstantPoolArray::NumberOfEntries* small_entries() { | |
574 return number_of_entries(ConstantPoolArray::SMALL_SECTION); | |
575 } | |
576 | |
577 inline ConstantPoolArray::NumberOfEntries* extended_entries() { | |
578 return number_of_entries(ConstantPoolArray::EXTENDED_SECTION); | |
579 } | |
580 | |
581 private: | |
582 struct ConstantPoolEntry { | |
583 ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section, | |
584 int merged_index) | |
585 : rinfo_(rinfo), section_(section), merged_index_(merged_index) {} | |
586 | |
587 RelocInfo rinfo_; | |
588 ConstantPoolArray::LayoutSection section_; | |
589 int merged_index_; | |
590 }; | |
591 | |
592 ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode); | |
593 | |
594 uint32_t size_; | |
595 std::vector<ConstantPoolEntry> entries_; | |
596 ConstantPoolArray::LayoutSection current_section_; | |
597 ConstantPoolArray::NumberOfEntries number_of_entries_[2]; | |
598 }; | |
599 #endif | |
600 | |
601 | |
602 class Assembler : public AssemblerBase { | 521 class Assembler : public AssemblerBase { |
603 public: | 522 public: |
604 // Create an assembler. Instructions and relocation information are emitted | 523 // Create an assembler. Instructions and relocation information are emitted |
605 // into a buffer, with the instructions starting from the beginning and the | 524 // into a buffer, with the instructions starting from the beginning and the |
606 // relocation information starting from the end of the buffer. See CodeDesc | 525 // relocation information starting from the end of the buffer. See CodeDesc |
607 // for a detailed comment on the layout (globals.h). | 526 // for a detailed comment on the layout (globals.h). |
608 // | 527 // |
609 // If the provided buffer is NULL, the assembler allocates and grows its own | 528 // If the provided buffer is NULL, the assembler allocates and grows its own |
610 // buffer, and buffer_size determines the initial buffer size. The buffer is | 529 // buffer, and buffer_size determines the initial buffer size. The buffer is |
611 // owned by the assembler and deallocated upon destruction of the assembler. | 530 // owned by the assembler and deallocated upon destruction of the assembler. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 // Manages the jump elimination optimization if the second parameter is true. | 572 // Manages the jump elimination optimization if the second parameter is true. |
654 int branch_offset(Label* L, bool jump_elimination_allowed) { | 573 int branch_offset(Label* L, bool jump_elimination_allowed) { |
655 int position = link(L); | 574 int position = link(L); |
656 return position - pc_offset(); | 575 return position - pc_offset(); |
657 } | 576 } |
658 | 577 |
659 // Puts a labels target address at the given position. | 578 // Puts a labels target address at the given position. |
660 // The high 8 bits are set to zero. | 579 // The high 8 bits are set to zero. |
661 void label_at_put(Label* L, int at_offset); | 580 void label_at_put(Label* L, int at_offset); |
662 | 581 |
663 #if V8_OOL_CONSTANT_POOL | |
664 INLINE(static bool IsConstantPoolLoadStart(Address pc)); | |
665 INLINE(static bool IsConstantPoolLoadEnd(Address pc)); | |
666 INLINE(static int GetConstantPoolOffset(Address pc)); | |
667 INLINE(static void SetConstantPoolOffset(Address pc, int offset)); | |
668 | |
669 // Return the address in the constant pool of the code target address used by | |
670 // the branch/call instruction at pc, or the object in a mov. | |
671 INLINE(static Address target_constant_pool_address_at( | |
672 Address pc, ConstantPoolArray* constant_pool)); | |
673 #endif | |
674 | |
675 // Read/Modify the code target address in the branch/call instruction at pc. | 582 // Read/Modify the code target address in the branch/call instruction at pc. |
676 INLINE(static Address target_address_at(Address pc, | 583 INLINE(static Address target_address_at(Address pc, |
677 ConstantPoolArray* constant_pool)); | 584 ConstantPoolArray* constant_pool)); |
678 INLINE(static void set_target_address_at( | 585 INLINE(static void set_target_address_at( |
679 Address pc, ConstantPoolArray* constant_pool, Address target, | 586 Address pc, ConstantPoolArray* constant_pool, Address target, |
680 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); | 587 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); |
681 INLINE(static Address target_address_at(Address pc, Code* code)) { | 588 INLINE(static Address target_address_at(Address pc, Code* code)) { |
682 ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; | 589 ConstantPoolArray* constant_pool = NULL; |
683 return target_address_at(pc, constant_pool); | 590 return target_address_at(pc, constant_pool); |
684 } | 591 } |
685 INLINE(static void set_target_address_at( | 592 INLINE(static void set_target_address_at( |
686 Address pc, Code* code, Address target, | 593 Address pc, Code* code, Address target, |
687 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { | 594 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) { |
688 ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; | 595 ConstantPoolArray* constant_pool = NULL; |
689 set_target_address_at(pc, constant_pool, target, icache_flush_mode); | 596 set_target_address_at(pc, constant_pool, target, icache_flush_mode); |
690 } | 597 } |
691 | 598 |
692 // Return the code target address at a call site from the return address | 599 // Return the code target address at a call site from the return address |
693 // of that call in the instruction stream. | 600 // of that call in the instruction stream. |
694 inline static Address target_address_from_return_address(Address pc); | 601 inline static Address target_address_from_return_address(Address pc); |
695 | 602 |
696 // Given the address of the beginning of a call, return the address | 603 // Given the address of the beginning of a call, return the address |
697 // in the instruction stream that the call will return to. | 604 // in the instruction stream that the call will return to. |
698 INLINE(static Address return_address_from_call_start(Address pc)); | 605 INLINE(static Address return_address_from_call_start(Address pc)); |
(...skipping 12 matching lines...) Expand all Loading... |
711 // Here we are patching the address in the LUI/ORI instruction pair. | 618 // Here we are patching the address in the LUI/ORI instruction pair. |
712 // These values are used in the serialization process and must be zero for | 619 // These values are used in the serialization process and must be zero for |
713 // PPC platform, as Code, Embedded Object or External-reference pointers | 620 // PPC platform, as Code, Embedded Object or External-reference pointers |
714 // are split across two consecutive instructions and don't exist separately | 621 // are split across two consecutive instructions and don't exist separately |
715 // in the code, so the serializer should not step forwards in memory after | 622 // in the code, so the serializer should not step forwards in memory after |
716 // a target is resolved and written. | 623 // a target is resolved and written. |
717 static const int kSpecialTargetSize = 0; | 624 static const int kSpecialTargetSize = 0; |
718 | 625 |
719 // Number of instructions to load an address via a mov sequence. | 626 // Number of instructions to load an address via a mov sequence. |
720 #if V8_TARGET_ARCH_PPC64 | 627 #if V8_TARGET_ARCH_PPC64 |
721 static const int kMovInstructionsConstantPool = 2; | 628 static const int kMovInstructions = 5; |
722 static const int kMovInstructionsNoConstantPool = 5; | 629 static const int kTaggedLoadInstructions = 2; |
723 #else | 630 #else |
724 static const int kMovInstructionsConstantPool = 1; | 631 static const int kMovInstructions = 2; |
725 static const int kMovInstructionsNoConstantPool = 2; | 632 static const int kTaggedLoadInstructions = 1; |
726 #endif | |
727 #if V8_OOL_CONSTANT_POOL | |
728 static const int kMovInstructions = kMovInstructionsConstantPool; | |
729 #else | |
730 static const int kMovInstructions = kMovInstructionsNoConstantPool; | |
731 #endif | 633 #endif |
732 | 634 |
733 // Distance between the instruction referring to the address of the call | 635 // Distance between the instruction referring to the address of the call |
734 // target and the return address. | 636 // target and the return address. |
735 | 637 |
736 // Call sequence is a FIXED_SEQUENCE: | 638 // Call sequence is a FIXED_SEQUENCE: |
737 // mov r8, @ call address | 639 // mov r8, @ call address |
738 // mtlr r8 | 640 // mtlr r8 |
739 // blrl | 641 // blrl |
740 // @ return address | 642 // @ return address |
(...skipping 11 matching lines...) Expand all Loading... |
752 // Distance between start of patched debug break slot and the emitted address | 654 // Distance between start of patched debug break slot and the emitted address |
753 // to jump to. | 655 // to jump to. |
754 // Patched debug break slot code is a FIXED_SEQUENCE: | 656 // Patched debug break slot code is a FIXED_SEQUENCE: |
755 // mov r0, <address> | 657 // mov r0, <address> |
756 // mtlr r0 | 658 // mtlr r0 |
757 // blrl | 659 // blrl |
758 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; | 660 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; |
759 | 661 |
760 // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn() | 662 // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn() |
761 // code patch FIXED_SEQUENCE | 663 // code patch FIXED_SEQUENCE |
762 static const int kJSReturnSequenceInstructions = | 664 static const int kJSReturnSequenceInstructions = kMovInstructions + 3; |
763 kMovInstructionsNoConstantPool + 3; | |
764 | 665 |
765 // This is the length of the code sequence from SetDebugBreakAtSlot() | 666 // This is the length of the code sequence from SetDebugBreakAtSlot() |
766 // FIXED_SEQUENCE | 667 // FIXED_SEQUENCE |
767 static const int kDebugBreakSlotInstructions = | 668 static const int kDebugBreakSlotInstructions = kMovInstructions + 2; |
768 kMovInstructionsNoConstantPool + 2; | |
769 static const int kDebugBreakSlotLength = | 669 static const int kDebugBreakSlotLength = |
770 kDebugBreakSlotInstructions * kInstrSize; | 670 kDebugBreakSlotInstructions * kInstrSize; |
771 | 671 |
772 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { | 672 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { |
773 return ((cr.code() * CRWIDTH) + crbit); | 673 return ((cr.code() * CRWIDTH) + crbit); |
774 } | 674 } |
775 | 675 |
776 // --------------------------------------------------------------------------- | 676 // --------------------------------------------------------------------------- |
777 // Code generation | 677 // Code generation |
778 | 678 |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 static bool IsCrSet(Instr instr); | 1248 static bool IsCrSet(Instr instr); |
1349 static Register GetCmpImmediateRegister(Instr instr); | 1249 static Register GetCmpImmediateRegister(Instr instr); |
1350 static int GetCmpImmediateRawImmediate(Instr instr); | 1250 static int GetCmpImmediateRawImmediate(Instr instr); |
1351 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); | 1251 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
1352 | 1252 |
1353 // Postpone the generation of the trampoline pool for the specified number of | 1253 // Postpone the generation of the trampoline pool for the specified number of |
1354 // instructions. | 1254 // instructions. |
1355 void BlockTrampolinePoolFor(int instructions); | 1255 void BlockTrampolinePoolFor(int instructions); |
1356 void CheckTrampolinePool(); | 1256 void CheckTrampolinePool(); |
1357 | 1257 |
1358 int instructions_required_for_mov(const Operand& x) const; | |
1359 | |
1360 #if V8_OOL_CONSTANT_POOL | |
1361 // Decide between using the constant pool vs. a mov immediate sequence. | |
1362 bool use_constant_pool_for_mov(const Operand& x, bool canOptimize) const; | |
1363 | |
1364 // The code currently calls CheckBuffer() too often. This has the side | 1258 // The code currently calls CheckBuffer() too often. This has the side |
1365 // effect of randomly growing the buffer in the middle of multi-instruction | 1259 // effect of randomly growing the buffer in the middle of multi-instruction |
1366 // sequences. | 1260 // sequences. |
1367 // MacroAssembler::LoadConstantPoolPointerRegister() includes a relocation | 1261 // MacroAssembler::LoadConstantPoolPointerRegister() includes a relocation |
1368 // and multiple instructions. We cannot grow the buffer until the | 1262 // and multiple instructions. We cannot grow the buffer until the |
1369 // relocation and all of the instructions are written. | 1263 // relocation and all of the instructions are written. |
1370 // | 1264 // |
1371 // This function allows outside callers to check and grow the buffer | 1265 // This function allows outside callers to check and grow the buffer |
1372 void EnsureSpaceFor(int space_needed); | 1266 void EnsureSpaceFor(int space_needed); |
1373 #endif | |
1374 | 1267 |
1375 // Allocate a constant pool of the correct size for the generated code. | 1268 // Allocate a constant pool of the correct size for the generated code. |
1376 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); | 1269 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); |
1377 | 1270 |
1378 // Generate the constant pool for the generated code. | 1271 // Generate the constant pool for the generated code. |
1379 void PopulateConstantPool(ConstantPoolArray* constant_pool); | 1272 void PopulateConstantPool(ConstantPoolArray* constant_pool); |
1380 | 1273 |
1381 #if V8_OOL_CONSTANT_POOL | |
1382 bool is_constant_pool_full() const { | |
1383 return constant_pool_builder_.is_full(); | |
1384 } | |
1385 | |
1386 bool use_extended_constant_pool() const { | |
1387 return constant_pool_builder_.current_section() == | |
1388 ConstantPoolArray::EXTENDED_SECTION; | |
1389 } | |
1390 #endif | |
1391 | |
1392 static void RelocateInternalReference( | 1274 static void RelocateInternalReference( |
1393 Address pc, intptr_t delta, Address code_start, RelocInfo::Mode rmode, | 1275 Address pc, intptr_t delta, Address code_start, RelocInfo::Mode rmode, |
1394 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); | 1276 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); |
1395 | 1277 |
1396 void AddBoundInternalReference(int position) { | 1278 void AddBoundInternalReference(int position) { |
1397 internal_reference_positions_.push_back(position); | 1279 internal_reference_positions_.push_back(position); |
1398 } | 1280 } |
1399 | 1281 |
1400 void AddBoundInternalReferenceLoad(int position) { | 1282 void AddBoundInternalReferenceLoad(int position) { |
1401 internal_reference_load_positions_.push_back(position); | 1283 internal_reference_load_positions_.push_back(position); |
1402 } | 1284 } |
1403 | 1285 |
1404 protected: | 1286 protected: |
1405 // Relocation for a type-recording IC has the AST id added to it. This | 1287 // Relocation for a type-recording IC has the AST id added to it. This |
1406 // member variable is a way to pass the information from the call site to | 1288 // member variable is a way to pass the information from the call site to |
1407 // the relocation info. | 1289 // the relocation info. |
1408 TypeFeedbackId recorded_ast_id_; | 1290 TypeFeedbackId recorded_ast_id_; |
1409 | 1291 |
1410 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1292 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
1411 | 1293 |
1412 // Decode branch instruction at pos and return branch target pos | 1294 // Decode branch instruction at pos and return branch target pos |
1413 int target_at(int pos); | 1295 int target_at(int pos); |
1414 | 1296 |
1415 // Patch branch instruction at pos to branch to given branch target pos | 1297 // Patch branch instruction at pos to branch to given branch target pos |
1416 void target_at_put(int pos, int target_pos); | 1298 void target_at_put(int pos, int target_pos); |
1417 | 1299 |
1418 // Record reloc info for current pc_ | 1300 // Record reloc info for current pc_ |
1419 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1301 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
1420 void RecordRelocInfo(const RelocInfo& rinfo); | 1302 void RecordRelocInfo(const RelocInfo& rinfo); |
1421 #if V8_OOL_CONSTANT_POOL | |
1422 ConstantPoolArray::LayoutSection ConstantPoolAddEntry( | |
1423 const RelocInfo& rinfo) { | |
1424 return constant_pool_builder_.AddEntry(this, rinfo); | |
1425 } | |
1426 #endif | |
1427 | 1303 |
1428 // Block the emission of the trampoline pool before pc_offset. | 1304 // Block the emission of the trampoline pool before pc_offset. |
1429 void BlockTrampolinePoolBefore(int pc_offset) { | 1305 void BlockTrampolinePoolBefore(int pc_offset) { |
1430 if (no_trampoline_pool_before_ < pc_offset) | 1306 if (no_trampoline_pool_before_ < pc_offset) |
1431 no_trampoline_pool_before_ = pc_offset; | 1307 no_trampoline_pool_before_ = pc_offset; |
1432 } | 1308 } |
1433 | 1309 |
1434 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } | 1310 void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; } |
1435 | |
1436 void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; } | 1311 void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; } |
1437 | |
1438 bool is_trampoline_pool_blocked() const { | 1312 bool is_trampoline_pool_blocked() const { |
1439 return trampoline_pool_blocked_nesting_ > 0; | 1313 return trampoline_pool_blocked_nesting_ > 0; |
1440 } | 1314 } |
1441 | 1315 |
1442 bool has_exception() const { return internal_trampoline_exception_; } | 1316 bool has_exception() const { return internal_trampoline_exception_; } |
1443 | 1317 |
1444 bool is_trampoline_emitted() const { return trampoline_emitted_; } | 1318 bool is_trampoline_emitted() const { return trampoline_emitted_; } |
1445 | 1319 |
1446 private: | 1320 private: |
1447 // Code generation | 1321 // Code generation |
(...skipping 19 matching lines...) Expand all Loading... |
1467 | 1341 |
1468 // Internal reference positions, required for (potential) patching in | 1342 // Internal reference positions, required for (potential) patching in |
1469 // GrowBuffer(); contains only those internal references whose labels | 1343 // GrowBuffer(); contains only those internal references whose labels |
1470 // are already bound. | 1344 // are already bound. |
1471 std::deque<int> internal_reference_positions_; | 1345 std::deque<int> internal_reference_positions_; |
1472 std::deque<int> internal_reference_load_positions_; | 1346 std::deque<int> internal_reference_load_positions_; |
1473 | 1347 |
1474 // The bound position, before this we cannot do instruction elimination. | 1348 // The bound position, before this we cannot do instruction elimination. |
1475 int last_bound_pos_; | 1349 int last_bound_pos_; |
1476 | 1350 |
1477 #if V8_OOL_CONSTANT_POOL | |
1478 ConstantPoolBuilder constant_pool_builder_; | |
1479 #endif | |
1480 | |
1481 // Code emission | 1351 // Code emission |
1482 inline void CheckBuffer(); | 1352 inline void CheckBuffer(); |
1483 void GrowBuffer(); | 1353 void GrowBuffer(int needed = 0); |
1484 inline void emit(Instr x); | 1354 inline void emit(Instr x); |
1485 inline void CheckTrampolinePoolQuick(); | 1355 inline void CheckTrampolinePoolQuick(); |
1486 | 1356 |
1487 // Instruction generation | 1357 // Instruction generation |
1488 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, | 1358 void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra, |
1489 DoubleRegister frb, RCBit r); | 1359 DoubleRegister frb, RCBit r); |
1490 void d_form(Instr instr, Register rt, Register ra, const intptr_t val, | 1360 void d_form(Instr instr, Register rt, Register ra, const intptr_t val, |
1491 bool signed_disp); | 1361 bool signed_disp); |
1492 void x_form(Instr instr, Register ra, Register rs, Register rb, RCBit r); | 1362 void x_form(Instr instr, Register ra, Register rs, Register rb, RCBit r); |
1493 void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o, | 1363 void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1561 | 1431 |
1562 | 1432 |
1563 class EnsureSpace BASE_EMBEDDED { | 1433 class EnsureSpace BASE_EMBEDDED { |
1564 public: | 1434 public: |
1565 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } | 1435 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } |
1566 }; | 1436 }; |
1567 } | 1437 } |
1568 } // namespace v8::internal | 1438 } // namespace v8::internal |
1569 | 1439 |
1570 #endif // V8_PPC_ASSEMBLER_PPC_H_ | 1440 #endif // V8_PPC_ASSEMBLER_PPC_H_ |
OLD | NEW |