Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(598)

Side by Side Diff: src/mips/simulator-mips.cc

Issue 13989008: MIPS: Accurate function prototypes for native calls from ARM simulator. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed register usage Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/simulator-mips.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 const_cast<int32_t*>(&FPUregisters_[fpureg])); 1084 const_cast<int32_t*>(&FPUregisters_[fpureg]));
1085 } 1085 }
1086 1086
1087 1087
1088 double Simulator::get_fpu_register_double(int fpureg) const { 1088 double Simulator::get_fpu_register_double(int fpureg) const {
1089 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); 1089 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
1090 return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg])); 1090 return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg]));
1091 } 1091 }
1092 1092
1093 1093
1094 // For use in calls that take two double values, constructed either 1094 // Runtime FP routines take up to two double arguments and zero
1095 // or one integer arguments. All are constructed here,
1095 // from a0-a3 or f12 and f14. 1096 // from a0-a3 or f12 and f14.
1096 void Simulator::GetFpArgs(double* x, double* y) { 1097 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
1097 if (!IsMipsSoftFloatABI) { 1098 if (!IsMipsSoftFloatABI) {
1098 *x = get_fpu_register_double(12); 1099 *x = get_fpu_register_double(12);
1099 *y = get_fpu_register_double(14); 1100 *y = get_fpu_register_double(14);
1101 *z = get_register(a2);
1100 } else { 1102 } else {
1101 // We use a char buffer to get around the strict-aliasing rules which 1103 // We use a char buffer to get around the strict-aliasing rules which
1102 // otherwise allow the compiler to optimize away the copy. 1104 // otherwise allow the compiler to optimize away the copy.
1103 char buffer[sizeof(*x)]; 1105 char buffer[sizeof(*x)];
1104 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer); 1106 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1105 1107
1106 // Registers a0 and a1 -> x. 1108 // Registers a0 and a1 -> x.
1107 reg_buffer[0] = get_register(a0); 1109 reg_buffer[0] = get_register(a0);
1108 reg_buffer[1] = get_register(a1); 1110 reg_buffer[1] = get_register(a1);
1109 memcpy(x, buffer, sizeof(buffer)); 1111 memcpy(x, buffer, sizeof(buffer));
1110
1111 // Registers a2 and a3 -> y. 1112 // Registers a2 and a3 -> y.
1112 reg_buffer[0] = get_register(a2); 1113 reg_buffer[0] = get_register(a2);
1113 reg_buffer[1] = get_register(a3); 1114 reg_buffer[1] = get_register(a3);
1114 memcpy(y, buffer, sizeof(buffer)); 1115 memcpy(y, buffer, sizeof(buffer));
1116 // Register 2 -> z.
1117 reg_buffer[0] = get_register(a2);
1118 memcpy(z, buffer, sizeof(*z));
1115 } 1119 }
1116 } 1120 }
1117 1121
1118
1119 // For use in calls that take one double value, constructed either
1120 // from a0 and a1 or f12.
1121 void Simulator::GetFpArgs(double* x) {
1122 if (!IsMipsSoftFloatABI) {
1123 *x = get_fpu_register_double(12);
1124 } else {
1125 // We use a char buffer to get around the strict-aliasing rules which
1126 // otherwise allow the compiler to optimize away the copy.
1127 char buffer[sizeof(*x)];
1128 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1129 // Registers a0 and a1 -> x.
1130 reg_buffer[0] = get_register(a0);
1131 reg_buffer[1] = get_register(a1);
1132 memcpy(x, buffer, sizeof(buffer));
1133 }
1134 }
1135
1136
1137 // For use in calls that take one double value constructed either
1138 // from a0 and a1 or f12 and one integer value.
1139 void Simulator::GetFpArgs(double* x, int32_t* y) {
1140 if (!IsMipsSoftFloatABI) {
1141 *x = get_fpu_register_double(12);
1142 *y = get_register(a2);
1143 } else {
1144 // We use a char buffer to get around the strict-aliasing rules which
1145 // otherwise allow the compiler to optimize away the copy.
1146 char buffer[sizeof(*x)];
1147 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1148 // Registers 0 and 1 -> x.
1149 reg_buffer[0] = get_register(a0);
1150 reg_buffer[1] = get_register(a1);
1151 memcpy(x, buffer, sizeof(buffer));
1152
1153 // Register 2 -> y.
1154 reg_buffer[0] = get_register(a2);
1155 memcpy(y, buffer, sizeof(*y));
1156 }
1157 }
1158
1159 1122
1160 // The return value is either in v0/v1 or f0. 1123 // The return value is either in v0/v1 or f0.
1161 void Simulator::SetFpResult(const double& result) { 1124 void Simulator::SetFpResult(const double& result) {
1162 if (!IsMipsSoftFloatABI) { 1125 if (!IsMipsSoftFloatABI) {
1163 set_fpu_register_double(0, result); 1126 set_fpu_register_double(0, result);
1164 } else { 1127 } else {
1165 char buffer[2 * sizeof(registers_[0])]; 1128 char buffer[2 * sizeof(registers_[0])];
1166 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer); 1129 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1167 memcpy(buffer, &result, sizeof(buffer)); 1130 memcpy(buffer, &result, sizeof(buffer));
1168 // Copy result to v0 and v1. 1131 // Copy result to v0 and v1.
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 // uses the ObjectPair which is essentially two 32-bit values stuffed into a 1371 // uses the ObjectPair which is essentially two 32-bit values stuffed into a
1409 // 64-bit value. With the code below we assume that all runtime calls return 1372 // 64-bit value. With the code below we assume that all runtime calls return
1410 // 64 bits of result. If they don't, the v1 result register contains a bogus 1373 // 64 bits of result. If they don't, the v1 result register contains a bogus
1411 // value, which is fine because it is caller-saved. 1374 // value, which is fine because it is caller-saved.
1412 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, 1375 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
1413 int32_t arg1, 1376 int32_t arg1,
1414 int32_t arg2, 1377 int32_t arg2,
1415 int32_t arg3, 1378 int32_t arg3,
1416 int32_t arg4, 1379 int32_t arg4,
1417 int32_t arg5); 1380 int32_t arg5);
1418 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, 1381
1419 int32_t arg1, 1382 // These prototypes handle the four types of FP calls.
1420 int32_t arg2, 1383 typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
1421 int32_t arg3); 1384 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
1385 typedef double (*SimulatorRuntimeFPCall)(double darg0);
1386 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
1422 1387
1423 // This signature supports direct call in to API function native callback 1388 // This signature supports direct call in to API function native callback
1424 // (refer to InvocationCallback in v8.h). 1389 // (refer to InvocationCallback in v8.h).
1425 typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0); 1390 typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
1426 1391
1427 // This signature supports direct call to accessor getter callback. 1392 // This signature supports direct call to accessor getter callback.
1428 typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, 1393 typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
1429 int32_t arg1); 1394 int32_t arg1);
1430 1395
1431 // Software interrupt instructions are used by the simulator to call into the 1396 // Software interrupt instructions are used by the simulator to call into the
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 int32_t saved_ra = get_register(ra); 1453 int32_t saved_ra = get_register(ra);
1489 1454
1490 intptr_t external = 1455 intptr_t external =
1491 reinterpret_cast<intptr_t>(redirection->external_function()); 1456 reinterpret_cast<intptr_t>(redirection->external_function());
1492 1457
1493 // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware 1458 // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware
1494 // FPU, or gcc soft-float routines. Hardware FPU is simulated in this 1459 // FPU, or gcc soft-float routines. Hardware FPU is simulated in this
1495 // simulator. Soft-float has additional abstraction of ExternalReference, 1460 // simulator. Soft-float has additional abstraction of ExternalReference,
1496 // to support serialization. 1461 // to support serialization.
1497 if (fp_call) { 1462 if (fp_call) {
1498 SimulatorRuntimeFPCall target = 1463 double dval0, dval1; // one or two double parameters
1499 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1464 int32_t ival; // zero or one integer parameters
1465 int64_t iresult = 0; // integer return value
1466 double dresult = 0; // double return value
1467 GetFpArgs(&dval0, &dval1, &ival);
1468 SimulatorRuntimeCall generic_target =
1469 reinterpret_cast<SimulatorRuntimeCall>(external);
1500 if (::v8::internal::FLAG_trace_sim) { 1470 if (::v8::internal::FLAG_trace_sim) {
1501 double dval0, dval1;
1502 int32_t ival;
1503 switch (redirection->type()) { 1471 switch (redirection->type()) {
1504 case ExternalReference::BUILTIN_FP_FP_CALL: 1472 case ExternalReference::BUILTIN_FP_FP_CALL:
1505 case ExternalReference::BUILTIN_COMPARE_CALL: 1473 case ExternalReference::BUILTIN_COMPARE_CALL:
1506 GetFpArgs(&dval0, &dval1);
1507 PrintF("Call to host function at %p with args %f, %f", 1474 PrintF("Call to host function at %p with args %f, %f",
1508 FUNCTION_ADDR(target), dval0, dval1); 1475 FUNCTION_ADDR(generic_target), dval0, dval1);
1509 break; 1476 break;
1510 case ExternalReference::BUILTIN_FP_CALL: 1477 case ExternalReference::BUILTIN_FP_CALL:
1511 GetFpArgs(&dval0);
1512 PrintF("Call to host function at %p with arg %f", 1478 PrintF("Call to host function at %p with arg %f",
1513 FUNCTION_ADDR(target), dval0); 1479 FUNCTION_ADDR(generic_target), dval0);
1514 break; 1480 break;
1515 case ExternalReference::BUILTIN_FP_INT_CALL: 1481 case ExternalReference::BUILTIN_FP_INT_CALL:
1516 GetFpArgs(&dval0, &ival);
1517 PrintF("Call to host function at %p with args %f, %d", 1482 PrintF("Call to host function at %p with args %f, %d",
1518 FUNCTION_ADDR(target), dval0, ival); 1483 FUNCTION_ADDR(generic_target), dval0, ival);
1519 break; 1484 break;
1520 default: 1485 default:
1521 UNREACHABLE(); 1486 UNREACHABLE();
1522 break; 1487 break;
1523 } 1488 }
1524 } 1489 }
1525 if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) { 1490 switch (redirection->type()) {
1491 case ExternalReference::BUILTIN_COMPARE_CALL: {
1492 SimulatorRuntimeCompareCall target =
1493 reinterpret_cast<SimulatorRuntimeCompareCall>(external);
1494 iresult = target(dval0, dval1);
1495 set_register(v0, static_cast<int32_t>(iresult));
1496 set_register(v1, static_cast<int32_t>(iresult >> 32));
1497 break;
1498 }
1499 case ExternalReference::BUILTIN_FP_FP_CALL: {
1500 SimulatorRuntimeFPFPCall target =
1501 reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
1502 dresult = target(dval0, dval1);
1503 SetFpResult(dresult);
1504 break;
1505 }
1506 case ExternalReference::BUILTIN_FP_CALL: {
1526 SimulatorRuntimeFPCall target = 1507 SimulatorRuntimeFPCall target =
1527 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1508 reinterpret_cast<SimulatorRuntimeFPCall>(external);
1528 double result = target(arg0, arg1, arg2, arg3); 1509 dresult = target(dval0);
1529 SetFpResult(result); 1510 SetFpResult(dresult);
1530 } else { 1511 break;
1531 SimulatorRuntimeCall target = 1512 }
1532 reinterpret_cast<SimulatorRuntimeCall>(external); 1513 case ExternalReference::BUILTIN_FP_INT_CALL: {
1533 uint64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5); 1514 SimulatorRuntimeFPIntCall target =
1534 int32_t gpreg_pair[2]; 1515 reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
1535 memcpy(&gpreg_pair[0], &result, 2 * sizeof(int32_t)); 1516 dresult = target(dval0, ival);
1536 set_register(v0, gpreg_pair[0]); 1517 SetFpResult(dresult);
1537 set_register(v1, gpreg_pair[1]); 1518 break;
1519 }
1520 default:
1521 UNREACHABLE();
1522 break;
1523 }
1524 if (::v8::internal::FLAG_trace_sim) {
1525 switch (redirection->type()) {
1526 case ExternalReference::BUILTIN_COMPARE_CALL:
1527 PrintF("Returned %08x\n", static_cast<int32_t>(iresult));
1528 break;
1529 case ExternalReference::BUILTIN_FP_FP_CALL:
1530 case ExternalReference::BUILTIN_FP_CALL:
1531 case ExternalReference::BUILTIN_FP_INT_CALL:
1532 PrintF("Returned %f\n", dresult);
1533 break;
1534 default:
1535 UNREACHABLE();
1536 break;
1537 }
1538 } 1538 }
1539 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { 1539 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1540 // See DirectCEntryStub::GenerateCall for explanation of register usage. 1540 // See DirectCEntryStub::GenerateCall for explanation of register usage.
1541 SimulatorRuntimeDirectApiCall target = 1541 SimulatorRuntimeDirectApiCall target =
1542 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); 1542 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
1543 if (::v8::internal::FLAG_trace_sim) { 1543 if (::v8::internal::FLAG_trace_sim) {
1544 PrintF("Call to host function at %p args %08x\n", 1544 PrintF("Call to host function at %p args %08x\n",
1545 FUNCTION_ADDR(target), arg1); 1545 FUNCTION_ADDR(target), arg1);
1546 } 1546 }
1547 v8::Handle<v8::Value> result = target(arg1); 1547 v8::Handle<v8::Value> result = target(arg1);
(...skipping 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after
2899 } 2899 }
2900 2900
2901 2901
2902 #undef UNSUPPORTED 2902 #undef UNSUPPORTED
2903 2903
2904 } } // namespace v8::internal 2904 } } // namespace v8::internal
2905 2905
2906 #endif // USE_SIMULATOR 2906 #endif // USE_SIMULATOR
2907 2907
2908 #endif // V8_TARGET_ARCH_MIPS 2908 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698