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

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

Issue 922043005: MIPS: Fix 'Assembler support for internal references.' (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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/mips/assembler-mips.h ('k') | src/mips/assembler-mips-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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 ra 190 ra
191 }; 191 };
192 return kRegisters[num]; 192 return kRegisters[num];
193 } 193 }
194 194
195 195
196 // ----------------------------------------------------------------------------- 196 // -----------------------------------------------------------------------------
197 // Implementation of RelocInfo. 197 // Implementation of RelocInfo.
198 198
199 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | 199 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
200 1 << RelocInfo::INTERNAL_REFERENCE; 200 1 << RelocInfo::INTERNAL_REFERENCE |
201 1 << RelocInfo::INTERNAL_REFERENCE_ENCODED;
201 202
202 203
203 bool RelocInfo::IsCodedSpecially() { 204 bool RelocInfo::IsCodedSpecially() {
204 // The deserializer needs to know whether a pointer is specially coded. Being 205 // The deserializer needs to know whether a pointer is specially coded. Being
205 // specially coded on MIPS means that it is a lui/ori instruction, and that is 206 // specially coded on MIPS means that it is a lui/ori instruction, and that is
206 // always the case inside code objects. 207 // always the case inside code objects.
207 return true; 208 return true;
208 } 209 }
209 210
210 211
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 DCHECK(IsAddImmediate(instr)); 656 DCHECK(IsAddImmediate(instr));
656 return ((instr & ~kImm16Mask) | (offset & kImm16Mask)); 657 return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
657 } 658 }
658 659
659 660
660 bool Assembler::IsAndImmediate(Instr instr) { 661 bool Assembler::IsAndImmediate(Instr instr) {
661 return GetOpcodeField(instr) == ANDI; 662 return GetOpcodeField(instr) == ANDI;
662 } 663 }
663 664
664 665
665 int Assembler::target_at(int32_t pos) { 666 int Assembler::target_at(int32_t pos, bool is_internal) {
666 Instr instr = instr_at(pos); 667 Instr instr = instr_at(pos);
668 if (is_internal) {
669 if (instr == 0) {
670 return kEndOfChain;
671 } else {
672 int32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
673 int32_t delta = instr_address - instr;
674 DCHECK(pos > delta);
675 return pos - delta;
676 }
677 }
667 if ((instr & ~kImm16Mask) == 0) { 678 if ((instr & ~kImm16Mask) == 0) {
668 // Emitted label constant, not part of a branch. 679 // Emitted label constant, not part of a branch.
669 if (instr == 0) { 680 if (instr == 0) {
670 return kEndOfChain; 681 return kEndOfChain;
671 } else { 682 } else {
672 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; 683 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
673 return (imm18 + pos); 684 return (imm18 + pos);
674 } 685 }
675 } 686 }
676 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming 687 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
(...skipping 28 matching lines...) Expand all
705 if (imm28 == kEndOfJumpChain) { 716 if (imm28 == kEndOfJumpChain) {
706 // EndOfChain sentinel is returned directly, not relative to pc or pos. 717 // EndOfChain sentinel is returned directly, not relative to pc or pos.
707 return kEndOfChain; 718 return kEndOfChain;
708 } else { 719 } else {
709 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); 720 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
710 instr_address &= kImm28Mask; 721 instr_address &= kImm28Mask;
711 int32_t delta = instr_address - imm28; 722 int32_t delta = instr_address - imm28;
712 DCHECK(pos > delta); 723 DCHECK(pos > delta);
713 return pos - delta; 724 return pos - delta;
714 } 725 }
715 } else { // IsLabel(instr) 726 } else {
716 int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; 727 UNREACHABLE();
717 if (imm28 == kEndOfJumpChain) { 728 return 0;
718 // EndOfChain sentinel is returned directly, not relative to pc or pos.
719 return kEndOfChain;
720 } else {
721 return pos + imm28;
722 }
723 } 729 }
724 } 730 }
725 731
726 732
727 void Assembler::target_at_put(int32_t pos, int32_t target_pos) { 733 void Assembler::target_at_put(int32_t pos, int32_t target_pos,
734 bool is_internal) {
728 Instr instr = instr_at(pos); 735 Instr instr = instr_at(pos);
736
737 if (is_internal) {
738 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
739 instr_at_put(pos, imm);
740 return;
741 }
729 if ((instr & ~kImm16Mask) == 0) { 742 if ((instr & ~kImm16Mask) == 0) {
730 DCHECK(target_pos == kEndOfChain || target_pos >= 0); 743 DCHECK(target_pos == kEndOfChain || target_pos >= 0);
731 // Emitted label constant, not part of a branch. 744 // Emitted label constant, not part of a branch.
732 // Make label relative to Code* of generated Code object. 745 // Make label relative to Code* of generated Code object.
733 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 746 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
734 return; 747 return;
735 } 748 }
736 749
737 if (IsBranch(instr)) { 750 if (IsBranch(instr)) {
738 int32_t imm18 = target_pos - (pos + kBranchPCOffset); 751 int32_t imm18 = target_pos - (pos + kBranchPCOffset);
(...skipping 22 matching lines...) Expand all
761 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; 774 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos;
762 imm28 &= kImm28Mask; 775 imm28 &= kImm28Mask;
763 DCHECK((imm28 & 3) == 0); 776 DCHECK((imm28 & 3) == 0);
764 777
765 instr &= ~kImm26Mask; 778 instr &= ~kImm26Mask;
766 uint32_t imm26 = imm28 >> 2; 779 uint32_t imm26 = imm28 >> 2;
767 DCHECK(is_uint26(imm26)); 780 DCHECK(is_uint26(imm26));
768 781
769 instr_at_put(pos, instr | (imm26 & kImm26Mask)); 782 instr_at_put(pos, instr | (imm26 & kImm26Mask));
770 } else { 783 } else {
771 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; 784 UNREACHABLE();
772 instr_at_put(pos, imm);
773 } 785 }
774 } 786 }
775 787
776 788
777 void Assembler::print(Label* L) { 789 void Assembler::print(Label* L) {
778 if (L->is_unused()) { 790 if (L->is_unused()) {
779 PrintF("unused label\n"); 791 PrintF("unused label\n");
780 } else if (L->is_bound()) { 792 } else if (L->is_bound()) {
781 PrintF("bound label to %d\n", L->pos()); 793 PrintF("bound label to %d\n", L->pos());
782 } else if (L->is_linked()) { 794 } else if (L->is_linked()) {
783 Label l = *L; 795 Label l = *L;
784 PrintF("unbound label"); 796 PrintF("unbound label");
785 while (l.is_linked()) { 797 while (l.is_linked()) {
786 PrintF("@ %d ", l.pos()); 798 PrintF("@ %d ", l.pos());
787 Instr instr = instr_at(l.pos()); 799 Instr instr = instr_at(l.pos());
788 if ((instr & ~kImm16Mask) == 0) { 800 if ((instr & ~kImm16Mask) == 0) {
789 PrintF("value\n"); 801 PrintF("value\n");
790 } else { 802 } else {
791 PrintF("%d\n", instr); 803 PrintF("%d\n", instr);
792 } 804 }
793 next(&l); 805 next(&l, internal_reference_positions_.find(l.pos()) !=
806 internal_reference_positions_.end());
794 } 807 }
795 } else { 808 } else {
796 PrintF("label in inconsistent state (pos = %d)\n", L->pos_); 809 PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
797 } 810 }
798 } 811 }
799 812
800 813
801 void Assembler::bind_to(Label* L, int pos) { 814 void Assembler::bind_to(Label* L, int pos) {
802 DCHECK(0 <= pos && pos <= pc_offset()); // Must have valid binding position. 815 DCHECK(0 <= pos && pos <= pc_offset()); // Must have valid binding position.
803 int32_t trampoline_pos = kInvalidSlotPos; 816 int32_t trampoline_pos = kInvalidSlotPos;
817 bool is_internal = false;
804 if (L->is_linked() && !trampoline_emitted_) { 818 if (L->is_linked() && !trampoline_emitted_) {
805 unbound_labels_count_--; 819 unbound_labels_count_--;
806 next_buffer_check_ += kTrampolineSlotsSize; 820 next_buffer_check_ += kTrampolineSlotsSize;
807 } 821 }
808 822
809 while (L->is_linked()) { 823 while (L->is_linked()) {
810 int32_t fixup_pos = L->pos(); 824 int32_t fixup_pos = L->pos();
811 int32_t dist = pos - fixup_pos; 825 int32_t dist = pos - fixup_pos;
812 next(L); // Call next before overwriting link with target at fixup_pos. 826 is_internal = internal_reference_positions_.find(fixup_pos) !=
827 internal_reference_positions_.end();
828 next(L, is_internal); // Call next before overwriting link with target at
829 // fixup_pos.
813 Instr instr = instr_at(fixup_pos); 830 Instr instr = instr_at(fixup_pos);
814 if (IsBranch(instr)) { 831 if (is_internal) {
832 target_at_put(fixup_pos, pos, is_internal);
833 } else if (!is_internal && IsBranch(instr)) {
815 if (dist > kMaxBranchOffset) { 834 if (dist > kMaxBranchOffset) {
816 if (trampoline_pos == kInvalidSlotPos) { 835 if (trampoline_pos == kInvalidSlotPos) {
817 trampoline_pos = get_trampoline_entry(fixup_pos); 836 trampoline_pos = get_trampoline_entry(fixup_pos);
818 CHECK(trampoline_pos != kInvalidSlotPos); 837 CHECK(trampoline_pos != kInvalidSlotPos);
819 } 838 }
820 DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset); 839 DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
821 target_at_put(fixup_pos, trampoline_pos); 840 target_at_put(fixup_pos, trampoline_pos, false);
822 fixup_pos = trampoline_pos; 841 fixup_pos = trampoline_pos;
823 dist = pos - fixup_pos; 842 dist = pos - fixup_pos;
824 } 843 }
825 target_at_put(fixup_pos, pos); 844 target_at_put(fixup_pos, pos, false);
826 } else { 845 } else {
827 target_at_put(fixup_pos, pos); 846 target_at_put(fixup_pos, pos, false);
828 } 847 }
829 } 848 }
830 L->bind_to(pos); 849 L->bind_to(pos);
831 850
832 // Keep track of the last bound label so we don't eliminate any instructions 851 // Keep track of the last bound label so we don't eliminate any instructions
833 // before a bound label. 852 // before a bound label.
834 if (pos > last_bound_pos_) 853 if (pos > last_bound_pos_)
835 last_bound_pos_ = pos; 854 last_bound_pos_ = pos;
836 } 855 }
837 856
838 857
839 void Assembler::bind(Label* L) { 858 void Assembler::bind(Label* L) {
840 DCHECK(!L->is_bound()); // Label can only be bound once. 859 DCHECK(!L->is_bound()); // Label can only be bound once.
841 bind_to(L, pc_offset()); 860 bind_to(L, pc_offset());
842 } 861 }
843 862
844 863
845 void Assembler::next(Label* L) { 864 void Assembler::next(Label* L, bool is_internal) {
846 DCHECK(L->is_linked()); 865 DCHECK(L->is_linked());
847 int link = target_at(L->pos()); 866 int link = target_at(L->pos(), is_internal);
848 if (link == kEndOfChain) { 867 if (link == kEndOfChain) {
849 L->Unuse(); 868 L->Unuse();
850 } else { 869 } else {
851 DCHECK(link >= 0); 870 DCHECK(link >= 0);
852 L->link_to(link); 871 L->link_to(link);
853 } 872 }
854 } 873 }
855 874
856 875
857 bool Assembler::is_near(Label* L) { 876 bool Assembler::is_near(Label* L) {
(...skipping 1467 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 2344
2326 2345
2327 void Assembler::bc1t(int16_t offset, uint16_t cc) { 2346 void Assembler::bc1t(int16_t offset, uint16_t cc) {
2328 DCHECK(is_uint3(cc)); 2347 DCHECK(is_uint3(cc));
2329 Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask); 2348 Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask);
2330 emit(instr); 2349 emit(instr);
2331 } 2350 }
2332 2351
2333 2352
2334 // Debugging. 2353 // Debugging.
2335 int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) { 2354 int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
2355 intptr_t pc_delta) {
2336 Instr instr = instr_at(pc); 2356 Instr instr = instr_at(pc);
2337 if (IsLui(instr)) {
2338 Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
2339 Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
2340 DCHECK(IsOri(instr_ori));
2341 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
2342 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
2343 if (imm == kEndOfJumpChain) {
2344 return 0; // Number of instructions patched.
2345 }
2346 imm += pc_delta;
2347 DCHECK((imm & 3) == 0);
2348 2357
2349 instr_lui &= ~kImm16Mask; 2358 if (RelocInfo::IsInternalReference(rmode)) {
2350 instr_ori &= ~kImm16Mask;
2351
2352 instr_at_put(pc + 0 * Assembler::kInstrSize,
2353 instr_lui | ((imm >> kLuiShift) & kImm16Mask));
2354 instr_at_put(pc + 1 * Assembler::kInstrSize,
2355 instr_ori | (imm & kImm16Mask));
2356 return 2; // Number of instructions patched.
2357 } else if (IsJ(instr)) {
2358 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
2359 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
2360 return 0; // Number of instructions patched.
2361 }
2362 imm28 += pc_delta;
2363 imm28 &= kImm28Mask;
2364 DCHECK((imm28 & 3) == 0);
2365
2366 instr &= ~kImm26Mask;
2367 uint32_t imm26 = imm28 >> 2;
2368 DCHECK(is_uint26(imm26));
2369
2370 instr_at_put(pc, instr | (imm26 & kImm26Mask));
2371 return 1; // Number of instructions patched.
2372 } else { // IsLabel(instr)
2373 int32_t* p = reinterpret_cast<int32_t*>(pc); 2359 int32_t* p = reinterpret_cast<int32_t*>(pc);
2374 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; 2360 if (*p == 0) {
2375 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
2376 return 0; // Number of instructions patched. 2361 return 0; // Number of instructions patched.
2377 } 2362 }
2378 *p += pc_delta; 2363 *p += pc_delta;
2379 return 1; // Number of instructions patched. 2364 return 1; // Number of instructions patched.
2365 } else {
2366 DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
2367 if (IsLui(instr)) {
2368 Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
2369 Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
2370 DCHECK(IsOri(instr_ori));
2371 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
2372 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
2373 if (imm == kEndOfJumpChain) {
2374 return 0; // Number of instructions patched.
2375 }
2376 imm += pc_delta;
2377 DCHECK((imm & 3) == 0);
2378
2379 instr_lui &= ~kImm16Mask;
2380 instr_ori &= ~kImm16Mask;
2381
2382 instr_at_put(pc + 0 * Assembler::kInstrSize,
2383 instr_lui | ((imm >> kLuiShift) & kImm16Mask));
2384 instr_at_put(pc + 1 * Assembler::kInstrSize,
2385 instr_ori | (imm & kImm16Mask));
2386 return 2; // Number of instructions patched.
2387 } else if (IsJ(instr)) {
2388 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
2389 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
2390 return 0; // Number of instructions patched.
2391 }
2392 imm28 += pc_delta;
2393 imm28 &= kImm28Mask;
2394 DCHECK((imm28 & 3) == 0);
2395
2396 instr &= ~kImm26Mask;
2397 uint32_t imm26 = imm28 >> 2;
2398 DCHECK(is_uint26(imm26));
2399
2400 instr_at_put(pc, instr | (imm26 & kImm26Mask));
2401 return 1; // Number of instructions patched.
2402 } else {
2403 UNREACHABLE();
2404 return 0;
2405 }
2380 } 2406 }
2381 } 2407 }
2382 2408
2383 2409
2384 void Assembler::GrowBuffer() { 2410 void Assembler::GrowBuffer() {
2385 if (!own_buffer_) FATAL("external code buffer is too small"); 2411 if (!own_buffer_) FATAL("external code buffer is too small");
2386 2412
2387 // Compute new buffer size. 2413 // Compute new buffer size.
2388 CodeDesc desc; // The new buffer. 2414 CodeDesc desc; // The new buffer.
2389 if (buffer_size_ < 1 * MB) { 2415 if (buffer_size_ < 1 * MB) {
(...skipping 20 matching lines...) Expand all
2410 DeleteArray(buffer_); 2436 DeleteArray(buffer_);
2411 buffer_ = desc.buffer; 2437 buffer_ = desc.buffer;
2412 buffer_size_ = desc.buffer_size; 2438 buffer_size_ = desc.buffer_size;
2413 pc_ += pc_delta; 2439 pc_ += pc_delta;
2414 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2440 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2415 reloc_info_writer.last_pc() + pc_delta); 2441 reloc_info_writer.last_pc() + pc_delta);
2416 2442
2417 // Relocate runtime entries. 2443 // Relocate runtime entries.
2418 for (RelocIterator it(desc); !it.done(); it.next()) { 2444 for (RelocIterator it(desc); !it.done(); it.next()) {
2419 RelocInfo::Mode rmode = it.rinfo()->rmode(); 2445 RelocInfo::Mode rmode = it.rinfo()->rmode();
2420 if (rmode == RelocInfo::INTERNAL_REFERENCE) { 2446 if (rmode == RelocInfo::INTERNAL_REFERENCE_ENCODED ||
2447 rmode == RelocInfo::INTERNAL_REFERENCE) {
2421 byte* p = reinterpret_cast<byte*>(it.rinfo()->pc()); 2448 byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
2422 RelocateInternalReference(p, pc_delta); 2449 RelocateInternalReference(rmode, p, pc_delta);
2423 } 2450 }
2424 } 2451 }
2425
2426 DCHECK(!overflow()); 2452 DCHECK(!overflow());
2427 } 2453 }
2428 2454
2429 2455
2430 void Assembler::db(uint8_t data) { 2456 void Assembler::db(uint8_t data) {
2431 CheckBuffer(); 2457 CheckBuffer();
2432 *reinterpret_cast<uint8_t*>(pc_) = data; 2458 *reinterpret_cast<uint8_t*>(pc_) = data;
2433 pc_ += sizeof(uint8_t); 2459 pc_ += sizeof(uint8_t);
2434 } 2460 }
2435 2461
2436 2462
2437 void Assembler::dd(uint32_t data) { 2463 void Assembler::dd(uint32_t data) {
2438 CheckBuffer(); 2464 CheckBuffer();
2439 *reinterpret_cast<uint32_t*>(pc_) = data; 2465 *reinterpret_cast<uint32_t*>(pc_) = data;
2440 pc_ += sizeof(uint32_t); 2466 pc_ += sizeof(uint32_t);
2441 } 2467 }
2442 2468
2443 2469
2444 void Assembler::dd(Label* label) { 2470 void Assembler::dd(Label* label) {
2445 CheckBuffer(); 2471 CheckBuffer();
2446 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 2472 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2447 if (label->is_bound()) { 2473 if (label->is_bound()) {
2448 uint32_t data = reinterpret_cast<uint32_t>(buffer_ + label->pos()); 2474 uint32_t data = reinterpret_cast<uint32_t>(buffer_ + label->pos());
2449 *reinterpret_cast<uint32_t*>(pc_) = data; 2475 *reinterpret_cast<uint32_t*>(pc_) = data;
2450 pc_ += sizeof(uint32_t); 2476 pc_ += sizeof(uint32_t);
2451 } else { 2477 } else {
2452 int target_pos; 2478 uint32_t target_pos = jump_address(label);
2453 if (label->is_linked()) { 2479 emit(target_pos);
2454 // Point to previous instruction that uses the link. 2480 internal_reference_positions_.insert(label->pos());
2455 target_pos = label->pos();
2456 } else {
2457 // First entry of the link chain points to itself.
2458 target_pos = pc_offset();
2459 }
2460 label->link_to(pc_offset());
2461 // Encode internal reference to unbound label. We set the least significant
2462 // bit to distinguish unbound internal references in GrowBuffer() below.
2463 int diff = target_pos - pc_offset();
2464 DCHECK_EQ(0, diff & 3);
2465 int imm26 = diff >> 2;
2466 DCHECK(is_int26(imm26));
2467 // Emit special LABEL instruction.
2468 emit(LABEL | (imm26 & kImm26Mask));
2469 } 2481 }
2470 } 2482 }
2471 2483
2472 2484
2473 void Assembler::emit_code_stub_address(Code* stub) { 2485 void Assembler::emit_code_stub_address(Code* stub) {
2474 CheckBuffer(); 2486 CheckBuffer();
2475 *reinterpret_cast<uint32_t*>(pc_) = 2487 *reinterpret_cast<uint32_t*>(pc_) =
2476 reinterpret_cast<uint32_t>(stub->instruction_start()); 2488 reinterpret_cast<uint32_t>(stub->instruction_start());
2477 pc_ += sizeof(uint32_t); 2489 pc_ += sizeof(uint32_t);
2478 } 2490 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2543 nop(); 2555 nop();
2544 2556
2545 int pool_start = pc_offset(); 2557 int pool_start = pc_offset();
2546 for (int i = 0; i < unbound_labels_count_; i++) { 2558 for (int i = 0; i < unbound_labels_count_; i++) {
2547 uint32_t imm32; 2559 uint32_t imm32;
2548 imm32 = jump_address(&after_pool); 2560 imm32 = jump_address(&after_pool);
2549 { BlockGrowBufferScope block_buf_growth(this); 2561 { BlockGrowBufferScope block_buf_growth(this);
2550 // Buffer growth (and relocation) must be blocked for internal 2562 // Buffer growth (and relocation) must be blocked for internal
2551 // references until associated instructions are emitted and available 2563 // references until associated instructions are emitted and available
2552 // to be patched. 2564 // to be patched.
2553 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 2565 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
2554 lui(at, (imm32 & kHiMask) >> kLuiShift); 2566 lui(at, (imm32 & kHiMask) >> kLuiShift);
2555 ori(at, at, (imm32 & kImm16Mask)); 2567 ori(at, at, (imm32 & kImm16Mask));
2556 } 2568 }
2557 jr(at); 2569 jr(at);
2558 nop(); 2570 nop();
2559 } 2571 }
2560 bind(&after_pool); 2572 bind(&after_pool);
2561 trampoline_ = Trampoline(pool_start, unbound_labels_count_); 2573 trampoline_ = Trampoline(pool_start, unbound_labels_count_);
2562 2574
2563 trampoline_emitted_ = true; 2575 trampoline_emitted_ = true;
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2761 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 2773 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2762 // No out-of-line constant pool support. 2774 // No out-of-line constant pool support.
2763 DCHECK(!FLAG_enable_ool_constant_pool); 2775 DCHECK(!FLAG_enable_ool_constant_pool);
2764 return; 2776 return;
2765 } 2777 }
2766 2778
2767 2779
2768 } } // namespace v8::internal 2780 } } // namespace v8::internal
2769 2781
2770 #endif // V8_TARGET_ARCH_MIPS 2782 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/assembler-mips.h ('k') | src/mips/assembler-mips-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698