| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdarg.h> | 5 #include <stdarg.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 #define SScanF sscanf // NOLINT | 30 #define SScanF sscanf // NOLINT |
| 31 | 31 |
| 32 // The PPCDebugger class is used by the simulator while debugging simulated | 32 // The PPCDebugger class is used by the simulator while debugging simulated |
| 33 // PowerPC code. | 33 // PowerPC code. |
| 34 class PPCDebugger { | 34 class PPCDebugger { |
| 35 public: | 35 public: |
| 36 explicit PPCDebugger(Simulator* sim) : sim_(sim) {} | 36 explicit PPCDebugger(Simulator* sim) : sim_(sim) {} |
| 37 ~PPCDebugger(); | 37 ~PPCDebugger(); |
| 38 | 38 |
| 39 void Stop(Instruction* instr); | 39 void Stop(Instruction* instr); |
| 40 void Info(Instruction* instr); | |
| 41 void Debug(); | 40 void Debug(); |
| 42 | 41 |
| 43 private: | 42 private: |
| 44 static const Instr kBreakpointInstr = (TWI | 0x1f * B21); | 43 static const Instr kBreakpointInstr = (TWI | 0x1f * B21); |
| 45 static const Instr kNopInstr = (ORI); // ori, 0,0,0 | 44 static const Instr kNopInstr = (ORI); // ori, 0,0,0 |
| 46 | 45 |
| 47 Simulator* sim_; | 46 Simulator* sim_; |
| 48 | 47 |
| 49 intptr_t GetRegisterValue(int regnum); | 48 intptr_t GetRegisterValue(int regnum); |
| 50 double GetRegisterPairDoubleValue(int regnum); | 49 double GetRegisterPairDoubleValue(int regnum); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 PrintF("Simulator hit stop %u: %s\n", code, msg); | 124 PrintF("Simulator hit stop %u: %s\n", code, msg); |
| 126 } else { | 125 } else { |
| 127 PrintF("Simulator hit %s\n", msg); | 126 PrintF("Simulator hit %s\n", msg); |
| 128 } | 127 } |
| 129 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize); | 128 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize); |
| 130 Debug(); | 129 Debug(); |
| 131 } | 130 } |
| 132 #endif | 131 #endif |
| 133 | 132 |
| 134 | 133 |
| 135 void PPCDebugger::Info(Instruction* instr) { | |
| 136 // Retrieve the encoded address immediately following the Info breakpoint. | |
| 137 char* msg = | |
| 138 *reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize); | |
| 139 PrintF("Simulator info %s\n", msg); | |
| 140 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize); | |
| 141 } | |
| 142 | |
| 143 | |
| 144 intptr_t PPCDebugger::GetRegisterValue(int regnum) { | 134 intptr_t PPCDebugger::GetRegisterValue(int regnum) { |
| 145 return sim_->get_register(regnum); | 135 return sim_->get_register(regnum); |
| 146 } | 136 } |
| 147 | 137 |
| 148 | 138 |
| 149 double PPCDebugger::GetRegisterPairDoubleValue(int regnum) { | 139 double PPCDebugger::GetRegisterPairDoubleValue(int regnum) { |
| 150 return sim_->get_double_from_register_pair(regnum); | 140 return sim_->get_double_from_register_pair(regnum); |
| 151 } | 141 } |
| 152 | 142 |
| 153 | 143 |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 // - one double argument and zero or one integer arguments. | 972 // - one double argument and zero or one integer arguments. |
| 983 // All are consructed here from d1, d2 and r3. | 973 // All are consructed here from d1, d2 and r3. |
| 984 void Simulator::GetFpArgs(double* x, double* y, intptr_t* z) { | 974 void Simulator::GetFpArgs(double* x, double* y, intptr_t* z) { |
| 985 *x = get_double_from_d_register(1); | 975 *x = get_double_from_d_register(1); |
| 986 *y = get_double_from_d_register(2); | 976 *y = get_double_from_d_register(2); |
| 987 *z = get_register(3); | 977 *z = get_register(3); |
| 988 } | 978 } |
| 989 | 979 |
| 990 | 980 |
| 991 // The return value is in d1. | 981 // The return value is in d1. |
| 992 void Simulator::SetFpResult(const double& result) { fp_registers_[1] = result; } | 982 void Simulator::SetFpResult(const double& result) { |
| 983 set_d_register_from_double(1, result); |
| 984 } |
| 993 | 985 |
| 994 | 986 |
| 995 void Simulator::TrashCallerSaveRegisters() { | 987 void Simulator::TrashCallerSaveRegisters() { |
| 996 // We don't trash the registers with the return value. | 988 // We don't trash the registers with the return value. |
| 997 #if 0 // A good idea to trash volatile registers, needs to be done | 989 #if 0 // A good idea to trash volatile registers, needs to be done |
| 998 registers_[2] = 0x50Bad4U; | 990 registers_[2] = 0x50Bad4U; |
| 999 registers_[3] = 0x50Bad4U; | 991 registers_[3] = 0x50Bad4U; |
| 1000 registers_[12] = 0x50Bad4U; | 992 registers_[12] = 0x50Bad4U; |
| 1001 #endif | 993 #endif |
| 1002 } | 994 } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1141 // operands have different signs | 1133 // operands have different signs |
| 1142 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) | 1134 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) |
| 1143 // and first operand and result have different signs | 1135 // and first operand and result have different signs |
| 1144 && | 1136 && |
| 1145 ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); | 1137 ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
| 1146 } | 1138 } |
| 1147 return overflow; | 1139 return overflow; |
| 1148 } | 1140 } |
| 1149 | 1141 |
| 1150 | 1142 |
| 1151 #if !V8_TARGET_ARCH_PPC64 | 1143 #if V8_TARGET_ARCH_PPC64 |
| 1152 // Calls into the V8 runtime are based on this very simple interface. | |
| 1153 // Note: To be able to return two values from some calls the code in runtime.cc | |
| 1154 // uses the ObjectPair which is essentially two 32-bit values stuffed into a | |
| 1155 // 64-bit value. With the code below we assume that all runtime calls return | |
| 1156 // 64 bits of result. If they don't, the r4 result register contains a bogus | |
| 1157 // value, which is fine because it is caller-saved. | |
| 1158 typedef int64_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, | |
| 1159 intptr_t arg2, intptr_t arg3, | |
| 1160 intptr_t arg4, intptr_t arg5); | |
| 1161 #else | |
| 1162 // For 64-bit, we need to be more explicit. | |
| 1163 typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, | |
| 1164 intptr_t arg2, intptr_t arg3, | |
| 1165 intptr_t arg4, intptr_t arg5); | |
| 1166 struct ObjectPair { | 1144 struct ObjectPair { |
| 1167 intptr_t x; | 1145 intptr_t x; |
| 1168 intptr_t y; | 1146 intptr_t y; |
| 1169 }; | 1147 }; |
| 1170 | 1148 |
| 1171 typedef struct ObjectPair (*SimulatorRuntimeObjectPairCall)( | 1149 |
| 1172 intptr_t arg0, intptr_t arg1, intptr_t arg2, intptr_t arg3, intptr_t arg4, | 1150 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { |
| 1173 intptr_t arg5); | 1151 *x = pair->x; |
| 1152 *y = pair->y; |
| 1153 } |
| 1154 #else |
| 1155 typedef uint64_t ObjectPair; |
| 1156 |
| 1157 |
| 1158 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { |
| 1159 #if V8_TARGET_BIG_ENDIAN |
| 1160 *x = static_cast<int32_t>(*pair >> 32); |
| 1161 *y = static_cast<int32_t>(*pair); |
| 1162 #else |
| 1163 *x = static_cast<int32_t>(*pair); |
| 1164 *y = static_cast<int32_t>(*pair >> 32); |
| 1174 #endif | 1165 #endif |
| 1166 } |
| 1167 #endif |
| 1168 |
| 1169 // Calls into the V8 runtime are based on this very simple interface. |
| 1170 // Note: To be able to return two values from some calls the code in |
| 1171 // runtime.cc uses the ObjectPair which is essentially two pointer |
| 1172 // values stuffed into a structure. With the code below we assume that |
| 1173 // all runtime calls return this pair. If they don't, the r4 result |
| 1174 // register contains a bogus value, which is fine because it is |
| 1175 // caller-saved. |
| 1176 typedef ObjectPair (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, |
| 1177 intptr_t arg2, intptr_t arg3, |
| 1178 intptr_t arg4, intptr_t arg5); |
| 1175 | 1179 |
| 1176 // These prototypes handle the four types of FP calls. | 1180 // These prototypes handle the four types of FP calls. |
| 1177 typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1); | 1181 typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1); |
| 1178 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); | 1182 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); |
| 1179 typedef double (*SimulatorRuntimeFPCall)(double darg0); | 1183 typedef double (*SimulatorRuntimeFPCall)(double darg0); |
| 1180 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0); | 1184 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0); |
| 1181 | 1185 |
| 1182 // This signature supports direct call in to API function native callback | 1186 // This signature supports direct call in to API function native callback |
| 1183 // (refer to InvocationCallback in v8.h). | 1187 // (refer to InvocationCallback in v8.h). |
| 1184 typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0); | 1188 typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1196 switch (svc) { | 1200 switch (svc) { |
| 1197 case kCallRtRedirected: { | 1201 case kCallRtRedirected: { |
| 1198 // Check if stack is aligned. Error if not aligned is reported below to | 1202 // Check if stack is aligned. Error if not aligned is reported below to |
| 1199 // include information on the function called. | 1203 // include information on the function called. |
| 1200 bool stack_aligned = | 1204 bool stack_aligned = |
| 1201 (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) == | 1205 (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) == |
| 1202 0; | 1206 0; |
| 1203 Redirection* redirection = Redirection::FromSwiInstruction(instr); | 1207 Redirection* redirection = Redirection::FromSwiInstruction(instr); |
| 1204 const int kArgCount = 6; | 1208 const int kArgCount = 6; |
| 1205 int arg0_regnum = 3; | 1209 int arg0_regnum = 3; |
| 1206 #if V8_TARGET_ARCH_PPC64 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS | 1210 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS |
| 1207 intptr_t result_buffer = 0; | 1211 intptr_t result_buffer = 0; |
| 1208 if (redirection->type() == ExternalReference::BUILTIN_OBJECTPAIR_CALL) { | 1212 if (redirection->type() == ExternalReference::BUILTIN_OBJECTPAIR_CALL) { |
| 1209 result_buffer = get_register(r3); | 1213 result_buffer = get_register(r3); |
| 1210 arg0_regnum++; | 1214 arg0_regnum++; |
| 1211 } | 1215 } |
| 1212 #endif | 1216 #endif |
| 1213 intptr_t arg[kArgCount]; | 1217 intptr_t arg[kArgCount]; |
| 1214 for (int i = 0; i < kArgCount; i++) { | 1218 for (int i = 0; i < kArgCount; i++) { |
| 1215 arg[i] = get_register(arg0_regnum + i); | 1219 arg[i] = get_register(arg0_regnum + i); |
| 1216 } | 1220 } |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR, | 1393 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR, |
| 1390 FUNCTION_ADDR(target), arg[0], arg[1], arg[2], arg[3], arg[4], | 1394 FUNCTION_ADDR(target), arg[0], arg[1], arg[2], arg[3], arg[4], |
| 1391 arg[5]); | 1395 arg[5]); |
| 1392 if (!stack_aligned) { | 1396 if (!stack_aligned) { |
| 1393 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", | 1397 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", |
| 1394 get_register(sp)); | 1398 get_register(sp)); |
| 1395 } | 1399 } |
| 1396 PrintF("\n"); | 1400 PrintF("\n"); |
| 1397 } | 1401 } |
| 1398 CHECK(stack_aligned); | 1402 CHECK(stack_aligned); |
| 1399 #if !V8_TARGET_ARCH_PPC64 | |
| 1400 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); | 1403 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); |
| 1401 SimulatorRuntimeCall target = | 1404 SimulatorRuntimeCall target = |
| 1402 reinterpret_cast<SimulatorRuntimeCall>(external); | 1405 reinterpret_cast<SimulatorRuntimeCall>(external); |
| 1403 int64_t result = target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); | 1406 ObjectPair result = |
| 1404 int32_t lo_res = static_cast<int32_t>(result); | 1407 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); |
| 1405 int32_t hi_res = static_cast<int32_t>(result >> 32); | 1408 intptr_t x; |
| 1406 #if V8_TARGET_BIG_ENDIAN | 1409 intptr_t y; |
| 1410 decodeObjectPair(&result, &x, &y); |
| 1407 if (::v8::internal::FLAG_trace_sim) { | 1411 if (::v8::internal::FLAG_trace_sim) { |
| 1408 PrintF("Returned %08x\n", hi_res); | 1412 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y); |
| 1409 } | 1413 } |
| 1410 set_register(r3, hi_res); | 1414 set_register(r3, x); |
| 1411 set_register(r4, lo_res); | 1415 set_register(r4, y); |
| 1412 #else | |
| 1413 if (::v8::internal::FLAG_trace_sim) { | |
| 1414 PrintF("Returned %08x\n", lo_res); | |
| 1415 } | |
| 1416 set_register(r3, lo_res); | |
| 1417 set_register(r4, hi_res); | |
| 1418 #endif | |
| 1419 #else | |
| 1420 if (redirection->type() == ExternalReference::BUILTIN_CALL) { | |
| 1421 SimulatorRuntimeCall target = | |
| 1422 reinterpret_cast<SimulatorRuntimeCall>(external); | |
| 1423 intptr_t result = | |
| 1424 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); | |
| 1425 if (::v8::internal::FLAG_trace_sim) { | |
| 1426 PrintF("Returned %08" V8PRIxPTR "\n", result); | |
| 1427 } | |
| 1428 set_register(r3, result); | |
| 1429 } else { | |
| 1430 DCHECK(redirection->type() == | |
| 1431 ExternalReference::BUILTIN_OBJECTPAIR_CALL); | |
| 1432 SimulatorRuntimeObjectPairCall target = | |
| 1433 reinterpret_cast<SimulatorRuntimeObjectPairCall>(external); | |
| 1434 struct ObjectPair result = | |
| 1435 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); | |
| 1436 if (::v8::internal::FLAG_trace_sim) { | |
| 1437 PrintF("Returned %08" V8PRIxPTR ", %08" V8PRIxPTR "\n", result.x, | |
| 1438 result.y); | |
| 1439 } | |
| 1440 #if ABI_RETURNS_OBJECT_PAIRS_IN_REGS | |
| 1441 set_register(r3, result.x); | |
| 1442 set_register(r4, result.y); | |
| 1443 #else | |
| 1444 memcpy(reinterpret_cast<void*>(result_buffer), &result, | |
| 1445 sizeof(struct ObjectPair)); | |
| 1446 #endif | |
| 1447 } | |
| 1448 #endif | |
| 1449 } | 1416 } |
| 1450 set_pc(saved_lr); | 1417 set_pc(saved_lr); |
| 1451 break; | 1418 break; |
| 1452 } | 1419 } |
| 1453 case kBreakpoint: { | 1420 case kBreakpoint: { |
| 1454 PPCDebugger dbg(this); | 1421 PPCDebugger dbg(this); |
| 1455 dbg.Debug(); | 1422 dbg.Debug(); |
| 1456 break; | 1423 break; |
| 1457 } | 1424 } |
| 1458 case kInfo: { | |
| 1459 PPCDebugger dbg(this); | |
| 1460 dbg.Info(instr); | |
| 1461 break; | |
| 1462 } | |
| 1463 // stop uses all codes greater than 1 << 23. | 1425 // stop uses all codes greater than 1 << 23. |
| 1464 default: { | 1426 default: { |
| 1465 if (svc >= (1 << 23)) { | 1427 if (svc >= (1 << 23)) { |
| 1466 uint32_t code = svc & kStopCodeMask; | 1428 uint32_t code = svc & kStopCodeMask; |
| 1467 if (isWatchedStop(code)) { | 1429 if (isWatchedStop(code)) { |
| 1468 IncreaseStopCounter(code); | 1430 IncreaseStopCounter(code); |
| 1469 } | 1431 } |
| 1470 // Stop if it is enabled, otherwise go on jumping over the stop | 1432 // Stop if it is enabled, otherwise go on jumping over the stop |
| 1471 // and the message address. | 1433 // and the message address. |
| 1472 if (isEnabledStop(code)) { | 1434 if (isEnabledStop(code)) { |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1823 } | 1785 } |
| 1824 break; | 1786 break; |
| 1825 } | 1787 } |
| 1826 case LFDUX: | 1788 case LFDUX: |
| 1827 case LFDX: { | 1789 case LFDX: { |
| 1828 int frt = instr->RTValue(); | 1790 int frt = instr->RTValue(); |
| 1829 int ra = instr->RAValue(); | 1791 int ra = instr->RAValue(); |
| 1830 int rb = instr->RBValue(); | 1792 int rb = instr->RBValue(); |
| 1831 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 1793 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 1832 intptr_t rb_val = get_register(rb); | 1794 intptr_t rb_val = get_register(rb); |
| 1833 double* dptr = reinterpret_cast<double*>(ReadDW(ra_val + rb_val)); | 1795 int64_t* dptr = reinterpret_cast<int64_t*>(ReadDW(ra_val + rb_val)); |
| 1834 set_d_register_from_double(frt, *dptr); | 1796 set_d_register(frt, *dptr); |
| 1835 if (opcode == LFDUX) { | 1797 if (opcode == LFDUX) { |
| 1836 DCHECK(ra != 0); | 1798 DCHECK(ra != 0); |
| 1837 set_register(ra, ra_val + rb_val); | 1799 set_register(ra, ra_val + rb_val); |
| 1838 } | 1800 } |
| 1839 break; | 1801 break; |
| 1840 } | 1802 } |
| 1841 case STFSUX: { | 1803 case STFSUX: { |
| 1842 case STFSX: | 1804 case STFSX: |
| 1843 int frs = instr->RSValue(); | 1805 int frs = instr->RSValue(); |
| 1844 int ra = instr->RAValue(); | 1806 int ra = instr->RAValue(); |
| 1845 int rb = instr->RBValue(); | 1807 int rb = instr->RBValue(); |
| 1846 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 1808 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 1847 intptr_t rb_val = get_register(rb); | 1809 intptr_t rb_val = get_register(rb); |
| 1848 float frs_val = static_cast<float>(get_double_from_d_register(frs)); | 1810 float frs_val = static_cast<float>(get_double_from_d_register(frs)); |
| 1849 int32_t* p = reinterpret_cast<int32_t*>(&frs_val); | 1811 int32_t* p = reinterpret_cast<int32_t*>(&frs_val); |
| 1850 WriteW(ra_val + rb_val, *p, instr); | 1812 WriteW(ra_val + rb_val, *p, instr); |
| 1851 if (opcode == STFSUX) { | 1813 if (opcode == STFSUX) { |
| 1852 DCHECK(ra != 0); | 1814 DCHECK(ra != 0); |
| 1853 set_register(ra, ra_val + rb_val); | 1815 set_register(ra, ra_val + rb_val); |
| 1854 } | 1816 } |
| 1855 break; | 1817 break; |
| 1856 } | 1818 } |
| 1857 case STFDUX: { | 1819 case STFDUX: { |
| 1858 case STFDX: | 1820 case STFDX: |
| 1859 int frs = instr->RSValue(); | 1821 int frs = instr->RSValue(); |
| 1860 int ra = instr->RAValue(); | 1822 int ra = instr->RAValue(); |
| 1861 int rb = instr->RBValue(); | 1823 int rb = instr->RBValue(); |
| 1862 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 1824 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 1863 intptr_t rb_val = get_register(rb); | 1825 intptr_t rb_val = get_register(rb); |
| 1864 double frs_val = get_double_from_d_register(frs); | 1826 int64_t frs_val = get_d_register(frs); |
| 1865 int64_t* p = reinterpret_cast<int64_t*>(&frs_val); | 1827 WriteDW(ra_val + rb_val, frs_val); |
| 1866 WriteDW(ra_val + rb_val, *p); | |
| 1867 if (opcode == STFDUX) { | 1828 if (opcode == STFDUX) { |
| 1868 DCHECK(ra != 0); | 1829 DCHECK(ra != 0); |
| 1869 set_register(ra, ra_val + rb_val); | 1830 set_register(ra, ra_val + rb_val); |
| 1870 } | 1831 } |
| 1871 break; | 1832 break; |
| 1872 } | 1833 } |
| 1873 case SYNC: { | 1834 case SYNC: { |
| 1874 // todo - simulate sync | 1835 // todo - simulate sync |
| 1875 break; | 1836 break; |
| 1876 } | 1837 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2008 int ra = instr->RAValue(); | 1969 int ra = instr->RAValue(); |
| 2009 int rb = instr->RBValue(); | 1970 int rb = instr->RBValue(); |
| 2010 int32_t ra_val = (get_register(ra) & 0xFFFFFFFF); | 1971 int32_t ra_val = (get_register(ra) & 0xFFFFFFFF); |
| 2011 int32_t rb_val = (get_register(rb) & 0xFFFFFFFF); | 1972 int32_t rb_val = (get_register(rb) & 0xFFFFFFFF); |
| 2012 int64_t alu_out = (int64_t)ra_val * (int64_t)rb_val; | 1973 int64_t alu_out = (int64_t)ra_val * (int64_t)rb_val; |
| 2013 alu_out >>= 32; | 1974 alu_out >>= 32; |
| 2014 set_register(rt, alu_out); | 1975 set_register(rt, alu_out); |
| 2015 if (instr->Bit(0)) { // RC bit set | 1976 if (instr->Bit(0)) { // RC bit set |
| 2016 SetCR0(static_cast<intptr_t>(alu_out)); | 1977 SetCR0(static_cast<intptr_t>(alu_out)); |
| 2017 } | 1978 } |
| 2018 // todo - handle OE bit | 1979 break; |
| 1980 } |
| 1981 case MULHWUX: { |
| 1982 int rt = instr->RTValue(); |
| 1983 int ra = instr->RAValue(); |
| 1984 int rb = instr->RBValue(); |
| 1985 uint32_t ra_val = (get_register(ra) & 0xFFFFFFFF); |
| 1986 uint32_t rb_val = (get_register(rb) & 0xFFFFFFFF); |
| 1987 uint64_t alu_out = (uint64_t)ra_val * (uint64_t)rb_val; |
| 1988 alu_out >>= 32; |
| 1989 set_register(rt, alu_out); |
| 1990 if (instr->Bit(0)) { // RC bit set |
| 1991 SetCR0(static_cast<intptr_t>(alu_out)); |
| 1992 } |
| 2019 break; | 1993 break; |
| 2020 } | 1994 } |
| 2021 case NEGX: { | 1995 case NEGX: { |
| 2022 int rt = instr->RTValue(); | 1996 int rt = instr->RTValue(); |
| 2023 int ra = instr->RAValue(); | 1997 int ra = instr->RAValue(); |
| 2024 intptr_t ra_val = get_register(ra); | 1998 intptr_t ra_val = get_register(ra); |
| 2025 intptr_t alu_out = 1 + ~ra_val; | 1999 intptr_t alu_out = 1 + ~ra_val; |
| 2026 #if V8_TARGET_ARCH_PPC64 | 2000 #if V8_TARGET_ARCH_PPC64 |
| 2027 intptr_t one = 1; // work-around gcc | 2001 intptr_t one = 1; // work-around gcc |
| 2028 intptr_t kOverflowVal = (one << 63); | 2002 intptr_t kOverflowVal = (one << 63); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2067 set_register(ra, result); | 2041 set_register(ra, result); |
| 2068 if (instr->Bit(0)) { // RC bit set | 2042 if (instr->Bit(0)) { // RC bit set |
| 2069 SetCR0(result); | 2043 SetCR0(result); |
| 2070 } | 2044 } |
| 2071 break; | 2045 break; |
| 2072 } | 2046 } |
| 2073 case MFVSRD: { | 2047 case MFVSRD: { |
| 2074 DCHECK(!instr->Bit(0)); | 2048 DCHECK(!instr->Bit(0)); |
| 2075 int frt = instr->RTValue(); | 2049 int frt = instr->RTValue(); |
| 2076 int ra = instr->RAValue(); | 2050 int ra = instr->RAValue(); |
| 2077 double frt_val = get_double_from_d_register(frt); | 2051 int64_t frt_val = get_d_register(frt); |
| 2078 int64_t* p = reinterpret_cast<int64_t*>(&frt_val); | 2052 set_register(ra, frt_val); |
| 2079 set_register(ra, *p); | |
| 2080 break; | 2053 break; |
| 2081 } | 2054 } |
| 2082 case MFVSRWZ: { | 2055 case MFVSRWZ: { |
| 2083 DCHECK(!instr->Bit(0)); | 2056 DCHECK(!instr->Bit(0)); |
| 2084 int frt = instr->RTValue(); | 2057 int frt = instr->RTValue(); |
| 2085 int ra = instr->RAValue(); | 2058 int ra = instr->RAValue(); |
| 2086 double frt_val = get_double_from_d_register(frt); | 2059 int64_t frt_val = get_d_register(frt); |
| 2087 int64_t* p = reinterpret_cast<int64_t*>(&frt_val); | 2060 set_register(ra, static_cast<uint32_t>(frt_val)); |
| 2088 set_register(ra, static_cast<uint32_t>(*p)); | |
| 2089 break; | 2061 break; |
| 2090 } | 2062 } |
| 2091 case MTVSRD: { | 2063 case MTVSRD: { |
| 2092 DCHECK(!instr->Bit(0)); | 2064 DCHECK(!instr->Bit(0)); |
| 2093 int frt = instr->RTValue(); | 2065 int frt = instr->RTValue(); |
| 2094 int ra = instr->RAValue(); | 2066 int ra = instr->RAValue(); |
| 2095 int64_t ra_val = get_register(ra); | 2067 int64_t ra_val = get_register(ra); |
| 2096 double* p = reinterpret_cast<double*>(&ra_val); | 2068 set_d_register(frt, ra_val); |
| 2097 set_d_register_from_double(frt, *p); | |
| 2098 break; | 2069 break; |
| 2099 } | 2070 } |
| 2100 case MTVSRWA: { | 2071 case MTVSRWA: { |
| 2101 DCHECK(!instr->Bit(0)); | 2072 DCHECK(!instr->Bit(0)); |
| 2102 int frt = instr->RTValue(); | 2073 int frt = instr->RTValue(); |
| 2103 int ra = instr->RAValue(); | 2074 int ra = instr->RAValue(); |
| 2104 int64_t ra_val = static_cast<int32_t>(get_register(ra)); | 2075 int64_t ra_val = static_cast<int32_t>(get_register(ra)); |
| 2105 double* p = reinterpret_cast<double*>(&ra_val); | 2076 set_d_register(frt, ra_val); |
| 2106 set_d_register_from_double(frt, *p); | |
| 2107 break; | 2077 break; |
| 2108 } | 2078 } |
| 2109 case MTVSRWZ: { | 2079 case MTVSRWZ: { |
| 2110 DCHECK(!instr->Bit(0)); | 2080 DCHECK(!instr->Bit(0)); |
| 2111 int frt = instr->RTValue(); | 2081 int frt = instr->RTValue(); |
| 2112 int ra = instr->RAValue(); | 2082 int ra = instr->RAValue(); |
| 2113 uint64_t ra_val = static_cast<uint32_t>(get_register(ra)); | 2083 uint64_t ra_val = static_cast<uint32_t>(get_register(ra)); |
| 2114 double* p = reinterpret_cast<double*>(&ra_val); | 2084 set_d_register(frt, ra_val); |
| 2115 set_d_register_from_double(frt, *p); | |
| 2116 break; | 2085 break; |
| 2117 } | 2086 } |
| 2118 #endif | 2087 #endif |
| 2119 default: { | 2088 default: { |
| 2120 found = false; | 2089 found = false; |
| 2121 break; | 2090 break; |
| 2122 } | 2091 } |
| 2123 } | 2092 } |
| 2124 | 2093 |
| 2125 return found; | 2094 return found; |
| 2126 } | 2095 } |
| 2127 | 2096 |
| 2128 | 2097 |
| 2129 void Simulator::ExecuteExt2_9bit_part2(Instruction* instr) { | 2098 bool Simulator::ExecuteExt2_9bit_part2(Instruction* instr) { |
| 2099 bool found = true; |
| 2130 int opcode = instr->Bits(9, 1) << 1; | 2100 int opcode = instr->Bits(9, 1) << 1; |
| 2131 switch (opcode) { | 2101 switch (opcode) { |
| 2132 case CNTLZWX: { | 2102 case CNTLZWX: { |
| 2133 int rs = instr->RSValue(); | 2103 int rs = instr->RSValue(); |
| 2134 int ra = instr->RAValue(); | 2104 int ra = instr->RAValue(); |
| 2135 uintptr_t rs_val = get_register(rs); | 2105 uintptr_t rs_val = get_register(rs); |
| 2136 uintptr_t count = 0; | 2106 uintptr_t count = 0; |
| 2137 int n = 0; | 2107 int n = 0; |
| 2138 uintptr_t bit = 0x80000000; | 2108 uintptr_t bit = 0x80000000; |
| 2139 for (; n < 32; n++) { | 2109 for (; n < 32; n++) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2337 } else { | 2307 } else { |
| 2338 special_reg_xer_ &= ~0x40000000; // clear OV | 2308 special_reg_xer_ &= ~0x40000000; // clear OV |
| 2339 } | 2309 } |
| 2340 } | 2310 } |
| 2341 if (instr->Bit(0)) { // RC bit set | 2311 if (instr->Bit(0)) { // RC bit set |
| 2342 bool setSO = (special_reg_xer_ & 0x80000000); | 2312 bool setSO = (special_reg_xer_ & 0x80000000); |
| 2343 SetCR0(alu_out, setSO); | 2313 SetCR0(alu_out, setSO); |
| 2344 } | 2314 } |
| 2345 break; | 2315 break; |
| 2346 } | 2316 } |
| 2317 case DIVWU: { |
| 2318 int rt = instr->RTValue(); |
| 2319 int ra = instr->RAValue(); |
| 2320 int rb = instr->RBValue(); |
| 2321 uint32_t ra_val = get_register(ra); |
| 2322 uint32_t rb_val = get_register(rb); |
| 2323 bool overflow = (rb_val == 0); |
| 2324 // result is undefined if divisor is zero |
| 2325 uint32_t alu_out = (overflow) ? -1 : ra_val / rb_val; |
| 2326 set_register(rt, alu_out); |
| 2327 if (instr->Bit(10)) { // OE bit set |
| 2328 if (overflow) { |
| 2329 special_reg_xer_ |= 0xC0000000; // set SO,OV |
| 2330 } else { |
| 2331 special_reg_xer_ &= ~0x40000000; // clear OV |
| 2332 } |
| 2333 } |
| 2334 if (instr->Bit(0)) { // RC bit set |
| 2335 bool setSO = (special_reg_xer_ & 0x80000000); |
| 2336 SetCR0(alu_out, setSO); |
| 2337 } |
| 2338 break; |
| 2339 } |
| 2347 #if V8_TARGET_ARCH_PPC64 | 2340 #if V8_TARGET_ARCH_PPC64 |
| 2348 case DIVD: { | 2341 case DIVD: { |
| 2349 int rt = instr->RTValue(); | 2342 int rt = instr->RTValue(); |
| 2350 int ra = instr->RAValue(); | 2343 int ra = instr->RAValue(); |
| 2351 int rb = instr->RBValue(); | 2344 int rb = instr->RBValue(); |
| 2352 int64_t ra_val = get_register(ra); | 2345 int64_t ra_val = get_register(ra); |
| 2353 int64_t rb_val = get_register(rb); | 2346 int64_t rb_val = get_register(rb); |
| 2354 int64_t one = 1; // work-around gcc | 2347 int64_t one = 1; // work-around gcc |
| 2355 int64_t kMinLongLong = (one << 63); | 2348 int64_t kMinLongLong = (one << 63); |
| 2356 // result is undefined if divisor is zero or if operation | 2349 // result is undefined if divisor is zero or if operation |
| 2357 // is 0x80000000_00000000 / -1. | 2350 // is 0x80000000_00000000 / -1. |
| 2358 int64_t alu_out = | 2351 int64_t alu_out = |
| 2359 (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1)) | 2352 (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1)) |
| 2360 ? -1 | 2353 ? -1 |
| 2361 : ra_val / rb_val; | 2354 : ra_val / rb_val; |
| 2362 set_register(rt, alu_out); | 2355 set_register(rt, alu_out); |
| 2363 if (instr->Bit(0)) { // RC bit set | 2356 if (instr->Bit(0)) { // RC bit set |
| 2364 SetCR0(alu_out); | 2357 SetCR0(alu_out); |
| 2365 } | 2358 } |
| 2366 // todo - handle OE bit | 2359 // todo - handle OE bit |
| 2367 break; | 2360 break; |
| 2368 } | 2361 } |
| 2362 case DIVDU: { |
| 2363 int rt = instr->RTValue(); |
| 2364 int ra = instr->RAValue(); |
| 2365 int rb = instr->RBValue(); |
| 2366 uint64_t ra_val = get_register(ra); |
| 2367 uint64_t rb_val = get_register(rb); |
| 2368 // result is undefined if divisor is zero |
| 2369 uint64_t alu_out = (rb_val == 0) ? -1 : ra_val / rb_val; |
| 2370 set_register(rt, alu_out); |
| 2371 if (instr->Bit(0)) { // RC bit set |
| 2372 SetCR0(alu_out); |
| 2373 } |
| 2374 // todo - handle OE bit |
| 2375 break; |
| 2376 } |
| 2369 #endif | 2377 #endif |
| 2370 case ADDX: { | 2378 case ADDX: { |
| 2371 int rt = instr->RTValue(); | 2379 int rt = instr->RTValue(); |
| 2372 int ra = instr->RAValue(); | 2380 int ra = instr->RAValue(); |
| 2373 int rb = instr->RBValue(); | 2381 int rb = instr->RBValue(); |
| 2374 // int oe = instr->Bit(10); | 2382 // int oe = instr->Bit(10); |
| 2375 intptr_t ra_val = get_register(ra); | 2383 intptr_t ra_val = get_register(ra); |
| 2376 intptr_t rb_val = get_register(rb); | 2384 intptr_t rb_val = get_register(rb); |
| 2377 intptr_t alu_out = ra_val + rb_val; | 2385 intptr_t alu_out = ra_val + rb_val; |
| 2378 set_register(rt, alu_out); | 2386 set_register(rt, alu_out); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2401 int rb = instr->RBValue(); | 2409 int rb = instr->RBValue(); |
| 2402 intptr_t rs_val = get_register(rs); | 2410 intptr_t rs_val = get_register(rs); |
| 2403 intptr_t rb_val = get_register(rb); | 2411 intptr_t rb_val = get_register(rb); |
| 2404 intptr_t alu_out = rs_val | rb_val; | 2412 intptr_t alu_out = rs_val | rb_val; |
| 2405 set_register(ra, alu_out); | 2413 set_register(ra, alu_out); |
| 2406 if (instr->Bit(0)) { // RC bit set | 2414 if (instr->Bit(0)) { // RC bit set |
| 2407 SetCR0(alu_out); | 2415 SetCR0(alu_out); |
| 2408 } | 2416 } |
| 2409 break; | 2417 break; |
| 2410 } | 2418 } |
| 2419 case ORC: { |
| 2420 int rs = instr->RSValue(); |
| 2421 int ra = instr->RAValue(); |
| 2422 int rb = instr->RBValue(); |
| 2423 intptr_t rs_val = get_register(rs); |
| 2424 intptr_t rb_val = get_register(rb); |
| 2425 intptr_t alu_out = rs_val | ~rb_val; |
| 2426 set_register(ra, alu_out); |
| 2427 if (instr->Bit(0)) { // RC bit set |
| 2428 SetCR0(alu_out); |
| 2429 } |
| 2430 break; |
| 2431 } |
| 2411 case MFSPR: { | 2432 case MFSPR: { |
| 2412 int rt = instr->RTValue(); | 2433 int rt = instr->RTValue(); |
| 2413 int spr = instr->Bits(20, 11); | 2434 int spr = instr->Bits(20, 11); |
| 2414 if (spr != 256) { | 2435 if (spr != 256) { |
| 2415 UNIMPLEMENTED(); // Only LRLR supported | 2436 UNIMPLEMENTED(); // Only LRLR supported |
| 2416 } | 2437 } |
| 2417 set_register(rt, special_reg_lr_); | 2438 set_register(rt, special_reg_lr_); |
| 2418 break; | 2439 break; |
| 2419 } | 2440 } |
| 2420 case MTSPR: { | 2441 case MTSPR: { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2490 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 2511 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 2491 intptr_t rb_val = get_register(rb); | 2512 intptr_t rb_val = get_register(rb); |
| 2492 set_register(rt, ReadWU(ra_val + rb_val, instr)); | 2513 set_register(rt, ReadWU(ra_val + rb_val, instr)); |
| 2493 if (opcode == LWZUX) { | 2514 if (opcode == LWZUX) { |
| 2494 DCHECK(ra != 0 && ra != rt); | 2515 DCHECK(ra != 0 && ra != rt); |
| 2495 set_register(ra, ra_val + rb_val); | 2516 set_register(ra, ra_val + rb_val); |
| 2496 } | 2517 } |
| 2497 break; | 2518 break; |
| 2498 } | 2519 } |
| 2499 #if V8_TARGET_ARCH_PPC64 | 2520 #if V8_TARGET_ARCH_PPC64 |
| 2521 case LWAX: { |
| 2522 int rt = instr->RTValue(); |
| 2523 int ra = instr->RAValue(); |
| 2524 int rb = instr->RBValue(); |
| 2525 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 2526 intptr_t rb_val = get_register(rb); |
| 2527 set_register(rt, ReadW(ra_val + rb_val, instr)); |
| 2528 break; |
| 2529 } |
| 2500 case LDX: | 2530 case LDX: |
| 2501 case LDUX: { | 2531 case LDUX: { |
| 2502 int rt = instr->RTValue(); | 2532 int rt = instr->RTValue(); |
| 2503 int ra = instr->RAValue(); | 2533 int ra = instr->RAValue(); |
| 2504 int rb = instr->RBValue(); | 2534 int rb = instr->RBValue(); |
| 2505 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 2535 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 2506 intptr_t rb_val = get_register(rb); | 2536 intptr_t rb_val = get_register(rb); |
| 2507 intptr_t* result = ReadDW(ra_val + rb_val); | 2537 intptr_t* result = ReadDW(ra_val + rb_val); |
| 2508 set_register(rt, *result); | 2538 set_register(rt, *result); |
| 2509 if (opcode == LDUX) { | 2539 if (opcode == LDUX) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2549 int rb = instr->RBValue(); | 2579 int rb = instr->RBValue(); |
| 2550 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 2580 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 2551 intptr_t rb_val = get_register(rb); | 2581 intptr_t rb_val = get_register(rb); |
| 2552 set_register(rt, ReadHU(ra_val + rb_val, instr) & 0xFFFF); | 2582 set_register(rt, ReadHU(ra_val + rb_val, instr) & 0xFFFF); |
| 2553 if (opcode == LHZUX) { | 2583 if (opcode == LHZUX) { |
| 2554 DCHECK(ra != 0 && ra != rt); | 2584 DCHECK(ra != 0 && ra != rt); |
| 2555 set_register(ra, ra_val + rb_val); | 2585 set_register(ra, ra_val + rb_val); |
| 2556 } | 2586 } |
| 2557 break; | 2587 break; |
| 2558 } | 2588 } |
| 2589 case LHAX: |
| 2590 case LHAUX: { |
| 2591 int rt = instr->RTValue(); |
| 2592 int ra = instr->RAValue(); |
| 2593 int rb = instr->RBValue(); |
| 2594 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 2595 intptr_t rb_val = get_register(rb); |
| 2596 set_register(rt, ReadH(ra_val + rb_val, instr)); |
| 2597 if (opcode == LHAUX) { |
| 2598 DCHECK(ra != 0 && ra != rt); |
| 2599 set_register(ra, ra_val + rb_val); |
| 2600 } |
| 2601 break; |
| 2602 } |
| 2559 case DCBF: { | 2603 case DCBF: { |
| 2560 // todo - simulate dcbf | 2604 // todo - simulate dcbf |
| 2561 break; | 2605 break; |
| 2562 } | 2606 } |
| 2563 default: { | 2607 default: { |
| 2608 found = false; |
| 2609 break; |
| 2610 } |
| 2611 } |
| 2612 |
| 2613 return found; |
| 2614 } |
| 2615 |
| 2616 |
| 2617 void Simulator::ExecuteExt2_5bit(Instruction* instr) { |
| 2618 int opcode = instr->Bits(5, 1) << 1; |
| 2619 switch (opcode) { |
| 2620 case ISEL: { |
| 2621 int rt = instr->RTValue(); |
| 2622 int ra = instr->RAValue(); |
| 2623 int rb = instr->RBValue(); |
| 2624 int condition_bit = instr->RCValue(); |
| 2625 int condition_mask = 0x80000000 >> condition_bit; |
| 2626 intptr_t ra_val = (ra == 0) ? 0 : get_register(ra); |
| 2627 intptr_t rb_val = get_register(rb); |
| 2628 intptr_t value = (condition_reg_ & condition_mask) ? ra_val : rb_val; |
| 2629 set_register(rt, value); |
| 2630 break; |
| 2631 } |
| 2632 default: { |
| 2564 PrintF("Unimplemented: %08x\n", instr->InstructionBits()); | 2633 PrintF("Unimplemented: %08x\n", instr->InstructionBits()); |
| 2565 UNIMPLEMENTED(); // Not used by V8. | 2634 UNIMPLEMENTED(); // Not used by V8. |
| 2566 } | 2635 } |
| 2567 } | 2636 } |
| 2568 } | 2637 } |
| 2569 | 2638 |
| 2570 | 2639 |
| 2571 void Simulator::ExecuteExt2(Instruction* instr) { | 2640 void Simulator::ExecuteExt2(Instruction* instr) { |
| 2572 // Check first the 10-1 bit versions | 2641 // Check first the 10-1 bit versions |
| 2573 if (ExecuteExt2_10bit(instr)) return; | 2642 if (ExecuteExt2_10bit(instr)) return; |
| 2574 // Now look at the lesser encodings | 2643 // Now look at the lesser encodings |
| 2575 if (ExecuteExt2_9bit_part1(instr)) return; | 2644 if (ExecuteExt2_9bit_part1(instr)) return; |
| 2576 ExecuteExt2_9bit_part2(instr); | 2645 if (ExecuteExt2_9bit_part2(instr)) return; |
| 2646 ExecuteExt2_5bit(instr); |
| 2577 } | 2647 } |
| 2578 | 2648 |
| 2579 | 2649 |
| 2580 void Simulator::ExecuteExt4(Instruction* instr) { | 2650 void Simulator::ExecuteExt4(Instruction* instr) { |
| 2581 switch (instr->Bits(5, 1) << 1) { | 2651 switch (instr->Bits(5, 1) << 1) { |
| 2582 case FDIV: { | 2652 case FDIV: { |
| 2583 int frt = instr->RTValue(); | 2653 int frt = instr->RTValue(); |
| 2584 int fra = instr->RAValue(); | 2654 int fra = instr->RAValue(); |
| 2585 int frb = instr->RBValue(); | 2655 int frb = instr->RBValue(); |
| 2586 double fra_val = get_double_from_d_register(fra); | 2656 double fra_val = get_double_from_d_register(fra); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2683 bf |= 0x20000000; | 2753 bf |= 0x20000000; |
| 2684 } | 2754 } |
| 2685 if (std::isunordered(fra_val, frb_val)) { | 2755 if (std::isunordered(fra_val, frb_val)) { |
| 2686 bf |= 0x10000000; | 2756 bf |= 0x10000000; |
| 2687 } | 2757 } |
| 2688 int condition_mask = 0xF0000000 >> (cr * 4); | 2758 int condition_mask = 0xF0000000 >> (cr * 4); |
| 2689 int condition = bf >> (cr * 4); | 2759 int condition = bf >> (cr * 4); |
| 2690 condition_reg_ = (condition_reg_ & ~condition_mask) | condition; | 2760 condition_reg_ = (condition_reg_ & ~condition_mask) | condition; |
| 2691 return; | 2761 return; |
| 2692 } | 2762 } |
| 2763 case FRIN: { |
| 2764 int frt = instr->RTValue(); |
| 2765 int frb = instr->RBValue(); |
| 2766 double frb_val = get_double_from_d_register(frb); |
| 2767 double frt_val = std::round(frb_val); |
| 2768 set_d_register_from_double(frt, frt_val); |
| 2769 if (instr->Bit(0)) { // RC bit set |
| 2770 // UNIMPLEMENTED(); |
| 2771 } |
| 2772 return; |
| 2773 } |
| 2774 case FRIZ: { |
| 2775 int frt = instr->RTValue(); |
| 2776 int frb = instr->RBValue(); |
| 2777 double frb_val = get_double_from_d_register(frb); |
| 2778 double frt_val = std::trunc(frb_val); |
| 2779 set_d_register_from_double(frt, frt_val); |
| 2780 if (instr->Bit(0)) { // RC bit set |
| 2781 // UNIMPLEMENTED(); |
| 2782 } |
| 2783 return; |
| 2784 } |
| 2785 case FRIP: { |
| 2786 int frt = instr->RTValue(); |
| 2787 int frb = instr->RBValue(); |
| 2788 double frb_val = get_double_from_d_register(frb); |
| 2789 double frt_val = std::ceil(frb_val); |
| 2790 set_d_register_from_double(frt, frt_val); |
| 2791 if (instr->Bit(0)) { // RC bit set |
| 2792 // UNIMPLEMENTED(); |
| 2793 } |
| 2794 return; |
| 2795 } |
| 2796 case FRIM: { |
| 2797 int frt = instr->RTValue(); |
| 2798 int frb = instr->RBValue(); |
| 2799 double frb_val = get_double_from_d_register(frb); |
| 2800 double frt_val = std::floor(frb_val); |
| 2801 set_d_register_from_double(frt, frt_val); |
| 2802 if (instr->Bit(0)) { // RC bit set |
| 2803 // UNIMPLEMENTED(); |
| 2804 } |
| 2805 return; |
| 2806 } |
| 2693 case FRSP: { | 2807 case FRSP: { |
| 2694 int frt = instr->RTValue(); | 2808 int frt = instr->RTValue(); |
| 2695 int frb = instr->RBValue(); | 2809 int frb = instr->RBValue(); |
| 2810 // frsp round 8-byte double-precision value to |
| 2811 // single-precision value |
| 2696 double frb_val = get_double_from_d_register(frb); | 2812 double frb_val = get_double_from_d_register(frb); |
| 2697 // frsp round 8-byte double-precision value to 8-byte | 2813 double frt_val = static_cast<float>(frb_val); |
| 2698 // single-precision value, ignore the round here | 2814 set_d_register_from_double(frt, frt_val); |
| 2699 set_d_register_from_double(frt, frb_val); | |
| 2700 if (instr->Bit(0)) { // RC bit set | 2815 if (instr->Bit(0)) { // RC bit set |
| 2701 // UNIMPLEMENTED(); | 2816 // UNIMPLEMENTED(); |
| 2702 } | 2817 } |
| 2703 return; | 2818 return; |
| 2704 } | 2819 } |
| 2705 case FCFID: { | 2820 case FCFID: { |
| 2706 int frt = instr->RTValue(); | 2821 int frt = instr->RTValue(); |
| 2707 int frb = instr->RBValue(); | 2822 int frb = instr->RBValue(); |
| 2708 double t_val = get_double_from_d_register(frb); | 2823 double t_val = get_double_from_d_register(frb); |
| 2709 int64_t* frb_val_p = reinterpret_cast<int64_t*>(&t_val); | 2824 int64_t* frb_val_p = reinterpret_cast<int64_t*>(&t_val); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2814 int frt = instr->RTValue(); | 2929 int frt = instr->RTValue(); |
| 2815 int frb = instr->RBValue(); | 2930 int frb = instr->RBValue(); |
| 2816 double frb_val = get_double_from_d_register(frb); | 2931 double frb_val = get_double_from_d_register(frb); |
| 2817 double frt_val = -frb_val; | 2932 double frt_val = -frb_val; |
| 2818 set_d_register_from_double(frt, frt_val); | 2933 set_d_register_from_double(frt, frt_val); |
| 2819 return; | 2934 return; |
| 2820 } | 2935 } |
| 2821 case FMR: { | 2936 case FMR: { |
| 2822 int frt = instr->RTValue(); | 2937 int frt = instr->RTValue(); |
| 2823 int frb = instr->RBValue(); | 2938 int frb = instr->RBValue(); |
| 2824 double frb_val = get_double_from_d_register(frb); | 2939 int64_t frb_val = get_d_register(frb); |
| 2825 double frt_val = frb_val; | 2940 set_d_register(frt, frb_val); |
| 2826 set_d_register_from_double(frt, frt_val); | |
| 2827 return; | 2941 return; |
| 2828 } | 2942 } |
| 2829 case MTFSFI: { | 2943 case MTFSFI: { |
| 2830 int bf = instr->Bits(25, 23); | 2944 int bf = instr->Bits(25, 23); |
| 2831 int imm = instr->Bits(15, 12); | 2945 int imm = instr->Bits(15, 12); |
| 2832 int fp_condition_mask = 0xF0000000 >> (bf * 4); | 2946 int fp_condition_mask = 0xF0000000 >> (bf * 4); |
| 2833 fp_condition_reg_ &= ~fp_condition_mask; | 2947 fp_condition_reg_ &= ~fp_condition_mask; |
| 2834 fp_condition_reg_ |= (imm << (28 - (bf * 4))); | 2948 fp_condition_reg_ |= (imm << (28 - (bf * 4))); |
| 2835 if (instr->Bit(0)) { // RC bit set | 2949 if (instr->Bit(0)) { // RC bit set |
| 2836 condition_reg_ &= 0xF0FFFFFF; | 2950 condition_reg_ &= 0xF0FFFFFF; |
| 2837 condition_reg_ |= (imm << 23); | 2951 condition_reg_ |= (imm << 23); |
| 2838 } | 2952 } |
| 2839 return; | 2953 return; |
| 2840 } | 2954 } |
| 2841 case MTFSF: { | 2955 case MTFSF: { |
| 2842 int frb = instr->RBValue(); | 2956 int frb = instr->RBValue(); |
| 2843 double frb_dval = get_double_from_d_register(frb); | 2957 int64_t frb_dval = get_d_register(frb); |
| 2844 int64_t* p = reinterpret_cast<int64_t*>(&frb_dval); | 2958 int32_t frb_ival = static_cast<int32_t>((frb_dval)&0xffffffff); |
| 2845 int32_t frb_ival = static_cast<int32_t>((*p) & 0xffffffff); | |
| 2846 int l = instr->Bits(25, 25); | 2959 int l = instr->Bits(25, 25); |
| 2847 if (l == 1) { | 2960 if (l == 1) { |
| 2848 fp_condition_reg_ = frb_ival; | 2961 fp_condition_reg_ = frb_ival; |
| 2849 } else { | 2962 } else { |
| 2850 UNIMPLEMENTED(); | 2963 UNIMPLEMENTED(); |
| 2851 } | 2964 } |
| 2852 if (instr->Bit(0)) { // RC bit set | 2965 if (instr->Bit(0)) { // RC bit set |
| 2853 UNIMPLEMENTED(); | 2966 UNIMPLEMENTED(); |
| 2854 // int w = instr->Bits(16, 16); | 2967 // int w = instr->Bits(16, 16); |
| 2855 // int flm = instr->Bits(24, 17); | 2968 // int flm = instr->Bits(24, 17); |
| 2856 } | 2969 } |
| 2857 return; | 2970 return; |
| 2858 } | 2971 } |
| 2859 case MFFS: { | 2972 case MFFS: { |
| 2860 int frt = instr->RTValue(); | 2973 int frt = instr->RTValue(); |
| 2861 int64_t lval = static_cast<int64_t>(fp_condition_reg_); | 2974 int64_t lval = static_cast<int64_t>(fp_condition_reg_); |
| 2862 double* p = reinterpret_cast<double*>(&lval); | 2975 set_d_register(frt, lval); |
| 2863 set_d_register_from_double(frt, *p); | |
| 2864 return; | 2976 return; |
| 2865 } | 2977 } |
| 2866 case FABS: { | 2978 case FABS: { |
| 2867 int frt = instr->RTValue(); | 2979 int frt = instr->RTValue(); |
| 2868 int frb = instr->RBValue(); | 2980 int frb = instr->RBValue(); |
| 2869 double frb_val = get_double_from_d_register(frb); | 2981 double frb_val = get_double_from_d_register(frb); |
| 2870 double frt_val = std::fabs(frb_val); | 2982 double frt_val = std::fabs(frb_val); |
| 2871 set_d_register_from_double(frt, frt_val); | 2983 set_d_register_from_double(frt, frt_val); |
| 2872 return; | 2984 return; |
| 2873 } | 2985 } |
| 2874 case FRIM: { | |
| 2875 int frt = instr->RTValue(); | |
| 2876 int frb = instr->RBValue(); | |
| 2877 double frb_val = get_double_from_d_register(frb); | |
| 2878 int64_t floor_val = (int64_t)frb_val; | |
| 2879 if (floor_val > frb_val) floor_val--; | |
| 2880 double frt_val = static_cast<double>(floor_val); | |
| 2881 set_d_register_from_double(frt, frt_val); | |
| 2882 return; | |
| 2883 } | |
| 2884 } | 2986 } |
| 2885 UNIMPLEMENTED(); // Not used by V8. | 2987 UNIMPLEMENTED(); // Not used by V8. |
| 2886 } | 2988 } |
| 2887 | 2989 |
| 2888 #if V8_TARGET_ARCH_PPC64 | 2990 #if V8_TARGET_ARCH_PPC64 |
| 2889 void Simulator::ExecuteExt5(Instruction* instr) { | 2991 void Simulator::ExecuteExt5(Instruction* instr) { |
| 2890 switch (instr->Bits(4, 2) << 2) { | 2992 switch (instr->Bits(4, 2) << 2) { |
| 2891 case RLDICL: { | 2993 case RLDICL: { |
| 2892 int ra = instr->RAValue(); | 2994 int ra = instr->RAValue(); |
| 2893 int rs = instr->RSValue(); | 2995 int rs = instr->RSValue(); |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3358 | 3460 |
| 3359 case LHZU: | 3461 case LHZU: |
| 3360 case LHZ: { | 3462 case LHZ: { |
| 3361 int ra = instr->RAValue(); | 3463 int ra = instr->RAValue(); |
| 3362 int rt = instr->RTValue(); | 3464 int rt = instr->RTValue(); |
| 3363 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 3465 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3364 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | 3466 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3365 uintptr_t result = ReadHU(ra_val + offset, instr) & 0xffff; | 3467 uintptr_t result = ReadHU(ra_val + offset, instr) & 0xffff; |
| 3366 set_register(rt, result); | 3468 set_register(rt, result); |
| 3367 if (opcode == LHZU) { | 3469 if (opcode == LHZU) { |
| 3368 DCHECK(ra != 0); | |
| 3369 set_register(ra, ra_val + offset); | 3470 set_register(ra, ra_val + offset); |
| 3370 } | 3471 } |
| 3371 break; | 3472 break; |
| 3372 } | 3473 } |
| 3373 | 3474 |
| 3374 case LHA: | 3475 case LHA: |
| 3375 case LHAU: { | 3476 case LHAU: { |
| 3376 UNIMPLEMENTED(); | 3477 int ra = instr->RAValue(); |
| 3478 int rt = instr->RTValue(); |
| 3479 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3480 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3481 intptr_t result = ReadH(ra_val + offset, instr); |
| 3482 set_register(rt, result); |
| 3483 if (opcode == LHAU) { |
| 3484 set_register(ra, ra_val + offset); |
| 3485 } |
| 3377 break; | 3486 break; |
| 3378 } | 3487 } |
| 3379 | 3488 |
| 3380 case STHU: | 3489 case STHU: |
| 3381 case STH: { | 3490 case STH: { |
| 3382 int ra = instr->RAValue(); | 3491 int ra = instr->RAValue(); |
| 3383 int rs = instr->RSValue(); | 3492 int rs = instr->RSValue(); |
| 3384 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 3493 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3385 int16_t rs_val = get_register(rs); | 3494 int16_t rs_val = get_register(rs); |
| 3386 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | 3495 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3413 } | 3522 } |
| 3414 break; | 3523 break; |
| 3415 } | 3524 } |
| 3416 | 3525 |
| 3417 case LFDU: | 3526 case LFDU: |
| 3418 case LFD: { | 3527 case LFD: { |
| 3419 int frt = instr->RTValue(); | 3528 int frt = instr->RTValue(); |
| 3420 int ra = instr->RAValue(); | 3529 int ra = instr->RAValue(); |
| 3421 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | 3530 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3422 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 3531 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3423 double* dptr = reinterpret_cast<double*>(ReadDW(ra_val + offset)); | 3532 int64_t* dptr = reinterpret_cast<int64_t*>(ReadDW(ra_val + offset)); |
| 3424 set_d_register_from_double(frt, *dptr); | 3533 set_d_register(frt, *dptr); |
| 3425 if (opcode == LFDU) { | 3534 if (opcode == LFDU) { |
| 3426 DCHECK(ra != 0); | 3535 DCHECK(ra != 0); |
| 3427 set_register(ra, ra_val + offset); | 3536 set_register(ra, ra_val + offset); |
| 3428 } | 3537 } |
| 3429 break; | 3538 break; |
| 3430 } | 3539 } |
| 3431 | 3540 |
| 3432 case STFSU: { | 3541 case STFSU: { |
| 3433 case STFS: | 3542 case STFS: |
| 3434 int frs = instr->RSValue(); | 3543 int frs = instr->RSValue(); |
| 3435 int ra = instr->RAValue(); | 3544 int ra = instr->RAValue(); |
| 3436 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | 3545 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3437 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 3546 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3438 float frs_val = static_cast<float>(get_double_from_d_register(frs)); | 3547 float frs_val = static_cast<float>(get_double_from_d_register(frs)); |
| 3439 int32_t* p = reinterpret_cast<int32_t*>(&frs_val); | 3548 int32_t* p = reinterpret_cast<int32_t*>(&frs_val); |
| 3440 WriteW(ra_val + offset, *p, instr); | 3549 WriteW(ra_val + offset, *p, instr); |
| 3441 if (opcode == STFSU) { | 3550 if (opcode == STFSU) { |
| 3442 DCHECK(ra != 0); | 3551 DCHECK(ra != 0); |
| 3443 set_register(ra, ra_val + offset); | 3552 set_register(ra, ra_val + offset); |
| 3444 } | 3553 } |
| 3445 break; | 3554 break; |
| 3446 } | 3555 } |
| 3447 | 3556 |
| 3448 case STFDU: | 3557 case STFDU: |
| 3449 case STFD: { | 3558 case STFD: { |
| 3450 int frs = instr->RSValue(); | 3559 int frs = instr->RSValue(); |
| 3451 int ra = instr->RAValue(); | 3560 int ra = instr->RAValue(); |
| 3452 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | 3561 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3453 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 3562 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3454 double frs_val = get_double_from_d_register(frs); | 3563 int64_t frs_val = get_d_register(frs); |
| 3455 int64_t* p = reinterpret_cast<int64_t*>(&frs_val); | 3564 WriteDW(ra_val + offset, frs_val); |
| 3456 WriteDW(ra_val + offset, *p); | |
| 3457 if (opcode == STFDU) { | 3565 if (opcode == STFDU) { |
| 3458 DCHECK(ra != 0); | 3566 DCHECK(ra != 0); |
| 3459 set_register(ra, ra_val + offset); | 3567 set_register(ra, ra_val + offset); |
| 3460 } | 3568 } |
| 3461 break; | 3569 break; |
| 3462 } | 3570 } |
| 3463 | 3571 |
| 3464 case EXT3: | 3572 case EXT3: |
| 3465 UNIMPLEMENTED(); | 3573 UNIMPLEMENTED(); |
| 3466 case EXT4: { | 3574 case EXT4: { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3508 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); | 3616 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); |
| 3509 WriteDW(ra_val + offset, rs_val); | 3617 WriteDW(ra_val + offset, rs_val); |
| 3510 if (instr->Bit(0) == 1) { // This is the STDU form | 3618 if (instr->Bit(0) == 1) { // This is the STDU form |
| 3511 DCHECK(ra != 0); | 3619 DCHECK(ra != 0); |
| 3512 set_register(ra, ra_val + offset); | 3620 set_register(ra, ra_val + offset); |
| 3513 } | 3621 } |
| 3514 break; | 3622 break; |
| 3515 } | 3623 } |
| 3516 #endif | 3624 #endif |
| 3517 | 3625 |
| 3518 case FAKE_OPCODE: { | |
| 3519 if (instr->Bits(MARKER_SUBOPCODE_BIT, MARKER_SUBOPCODE_BIT) == 1) { | |
| 3520 int marker_code = instr->Bits(STUB_MARKER_HIGH_BIT, 0); | |
| 3521 DCHECK(marker_code < F_NEXT_AVAILABLE_STUB_MARKER); | |
| 3522 PrintF("Hit stub-marker: %d (EMIT_STUB_MARKER)\n", marker_code); | |
| 3523 } else { | |
| 3524 int fake_opcode = instr->Bits(FAKE_OPCODE_HIGH_BIT, 0); | |
| 3525 if (fake_opcode == fBKPT) { | |
| 3526 PPCDebugger dbg(this); | |
| 3527 PrintF("Simulator hit BKPT.\n"); | |
| 3528 dbg.Debug(); | |
| 3529 } else { | |
| 3530 DCHECK(fake_opcode < fLastFaker); | |
| 3531 PrintF("Hit ARM opcode: %d(FAKE_OPCODE defined in constant-ppc.h)\n", | |
| 3532 fake_opcode); | |
| 3533 UNIMPLEMENTED(); | |
| 3534 } | |
| 3535 } | |
| 3536 break; | |
| 3537 } | |
| 3538 | |
| 3539 default: { | 3626 default: { |
| 3540 UNIMPLEMENTED(); | 3627 UNIMPLEMENTED(); |
| 3541 break; | 3628 break; |
| 3542 } | 3629 } |
| 3543 } | 3630 } |
| 3544 } // NOLINT | 3631 } // NOLINT |
| 3545 | 3632 |
| 3546 | 3633 |
| 3547 void Simulator::Trace(Instruction* instr) { | 3634 void Simulator::Trace(Instruction* instr) { |
| 3548 disasm::NameConverter converter; | 3635 disasm::NameConverter converter; |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3794 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 3881 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
| 3795 uintptr_t address = *stack_slot; | 3882 uintptr_t address = *stack_slot; |
| 3796 set_register(sp, current_sp + sizeof(uintptr_t)); | 3883 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 3797 return address; | 3884 return address; |
| 3798 } | 3885 } |
| 3799 } | 3886 } |
| 3800 } // namespace v8::internal | 3887 } // namespace v8::internal |
| 3801 | 3888 |
| 3802 #endif // USE_SIMULATOR | 3889 #endif // USE_SIMULATOR |
| 3803 #endif // V8_TARGET_ARCH_PPC | 3890 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |