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 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 } | 983 } |
984 default: { | 984 default: { |
985 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits()); | 985 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits()); |
986 UnimplementedInstruction(instr); | 986 UnimplementedInstruction(instr); |
987 break; | 987 break; |
988 } | 988 } |
989 } | 989 } |
990 } | 990 } |
991 | 991 |
992 | 992 |
| 993 void Simulator::DoBranch(Instr* instr, bool taken, bool likely) { |
| 994 ASSERT(!delay_slot_); |
| 995 int32_t imm_val = instr->SImmField() << 2; |
| 996 |
| 997 uword next_pc; |
| 998 if (taken) { |
| 999 next_pc = pc_ + imm_val; |
| 1000 if (likely) { |
| 1001 ExecuteDelaySlot(); |
| 1002 } |
| 1003 } else { |
| 1004 next_pc = pc_ + (2 * Instr::kInstrSize); // Next after delay slot. |
| 1005 } |
| 1006 if (!likely) { |
| 1007 ExecuteDelaySlot(); |
| 1008 } |
| 1009 pc_ = next_pc - Instr::kInstrSize; |
| 1010 |
| 1011 return; |
| 1012 } |
| 1013 |
| 1014 |
| 1015 void Simulator::DecodeRegImm(Instr* instr) { |
| 1016 ASSERT(instr->OpcodeField() == REGIMM); |
| 1017 switch (instr->RegImmFnField()) { |
| 1018 case BGEZ: { |
| 1019 // Format(instr, "bgez 'rs, 'dest"); |
| 1020 int32_t rs_val = get_register(instr->RsField()); |
| 1021 DoBranch(instr, rs_val >= 0, false); |
| 1022 break; |
| 1023 } |
| 1024 case BGEZL: { |
| 1025 // Format(instr, "bgezl 'rs, 'dest"); |
| 1026 int32_t rs_val = get_register(instr->RsField()); |
| 1027 DoBranch(instr, rs_val >= 0, true); |
| 1028 break; |
| 1029 } |
| 1030 case BLTZ: { |
| 1031 // Format(instr, "bltz 'rs, 'dest"); |
| 1032 int32_t rs_val = get_register(instr->RsField()); |
| 1033 DoBranch(instr, rs_val < 0, false); |
| 1034 break; |
| 1035 } |
| 1036 case BLTZL: { |
| 1037 // Format(instr, "bltzl 'rs, 'dest"); |
| 1038 int32_t rs_val = get_register(instr->RsField()); |
| 1039 DoBranch(instr, rs_val < 0, true); |
| 1040 break; |
| 1041 } |
| 1042 default: { |
| 1043 OS::PrintErr("DecodeRegImm: 0x%x\n", instr->InstructionBits()); |
| 1044 UnimplementedInstruction(instr); |
| 1045 break; |
| 1046 } |
| 1047 } |
| 1048 } |
| 1049 |
| 1050 |
993 void Simulator::InstructionDecode(Instr* instr) { | 1051 void Simulator::InstructionDecode(Instr* instr) { |
994 switch (instr->OpcodeField()) { | 1052 switch (instr->OpcodeField()) { |
995 case SPECIAL: { | 1053 case SPECIAL: { |
996 DecodeSpecial(instr); | 1054 DecodeSpecial(instr); |
997 break; | 1055 break; |
998 } | 1056 } |
999 case SPECIAL2: { | 1057 case SPECIAL2: { |
1000 DecodeSpecial2(instr); | 1058 DecodeSpecial2(instr); |
1001 break; | 1059 break; |
1002 } | 1060 } |
| 1061 case REGIMM: { |
| 1062 DecodeRegImm(instr); |
| 1063 break; |
| 1064 } |
1003 case ADDIU: { | 1065 case ADDIU: { |
1004 // Format(instr, "addiu 'rt, 'rs, 'imms"); | 1066 // Format(instr, "addiu 'rt, 'rs, 'imms"); |
1005 int32_t rs_val = get_register(instr->RsField()); | 1067 int32_t rs_val = get_register(instr->RsField()); |
1006 int32_t imm_val = instr->SImmField(); | 1068 int32_t imm_val = instr->SImmField(); |
1007 int32_t res = rs_val + imm_val; | 1069 int32_t res = rs_val + imm_val; |
1008 // Rt is set even on overflow. | 1070 // Rt is set even on overflow. |
1009 set_register(instr->RtField(), res); | 1071 set_register(instr->RtField(), res); |
1010 break; | 1072 break; |
1011 } | 1073 } |
1012 case ANDI: { | 1074 case ANDI: { |
1013 // Format(instr, "andi 'rt, 'rs, 'immu"); | 1075 // Format(instr, "andi 'rt, 'rs, 'immu"); |
1014 int32_t rs_val = get_register(instr->RsField()); | 1076 int32_t rs_val = get_register(instr->RsField()); |
1015 set_register(instr->RtField(), rs_val & instr->UImmField()); | 1077 set_register(instr->RtField(), rs_val & instr->UImmField()); |
1016 break; | 1078 break; |
1017 } | 1079 } |
| 1080 case BEQ: { |
| 1081 // Format(instr, "beq 'rs, 'rt, 'dest"); |
| 1082 int32_t rs_val = get_register(instr->RsField()); |
| 1083 int32_t rt_val = get_register(instr->RtField()); |
| 1084 DoBranch(instr, rs_val == rt_val, false); |
| 1085 break; |
| 1086 } |
| 1087 case BEQL: { |
| 1088 // Format(instr, "beql 'rs, 'rt, 'dest"); |
| 1089 int32_t rs_val = get_register(instr->RsField()); |
| 1090 int32_t rt_val = get_register(instr->RtField()); |
| 1091 DoBranch(instr, rs_val == rt_val, true); |
| 1092 break; |
| 1093 } |
| 1094 case BGTZ: { |
| 1095 ASSERT(instr->RtField() == R0); |
| 1096 // Format(instr, "bgtz 'rs, 'dest"); |
| 1097 int32_t rs_val = get_register(instr->RsField()); |
| 1098 DoBranch(instr, rs_val > 0, false); |
| 1099 break; |
| 1100 } |
| 1101 case BGTZL: { |
| 1102 ASSERT(instr->RtField() == R0); |
| 1103 // Format(instr, "bgtzl 'rs, 'dest"); |
| 1104 int32_t rs_val = get_register(instr->RsField()); |
| 1105 DoBranch(instr, rs_val > 0, true); |
| 1106 break; |
| 1107 } |
| 1108 case BLEZ: { |
| 1109 ASSERT(instr->RtField() == R0); |
| 1110 // Format(instr, "blez 'rs, 'dest"); |
| 1111 int32_t rs_val = get_register(instr->RsField()); |
| 1112 DoBranch(instr, rs_val <= 0, false); |
| 1113 break; |
| 1114 } |
| 1115 case BLEZL: { |
| 1116 ASSERT(instr->RtField() == R0); |
| 1117 // Format(instr, "blezl 'rs, 'dest"); |
| 1118 int32_t rs_val = get_register(instr->RsField()); |
| 1119 DoBranch(instr, rs_val <= 0, true); |
| 1120 break; |
| 1121 } |
| 1122 case BNE: { |
| 1123 // Format(instr, "bne 'rs, 'rt, 'dest"); |
| 1124 int32_t rs_val = get_register(instr->RsField()); |
| 1125 int32_t rt_val = get_register(instr->RtField()); |
| 1126 DoBranch(instr, rs_val != rt_val, false); |
| 1127 break; |
| 1128 } |
| 1129 case BNEL: { |
| 1130 // Format(instr, "bnel 'rs, 'rt, 'dest"); |
| 1131 int32_t rs_val = get_register(instr->RsField()); |
| 1132 int32_t rt_val = get_register(instr->RtField()); |
| 1133 DoBranch(instr, rs_val != rt_val, true); |
| 1134 break; |
| 1135 } |
1018 case LB: { | 1136 case LB: { |
1019 // Format(instr, "lb 'rt, 'imms('rs)"); | 1137 // Format(instr, "lb 'rt, 'imms('rs)"); |
1020 int32_t base_val = get_register(instr->RsField()); | 1138 int32_t base_val = get_register(instr->RsField()); |
1021 int32_t imm_val = instr->SImmField(); | 1139 int32_t imm_val = instr->SImmField(); |
1022 uword addr = base_val + imm_val; | 1140 uword addr = base_val + imm_val; |
1023 if (Simulator::IsIllegalAddress(addr)) { | 1141 if (Simulator::IsIllegalAddress(addr)) { |
1024 HandleIllegalAccess(addr, instr); | 1142 HandleIllegalAccess(addr, instr); |
1025 } else { | 1143 } else { |
1026 int32_t res = ReadB(addr); | 1144 int32_t res = ReadB(addr); |
1027 set_register(instr->RtField(), res); | 1145 set_register(instr->RtField(), res); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 // Restore the SP register and return R1:R0. | 1386 // Restore the SP register and return R1:R0. |
1269 set_register(SP, sp_before_call); | 1387 set_register(SP, sp_before_call); |
1270 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); | 1388 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); |
1271 } | 1389 } |
1272 | 1390 |
1273 } // namespace dart | 1391 } // namespace dart |
1274 | 1392 |
1275 #endif // !defined(HOST_ARCH_MIPS) | 1393 #endif // !defined(HOST_ARCH_MIPS) |
1276 | 1394 |
1277 #endif // defined TARGET_ARCH_MIPS | 1395 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |