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

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

Issue 6966031: MIPS: Update for 23-May commits, and a few older ones. (Closed)
Patch Set: Created 9 years, 7 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
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 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 if (argc == next_arg) { 489 if (argc == next_arg) {
490 words = 10; 490 words = 10;
491 } else if (argc == next_arg + 1) { 491 } else if (argc == next_arg + 1) {
492 if (!GetValue(argv[next_arg], &words)) { 492 if (!GetValue(argv[next_arg], &words)) {
493 words = 10; 493 words = 10;
494 } 494 }
495 } 495 }
496 end = cur + words; 496 end = cur + words;
497 497
498 while (cur < end) { 498 while (cur < end) {
499 PrintF(" 0x%08x: 0x%08x %10d\n", 499 PrintF(" 0x%08x: 0x%08x %10d",
500 reinterpret_cast<intptr_t>(cur), *cur, *cur); 500 reinterpret_cast<intptr_t>(cur), *cur, *cur);
501 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
502 int value = *cur;
503 Heap* current_heap = v8::internal::Isolate::Current()->heap();
504 if (current_heap->Contains(obj) || ((value & 1) == 0)) {
505 PrintF(" (");
506 if ((value & 1) == 0) {
507 PrintF("smi %d", value / 2);
508 } else {
509 obj->ShortPrint();
510 }
511 PrintF(")");
512 }
513 PrintF("\n");
501 cur++; 514 cur++;
502 } 515 }
503 516
504 } else if ((strcmp(cmd, "disasm") == 0) || (strcmp(cmd, "dpc") == 0)) { 517 } else if ((strcmp(cmd, "disasm") == 0) ||
518 (strcmp(cmd, "dpc") == 0) ||
519 (strcmp(cmd, "di") == 0)) {
505 disasm::NameConverter converter; 520 disasm::NameConverter converter;
506 disasm::Disassembler dasm(converter); 521 disasm::Disassembler dasm(converter);
507 // Use a reasonably large buffer. 522 // Use a reasonably large buffer.
508 v8::internal::EmbeddedVector<char, 256> buffer; 523 v8::internal::EmbeddedVector<char, 256> buffer;
509 524
510 byte* cur = NULL; 525 byte* cur = NULL;
511 byte* end = NULL; 526 byte* end = NULL;
512 527
513 if (argc == 1) { 528 if (argc == 1) {
514 cur = reinterpret_cast<byte*>(sim_->get_pc()); 529 cur = reinterpret_cast<byte*>(sim_->get_pc());
515 end = cur + (10 * Instruction::kInstrSize); 530 end = cur + (10 * Instruction::kInstrSize);
516 } else if (argc == 2) { 531 } else if (argc == 2) {
517 int32_t value; 532 int regnum = Registers::Number(arg1);
518 if (GetValue(arg1, &value)) { 533 if (regnum != kInvalidRegister || strncmp(arg1, "0x", 2) == 0) {
519 cur = reinterpret_cast<byte*>(value); 534 // The argument is an address or a register name.
520 // No length parameter passed, assume 10 instructions. 535 int32_t value;
521 end = cur + (10 * Instruction::kInstrSize); 536 if (GetValue(arg1, &value)) {
537 cur = reinterpret_cast<byte*>(value);
538 // Disassemble 10 instructions at <arg1>.
539 end = cur + (10 * Instruction::kInstrSize);
540 }
541 } else {
542 // The argument is the number of instructions.
543 int32_t value;
544 if (GetValue(arg1, &value)) {
545 cur = reinterpret_cast<byte*>(sim_->get_pc());
546 // Disassemble <arg1> instructions.
547 end = cur + (value * Instruction::kInstrSize);
548 }
522 } 549 }
523 } else { 550 } else {
524 int32_t value1; 551 int32_t value1;
525 int32_t value2; 552 int32_t value2;
526 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) { 553 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
527 cur = reinterpret_cast<byte*>(value1); 554 cur = reinterpret_cast<byte*>(value1);
528 end = cur + (value2 * Instruction::kInstrSize); 555 end = cur + (value2 * Instruction::kInstrSize);
529 } 556 }
530 } 557 }
531 558
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 PrintF(" use register name 'all' to print all registers\n"); 635 PrintF(" use register name 'all' to print all registers\n");
609 PrintF("printobject <register>\n"); 636 PrintF("printobject <register>\n");
610 PrintF(" print an object from a register (alias 'po')\n"); 637 PrintF(" print an object from a register (alias 'po')\n");
611 PrintF("stack [<words>]\n"); 638 PrintF("stack [<words>]\n");
612 PrintF(" dump stack content, default dump 10 words)\n"); 639 PrintF(" dump stack content, default dump 10 words)\n");
613 PrintF("mem <address> [<words>]\n"); 640 PrintF("mem <address> [<words>]\n");
614 PrintF(" dump memory content, default dump 10 words)\n"); 641 PrintF(" dump memory content, default dump 10 words)\n");
615 PrintF("flags\n"); 642 PrintF("flags\n");
616 PrintF(" print flags\n"); 643 PrintF(" print flags\n");
617 PrintF("disasm [<instructions>]\n"); 644 PrintF("disasm [<instructions>]\n");
618 PrintF("disasm [[<address>] <instructions>]\n"); 645 PrintF("disasm [<address/register>]\n");
619 PrintF(" disassemble code, default is 10 instructions from pc\n"); 646 PrintF("disasm [[<address/register>] <instructions>]\n");
647 PrintF(" disassemble code, default is 10 instructions\n");
648 PrintF(" from pc (alias 'di')\n");
620 PrintF("gdb\n"); 649 PrintF("gdb\n");
621 PrintF(" enter gdb\n"); 650 PrintF(" enter gdb\n");
622 PrintF("break <address>\n"); 651 PrintF("break <address>\n");
623 PrintF(" set a break point on the address\n"); 652 PrintF(" set a break point on the address\n");
624 PrintF("del\n"); 653 PrintF("del\n");
625 PrintF(" delete the breakpoint\n"); 654 PrintF(" delete the breakpoint\n");
626 PrintF("unstop\n"); 655 PrintF("unstop\n");
627 PrintF(" ignore the stop instruction at the current location"); 656 PrintF(" ignore the stop instruction at the current location");
628 PrintF(" from now on\n"); 657 PrintF(" from now on\n");
629 } else { 658 } else {
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 const_cast<int32_t*>(&FPUregisters_[fpureg])); 956 const_cast<int32_t*>(&FPUregisters_[fpureg]));
928 } 957 }
929 958
930 959
931 double Simulator::get_fpu_register_double(int fpureg) const { 960 double Simulator::get_fpu_register_double(int fpureg) const {
932 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); 961 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
933 return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg])); 962 return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg]));
934 } 963 }
935 964
936 965
966 // For use in calls that take two double values, constructed either
967 // from a0-a3 or f12 and f14.
968 void Simulator::GetFpArgs(double* x, double* y) {
969 if (!IsMipsSoftFloatABI) {
970 *x = get_fpu_register_double(12);
971 *y = get_fpu_register_double(14);
972 } else {
973 // We use a char buffer to get around the strict-aliasing rules which
974 // otherwise allow the compiler to optimize away the copy.
975 char buffer[sizeof(*x)];
976 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
977
978 // Registers a0 and a1 -> x.
979 reg_buffer[0] = get_register(a0);
980 reg_buffer[1] = get_register(a1);
981 memcpy(x, buffer, sizeof(buffer));
982
983 // Registers a2 and a3 -> y.
984 reg_buffer[0] = get_register(a2);
985 reg_buffer[1] = get_register(a3);
986 memcpy(y, buffer, sizeof(buffer));
987 }
988 }
989
990
991 // For use in calls that take one double value, constructed either
992 // from a0 and a1 or f12.
993 void Simulator::GetFpArgs(double* x) {
994 if (!IsMipsSoftFloatABI) {
995 *x = get_fpu_register_double(12);
996 } else {
997 // We use a char buffer to get around the strict-aliasing rules which
998 // otherwise allow the compiler to optimize away the copy.
999 char buffer[sizeof(*x)];
1000 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1001 // Registers a0 and a1 -> x.
1002 reg_buffer[0] = get_register(a0);
1003 reg_buffer[1] = get_register(a1);
1004 memcpy(x, buffer, sizeof(buffer));
1005 }
1006 }
1007
1008
1009 // For use in calls that take one double value constructed either
1010 // from a0 and a1 or f12 and one integer value.
1011 void Simulator::GetFpArgs(double* x, int32_t* y) {
1012 if (!IsMipsSoftFloatABI) {
1013 *x = get_fpu_register_double(12);
1014 *y = get_register(a2);
1015 } else {
1016 // We use a char buffer to get around the strict-aliasing rules which
1017 // otherwise allow the compiler to optimize away the copy.
1018 char buffer[sizeof(*x)];
1019 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1020 // Registers 0 and 1 -> x.
1021 reg_buffer[0] = get_register(a0);
1022 reg_buffer[1] = get_register(a1);
1023 memcpy(x, buffer, sizeof(buffer));
1024
1025 // Register 2 -> y.
1026 reg_buffer[0] = get_register(a2);
1027 memcpy(y, buffer, sizeof(*y));
1028 }
1029 }
1030
1031
1032 // The return value is either in v0/v1 or f0.
1033 void Simulator::SetFpResult(const double& result) {
1034 if (!IsMipsSoftFloatABI) {
1035 set_fpu_register_double(0, result);
1036 } else {
1037 char buffer[2 * sizeof(registers_[0])];
1038 int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
1039 memcpy(buffer, &result, sizeof(buffer));
1040 // Copy result to v0 and v1.
1041 set_register(v0, reg_buffer[0]);
1042 set_register(v1, reg_buffer[1]);
1043 }
1044 }
1045
1046
937 // Helper functions for setting and testing the FCSR register's bits. 1047 // Helper functions for setting and testing the FCSR register's bits.
938 void Simulator::set_fcsr_bit(uint32_t cc, bool value) { 1048 void Simulator::set_fcsr_bit(uint32_t cc, bool value) {
939 if (value) { 1049 if (value) {
940 FCSR_ |= (1 << cc); 1050 FCSR_ |= (1 << cc);
941 } else { 1051 } else {
942 FCSR_ &= ~(1 << cc); 1052 FCSR_ &= ~(1 << cc);
943 } 1053 }
944 } 1054 }
945 1055
946 1056
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 arg4 = stack_pointer[4]; 1311 arg4 = stack_pointer[4];
1202 arg5 = stack_pointer[5]; 1312 arg5 = stack_pointer[5];
1203 } 1313 }
1204 1314
1205 bool fp_call = 1315 bool fp_call =
1206 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || 1316 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1207 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || 1317 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1208 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || 1318 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1209 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); 1319 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1210 1320
1321 if (!IsMipsSoftFloatABI) {
1322 // With the hard floating point calling convention, double
1323 // arguments are passed in FPU registers. Fetch the arguments
1324 // from there and call the builtin using soft floating point
1325 // convention.
1326 switch (redirection->type()) {
1327 case ExternalReference::BUILTIN_FP_FP_CALL:
1328 case ExternalReference::BUILTIN_COMPARE_CALL:
1329 arg0 = get_fpu_register(f12);
1330 arg1 = get_fpu_register(f13);
1331 arg2 = get_fpu_register(f14);
1332 arg3 = get_fpu_register(f15);
1333 break;
1334 case ExternalReference::BUILTIN_FP_CALL:
1335 arg0 = get_fpu_register(f12);
1336 arg1 = get_fpu_register(f13);
1337 break;
1338 case ExternalReference::BUILTIN_FP_INT_CALL:
1339 arg0 = get_fpu_register(f12);
1340 arg1 = get_fpu_register(f13);
1341 arg2 = get_register(a2);
1342 break;
1343 default:
1344 break;
1345 }
1346 }
1347
1211 // This is dodgy but it works because the C entry stubs are never moved. 1348 // This is dodgy but it works because the C entry stubs are never moved.
1212 // See comment in codegen-arm.cc and bug 1242173. 1349 // See comment in codegen-arm.cc and bug 1242173.
1213 int32_t saved_ra = get_register(ra); 1350 int32_t saved_ra = get_register(ra);
1214 1351
1215 intptr_t external = 1352 intptr_t external =
1216 reinterpret_cast<intptr_t>(redirection->external_function()); 1353 reinterpret_cast<intptr_t>(redirection->external_function());
1217 1354
1218 // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware 1355 // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware
1219 // FPU, or gcc soft-float routines. Hardware FPU is simulated in this 1356 // FPU, or gcc soft-float routines. Hardware FPU is simulated in this
1220 // simulator. Soft-float has additional abstraction of ExternalReference, 1357 // simulator. Soft-float has additional abstraction of ExternalReference,
1221 // to support serialization. Finally, when simulated on x86 host, the 1358 // to support serialization.
1222 // x86 softfloat routines are used, and this Redirection infrastructure
1223 // lets simulated-mips make calls into x86 C code.
1224 // When doing that, the 'double' return type must be handled differently
1225 // than the usual int64_t return. The data is returned in different
1226 // registers and cannot be cast from one type to the other. However, the
1227 // calling arguments are passed the same way in both cases.
1228 if (fp_call) { 1359 if (fp_call) {
1229 SimulatorRuntimeFPCall target = 1360 SimulatorRuntimeFPCall target =
1230 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1361 reinterpret_cast<SimulatorRuntimeFPCall>(external);
1231 if (::v8::internal::FLAG_trace_sim) { 1362 if (::v8::internal::FLAG_trace_sim) {
1232 PrintF( 1363 double dval0, dval1;
1233 "Call to host function at %p args %08x, %08x, %08x, %08x\n", 1364 int32_t ival;
1234 FUNCTION_ADDR(target), 1365 switch (redirection->type()) {
1235 arg0, 1366 case ExternalReference::BUILTIN_FP_FP_CALL:
1236 arg1, 1367 case ExternalReference::BUILTIN_COMPARE_CALL:
1237 arg2, 1368 GetFpArgs(&dval0, &dval1);
1238 arg3); 1369 PrintF("Call to host function at %p with args %f, %f",
1239 } 1370 FUNCTION_ADDR(target), dval0, dval1);
1371 break;
1372 case ExternalReference::BUILTIN_FP_CALL:
1373 GetFpArgs(&dval0);
1374 PrintF("Call to host function at %p with arg %f",
1375 FUNCTION_ADDR(target), dval1);
1376 break;
1377 case ExternalReference::BUILTIN_FP_INT_CALL:
1378 GetFpArgs(&dval0, &ival);
1379 PrintF("Call to host function at %p with args %f, %d",
1380 FUNCTION_ADDR(target), dval0, ival);
1381 break;
1382 default:
1383 UNREACHABLE();
1384 break;
1385 }
1386 }
1240 double result = target(arg0, arg1, arg2, arg3); 1387 double result = target(arg0, arg1, arg2, arg3);
1241 // fp result -> registers v0 and v1. 1388 if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) {
1242 int32_t gpreg_pair[2]; 1389 SetFpResult(result);
1243 memcpy(&gpreg_pair[0], &result, 2 * sizeof(int32_t)); 1390 } else {
1244 set_register(v0, gpreg_pair[0]); 1391 int32_t gpreg_pair[2];
1245 set_register(v1, gpreg_pair[1]); 1392 memcpy(&gpreg_pair[0], &result, 2 * sizeof(int32_t));
1393 set_register(v0, gpreg_pair[0]);
1394 set_register(v1, gpreg_pair[1]);
1395 }
1246 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { 1396 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1247 // See DirectCEntryStub::GenerateCall for explanation of register usage. 1397 // See DirectCEntryStub::GenerateCall for explanation of register usage.
1248 SimulatorRuntimeDirectApiCall target = 1398 SimulatorRuntimeDirectApiCall target =
1249 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); 1399 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
1250 if (::v8::internal::FLAG_trace_sim) { 1400 if (::v8::internal::FLAG_trace_sim) {
1251 PrintF("Call to host function at %p args %08x\n", 1401 PrintF("Call to host function at %p args %08x\n",
1252 FUNCTION_ADDR(target), arg1); 1402 FUNCTION_ADDR(target), arg1);
1253 } 1403 }
1254 v8::Handle<v8::Value> result = target(arg1); 1404 v8::Handle<v8::Value> result = target(arg1);
1255 *(reinterpret_cast<int*>(arg0)) = (int32_t) *result; 1405 *(reinterpret_cast<int*>(arg0)) = (int32_t) *result;
(...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2462 } 2612 }
2463 2613
2464 2614
2465 #undef UNSUPPORTED 2615 #undef UNSUPPORTED
2466 2616
2467 } } // namespace v8::internal 2617 } } // namespace v8::internal
2468 2618
2469 #endif // USE_SIMULATOR 2619 #endif // USE_SIMULATOR
2470 2620
2471 #endif // V8_TARGET_ARCH_MIPS 2621 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698