| 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 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 // Only build the simulator if not compiling for real MIPS hardware. | 8 // Only build the simulator if not compiling for real MIPS hardware. |
| 9 #if !defined(HOST_ARCH_MIPS) | 9 #if !defined(HOST_ARCH_MIPS) |
| 10 | 10 |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 set_hi_register(0); | 750 set_hi_register(0); |
| 751 set_lo_register(0); | 751 set_lo_register(0); |
| 752 // TODO(zra): Drop into the debugger here. | 752 // TODO(zra): Drop into the debugger here. |
| 753 break; | 753 break; |
| 754 } | 754 } |
| 755 | 755 |
| 756 set_lo_register(rs_val / rt_val); | 756 set_lo_register(rs_val / rt_val); |
| 757 set_hi_register(rs_val % rt_val); | 757 set_hi_register(rs_val % rt_val); |
| 758 break; | 758 break; |
| 759 } | 759 } |
| 760 case JALR: { |
| 761 ASSERT(instr->RtField() == R0); |
| 762 ASSERT(instr->RsField() != instr->RdField()); |
| 763 ASSERT(!delay_slot_); |
| 764 // Format(instr, "jalr'hint 'rd, rs"); |
| 765 uword next_pc = get_register(instr->RsField()); |
| 766 ExecuteDelaySlot(); |
| 767 // Set return address to be the instruction after the delay slot. |
| 768 set_register(instr->RdField(), pc_ + Instr::kInstrSize); |
| 769 pc_ = next_pc - Instr::kInstrSize; // Account for regular PC increment. |
| 770 break; |
| 771 } |
| 772 case JR: { |
| 773 ASSERT(instr->RtField() == R0); |
| 774 ASSERT(instr->RdField() == R0); |
| 775 ASSERT(!delay_slot_); |
| 776 // Format(instr, "jr'hint 'rs"); |
| 777 uword next_pc = get_register(instr->RsField()); |
| 778 ExecuteDelaySlot(); |
| 779 pc_ = next_pc - Instr::kInstrSize; // Account for regular PC increment. |
| 780 break; |
| 781 } |
| 760 case MFHI: { | 782 case MFHI: { |
| 761 ASSERT(instr->RsField() == 0); | 783 ASSERT(instr->RsField() == 0); |
| 762 ASSERT(instr->RtField() == 0); | 784 ASSERT(instr->RtField() == 0); |
| 763 ASSERT(instr->SaField() == 0); | 785 ASSERT(instr->SaField() == 0); |
| 764 // Format(instr, "mfhi 'rd"); | 786 // Format(instr, "mfhi 'rd"); |
| 765 set_register(instr->RdField(), get_hi_register()); | 787 set_register(instr->RdField(), get_hi_register()); |
| 766 break; | 788 break; |
| 767 } | 789 } |
| 768 case MFLO: { | 790 case MFLO: { |
| 769 ASSERT(instr->RsField() == 0); | 791 ASSERT(instr->RsField() == 0); |
| 770 ASSERT(instr->RtField() == 0); | 792 ASSERT(instr->RtField() == 0); |
| 771 ASSERT(instr->SaField() == 0); | 793 ASSERT(instr->SaField() == 0); |
| 772 // Format(instr, "mflo 'rd"); | 794 // Format(instr, "mflo 'rd"); |
| 773 set_register(instr->RdField(), get_lo_register()); | 795 set_register(instr->RdField(), get_lo_register()); |
| 774 break; | 796 break; |
| 775 } | 797 } |
| 798 case MOVN: { |
| 799 ASSERT(instr->SaField() == 0); |
| 800 // Format(instr, "movn 'rd, 'rs, 'rt"); |
| 801 int32_t rt_val = get_register(instr->RtField()); |
| 802 int32_t rs_val = get_register(instr->RsField()); |
| 803 if (rt_val != 0) { |
| 804 set_register(instr->RdField(), rs_val); |
| 805 } |
| 806 break; |
| 807 } |
| 808 case MOVZ: { |
| 809 ASSERT(instr->SaField() == 0); |
| 810 // Format(instr, "movz 'rd, 'rs, 'rt"); |
| 811 int32_t rt_val = get_register(instr->RtField()); |
| 812 int32_t rs_val = get_register(instr->RsField()); |
| 813 if (rt_val == 0) { |
| 814 set_register(instr->RdField(), rs_val); |
| 815 } |
| 816 break; |
| 817 } |
| 818 case MULT: { |
| 819 ASSERT(instr->RdField() == 0); |
| 820 ASSERT(instr->SaField() == 0); |
| 821 // Format(instr, "mult 'rs, 'rt"); |
| 822 int64_t rs = static_cast<int64_t>(get_register(instr->RsField())); |
| 823 int64_t rt = static_cast<int64_t>(get_register(instr->RtField())); |
| 824 int64_t res = rs * rt; |
| 825 set_hi_register(Utils::High32Bits(res)); |
| 826 set_lo_register(Utils::Low32Bits(res)); |
| 827 break; |
| 828 } |
| 829 case MULTU: { |
| 830 ASSERT(instr->RdField() == 0); |
| 831 ASSERT(instr->SaField() == 0); |
| 832 // Format(instr, "multu 'rs, 'rt"); |
| 833 uint64_t rs = static_cast<uint64_t>(get_register(instr->RsField())); |
| 834 uint64_t rt = static_cast<uint64_t>(get_register(instr->RtField())); |
| 835 uint64_t res = rs * rt; |
| 836 set_hi_register(Utils::High32Bits(res)); |
| 837 set_lo_register(Utils::Low32Bits(res)); |
| 838 break; |
| 839 } |
| 840 case NOR: { |
| 841 ASSERT(instr->SaField() == 0); |
| 842 // Format(instr, "nor 'rd, 'rs, 'rt"); |
| 843 int32_t rs_val = get_register(instr->RsField()); |
| 844 int32_t rt_val = get_register(instr->RtField()); |
| 845 set_register(instr->RdField(), ~(rs_val | rt_val)); |
| 846 break; |
| 847 } |
| 848 case OR: { |
| 849 ASSERT(instr->SaField() == 0); |
| 850 // Format(instr, "or 'rd, 'rs, 'rt"); |
| 851 int32_t rs_val = get_register(instr->RsField()); |
| 852 int32_t rt_val = get_register(instr->RtField()); |
| 853 set_register(instr->RdField(), rs_val | rt_val); |
| 854 break; |
| 855 } |
| 776 case SLL: { | 856 case SLL: { |
| 777 ASSERT(instr->RsField() == 0); | 857 ASSERT(instr->RsField() == 0); |
| 778 if ((instr->RdField() == R0) && | 858 if ((instr->RdField() == R0) && |
| 779 (instr->RtField() == R0) && | 859 (instr->RtField() == R0) && |
| 780 (instr->SaField() == 0)) { | 860 (instr->SaField() == 0)) { |
| 781 // Format(instr, "nop"); | 861 // Format(instr, "nop"); |
| 782 // Nothing to be done for NOP. | 862 // Nothing to be done for NOP. |
| 783 } else { | 863 } else { |
| 784 int32_t rt_val = get_register(instr->RtField()); | 864 int32_t rt_val = get_register(instr->RtField()); |
| 785 int sa = instr->SaField(); | 865 int sa = instr->SaField(); |
| 786 set_register(instr->RdField(), rt_val << sa); | 866 set_register(instr->RdField(), rt_val << sa); |
| 787 } | 867 } |
| 788 break; | 868 break; |
| 789 } | 869 } |
| 790 case JR: { | 870 case SLLV: { |
| 791 ASSERT(instr->RtField() == R0); | 871 ASSERT(instr->SaField() == 0); |
| 792 ASSERT(instr->RdField() == R0); | 872 // Format(instr, "sllv 'rd, 'rt, 'rs"); |
| 793 ASSERT(!delay_slot_); | 873 int32_t rt_val = get_register(instr->RtField()); |
| 794 // Format(instr, "jr'hint 'rs"); | 874 int32_t rs_val = get_register(instr->RsField()); |
| 795 uword next_pc = get_register(instr->RsField()); | 875 set_register(instr->RdField(), rt_val << (rs_val & 0x1f)); |
| 796 ExecuteDelaySlot(); | 876 break; |
| 797 pc_ = next_pc - Instr::kInstrSize; // Account for regular PC increment. | 877 } |
| 878 case SLT: { |
| 879 ASSERT(instr->SaField() == 0); |
| 880 // Format(instr, "slt 'rd, 'rs, 'rt"); |
| 881 int32_t rs_val = get_register(instr->RsField()); |
| 882 int32_t rt_val = get_register(instr->RtField()); |
| 883 set_register(instr->RdField(), rs_val < rt_val ? 1 : 0); |
| 884 break; |
| 885 } |
| 886 case SLTU: { |
| 887 ASSERT(instr->SaField() == 0); |
| 888 // Format(instr, "sltu 'rd, 'rs, 'rt"); |
| 889 uint32_t rs_val = static_cast<uint32_t>(get_register(instr->RsField())); |
| 890 uint32_t rt_val = static_cast<uint32_t>(get_register(instr->RtField())); |
| 891 set_register(instr->RdField(), rs_val < rt_val ? 1 : 0); |
| 892 break; |
| 893 } |
| 894 case SRA: { |
| 895 ASSERT(instr->RsField() == 0); |
| 896 // Format(instr, "sra 'rd, 'rt, 'sa"); |
| 897 int32_t rt_val = get_register(instr->RtField()); |
| 898 int32_t sa = instr->SaField(); |
| 899 set_register(instr->RdField(), rt_val >> sa); |
| 900 break; |
| 901 } |
| 902 case SRAV: { |
| 903 ASSERT(instr->SaField() == 0); |
| 904 // Format(instr, "srav 'rd, 'rt, 'rs"); |
| 905 int32_t rt_val = get_register(instr->RtField()); |
| 906 int32_t rs_val = get_register(instr->RsField()); |
| 907 set_register(instr->RdField(), rt_val >> (rs_val & 0x1f)); |
| 908 break; |
| 909 } |
| 910 case SRL: { |
| 911 ASSERT(instr->RsField() == 0); |
| 912 // Format(instr, "srl 'rd, 'rt, 'sa"); |
| 913 uint32_t rt_val = get_register(instr->RtField()); |
| 914 uint32_t sa = instr->SaField(); |
| 915 set_register(instr->RdField(), rt_val >> sa); |
| 916 break; |
| 917 } |
| 918 case SRLV: { |
| 919 ASSERT(instr->SaField() == 0); |
| 920 // Format(instr, "srlv 'rd, 'rt, 'rs"); |
| 921 uint32_t rt_val = get_register(instr->RtField()); |
| 922 uint32_t rs_val = get_register(instr->RsField()); |
| 923 set_register(instr->RdField(), rt_val >> (rs_val & 0x1f)); |
| 924 break; |
| 925 } |
| 926 case SUBU: { |
| 927 ASSERT(instr->SaField() == 0); |
| 928 // Format(instr, "subu 'rd, 'rs, 'rt"); |
| 929 int32_t rs_val = get_register(instr->RsField()); |
| 930 int32_t rt_val = get_register(instr->RtField()); |
| 931 set_register(instr->RdField(), rs_val - rt_val); |
| 932 break; |
| 933 } |
| 934 case XOR: { |
| 935 ASSERT(instr->SaField() == 0); |
| 936 // Format(instr, "xor 'rd, 'rs, 'rt"); |
| 937 int32_t rs_val = get_register(instr->RsField()); |
| 938 int32_t rt_val = get_register(instr->RtField()); |
| 939 set_register(instr->RdField(), rs_val ^ rt_val); |
| 798 break; | 940 break; |
| 799 } | 941 } |
| 800 default: { | 942 default: { |
| 801 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits()); | 943 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits()); |
| 802 UNIMPLEMENTED(); | 944 UNIMPLEMENTED(); |
| 803 break; | 945 break; |
| 804 } | 946 } |
| 805 } | 947 } |
| 806 } | 948 } |
| 807 | 949 |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 // Restore the SP register and return R1:R0. | 1258 // Restore the SP register and return R1:R0. |
| 1117 set_register(SP, sp_before_call); | 1259 set_register(SP, sp_before_call); |
| 1118 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); | 1260 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); |
| 1119 } | 1261 } |
| 1120 | 1262 |
| 1121 } // namespace dart | 1263 } // namespace dart |
| 1122 | 1264 |
| 1123 #endif // !defined(HOST_ARCH_MIPS) | 1265 #endif // !defined(HOST_ARCH_MIPS) |
| 1124 | 1266 |
| 1125 #endif // defined TARGET_ARCH_MIPS | 1267 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |