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 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 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 if ((instr & ~kImm16Mask) == 0) { | 656 if ((instr & ~kImm16Mask) == 0) { |
657 // Emitted label constant, not part of a branch. | 657 // Emitted label constant, not part of a branch. |
658 if (instr == 0) { | 658 if (instr == 0) { |
659 return kEndOfChain; | 659 return kEndOfChain; |
660 } else { | 660 } else { |
661 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; | 661 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; |
662 return (imm18 + pos); | 662 return (imm18 + pos); |
663 } | 663 } |
664 } | 664 } |
665 // Check we have a branch or jump instruction. | 665 // Check we have a branch or jump instruction. |
666 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); | 666 DCHECK(IsBranch(instr) || IsLui(instr)); |
667 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming | 667 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming |
668 // the compiler uses arithmectic shifts for signed integers. | 668 // the compiler uses arithmectic shifts for signed integers. |
669 if (IsBranch(instr)) { | 669 if (IsBranch(instr)) { |
670 int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; | 670 int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; |
671 | 671 |
672 if (imm18 == kEndOfChain) { | 672 if (imm18 == kEndOfChain) { |
673 // EndOfChain sentinel is returned directly, not relative to pc or pos. | 673 // EndOfChain sentinel is returned directly, not relative to pc or pos. |
674 return kEndOfChain; | 674 return kEndOfChain; |
675 } else { | 675 } else { |
676 return pos + kBranchPCOffset + imm18; | 676 return pos + kBranchPCOffset + imm18; |
677 } | 677 } |
678 } else if (IsLui(instr)) { | 678 } else if (IsLui(instr)) { |
679 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); | 679 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); |
680 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); | 680 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); |
681 DCHECK(IsOri(instr_ori)); | 681 DCHECK(IsOri(instr_ori)); |
682 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; | 682 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; |
683 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); | 683 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); |
684 | 684 |
685 if (imm == kEndOfJumpChain) { | 685 if (imm == kEndOfJumpChain) { |
686 // EndOfChain sentinel is returned directly, not relative to pc or pos. | 686 // EndOfChain sentinel is returned directly, not relative to pc or pos. |
687 return kEndOfChain; | 687 return kEndOfChain; |
688 } else { | 688 } else { |
689 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); | 689 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); |
690 int32_t delta = instr_address - imm; | 690 int32_t delta = instr_address - imm; |
691 DCHECK(pos > delta); | 691 DCHECK(pos > delta); |
692 return pos - delta; | 692 return pos - delta; |
693 } | 693 } |
694 } else { | 694 } else { |
695 int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; | 695 UNREACHABLE(); |
696 if (imm28 == kEndOfJumpChain) { | 696 return 0; |
697 // EndOfChain sentinel is returned directly, not relative to pc or pos. | |
698 return kEndOfChain; | |
699 } else { | |
700 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); | |
701 instr_address &= kImm28Mask; | |
702 int delta = static_cast<int>(instr_address - imm28); | |
703 DCHECK(pos > delta); | |
704 return pos - delta; | |
705 } | |
706 } | 697 } |
707 } | 698 } |
708 | 699 |
709 | 700 |
710 void Assembler::target_at_put(int32_t pos, int32_t target_pos, | 701 void Assembler::target_at_put(int32_t pos, int32_t target_pos, |
711 bool is_internal) { | 702 bool is_internal) { |
712 Instr instr = instr_at(pos); | 703 Instr instr = instr_at(pos); |
713 | 704 |
714 if (is_internal) { | 705 if (is_internal) { |
715 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 706 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
716 instr_at_put(pos, imm); | 707 instr_at_put(pos, imm); |
717 return; | 708 return; |
718 } | 709 } |
719 if ((instr & ~kImm16Mask) == 0) { | 710 if ((instr & ~kImm16Mask) == 0) { |
720 DCHECK(target_pos == kEndOfChain || target_pos >= 0); | 711 DCHECK(target_pos == kEndOfChain || target_pos >= 0); |
721 // Emitted label constant, not part of a branch. | 712 // Emitted label constant, not part of a branch. |
722 // Make label relative to Code* of generated Code object. | 713 // Make label relative to Code* of generated Code object. |
723 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); | 714 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); |
724 return; | 715 return; |
725 } | 716 } |
726 | 717 |
727 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); | 718 DCHECK(IsBranch(instr) || IsLui(instr)); |
728 if (IsBranch(instr)) { | 719 if (IsBranch(instr)) { |
729 int32_t imm18 = target_pos - (pos + kBranchPCOffset); | 720 int32_t imm18 = target_pos - (pos + kBranchPCOffset); |
730 DCHECK((imm18 & 3) == 0); | 721 DCHECK((imm18 & 3) == 0); |
731 | 722 |
732 instr &= ~kImm16Mask; | 723 instr &= ~kImm16Mask; |
733 int32_t imm16 = imm18 >> 2; | 724 int32_t imm16 = imm18 >> 2; |
734 DCHECK(is_int16(imm16)); | 725 DCHECK(is_int16(imm16)); |
735 | 726 |
736 instr_at_put(pos, instr | (imm16 & kImm16Mask)); | 727 instr_at_put(pos, instr | (imm16 & kImm16Mask)); |
737 } else if (IsLui(instr)) { | 728 } else if (IsLui(instr)) { |
738 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); | 729 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); |
739 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); | 730 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); |
740 DCHECK(IsOri(instr_ori)); | 731 DCHECK(IsOri(instr_ori)); |
741 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 732 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
742 DCHECK((imm & 3) == 0); | 733 DCHECK((imm & 3) == 0); |
743 | 734 |
744 instr_lui &= ~kImm16Mask; | 735 instr_lui &= ~kImm16Mask; |
745 instr_ori &= ~kImm16Mask; | 736 instr_ori &= ~kImm16Mask; |
746 | 737 |
747 instr_at_put(pos + 0 * Assembler::kInstrSize, | 738 instr_at_put(pos + 0 * Assembler::kInstrSize, |
748 instr_lui | ((imm & kHiMask) >> kLuiShift)); | 739 instr_lui | ((imm & kHiMask) >> kLuiShift)); |
749 instr_at_put(pos + 1 * Assembler::kInstrSize, | 740 instr_at_put(pos + 1 * Assembler::kInstrSize, |
750 instr_ori | (imm & kImm16Mask)); | 741 instr_ori | (imm & kImm16Mask)); |
751 } else { | 742 } else { |
752 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 743 UNREACHABLE(); |
753 imm28 &= kImm28Mask; | |
754 DCHECK((imm28 & 3) == 0); | |
755 | |
756 instr &= ~kImm26Mask; | |
757 uint32_t imm26 = imm28 >> 2; | |
758 DCHECK(is_uint26(imm26)); | |
759 | |
760 instr_at_put(pos, instr | (imm26 & kImm26Mask)); | |
761 } | 744 } |
762 } | 745 } |
763 | 746 |
764 | 747 |
765 void Assembler::print(Label* L) { | 748 void Assembler::print(Label* L) { |
766 if (L->is_unused()) { | 749 if (L->is_unused()) { |
767 PrintF("unused label\n"); | 750 PrintF("unused label\n"); |
768 } else if (L->is_bound()) { | 751 } else if (L->is_bound()) { |
769 PrintF("bound label to %d\n", L->pos()); | 752 PrintF("bound label to %d\n", L->pos()); |
770 } else if (L->is_linked()) { | 753 } else if (L->is_linked()) { |
(...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2411 DCHECK((imm & 3) == 0); | 2394 DCHECK((imm & 3) == 0); |
2412 | 2395 |
2413 instr_lui &= ~kImm16Mask; | 2396 instr_lui &= ~kImm16Mask; |
2414 instr_ori &= ~kImm16Mask; | 2397 instr_ori &= ~kImm16Mask; |
2415 | 2398 |
2416 instr_at_put(pc + 0 * Assembler::kInstrSize, | 2399 instr_at_put(pc + 0 * Assembler::kInstrSize, |
2417 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); | 2400 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); |
2418 instr_at_put(pc + 1 * Assembler::kInstrSize, | 2401 instr_at_put(pc + 1 * Assembler::kInstrSize, |
2419 instr_ori | (imm & kImm16Mask)); | 2402 instr_ori | (imm & kImm16Mask)); |
2420 return 2; // Number of instructions patched. | 2403 return 2; // Number of instructions patched. |
2421 } else if (IsJ(instr)) { | |
2422 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; | |
2423 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) { | |
2424 return 0; // Number of instructions patched. | |
2425 } | |
2426 imm28 += pc_delta; | |
2427 imm28 &= kImm28Mask; | |
2428 DCHECK((imm28 & 3) == 0); | |
2429 | |
2430 instr &= ~kImm26Mask; | |
2431 uint32_t imm26 = imm28 >> 2; | |
2432 DCHECK(is_uint26(imm26)); | |
2433 | |
2434 instr_at_put(pc, instr | (imm26 & kImm26Mask)); | |
2435 return 1; // Number of instructions patched. | |
2436 } else { | 2404 } else { |
2437 UNREACHABLE(); | 2405 UNREACHABLE(); |
2438 return 0; | 2406 return 0; |
2439 } | 2407 } |
2440 } | 2408 } |
2441 } | 2409 } |
2442 | 2410 |
2443 | 2411 |
2444 void Assembler::GrowBuffer() { | 2412 void Assembler::GrowBuffer() { |
2445 if (!own_buffer_) FATAL("external code buffer is too small"); | 2413 if (!own_buffer_) FATAL("external code buffer is too small"); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2752 } | 2720 } |
2753 patched_jump = true; | 2721 patched_jump = true; |
2754 } | 2722 } |
2755 | 2723 |
2756 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 2724 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
2757 CpuFeatures::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t)); | 2725 CpuFeatures::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t)); |
2758 } | 2726 } |
2759 } | 2727 } |
2760 | 2728 |
2761 | 2729 |
2762 void Assembler::JumpLabelToJumpRegister(Address pc) { | 2730 void Assembler::JumpToJumpRegister(Address pc) { |
2763 // Address pc points to lui/ori instructions. | 2731 // Address pc points to lui/ori instructions. |
2764 // Jump to label may follow at pc + 2 * kInstrSize. | 2732 // Jump to label may follow at pc + 2 * kInstrSize. |
2765 uint32_t* p = reinterpret_cast<uint32_t*>(pc); | 2733 uint32_t* p = reinterpret_cast<uint32_t*>(pc); |
2766 #ifdef DEBUG | 2734 #ifdef DEBUG |
2767 Instr instr1 = instr_at(pc); | 2735 Instr instr1 = instr_at(pc); |
2768 #endif | 2736 #endif |
2769 Instr instr2 = instr_at(pc + 1 * kInstrSize); | 2737 Instr instr2 = instr_at(pc + 1 * kInstrSize); |
2770 Instr instr3 = instr_at(pc + 2 * kInstrSize); | 2738 Instr instr3 = instr_at(pc + 2 * kInstrSize); |
2771 bool patched = false; | 2739 bool patched = false; |
2772 | 2740 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2807 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { | 2775 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { |
2808 // No out-of-line constant pool support. | 2776 // No out-of-line constant pool support. |
2809 DCHECK(!FLAG_enable_ool_constant_pool); | 2777 DCHECK(!FLAG_enable_ool_constant_pool); |
2810 return; | 2778 return; |
2811 } | 2779 } |
2812 | 2780 |
2813 | 2781 |
2814 } } // namespace v8::internal | 2782 } } // namespace v8::internal |
2815 | 2783 |
2816 #endif // V8_TARGET_ARCH_MIPS | 2784 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |