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 #if V8_TARGET_ARCH_PPC | 9 #if V8_TARGET_ARCH_PPC |
10 | 10 |
11 #include "src/assembler.h" | 11 #include "src/assembler.h" |
12 #include "src/base/bits.h" | 12 #include "src/base/bits.h" |
13 #include "src/codegen.h" | 13 #include "src/codegen.h" |
14 #include "src/disasm.h" | 14 #include "src/disasm.h" |
15 #include "src/ppc/constants-ppc.h" | 15 #include "src/ppc/constants-ppc.h" |
16 #include "src/ppc/frames-ppc.h" | 16 #include "src/ppc/frames-ppc.h" |
17 #include "src/ppc/simulator-ppc.h" | 17 #include "src/ppc/simulator-ppc.h" |
| 18 #include "src/runtime/runtime-utils.h" |
18 | 19 |
19 #if defined(USE_SIMULATOR) | 20 #if defined(USE_SIMULATOR) |
20 | 21 |
21 // Only build the simulator if not compiling for real PPC hardware. | 22 // Only build the simulator if not compiling for real PPC hardware. |
22 namespace v8 { | 23 namespace v8 { |
23 namespace internal { | 24 namespace internal { |
24 | 25 |
25 // This macro provides a platform independent use of sscanf. The reason for | 26 // This macro provides a platform independent use of sscanf. The reason for |
26 // SScanF not being implemented in a platform independent way through | 27 // SScanF not being implemented in a platform independent way through |
27 // ::v8::internal::OS in the same way as SNPrintF is that the | 28 // ::v8::internal::OS in the same way as SNPrintF is that the |
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) | 1165 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) |
1165 // and first operand and result have different signs | 1166 // and first operand and result have different signs |
1166 && | 1167 && |
1167 ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); | 1168 ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
1168 } | 1169 } |
1169 return overflow; | 1170 return overflow; |
1170 } | 1171 } |
1171 | 1172 |
1172 | 1173 |
1173 #if V8_TARGET_ARCH_PPC64 | 1174 #if V8_TARGET_ARCH_PPC64 |
1174 struct ObjectPair { | |
1175 intptr_t x; | |
1176 intptr_t y; | |
1177 }; | |
1178 | |
1179 | |
1180 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { | 1175 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { |
1181 *x = pair->x; | 1176 *x = reinterpret_cast<intptr_t>(pair->x); |
1182 *y = pair->y; | 1177 *y = reinterpret_cast<intptr_t>(pair->y); |
1183 } | 1178 } |
1184 #else | 1179 #else |
1185 typedef uint64_t ObjectPair; | |
1186 | |
1187 | |
1188 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { | 1180 static void decodeObjectPair(ObjectPair* pair, intptr_t* x, intptr_t* y) { |
1189 #if V8_TARGET_BIG_ENDIAN | 1181 #if V8_TARGET_BIG_ENDIAN |
1190 *x = static_cast<int32_t>(*pair >> 32); | 1182 *x = static_cast<int32_t>(*pair >> 32); |
1191 *y = static_cast<int32_t>(*pair); | 1183 *y = static_cast<int32_t>(*pair); |
1192 #else | 1184 #else |
1193 *x = static_cast<int32_t>(*pair); | 1185 *x = static_cast<int32_t>(*pair); |
1194 *y = static_cast<int32_t>(*pair >> 32); | 1186 *y = static_cast<int32_t>(*pair >> 32); |
1195 #endif | 1187 #endif |
1196 } | 1188 } |
1197 #endif | 1189 #endif |
1198 | 1190 |
1199 // Calls into the V8 runtime are based on this very simple interface. | 1191 // Calls into the V8 runtime are based on this very simple interface. |
1200 // Note: To be able to return two values from some calls the code in | 1192 // Note: To be able to return two values from some calls the code in |
1201 // runtime.cc uses the ObjectPair which is essentially two pointer | 1193 // runtime.cc uses the ObjectPair which is essentially two pointer |
1202 // values stuffed into a structure. With the code below we assume that | 1194 // values stuffed into a structure. With the code below we assume that |
1203 // all runtime calls return this pair. If they don't, the r4 result | 1195 // all runtime calls return this pair. If they don't, the r4 result |
1204 // register contains a bogus value, which is fine because it is | 1196 // register contains a bogus value, which is fine because it is |
1205 // caller-saved. | 1197 // caller-saved. |
1206 typedef ObjectPair (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, | 1198 typedef ObjectPair (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1, |
1207 intptr_t arg2, intptr_t arg3, | 1199 intptr_t arg2, intptr_t arg3, |
1208 intptr_t arg4, intptr_t arg5); | 1200 intptr_t arg4, intptr_t arg5); |
1209 | 1201 |
| 1202 typedef ObjectTriple (*SimulatorRuntimeTripleCall)(intptr_t arg0, intptr_t arg1, |
| 1203 intptr_t arg2, intptr_t arg3, |
| 1204 intptr_t arg4, |
| 1205 intptr_t arg5); |
| 1206 |
1210 // These prototypes handle the four types of FP calls. | 1207 // These prototypes handle the four types of FP calls. |
1211 typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1); | 1208 typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1); |
1212 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); | 1209 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); |
1213 typedef double (*SimulatorRuntimeFPCall)(double darg0); | 1210 typedef double (*SimulatorRuntimeFPCall)(double darg0); |
1214 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0); | 1211 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0); |
1215 | 1212 |
1216 // This signature supports direct call in to API function native callback | 1213 // This signature supports direct call in to API function native callback |
1217 // (refer to InvocationCallback in v8.h). | 1214 // (refer to InvocationCallback in v8.h). |
1218 typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0); | 1215 typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0); |
1219 typedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0, void* arg1); | 1216 typedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0, void* arg1); |
(...skipping 10 matching lines...) Expand all Loading... |
1230 switch (svc) { | 1227 switch (svc) { |
1231 case kCallRtRedirected: { | 1228 case kCallRtRedirected: { |
1232 // Check if stack is aligned. Error if not aligned is reported below to | 1229 // Check if stack is aligned. Error if not aligned is reported below to |
1233 // include information on the function called. | 1230 // include information on the function called. |
1234 bool stack_aligned = | 1231 bool stack_aligned = |
1235 (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) == | 1232 (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) == |
1236 0; | 1233 0; |
1237 Redirection* redirection = Redirection::FromSwiInstruction(instr); | 1234 Redirection* redirection = Redirection::FromSwiInstruction(instr); |
1238 const int kArgCount = 6; | 1235 const int kArgCount = 6; |
1239 int arg0_regnum = 3; | 1236 int arg0_regnum = 3; |
1240 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS | |
1241 intptr_t result_buffer = 0; | 1237 intptr_t result_buffer = 0; |
1242 if (redirection->type() == ExternalReference::BUILTIN_OBJECTPAIR_CALL) { | 1238 if (redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE || |
| 1239 (redirection->type() == ExternalReference::BUILTIN_CALL_PAIR && |
| 1240 !ABI_RETURNS_OBJECT_PAIRS_IN_REGS)) { |
1243 result_buffer = get_register(r3); | 1241 result_buffer = get_register(r3); |
1244 arg0_regnum++; | 1242 arg0_regnum++; |
1245 } | 1243 } |
1246 #endif | |
1247 intptr_t arg[kArgCount]; | 1244 intptr_t arg[kArgCount]; |
1248 for (int i = 0; i < kArgCount; i++) { | 1245 for (int i = 0; i < kArgCount; i++) { |
1249 arg[i] = get_register(arg0_regnum + i); | 1246 arg[i] = get_register(arg0_regnum + i); |
1250 } | 1247 } |
1251 bool fp_call = | 1248 bool fp_call = |
1252 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || | 1249 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || |
1253 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || | 1250 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || |
1254 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || | 1251 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || |
1255 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); | 1252 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); |
1256 // This is dodgy but it works because the C entry stubs are never moved. | 1253 // This is dodgy but it works because the C entry stubs are never moved. |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1423 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR, | 1420 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR, |
1424 FUNCTION_ADDR(target), arg[0], arg[1], arg[2], arg[3], arg[4], | 1421 FUNCTION_ADDR(target), arg[0], arg[1], arg[2], arg[3], arg[4], |
1425 arg[5]); | 1422 arg[5]); |
1426 if (!stack_aligned) { | 1423 if (!stack_aligned) { |
1427 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", | 1424 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", |
1428 get_register(sp)); | 1425 get_register(sp)); |
1429 } | 1426 } |
1430 PrintF("\n"); | 1427 PrintF("\n"); |
1431 } | 1428 } |
1432 CHECK(stack_aligned); | 1429 CHECK(stack_aligned); |
1433 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); | 1430 if (redirection->type() == ExternalReference::BUILTIN_CALL_TRIPLE) { |
1434 SimulatorRuntimeCall target = | 1431 SimulatorRuntimeTripleCall target = |
1435 reinterpret_cast<SimulatorRuntimeCall>(external); | 1432 reinterpret_cast<SimulatorRuntimeTripleCall>(external); |
1436 ObjectPair result = | 1433 ObjectTriple result = |
1437 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); | 1434 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); |
1438 intptr_t x; | 1435 if (::v8::internal::FLAG_trace_sim) { |
1439 intptr_t y; | 1436 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR |
1440 decodeObjectPair(&result, &x, &y); | 1437 "}\n", |
1441 if (::v8::internal::FLAG_trace_sim) { | 1438 reinterpret_cast<intptr_t>(result.x), |
1442 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y); | 1439 reinterpret_cast<intptr_t>(result.y), |
| 1440 reinterpret_cast<intptr_t>(result.z)); |
| 1441 } |
| 1442 memcpy(reinterpret_cast<void*>(result_buffer), &result, |
| 1443 sizeof(ObjectTriple)); |
| 1444 set_register(r3, result_buffer); |
| 1445 } else { |
| 1446 DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL); |
| 1447 SimulatorRuntimeCall target = |
| 1448 reinterpret_cast<SimulatorRuntimeCall>(external); |
| 1449 ObjectPair result = |
| 1450 target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]); |
| 1451 intptr_t x; |
| 1452 intptr_t y; |
| 1453 decodeObjectPair(&result, &x, &y); |
| 1454 if (::v8::internal::FLAG_trace_sim) { |
| 1455 PrintF("Returned {%08" V8PRIxPTR ", %08" V8PRIxPTR "}\n", x, y); |
| 1456 } |
| 1457 set_register(r3, x); |
| 1458 set_register(r4, y); |
1443 } | 1459 } |
1444 set_register(r3, x); | |
1445 set_register(r4, y); | |
1446 } | 1460 } |
1447 set_pc(saved_lr); | 1461 set_pc(saved_lr); |
1448 break; | 1462 break; |
1449 } | 1463 } |
1450 case kBreakpoint: { | 1464 case kBreakpoint: { |
1451 PPCDebugger dbg(this); | 1465 PPCDebugger dbg(this); |
1452 dbg.Debug(); | 1466 dbg.Debug(); |
1453 break; | 1467 break; |
1454 } | 1468 } |
1455 // stop uses all codes greater than 1 << 23. | 1469 // stop uses all codes greater than 1 << 23. |
(...skipping 2584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4040 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 4054 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
4041 uintptr_t address = *stack_slot; | 4055 uintptr_t address = *stack_slot; |
4042 set_register(sp, current_sp + sizeof(uintptr_t)); | 4056 set_register(sp, current_sp + sizeof(uintptr_t)); |
4043 return address; | 4057 return address; |
4044 } | 4058 } |
4045 } // namespace internal | 4059 } // namespace internal |
4046 } // namespace v8 | 4060 } // namespace v8 |
4047 | 4061 |
4048 #endif // USE_SIMULATOR | 4062 #endif // USE_SIMULATOR |
4049 #endif // V8_TARGET_ARCH_PPC | 4063 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |