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 DCHECK(IsAddImmediate(instr)); | 656 DCHECK(IsAddImmediate(instr)); |
657 return ((instr & ~kImm16Mask) | (offset & kImm16Mask)); | 657 return ((instr & ~kImm16Mask) | (offset & kImm16Mask)); |
658 } | 658 } |
659 | 659 |
660 | 660 |
661 bool Assembler::IsAndImmediate(Instr instr) { | 661 bool Assembler::IsAndImmediate(Instr instr) { |
662 return GetOpcodeField(instr) == ANDI; | 662 return GetOpcodeField(instr) == ANDI; |
663 } | 663 } |
664 | 664 |
665 | 665 |
666 int Assembler::target_at(int32_t pos, bool is_internal) { | 666 int Assembler::target_at(int pos, bool is_internal) { |
667 Instr instr = instr_at(pos); | 667 Instr instr = instr_at(pos); |
668 if (is_internal) { | 668 if (is_internal) { |
669 if (instr == 0) { | 669 if (instr == 0) { |
670 return kEndOfChain; | 670 return kEndOfChain; |
671 } else { | 671 } else { |
672 int32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); | 672 int32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); |
673 int32_t delta = instr_address - instr; | 673 int delta = static_cast<int>(instr_address - instr); |
674 DCHECK(pos > delta); | 674 DCHECK(pos > delta); |
675 return pos - delta; | 675 return pos - delta; |
676 } | 676 } |
677 } | 677 } |
678 if ((instr & ~kImm16Mask) == 0) { | 678 if ((instr & ~kImm16Mask) == 0) { |
679 // Emitted label constant, not part of a branch. | 679 // Emitted label constant, not part of a branch. |
680 if (instr == 0) { | 680 if (instr == 0) { |
681 return kEndOfChain; | 681 return kEndOfChain; |
682 } else { | 682 } else { |
683 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; | 683 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; |
684 return (imm18 + pos); | 684 return (imm18 + pos); |
685 } | 685 } |
686 } | 686 } |
| 687 // Check we have a branch or jump instruction. |
| 688 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); |
687 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming | 689 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming |
688 // the compiler uses arithmectic shifts for signed integers. | 690 // the compiler uses arithmectic shifts for signed integers. |
689 if (IsBranch(instr)) { | 691 if (IsBranch(instr)) { |
690 int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; | 692 int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; |
691 | 693 |
692 if (imm18 == kEndOfChain) { | 694 if (imm18 == kEndOfChain) { |
693 // EndOfChain sentinel is returned directly, not relative to pc or pos. | 695 // EndOfChain sentinel is returned directly, not relative to pc or pos. |
694 return kEndOfChain; | 696 return kEndOfChain; |
695 } else { | 697 } else { |
696 return pos + kBranchPCOffset + imm18; | 698 return pos + kBranchPCOffset + imm18; |
697 } | 699 } |
698 } else if (IsLui(instr)) { | 700 } else if (IsLui(instr)) { |
699 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); | 701 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); |
700 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); | 702 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); |
701 DCHECK(IsOri(instr_ori)); | 703 DCHECK(IsOri(instr_ori)); |
702 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; | 704 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; |
703 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); | 705 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); |
704 | 706 |
705 if (imm == kEndOfJumpChain) { | 707 if (imm == kEndOfJumpChain) { |
706 // EndOfChain sentinel is returned directly, not relative to pc or pos. | 708 // EndOfChain sentinel is returned directly, not relative to pc or pos. |
707 return kEndOfChain; | 709 return kEndOfChain; |
708 } else { | 710 } else { |
709 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); | 711 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); |
710 int32_t delta = instr_address - imm; | 712 int32_t delta = instr_address - imm; |
711 DCHECK(pos > delta); | 713 DCHECK(pos > delta); |
712 return pos - delta; | 714 return pos - delta; |
713 } | 715 } |
714 } else if (IsJ(instr)) { | 716 } else { |
715 int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; | 717 int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; |
716 if (imm28 == kEndOfJumpChain) { | 718 if (imm28 == kEndOfJumpChain) { |
717 // EndOfChain sentinel is returned directly, not relative to pc or pos. | 719 // EndOfChain sentinel is returned directly, not relative to pc or pos. |
718 return kEndOfChain; | 720 return kEndOfChain; |
719 } else { | 721 } else { |
720 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); | 722 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); |
721 instr_address &= kImm28Mask; | 723 instr_address &= kImm28Mask; |
722 int32_t delta = instr_address - imm28; | 724 int delta = static_cast<int>(instr_address - imm28); |
723 DCHECK(pos > delta); | 725 DCHECK(pos > delta); |
724 return pos - delta; | 726 return pos - delta; |
725 } | 727 } |
726 } else { | |
727 UNREACHABLE(); | |
728 return 0; | |
729 } | 728 } |
730 } | 729 } |
731 | 730 |
732 | 731 |
733 void Assembler::target_at_put(int32_t pos, int32_t target_pos, | 732 void Assembler::target_at_put(int32_t pos, int32_t target_pos, |
734 bool is_internal) { | 733 bool is_internal) { |
735 Instr instr = instr_at(pos); | 734 Instr instr = instr_at(pos); |
736 | 735 |
737 if (is_internal) { | 736 if (is_internal) { |
738 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 737 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
739 instr_at_put(pos, imm); | 738 instr_at_put(pos, imm); |
740 return; | 739 return; |
741 } | 740 } |
742 if ((instr & ~kImm16Mask) == 0) { | 741 if ((instr & ~kImm16Mask) == 0) { |
743 DCHECK(target_pos == kEndOfChain || target_pos >= 0); | 742 DCHECK(target_pos == kEndOfChain || target_pos >= 0); |
744 // Emitted label constant, not part of a branch. | 743 // Emitted label constant, not part of a branch. |
745 // Make label relative to Code* of generated Code object. | 744 // Make label relative to Code* of generated Code object. |
746 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); | 745 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); |
747 return; | 746 return; |
748 } | 747 } |
749 | 748 |
| 749 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr)); |
750 if (IsBranch(instr)) { | 750 if (IsBranch(instr)) { |
751 int32_t imm18 = target_pos - (pos + kBranchPCOffset); | 751 int32_t imm18 = target_pos - (pos + kBranchPCOffset); |
752 DCHECK((imm18 & 3) == 0); | 752 DCHECK((imm18 & 3) == 0); |
753 | 753 |
754 instr &= ~kImm16Mask; | 754 instr &= ~kImm16Mask; |
755 int32_t imm16 = imm18 >> 2; | 755 int32_t imm16 = imm18 >> 2; |
756 DCHECK(is_int16(imm16)); | 756 DCHECK(is_int16(imm16)); |
757 | 757 |
758 instr_at_put(pos, instr | (imm16 & kImm16Mask)); | 758 instr_at_put(pos, instr | (imm16 & kImm16Mask)); |
759 } else if (IsLui(instr)) { | 759 } else if (IsLui(instr)) { |
760 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); | 760 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); |
761 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); | 761 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); |
762 DCHECK(IsOri(instr_ori)); | 762 DCHECK(IsOri(instr_ori)); |
763 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 763 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
764 DCHECK((imm & 3) == 0); | 764 DCHECK((imm & 3) == 0); |
765 | 765 |
766 instr_lui &= ~kImm16Mask; | 766 instr_lui &= ~kImm16Mask; |
767 instr_ori &= ~kImm16Mask; | 767 instr_ori &= ~kImm16Mask; |
768 | 768 |
769 instr_at_put(pos + 0 * Assembler::kInstrSize, | 769 instr_at_put(pos + 0 * Assembler::kInstrSize, |
770 instr_lui | ((imm & kHiMask) >> kLuiShift)); | 770 instr_lui | ((imm & kHiMask) >> kLuiShift)); |
771 instr_at_put(pos + 1 * Assembler::kInstrSize, | 771 instr_at_put(pos + 1 * Assembler::kInstrSize, |
772 instr_ori | (imm & kImm16Mask)); | 772 instr_ori | (imm & kImm16Mask)); |
773 } else if (IsJ(instr)) { | 773 } else { |
774 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; | 774 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; |
775 imm28 &= kImm28Mask; | 775 imm28 &= kImm28Mask; |
776 DCHECK((imm28 & 3) == 0); | 776 DCHECK((imm28 & 3) == 0); |
777 | 777 |
778 instr &= ~kImm26Mask; | 778 instr &= ~kImm26Mask; |
779 uint32_t imm26 = imm28 >> 2; | 779 uint32_t imm26 = imm28 >> 2; |
780 DCHECK(is_uint26(imm26)); | 780 DCHECK(is_uint26(imm26)); |
781 | 781 |
782 instr_at_put(pos, instr | (imm26 & kImm26Mask)); | 782 instr_at_put(pos, instr | (imm26 & kImm26Mask)); |
783 } else { | |
784 UNREACHABLE(); | |
785 } | 783 } |
786 } | 784 } |
787 | 785 |
788 | 786 |
789 void Assembler::print(Label* L) { | 787 void Assembler::print(Label* L) { |
790 if (L->is_unused()) { | 788 if (L->is_unused()) { |
791 PrintF("unused label\n"); | 789 PrintF("unused label\n"); |
792 } else if (L->is_bound()) { | 790 } else if (L->is_bound()) { |
793 PrintF("bound label to %d\n", L->pos()); | 791 PrintF("bound label to %d\n", L->pos()); |
794 } else if (L->is_linked()) { | 792 } else if (L->is_linked()) { |
(...skipping 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2773 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { | 2771 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { |
2774 // No out-of-line constant pool support. | 2772 // No out-of-line constant pool support. |
2775 DCHECK(!FLAG_enable_ool_constant_pool); | 2773 DCHECK(!FLAG_enable_ool_constant_pool); |
2776 return; | 2774 return; |
2777 } | 2775 } |
2778 | 2776 |
2779 | 2777 |
2780 } } // namespace v8::internal | 2778 } } // namespace v8::internal |
2781 | 2779 |
2782 #endif // V8_TARGET_ARCH_MIPS | 2780 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |