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 |