| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_ASSEMBLER_MIPS_H_ | 5 #ifndef VM_ASSEMBLER_MIPS_H_ |
| 6 #define VM_ASSEMBLER_MIPS_H_ | 6 #define VM_ASSEMBLER_MIPS_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_mips.h directly; use assembler.h instead. | 9 #error Do not include assembler_mips.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 } | 731 } |
| 732 | 732 |
| 733 void xor_(Register rd, Register rs, Register rt) { | 733 void xor_(Register rd, Register rs, Register rt) { |
| 734 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); | 734 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); |
| 735 } | 735 } |
| 736 | 736 |
| 737 // Macros in alphabetical order. | 737 // Macros in alphabetical order. |
| 738 | 738 |
| 739 // Addition of rs and rt with the result placed in rd. | 739 // Addition of rs and rt with the result placed in rd. |
| 740 // After, ro < 0 if there was signed overflow, ro >= 0 otherwise. | 740 // After, ro < 0 if there was signed overflow, ro >= 0 otherwise. |
| 741 // rd and ro must not be TMP1. | 741 // rd and ro must not be TMP. |
| 742 // ro must be different from all the other registers. | 742 // ro must be different from all the other registers. |
| 743 // If rd, rs, and rt are the same register, then a scratch register different | 743 // If rd, rs, and rt are the same register, then a scratch register different |
| 744 // from the other registers is needed. | 744 // from the other registers is needed. |
| 745 void AdduDetectOverflow(Register rd, Register rs, Register rt, Register ro, | 745 void AdduDetectOverflow(Register rd, Register rs, Register rt, Register ro, |
| 746 Register scratch = kNoRegister); | 746 Register scratch = kNoRegister); |
| 747 | 747 |
| 748 // ro must be different from rd and rs. | 748 // ro must be different from rd and rs. |
| 749 // rd and ro must not be TMP1. | 749 // rd and ro must not be TMP. |
| 750 // If rd and rs are the same, a scratch register different from the other | 750 // If rd and rs are the same, a scratch register different from the other |
| 751 // registers is needed. | 751 // registers is needed. |
| 752 void AddImmediateDetectOverflow(Register rd, Register rs, int32_t imm, | 752 void AddImmediateDetectOverflow(Register rd, Register rs, int32_t imm, |
| 753 Register ro, Register scratch = kNoRegister) { | 753 Register ro, Register scratch = kNoRegister) { |
| 754 LoadImmediate(rd, imm); | 754 LoadImmediate(rd, imm); |
| 755 AdduDetectOverflow(rd, rs, rd, ro, scratch); | 755 AdduDetectOverflow(rd, rs, rd, ro, scratch); |
| 756 } | 756 } |
| 757 | 757 |
| 758 // Subtraction of rt from rs (rs - rt) with the result placed in rd. | 758 // Subtraction of rt from rs (rs - rt) with the result placed in rd. |
| 759 // After, ro < 0 if there was signed overflow, ro >= 0 otherwise. | 759 // After, ro < 0 if there was signed overflow, ro >= 0 otherwise. |
| 760 // None of rd, rs, rt, or ro may be TMP1. | 760 // None of rd, rs, rt, or ro may be TMP. |
| 761 // ro must be different from the other registers. | 761 // ro must be different from the other registers. |
| 762 void SubuDetectOverflow(Register rd, Register rs, Register rt, Register ro); | 762 void SubuDetectOverflow(Register rd, Register rs, Register rt, Register ro); |
| 763 | 763 |
| 764 // ro must be different from rd and rs. | 764 // ro must be different from rd and rs. |
| 765 // None of rd, rs, rt, or ro may be TMP1. | 765 // None of rd, rs, rt, or ro may be TMP. |
| 766 void SubImmediateDetectOverflow(Register rd, Register rs, int32_t imm, | 766 void SubImmediateDetectOverflow(Register rd, Register rs, int32_t imm, |
| 767 Register ro) { | 767 Register ro) { |
| 768 LoadImmediate(rd, imm); | 768 LoadImmediate(rd, imm); |
| 769 SubuDetectOverflow(rd, rs, rd, ro); | 769 SubuDetectOverflow(rd, rs, rd, ro); |
| 770 } | 770 } |
| 771 | 771 |
| 772 void Branch(const ExternalLabel* label) { | 772 void Branch(const ExternalLabel* label) { |
| 773 LoadImmediate(TMP1, label->address()); | 773 LoadImmediate(TMP, label->address()); |
| 774 jr(TMP1); | 774 jr(TMP); |
| 775 } | 775 } |
| 776 | 776 |
| 777 void BranchPatchable(const ExternalLabel* label) { | 777 void BranchPatchable(const ExternalLabel* label) { |
| 778 const uint16_t low = Utils::Low16Bits(label->address()); | 778 const uint16_t low = Utils::Low16Bits(label->address()); |
| 779 const uint16_t high = Utils::High16Bits(label->address()); | 779 const uint16_t high = Utils::High16Bits(label->address()); |
| 780 lui(TMP1, Immediate(high)); | 780 lui(TMP, Immediate(high)); |
| 781 ori(TMP1, TMP1, Immediate(low)); | 781 ori(TMP, TMP, Immediate(low)); |
| 782 jr(TMP1); | 782 jr(TMP); |
| 783 delay_slot_available_ = false; // CodePatcher expects a nop. | 783 delay_slot_available_ = false; // CodePatcher expects a nop. |
| 784 } | 784 } |
| 785 | 785 |
| 786 void BranchLink(const ExternalLabel* label) { | 786 void BranchLink(const ExternalLabel* label) { |
| 787 LoadImmediate(TMP1, label->address()); | 787 LoadImmediate(TMP, label->address()); |
| 788 jalr(TMP1); | 788 jalr(TMP); |
| 789 } | 789 } |
| 790 | 790 |
| 791 void BranchLinkPatchable(const ExternalLabel* label) { | 791 void BranchLinkPatchable(const ExternalLabel* label) { |
| 792 const int32_t offset = | 792 const int32_t offset = |
| 793 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; | 793 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; |
| 794 LoadWordFromPoolOffset(TMP1, offset); | 794 LoadWordFromPoolOffset(TMP, offset); |
| 795 jalr(TMP1); | 795 jalr(TMP); |
| 796 delay_slot_available_ = false; // CodePatcher expects a nop. | 796 delay_slot_available_ = false; // CodePatcher expects a nop. |
| 797 } | 797 } |
| 798 | 798 |
| 799 void Drop(intptr_t stack_elements) { | 799 void Drop(intptr_t stack_elements) { |
| 800 ASSERT(stack_elements >= 0); | 800 ASSERT(stack_elements >= 0); |
| 801 if (stack_elements > 0) { | 801 if (stack_elements > 0) { |
| 802 addiu(SP, SP, Immediate(stack_elements * kWordSize)); | 802 addiu(SP, SP, Immediate(stack_elements * kWordSize)); |
| 803 } | 803 } |
| 804 } | 804 } |
| 805 | 805 |
| 806 void LoadImmediate(Register rd, int32_t value) { | 806 void LoadImmediate(Register rd, int32_t value) { |
| 807 if (Utils::IsInt(kImmBits, value)) { | 807 if (Utils::IsInt(kImmBits, value)) { |
| 808 addiu(rd, ZR, Immediate(value)); | 808 addiu(rd, ZR, Immediate(value)); |
| 809 } else { | 809 } else { |
| 810 const uint16_t low = Utils::Low16Bits(value); | 810 const uint16_t low = Utils::Low16Bits(value); |
| 811 const uint16_t high = Utils::High16Bits(value); | 811 const uint16_t high = Utils::High16Bits(value); |
| 812 lui(rd, Immediate(high)); | 812 lui(rd, Immediate(high)); |
| 813 ori(rd, rd, Immediate(low)); | 813 ori(rd, rd, Immediate(low)); |
| 814 } | 814 } |
| 815 } | 815 } |
| 816 | 816 |
| 817 void LoadImmediate(DRegister rd, double value) { | 817 void LoadImmediate(DRegister rd, double value) { |
| 818 FRegister frd = static_cast<FRegister>(rd * 2); | 818 FRegister frd = static_cast<FRegister>(rd * 2); |
| 819 const int64_t ival = bit_cast<uint64_t, double>(value); | 819 const int64_t ival = bit_cast<uint64_t, double>(value); |
| 820 const int32_t low = Utils::Low32Bits(ival); | 820 const int32_t low = Utils::Low32Bits(ival); |
| 821 const int32_t high = Utils::High32Bits(ival); | 821 const int32_t high = Utils::High32Bits(ival); |
| 822 if (low != 0) { | 822 if (low != 0) { |
| 823 LoadImmediate(TMP1, low); | 823 LoadImmediate(TMP, low); |
| 824 mtc1(TMP1, frd); | 824 mtc1(TMP, frd); |
| 825 } else { | 825 } else { |
| 826 mtc1(ZR, frd); | 826 mtc1(ZR, frd); |
| 827 } | 827 } |
| 828 | 828 |
| 829 if (high != 0) { | 829 if (high != 0) { |
| 830 LoadImmediate(TMP1, high); | 830 LoadImmediate(TMP, high); |
| 831 mtc1(TMP1, static_cast<FRegister>(frd + 1)); | 831 mtc1(TMP, static_cast<FRegister>(frd + 1)); |
| 832 } else { | 832 } else { |
| 833 mtc1(ZR, static_cast<FRegister>(frd + 1)); | 833 mtc1(ZR, static_cast<FRegister>(frd + 1)); |
| 834 } | 834 } |
| 835 } | 835 } |
| 836 | 836 |
| 837 void LoadImmediate(FRegister rd, float value) { | 837 void LoadImmediate(FRegister rd, float value) { |
| 838 const int32_t ival = bit_cast<int32_t, float>(value); | 838 const int32_t ival = bit_cast<int32_t, float>(value); |
| 839 if (ival == 0) { | 839 if (ival == 0) { |
| 840 mtc1(ZR, rd); | 840 mtc1(ZR, rd); |
| 841 } else { | 841 } else { |
| 842 LoadImmediate(TMP1, ival); | 842 LoadImmediate(TMP, ival); |
| 843 mtc1(TMP1, rd); | 843 mtc1(TMP, rd); |
| 844 } | 844 } |
| 845 } | 845 } |
| 846 | 846 |
| 847 void AddImmediate(Register rd, Register rs, int32_t value) { | 847 void AddImmediate(Register rd, Register rs, int32_t value) { |
| 848 if ((value == 0) && (rd == rs)) return; | 848 if ((value == 0) && (rd == rs)) return; |
| 849 // If value is 0, we still want to move rs to rd if they aren't the same. | 849 // If value is 0, we still want to move rs to rd if they aren't the same. |
| 850 if (Utils::IsInt(kImmBits, value)) { | 850 if (Utils::IsInt(kImmBits, value)) { |
| 851 addiu(rd, rs, Immediate(value)); | 851 addiu(rd, rs, Immediate(value)); |
| 852 } else { | 852 } else { |
| 853 LoadImmediate(TMP1, value); | 853 LoadImmediate(TMP, value); |
| 854 addu(rd, rs, TMP1); | 854 addu(rd, rs, TMP); |
| 855 } | 855 } |
| 856 } | 856 } |
| 857 | 857 |
| 858 void AddImmediate(Register rd, int32_t value) { | 858 void AddImmediate(Register rd, int32_t value) { |
| 859 AddImmediate(rd, rd, value); | 859 AddImmediate(rd, rd, value); |
| 860 } | 860 } |
| 861 | 861 |
| 862 void AndImmediate(Register rd, Register rs, int32_t imm) { | 862 void AndImmediate(Register rd, Register rs, int32_t imm) { |
| 863 if (imm == 0) { | 863 if (imm == 0) { |
| 864 mov(rd, ZR); | 864 mov(rd, ZR); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 Register value, | 1275 Register value, |
| 1276 Label* no_update); | 1276 Label* no_update); |
| 1277 | 1277 |
| 1278 DISALLOW_ALLOCATION(); | 1278 DISALLOW_ALLOCATION(); |
| 1279 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1279 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1280 }; | 1280 }; |
| 1281 | 1281 |
| 1282 } // namespace dart | 1282 } // namespace dart |
| 1283 | 1283 |
| 1284 #endif // VM_ASSEMBLER_MIPS_H_ | 1284 #endif // VM_ASSEMBLER_MIPS_H_ |
| OLD | NEW |