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 UNIMPLEMENTED(); | |
regis
2013/03/22 19:51:16
Why not UnimplementedInstruction(instr)?
zra
2013/03/22 20:16:01
Ah right. Thanks. I missed this one.
| |
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 |