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

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

Issue 7062014: MIPS: Added the stop() instruction with same behavior as on Arm simulator. (Closed)
Patch Set: Created 9 years, 6 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
« src/mips/simulator-mips.h ('K') | « 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 119
120 static void InitializeCoverage() { 120 static void InitializeCoverage() {
121 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); 121 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
122 if (file_name != NULL) { 122 if (file_name != NULL) {
123 coverage_log = fopen(file_name, "aw+"); 123 coverage_log = fopen(file_name, "aw+");
124 } 124 }
125 } 125 }
126 126
127 127
128 void MipsDebugger::Stop(Instruction* instr) { 128 void MipsDebugger::Stop(Instruction* instr) {
129 UNIMPLEMENTED_MIPS(); 129 // Get the stop code.
130 char* str = reinterpret_cast<char*>(instr->InstructionBits()); 130 uint32_t code = instr->Bits(25, 6);
131 if (strlen(str) > 0) { 131 // Retrieve the encoded address, which comes just after this stop.
132 char** msg_address =
133 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);
134 char* msg = *msg_address;
135 ASSERT(msg != NULL);
136
137 // Update this stop description.
138 if (!watched_stops[code].desc) {
139 watched_stops[code].desc = msg;
140 }
141
142 if (strlen(msg) > 0) {
132 if (coverage_log != NULL) { 143 if (coverage_log != NULL) {
133 fprintf(coverage_log, "%s\n", str); 144 fprintf(coverage_log, "%s\n", str);
134 fflush(coverage_log); 145 fflush(coverage_log);
135 } 146 }
136 instr->SetInstructionBits(0x0); // Overwrite with nop. 147 // Overwrite the instruction and address with nops.
148 instr->SetInstructionBits(kNopInstr);
149 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr);
137 } 150 }
138 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize); 151 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstructionSize);
139 } 152 }
140 153
141 154
142 #else // GENERATED_CODE_COVERAGE 155 #else // GENERATED_CODE_COVERAGE
143 156
144 #define UNSUPPORTED() printf("Unsupported instruction.\n"); 157 #define UNSUPPORTED() printf("Unsupported instruction.\n");
145 158
146 static void InitializeCoverage() {} 159 static void InitializeCoverage() {}
147 160
148 161
149 void MipsDebugger::Stop(Instruction* instr) { 162 void MipsDebugger::Stop(Instruction* instr) {
150 const char* str = reinterpret_cast<char*>(instr->InstructionBits()); 163 // Get the stop code.
151 PrintF("Simulator hit %s\n", str); 164 uint32_t code = instr->Bits(25, 6);
152 sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize); 165 // Retrieve the encoded address, which comes just after this stop.
166 char* msg = *reinterpret_cast<char**>(sim_->get_pc() +
167 Instruction::kInstrSize);
168 // Update this stop description.
169 if (!sim_->watched_stops[code].desc) {
170 sim_->watched_stops[code].desc = msg;
171 }
172 PrintF("Simulator hit %s (%u)\n", msg, code);
173 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
153 Debug(); 174 Debug();
154 } 175 }
155 #endif // GENERATED_CODE_COVERAGE 176 #endif // GENERATED_CODE_COVERAGE
156 177
157 178
158 int32_t MipsDebugger::GetRegisterValue(int regnum) { 179 int32_t MipsDebugger::GetRegisterValue(int regnum) {
159 if (regnum == kNumSimuRegisters) { 180 if (regnum == kNumSimuRegisters) {
160 return sim_->get_pc(); 181 return sim_->get_pc();
161 } else { 182 } else {
162 return sim_->get_register(regnum); 183 return sim_->get_register(regnum);
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 } 599 }
579 } else { 600 } else {
580 PrintF("break <address>\n"); 601 PrintF("break <address>\n");
581 } 602 }
582 } else if (strcmp(cmd, "del") == 0) { 603 } else if (strcmp(cmd, "del") == 0) {
583 if (!DeleteBreakpoint(NULL)) { 604 if (!DeleteBreakpoint(NULL)) {
584 PrintF("deleting breakpoint failed\n"); 605 PrintF("deleting breakpoint failed\n");
585 } 606 }
586 } else if (strcmp(cmd, "flags") == 0) { 607 } else if (strcmp(cmd, "flags") == 0) {
587 PrintF("No flags on MIPS !\n"); 608 PrintF("No flags on MIPS !\n");
588 } else if (strcmp(cmd, "unstop") == 0) { 609 } else if (strcmp(cmd, "stop") == 0) {
589 PrintF("Unstop command not implemented on MIPS."); 610 int32_t value;
611 intptr_t stop_pc = sim_->get_pc() -
612 2 * Instruction::kInstrSize;
613 Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
614 Instruction* msg_address =
615 reinterpret_cast<Instruction*>(stop_pc +
616 Instruction::kInstrSize);
617 if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
618 // Remove the current stop.
619 if (sim_->isStopInstruction(stop_instr)) {
620 stop_instr->SetInstructionBits(kNopInstr);
621 msg_address->SetInstructionBits(kNopInstr);
622 } else {
623 PrintF("Not at debugger stop.\n");
624 }
625 } else if (argc == 3) {
626 // Print information about all/the specified breakpoint(s).
627 if (strcmp(arg1, "info") == 0) {
628 if (strcmp(arg2, "all") == 0) {
629 PrintF("Stop information:\n");
630 for (uint32_t i = kMaxWatchpointCode + 1;
631 i <= kMaxStopCode;
632 i++) {
633 sim_->PrintStopInfo(i);
634 }
635 } else if (GetValue(arg2, &value)) {
636 sim_->PrintStopInfo(value);
637 } else {
638 PrintF("Unrecognized argument.\n");
639 }
640 } else if (strcmp(arg1, "enable") == 0) {
641 // Enable all/the specified breakpoint(s).
642 if (strcmp(arg2, "all") == 0) {
643 for (uint32_t i = kMaxWatchpointCode + 1;
644 i <= kMaxStopCode;
645 i++) {
646 sim_->EnableStop(i);
647 }
648 } else if (GetValue(arg2, &value)) {
649 sim_->EnableStop(value);
650 } else {
651 PrintF("Unrecognized argument.\n");
652 }
653 } else if (strcmp(arg1, "disable") == 0) {
654 // Disable all/the specified breakpoint(s).
655 if (strcmp(arg2, "all") == 0) {
656 for (uint32_t i = kMaxWatchpointCode + 1;
657 i <= kMaxStopCode;
658 i++) {
659 sim_->DisableStop(i);
660 }
661 } else if (GetValue(arg2, &value)) {
662 sim_->DisableStop(value);
663 } else {
664 PrintF("Unrecognized argument.\n");
665 }
666 }
667 } else {
668 PrintF("Wrong usage. Use help command for more information.\n");
669 }
590 } else if ((strcmp(cmd, "stat") == 0) || (strcmp(cmd, "st") == 0)) { 670 } else if ((strcmp(cmd, "stat") == 0) || (strcmp(cmd, "st") == 0)) {
591 // Print registers and disassemble. 671 // Print registers and disassemble.
592 PrintAllRegs(); 672 PrintAllRegs();
593 PrintF("\n"); 673 PrintF("\n");
594 674
595 disasm::NameConverter converter; 675 disasm::NameConverter converter;
596 disasm::Disassembler dasm(converter); 676 disasm::Disassembler dasm(converter);
597 // Use a reasonably large buffer. 677 // Use a reasonably large buffer.
598 v8::internal::EmbeddedVector<char, 256> buffer; 678 v8::internal::EmbeddedVector<char, 256> buffer;
599 679
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 PrintF("disasm [<address/register>]\n"); 725 PrintF("disasm [<address/register>]\n");
646 PrintF("disasm [[<address/register>] <instructions>]\n"); 726 PrintF("disasm [[<address/register>] <instructions>]\n");
647 PrintF(" disassemble code, default is 10 instructions\n"); 727 PrintF(" disassemble code, default is 10 instructions\n");
648 PrintF(" from pc (alias 'di')\n"); 728 PrintF(" from pc (alias 'di')\n");
649 PrintF("gdb\n"); 729 PrintF("gdb\n");
650 PrintF(" enter gdb\n"); 730 PrintF(" enter gdb\n");
651 PrintF("break <address>\n"); 731 PrintF("break <address>\n");
652 PrintF(" set a break point on the address\n"); 732 PrintF(" set a break point on the address\n");
653 PrintF("del\n"); 733 PrintF("del\n");
654 PrintF(" delete the breakpoint\n"); 734 PrintF(" delete the breakpoint\n");
655 PrintF("unstop\n"); 735 PrintF("stop feature:\n");
656 PrintF(" ignore the stop instruction at the current location"); 736 PrintF(" Description:\n");
657 PrintF(" from now on\n"); 737 PrintF(" Stops are debug instructions inserted by\n");
738 PrintF(" the Assembler::stop() function.\n");
739 PrintF(" When hitting a stop, the Simulator will\n");
740 PrintF(" stop and and give control to the Debugger.\n");
741 PrintF(" All stop codes are watched:\n");
742 PrintF(" - They can be enabled / disabled: the Simulator\n");
743 PrintF(" will / won't stop when hitting them.\n");
744 PrintF(" - The Simulator keeps track of how many times they \n");
745 PrintF(" are met. (See the info command.) Going over a\n");
746 PrintF(" disabled stop still increases its counter. \n");
747 PrintF(" Commands:\n");
748 PrintF(" stop info all/<code> : print infos about number <code>\n");
749 PrintF(" or all stop(s).\n");
750 PrintF(" stop enable/disable all/<code> : enables / disables\n");
751 PrintF(" all or number <code> stop(s)\n");
752 PrintF(" stop unstop\n");
753 PrintF(" ignore the stop instruction at the current location\n");
754 PrintF(" from now on\n");
658 } else { 755 } else {
659 PrintF("Unknown command: %s\n", cmd); 756 PrintF("Unknown command: %s\n", cmd);
660 } 757 }
661 } 758 }
662 DeleteArray(line); 759 DeleteArray(line);
663 } 760 }
664 761
665 // Add all the breakpoints back to stop execution and enter the debugger 762 // Add all the breakpoints back to stop execution and enter the debugger
666 // shell when hit. 763 // shell when hit.
667 RedoBreakpoints(); 764 RedoBreakpoints();
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, 1378 typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
1282 int32_t arg1); 1379 int32_t arg1);
1283 1380
1284 // Software interrupt instructions are used by the simulator to call into the 1381 // Software interrupt instructions are used by the simulator to call into the
1285 // C-based V8 runtime. They are also used for debugging with simulator. 1382 // C-based V8 runtime. They are also used for debugging with simulator.
1286 void Simulator::SoftwareInterrupt(Instruction* instr) { 1383 void Simulator::SoftwareInterrupt(Instruction* instr) {
1287 // There are several instructions that could get us here, 1384 // There are several instructions that could get us here,
1288 // the break_ instruction, or several variants of traps. All 1385 // the break_ instruction, or several variants of traps. All
1289 // Are "SPECIAL" class opcode, and are distinuished by function. 1386 // Are "SPECIAL" class opcode, and are distinuished by function.
1290 int32_t func = instr->FunctionFieldRaw(); 1387 int32_t func = instr->FunctionFieldRaw();
1291 int32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1; 1388 uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1;
1292 1389
1293 // We first check if we met a call_rt_redirected. 1390 // We first check if we met a call_rt_redirected.
1294 if (instr->InstructionBits() == rtCallRedirInstr) { 1391 if (instr->InstructionBits() == rtCallRedirInstr) {
1295 Redirection* redirection = Redirection::FromSwiInstruction(instr); 1392 Redirection* redirection = Redirection::FromSwiInstruction(instr);
1296 int32_t arg0 = get_register(a0); 1393 int32_t arg0 = get_register(a0);
1297 int32_t arg1 = get_register(a1); 1394 int32_t arg1 = get_register(a1);
1298 int32_t arg2 = get_register(a2); 1395 int32_t arg2 = get_register(a2);
1299 int32_t arg3 = get_register(a3); 1396 int32_t arg3 = get_register(a3);
1300 int32_t arg4 = 0; 1397 int32_t arg4 = 0;
1301 int32_t arg5 = 0; 1398 int32_t arg5 = 0;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5); 1530 int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
1434 set_register(v0, static_cast<int32_t>(result)); 1531 set_register(v0, static_cast<int32_t>(result));
1435 set_register(v1, static_cast<int32_t>(result >> 32)); 1532 set_register(v1, static_cast<int32_t>(result >> 32));
1436 } 1533 }
1437 if (::v8::internal::FLAG_trace_sim) { 1534 if (::v8::internal::FLAG_trace_sim) {
1438 PrintF("Returned %08x : %08x\n", get_register(v1), get_register(v0)); 1535 PrintF("Returned %08x : %08x\n", get_register(v1), get_register(v0));
1439 } 1536 }
1440 set_register(ra, saved_ra); 1537 set_register(ra, saved_ra);
1441 set_pc(get_register(ra)); 1538 set_pc(get_register(ra));
1442 1539
1443 } else if (func == BREAK && code >= 0 && code < 32) { 1540 } else if (func == BREAK && code <= kMaxStopCode) {
1444 // First 32 break_ codes interpreted as debug-markers/watchpoints. 1541 if (isWatchpoint(code)) {
1445 MipsDebugger dbg(this); 1542 PrintWatchpoint(code);
1446 ++break_count_; 1543 } else {
1447 PrintF("\n---- break %d marker: %3d (instr count: %8d) ----------" 1544 IncreaseStopCounter(code);
1448 "----------------------------------", 1545 HandleStop(code, instr);
1449 code, break_count_, icount_); 1546 }
1450 dbg.PrintAllRegs(); // Print registers and continue running.
1451 } else { 1547 } else {
1452 // All remaining break_ codes, and all traps are handled here. 1548 // All remaining break_ codes, and all traps are handled here.
1453 MipsDebugger dbg(this); 1549 MipsDebugger dbg(this);
1454 dbg.Debug(); 1550 dbg.Debug();
1455 } 1551 }
1456 } 1552 }
1457 1553
1458 1554
1555 // Stop helper functions.
1556 bool Simulator::isWatchpoint(uint32_t code) {
1557 return (code <= kMaxWatchpointCode);
1558 }
1559
1560
1561 void Simulator::PrintWatchpoint(uint32_t code) {
1562 MipsDebugger dbg(this);
1563 ++break_count_;
1564 PrintF("\n---- break %d marker: %3d (instr count: %8d) ----------"
1565 "----------------------------------",
1566 code, break_count_, icount_);
1567 dbg.PrintAllRegs(); // Print registers and continue running.
1568 }
1569
1570
1571 void Simulator::HandleStop(uint32_t code, Instruction* instr) {
1572 // Stop if it is enabled, otherwise go on jumping over the stop
1573 // and the message address.
1574 if (isEnabledStop(code)) {
1575 MipsDebugger dbg(this);
1576 dbg.Stop(instr);
1577 } else {
1578 set_pc(get_pc() + 2 * Instruction::kInstrSize);
1579 }
1580 }
1581
1582
1583 bool Simulator::isStopInstruction(Instruction* instr) {
1584 int32_t func = instr->FunctionFieldRaw();
1585 uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6));
1586 return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode;
1587 }
1588
1589
1590 bool Simulator::isEnabledStop(uint32_t code) {
1591 ASSERT(code <= kMaxStopCode);
1592 ASSERT(code > kMaxWatchpointCode);
1593 return !(watched_stops[code].count & kStopDisabledBit);
1594 }
1595
1596
1597 void Simulator::EnableStop(uint32_t code) {
1598 if (!isEnabledStop(code)) {
1599 watched_stops[code].count &= ~kStopDisabledBit;
1600 }
1601 }
1602
1603
1604 void Simulator::DisableStop(uint32_t code) {
1605 if (isEnabledStop(code)) {
1606 watched_stops[code].count |= kStopDisabledBit;
1607 }
1608 }
1609
1610
1611 void Simulator::IncreaseStopCounter(uint32_t code) {
1612 ASSERT(code <= kMaxStopCode);
1613 if ((watched_stops[code].count & ~(1 << 31)) == 0x7fffffff) {
1614 PrintF("Stop counter for code %i has overflowed.\n"
1615 "Enabling this code and reseting the counter to 0.\n", code);
1616 watched_stops[code].count = 0;
1617 EnableStop(code);
1618 } else {
1619 watched_stops[code].count++;
1620 }
1621 }
1622
1623
1624 // Print a stop status.
1625 void Simulator::PrintStopInfo(uint32_t code) {
1626 if (code <= kMaxWatchpointCode) {
1627 PrintF("That is a watchpoint, not a stop.\n");
1628 return;
1629 } else if (code > kMaxStopCode) {
1630 PrintF("Code too large, only %u stops can be used\n", kMaxStopCode + 1);
1631 return;
1632 }
1633 const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
1634 int32_t count = watched_stops[code].count & ~kStopDisabledBit;
1635 // Don't print the state of unused breakpoints.
1636 if (count != 0) {
1637 if (watched_stops[code].desc) {
1638 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
1639 code, code, state, count, watched_stops[code].desc);
1640 } else {
1641 PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n",
1642 code, code, state, count);
1643 }
1644 }
1645 }
1646
1647
1459 void Simulator::SignalExceptions() { 1648 void Simulator::SignalExceptions() {
1460 for (int i = 1; i < kNumExceptions; i++) { 1649 for (int i = 1; i < kNumExceptions; i++) {
1461 if (exceptions[i] != 0) { 1650 if (exceptions[i] != 0) {
1462 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i); 1651 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i);
1463 } 1652 }
1464 } 1653 }
1465 } 1654 }
1466 1655
1467 1656
1468 // Handle execution based on instruction types. 1657 // Handle execution based on instruction types.
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 } 2801 }
2613 2802
2614 2803
2615 #undef UNSUPPORTED 2804 #undef UNSUPPORTED
2616 2805
2617 } } // namespace v8::internal 2806 } } // namespace v8::internal
2618 2807
2619 #endif // USE_SIMULATOR 2808 #endif // USE_SIMULATOR
2620 2809
2621 #endif // V8_TARGET_ARCH_MIPS 2810 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« src/mips/simulator-mips.h ('K') | « src/mips/simulator-mips.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698