Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: src/mips64/assembler-mips64.cc

Issue 930623003: MIPS64: Assembler support for internal references. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix compilation problem. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips64/assembler-mips64.h ('k') | src/mips64/assembler-mips64-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 ra 168 ra
169 }; 169 };
170 return kRegisters[num]; 170 return kRegisters[num];
171 } 171 }
172 172
173 173
174 // ----------------------------------------------------------------------------- 174 // -----------------------------------------------------------------------------
175 // Implementation of RelocInfo. 175 // Implementation of RelocInfo.
176 176
177 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | 177 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
178 1 << RelocInfo::INTERNAL_REFERENCE; 178 1 << RelocInfo::INTERNAL_REFERENCE |
179 1 << RelocInfo::INTERNAL_REFERENCE_ENCODED;
179 180
180 181
181 bool RelocInfo::IsCodedSpecially() { 182 bool RelocInfo::IsCodedSpecially() {
182 // The deserializer needs to know whether a pointer is specially coded. Being 183 // The deserializer needs to know whether a pointer is specially coded. Being
183 // specially coded on MIPS means that it is a lui/ori instruction, and that is 184 // specially coded on MIPS means that it is a lui/ori instruction, and that is
184 // always the case inside code objects. 185 // always the case inside code objects.
185 return true; 186 return true;
186 } 187 }
187 188
188 189
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 DCHECK(IsAddImmediate(instr)); 628 DCHECK(IsAddImmediate(instr));
628 return ((instr & ~kImm16Mask) | (offset & kImm16Mask)); 629 return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
629 } 630 }
630 631
631 632
632 bool Assembler::IsAndImmediate(Instr instr) { 633 bool Assembler::IsAndImmediate(Instr instr) {
633 return GetOpcodeField(instr) == ANDI; 634 return GetOpcodeField(instr) == ANDI;
634 } 635 }
635 636
636 637
637 int64_t Assembler::target_at(int64_t pos) { 638 int64_t Assembler::target_at(int64_t pos, bool is_internal) {
639 if (is_internal) {
640 int64_t* p = reinterpret_cast<int64_t*>(buffer_ + pos);
641 int64_t address = *p;
642 if (address == kEndOfJumpChain) {
643 return kEndOfChain;
644 } else {
645 int64_t instr_address = reinterpret_cast<int64_t>(p);
646 int64_t delta = instr_address - address;
647 DCHECK(pos > delta);
648 return pos - delta;
649 }
650 }
638 Instr instr = instr_at(pos); 651 Instr instr = instr_at(pos);
639 if ((instr & ~kImm16Mask) == 0) { 652 if ((instr & ~kImm16Mask) == 0) {
640 // Emitted label constant, not part of a branch. 653 // Emitted label constant, not part of a branch.
641 if (instr == 0) { 654 if (instr == 0) {
642 return kEndOfChain; 655 return kEndOfChain;
643 } else { 656 } else {
644 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; 657 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
645 return (imm18 + pos); 658 return (imm18 + pos);
646 } 659 }
647 } 660 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos); 702 uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
690 instr_address &= kImm28Mask; 703 instr_address &= kImm28Mask;
691 int64_t delta = instr_address - imm28; 704 int64_t delta = instr_address - imm28;
692 DCHECK(pos > delta); 705 DCHECK(pos > delta);
693 return pos - delta; 706 return pos - delta;
694 } 707 }
695 } 708 }
696 } 709 }
697 710
698 711
699 void Assembler::target_at_put(int64_t pos, int64_t target_pos) { 712 void Assembler::target_at_put(int64_t pos, int64_t target_pos,
713 bool is_internal) {
714 if (is_internal) {
715 uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
716 *reinterpret_cast<uint64_t*>(buffer_ + pos) = imm;
717 return;
718 }
700 Instr instr = instr_at(pos); 719 Instr instr = instr_at(pos);
701 if ((instr & ~kImm16Mask) == 0) { 720 if ((instr & ~kImm16Mask) == 0) {
702 DCHECK(target_pos == kEndOfChain || target_pos >= 0); 721 DCHECK(target_pos == kEndOfChain || target_pos >= 0);
703 // Emitted label constant, not part of a branch. 722 // Emitted label constant, not part of a branch.
704 // Make label relative to Code* of generated Code object. 723 // Make label relative to Code* of generated Code object.
705 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 724 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
706 return; 725 return;
707 } 726 }
708 727
709 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); 728 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 Label l = *L; 778 Label l = *L;
760 PrintF("unbound label"); 779 PrintF("unbound label");
761 while (l.is_linked()) { 780 while (l.is_linked()) {
762 PrintF("@ %d ", l.pos()); 781 PrintF("@ %d ", l.pos());
763 Instr instr = instr_at(l.pos()); 782 Instr instr = instr_at(l.pos());
764 if ((instr & ~kImm16Mask) == 0) { 783 if ((instr & ~kImm16Mask) == 0) {
765 PrintF("value\n"); 784 PrintF("value\n");
766 } else { 785 } else {
767 PrintF("%d\n", instr); 786 PrintF("%d\n", instr);
768 } 787 }
769 next(&l); 788 next(&l, internal_reference_positions_.find(l.pos()) !=
789 internal_reference_positions_.end());
770 } 790 }
771 } else { 791 } else {
772 PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 792 PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
773 } 793 }
774 } 794 }
775 795
776 796
777 void Assembler::bind_to(Label* L, int pos) { 797 void Assembler::bind_to(Label* L, int pos) {
778 DCHECK(0 <= pos && pos <= pc_offset()); // Must have valid binding position. 798 DCHECK(0 <= pos && pos <= pc_offset()); // Must have valid binding position.
779 int32_t trampoline_pos = kInvalidSlotPos; 799 int32_t trampoline_pos = kInvalidSlotPos;
800 bool is_internal = false;
780 if (L->is_linked() && !trampoline_emitted_) { 801 if (L->is_linked() && !trampoline_emitted_) {
781 unbound_labels_count_--; 802 unbound_labels_count_--;
782 next_buffer_check_ += kTrampolineSlotsSize; 803 next_buffer_check_ += kTrampolineSlotsSize;
783 } 804 }
784 805
785 while (L->is_linked()) { 806 while (L->is_linked()) {
786 int32_t fixup_pos = L->pos(); 807 int32_t fixup_pos = L->pos();
787 int32_t dist = pos - fixup_pos; 808 int32_t dist = pos - fixup_pos;
788 next(L); // Call next before overwriting link with target at fixup_pos. 809 is_internal = internal_reference_positions_.find(fixup_pos) !=
810 internal_reference_positions_.end();
811 next(L, is_internal); // Call next before overwriting link with target at
812 // fixup_pos.
789 Instr instr = instr_at(fixup_pos); 813 Instr instr = instr_at(fixup_pos);
790 if (IsBranch(instr)) { 814 if (is_internal) {
815 target_at_put(fixup_pos, pos, is_internal);
816 } else if (IsBranch(instr)) {
791 if (dist > kMaxBranchOffset) { 817 if (dist > kMaxBranchOffset) {
792 if (trampoline_pos == kInvalidSlotPos) { 818 if (trampoline_pos == kInvalidSlotPos) {
793 trampoline_pos = get_trampoline_entry(fixup_pos); 819 trampoline_pos = get_trampoline_entry(fixup_pos);
794 CHECK(trampoline_pos != kInvalidSlotPos); 820 CHECK(trampoline_pos != kInvalidSlotPos);
795 } 821 }
796 DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset); 822 DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
797 target_at_put(fixup_pos, trampoline_pos); 823 target_at_put(fixup_pos, trampoline_pos, false);
798 fixup_pos = trampoline_pos; 824 fixup_pos = trampoline_pos;
799 dist = pos - fixup_pos; 825 dist = pos - fixup_pos;
800 } 826 }
801 target_at_put(fixup_pos, pos); 827 target_at_put(fixup_pos, pos, false);
802 } else { 828 } else {
803 DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr)); 829 DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
804 target_at_put(fixup_pos, pos); 830 target_at_put(fixup_pos, pos, false);
805 } 831 }
806 } 832 }
807 L->bind_to(pos); 833 L->bind_to(pos);
808 834
809 // Keep track of the last bound label so we don't eliminate any instructions 835 // Keep track of the last bound label so we don't eliminate any instructions
810 // before a bound label. 836 // before a bound label.
811 if (pos > last_bound_pos_) 837 if (pos > last_bound_pos_)
812 last_bound_pos_ = pos; 838 last_bound_pos_ = pos;
813 } 839 }
814 840
815 841
816 void Assembler::bind(Label* L) { 842 void Assembler::bind(Label* L) {
817 DCHECK(!L->is_bound()); // Label can only be bound once. 843 DCHECK(!L->is_bound()); // Label can only be bound once.
818 bind_to(L, pc_offset()); 844 bind_to(L, pc_offset());
819 } 845 }
820 846
821 847
822 void Assembler::next(Label* L) { 848 void Assembler::next(Label* L, bool is_internal) {
823 DCHECK(L->is_linked()); 849 DCHECK(L->is_linked());
824 int link = target_at(L->pos()); 850 int link = target_at(L->pos(), is_internal);
825 if (link == kEndOfChain) { 851 if (link == kEndOfChain) {
826 L->Unuse(); 852 L->Unuse();
827 } else { 853 } else {
828 DCHECK(link >= 0); 854 DCHECK(link >= 0);
829 L->link_to(link); 855 L->link_to(link);
830 } 856 }
831 } 857 }
832 858
833 859
834 bool Assembler::is_near(Label* L) { 860 bool Assembler::is_near(Label* L) {
(...skipping 1717 matching lines...) Expand 10 before | Expand all | Expand 10 after
2552 2578
2553 2579
2554 void Assembler::bc1t(int16_t offset, uint16_t cc) { 2580 void Assembler::bc1t(int16_t offset, uint16_t cc) {
2555 DCHECK(is_uint3(cc)); 2581 DCHECK(is_uint3(cc));
2556 Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask); 2582 Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask);
2557 emit(instr); 2583 emit(instr);
2558 } 2584 }
2559 2585
2560 2586
2561 // Debugging. 2587 // Debugging.
2562 int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) { 2588 int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
2589 intptr_t pc_delta) {
2590 if (RelocInfo::IsInternalReference(rmode)) {
2591 int64_t* p = reinterpret_cast<int64_t*>(pc);
2592 if (*p == kEndOfJumpChain) {
2593 return 0; // Number of instructions patched.
2594 }
2595 *p += pc_delta;
2596 return 2; // Number of instructions patched.
2597 }
2563 Instr instr = instr_at(pc); 2598 Instr instr = instr_at(pc);
2599 DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
2564 DCHECK(IsJ(instr) || IsLui(instr)); 2600 DCHECK(IsJ(instr) || IsLui(instr));
2565 if (IsLui(instr)) { 2601 if (IsLui(instr)) {
2566 Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize); 2602 Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
2567 Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize); 2603 Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
2568 Instr instr_ori2 = instr_at(pc + 3 * Assembler::kInstrSize); 2604 Instr instr_ori2 = instr_at(pc + 3 * Assembler::kInstrSize);
2569 DCHECK(IsOri(instr_ori)); 2605 DCHECK(IsOri(instr_ori));
2570 DCHECK(IsOri(instr_ori2)); 2606 DCHECK(IsOri(instr_ori2));
2571 // TODO(plind): symbolic names for the shifts. 2607 // TODO(plind): symbolic names for the shifts.
2572 int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 48; 2608 int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 48;
2573 imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 32; 2609 imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 32;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 DeleteArray(buffer_); 2678 DeleteArray(buffer_);
2643 buffer_ = desc.buffer; 2679 buffer_ = desc.buffer;
2644 buffer_size_ = desc.buffer_size; 2680 buffer_size_ = desc.buffer_size;
2645 pc_ += pc_delta; 2681 pc_ += pc_delta;
2646 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2682 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2647 reloc_info_writer.last_pc() + pc_delta); 2683 reloc_info_writer.last_pc() + pc_delta);
2648 2684
2649 // Relocate runtime entries. 2685 // Relocate runtime entries.
2650 for (RelocIterator it(desc); !it.done(); it.next()) { 2686 for (RelocIterator it(desc); !it.done(); it.next()) {
2651 RelocInfo::Mode rmode = it.rinfo()->rmode(); 2687 RelocInfo::Mode rmode = it.rinfo()->rmode();
2652 if (rmode == RelocInfo::INTERNAL_REFERENCE) { 2688 if (rmode == RelocInfo::INTERNAL_REFERENCE_ENCODED ||
2689 rmode == RelocInfo::INTERNAL_REFERENCE) {
2653 byte* p = reinterpret_cast<byte*>(it.rinfo()->pc()); 2690 byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
2654 RelocateInternalReference(p, pc_delta); 2691 RelocateInternalReference(rmode, p, pc_delta);
2655 } 2692 }
2656 } 2693 }
2657
2658 DCHECK(!overflow()); 2694 DCHECK(!overflow());
2659 } 2695 }
2660 2696
2661 2697
2662 void Assembler::db(uint8_t data) { 2698 void Assembler::db(uint8_t data) {
2663 CheckBuffer(); 2699 CheckBuffer();
2664 *reinterpret_cast<uint8_t*>(pc_) = data; 2700 *reinterpret_cast<uint8_t*>(pc_) = data;
2665 pc_ += sizeof(uint8_t); 2701 pc_ += sizeof(uint8_t);
2666 } 2702 }
2667 2703
2668 2704
2669 void Assembler::dd(uint32_t data) { 2705 void Assembler::dd(uint32_t data) {
2670 CheckBuffer(); 2706 CheckBuffer();
2671 *reinterpret_cast<uint32_t*>(pc_) = data; 2707 *reinterpret_cast<uint32_t*>(pc_) = data;
2672 pc_ += sizeof(uint32_t); 2708 pc_ += sizeof(uint32_t);
2673 } 2709 }
2674 2710
2675 2711
2712 void Assembler::dd(Label* label) {
2713 CheckBuffer();
2714 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2715 if (label->is_bound()) {
2716 uint64_t data = reinterpret_cast<uint64_t>(buffer_ + label->pos());
2717 *reinterpret_cast<uint64_t*>(pc_) = data;
2718 pc_ += sizeof(uint64_t);
2719 } else {
2720 uint64_t target_pos = jump_address(label);
2721 emit(target_pos);
2722 internal_reference_positions_.insert(label->pos());
2723 }
2724 }
2725
2726
2676 void Assembler::emit_code_stub_address(Code* stub) { 2727 void Assembler::emit_code_stub_address(Code* stub) {
2677 CheckBuffer(); 2728 CheckBuffer();
2678 *reinterpret_cast<uint64_t*>(pc_) = 2729 *reinterpret_cast<uint64_t*>(pc_) =
2679 reinterpret_cast<uint64_t>(stub->instruction_start()); 2730 reinterpret_cast<uint64_t>(stub->instruction_start());
2680 pc_ += sizeof(uint64_t); 2731 pc_ += sizeof(uint64_t);
2681 } 2732 }
2682 2733
2683 2734
2684 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2735 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2685 // We do not try to reuse pool constants. 2736 // We do not try to reuse pool constants.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2746 nop(); 2797 nop();
2747 2798
2748 int pool_start = pc_offset(); 2799 int pool_start = pc_offset();
2749 for (int i = 0; i < unbound_labels_count_; i++) { 2800 for (int i = 0; i < unbound_labels_count_; i++) {
2750 uint64_t imm64; 2801 uint64_t imm64;
2751 imm64 = jump_address(&after_pool); 2802 imm64 = jump_address(&after_pool);
2752 { BlockGrowBufferScope block_buf_growth(this); 2803 { BlockGrowBufferScope block_buf_growth(this);
2753 // Buffer growth (and relocation) must be blocked for internal 2804 // Buffer growth (and relocation) must be blocked for internal
2754 // references until associated instructions are emitted and available 2805 // references until associated instructions are emitted and available
2755 // to be patched. 2806 // to be patched.
2756 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 2807 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
2757 // TODO(plind): Verify this, presume I cannot use macro-assembler 2808 // TODO(plind): Verify this, presume I cannot use macro-assembler
2758 // here. 2809 // here.
2759 lui(at, (imm64 >> 32) & kImm16Mask); 2810 lui(at, (imm64 >> 32) & kImm16Mask);
2760 ori(at, at, (imm64 >> 16) & kImm16Mask); 2811 ori(at, at, (imm64 >> 16) & kImm16Mask);
2761 dsll(at, at, 16); 2812 dsll(at, at, 16);
2762 ori(at, at, imm64 & kImm16Mask); 2813 ori(at, at, imm64 & kImm16Mask);
2763 } 2814 }
2764 jr(at); 2815 jr(at);
2765 nop(); 2816 nop();
2766 } 2817 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
2910 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 2961 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2911 // No out-of-line constant pool support. 2962 // No out-of-line constant pool support.
2912 DCHECK(!FLAG_enable_ool_constant_pool); 2963 DCHECK(!FLAG_enable_ool_constant_pool);
2913 return; 2964 return;
2914 } 2965 }
2915 2966
2916 2967
2917 } } // namespace v8::internal 2968 } } // namespace v8::internal
2918 2969
2919 #endif // V8_TARGET_ARCH_MIPS64 2970 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/assembler-mips64.h ('k') | src/mips64/assembler-mips64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698