| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <limits.h> | 5 #include <limits.h> |
| 6 #include <stdarg.h> | 6 #include <stdarg.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #if V8_TARGET_ARCH_MIPS | 10 #if V8_TARGET_ARCH_MIPS |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 // SScanF not being implemented in a platform independent was through | 44 // SScanF not being implemented in a platform independent was through |
| 45 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time | 45 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time |
| 46 // Library does not provide vsscanf. | 46 // Library does not provide vsscanf. |
| 47 #define SScanF sscanf // NOLINT | 47 #define SScanF sscanf // NOLINT |
| 48 | 48 |
| 49 // The MipsDebugger class is used by the simulator while debugging simulated | 49 // The MipsDebugger class is used by the simulator while debugging simulated |
| 50 // code. | 50 // code. |
| 51 class MipsDebugger { | 51 class MipsDebugger { |
| 52 public: | 52 public: |
| 53 explicit MipsDebugger(Simulator* sim) : sim_(sim) { } | 53 explicit MipsDebugger(Simulator* sim) : sim_(sim) { } |
| 54 ~MipsDebugger(); | |
| 55 | 54 |
| 56 void Stop(Instruction* instr); | 55 void Stop(Instruction* instr); |
| 57 void Debug(); | 56 void Debug(); |
| 58 // Print all registers with a nice formatting. | 57 // Print all registers with a nice formatting. |
| 59 void PrintAllRegs(); | 58 void PrintAllRegs(); |
| 60 void PrintAllRegsIncludingFPU(); | 59 void PrintAllRegsIncludingFPU(); |
| 61 | 60 |
| 62 private: | 61 private: |
| 63 // We set the breakpoint code to 0xfffff to easily recognize it. | 62 // We set the breakpoint code to 0xfffff to easily recognize it. |
| 64 static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6; | 63 static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 78 bool SetBreakpoint(Instruction* breakpc); | 77 bool SetBreakpoint(Instruction* breakpc); |
| 79 bool DeleteBreakpoint(Instruction* breakpc); | 78 bool DeleteBreakpoint(Instruction* breakpc); |
| 80 | 79 |
| 81 // Undo and redo all breakpoints. This is needed to bracket disassembly and | 80 // Undo and redo all breakpoints. This is needed to bracket disassembly and |
| 82 // execution to skip past breakpoints when run from the debugger. | 81 // execution to skip past breakpoints when run from the debugger. |
| 83 void UndoBreakpoints(); | 82 void UndoBreakpoints(); |
| 84 void RedoBreakpoints(); | 83 void RedoBreakpoints(); |
| 85 }; | 84 }; |
| 86 | 85 |
| 87 | 86 |
| 88 MipsDebugger::~MipsDebugger() { | 87 #define UNSUPPORTED() printf("Sim: Unsupported instruction.\n"); |
| 89 } | |
| 90 | |
| 91 | |
| 92 #ifdef GENERATED_CODE_COVERAGE | |
| 93 static FILE* coverage_log = NULL; | |
| 94 | |
| 95 | |
| 96 static void InitializeCoverage() { | |
| 97 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); | |
| 98 if (file_name != NULL) { | |
| 99 coverage_log = fopen(file_name, "aw+"); | |
| 100 } | |
| 101 } | |
| 102 | 88 |
| 103 | 89 |
| 104 void MipsDebugger::Stop(Instruction* instr) { | 90 void MipsDebugger::Stop(Instruction* instr) { |
| 105 // Get the stop code. | 91 // Get the stop code. |
| 106 uint32_t code = instr->Bits(25, 6); | |
| 107 // Retrieve the encoded address, which comes just after this stop. | |
| 108 char** msg_address = | |
| 109 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); | |
| 110 char* msg = *msg_address; | |
| 111 DCHECK(msg != NULL); | |
| 112 | |
| 113 // Update this stop description. | |
| 114 if (!watched_stops_[code].desc) { | |
| 115 watched_stops_[code].desc = msg; | |
| 116 } | |
| 117 | |
| 118 if (strlen(msg) > 0) { | |
| 119 if (coverage_log != NULL) { | |
| 120 fprintf(coverage_log, "%s\n", str); | |
| 121 fflush(coverage_log); | |
| 122 } | |
| 123 // Overwrite the instruction and address with nops. | |
| 124 instr->SetInstructionBits(kNopInstr); | |
| 125 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr); | |
| 126 } | |
| 127 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstructionSize); | |
| 128 } | |
| 129 | |
| 130 | |
| 131 #else // GENERATED_CODE_COVERAGE | |
| 132 | |
| 133 #define UNSUPPORTED() printf("Sim: Unsupported instruction.\n"); | |
| 134 | |
| 135 static void InitializeCoverage() {} | |
| 136 | |
| 137 | |
| 138 void MipsDebugger::Stop(Instruction* instr) { | |
| 139 // Get the stop code. | |
| 140 uint32_t code = instr->Bits(25, 6); | 92 uint32_t code = instr->Bits(25, 6); |
| 141 // Retrieve the encoded address, which comes just after this stop. | 93 // Retrieve the encoded address, which comes just after this stop. |
| 142 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + | 94 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + |
| 143 Instruction::kInstrSize); | 95 Instruction::kInstrSize); |
| 144 // Update this stop description. | 96 // Update this stop description. |
| 145 if (!sim_->watched_stops_[code].desc) { | 97 if (!sim_->watched_stops_[code].desc) { |
| 146 sim_->watched_stops_[code].desc = msg; | 98 sim_->watched_stops_[code].desc = msg; |
| 147 } | 99 } |
| 148 PrintF("Simulator hit %s (%u)\n", msg, code); | 100 PrintF("Simulator hit %s (%u)\n", msg, code); |
| 149 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize); | 101 sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize); |
| 150 Debug(); | 102 Debug(); |
| 151 } | 103 } |
| 152 #endif // GENERATED_CODE_COVERAGE | |
| 153 | 104 |
| 154 | 105 |
| 155 int32_t MipsDebugger::GetRegisterValue(int regnum) { | 106 int32_t MipsDebugger::GetRegisterValue(int regnum) { |
| 156 if (regnum == kNumSimuRegisters) { | 107 if (regnum == kNumSimuRegisters) { |
| 157 return sim_->get_pc(); | 108 return sim_->get_pc(); |
| 158 } else { | 109 } else { |
| 159 return sim_->get_register(regnum); | 110 return sim_->get_register(regnum); |
| 160 } | 111 } |
| 161 } | 112 } |
| 162 | 113 |
| (...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 } | 921 } |
| 971 | 922 |
| 972 // The sp is initialized to point to the bottom (high address) of the | 923 // The sp is initialized to point to the bottom (high address) of the |
| 973 // allocated stack area. To be safe in potential stack underflows we leave | 924 // allocated stack area. To be safe in potential stack underflows we leave |
| 974 // some buffer below. | 925 // some buffer below. |
| 975 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size_ - 64; | 926 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size_ - 64; |
| 976 // The ra and pc are initialized to a known bad value that will cause an | 927 // The ra and pc are initialized to a known bad value that will cause an |
| 977 // access violation if the simulator ever tries to execute it. | 928 // access violation if the simulator ever tries to execute it. |
| 978 registers_[pc] = bad_ra; | 929 registers_[pc] = bad_ra; |
| 979 registers_[ra] = bad_ra; | 930 registers_[ra] = bad_ra; |
| 980 InitializeCoverage(); | |
| 981 last_debugger_input_ = NULL; | 931 last_debugger_input_ = NULL; |
| 982 } | 932 } |
| 983 | 933 |
| 984 | 934 |
| 985 Simulator::~Simulator() { free(stack_); } | 935 Simulator::~Simulator() { free(stack_); } |
| 986 | 936 |
| 987 | 937 |
| 988 // When the generated code calls an external reference we need to catch that in | 938 // When the generated code calls an external reference we need to catch that in |
| 989 // the simulator. The external reference will be a function compiled for the | 939 // the simulator. The external reference will be a function compiled for the |
| 990 // host architecture. We need to call that function instead of trying to | 940 // host architecture. We need to call that function instead of trying to |
| (...skipping 3647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4638 | 4588 |
| 4639 | 4589 |
| 4640 #undef UNSUPPORTED | 4590 #undef UNSUPPORTED |
| 4641 | 4591 |
| 4642 } // namespace internal | 4592 } // namespace internal |
| 4643 } // namespace v8 | 4593 } // namespace v8 |
| 4644 | 4594 |
| 4645 #endif // USE_SIMULATOR | 4595 #endif // USE_SIMULATOR |
| 4646 | 4596 |
| 4647 #endif // V8_TARGET_ARCH_MIPS | 4597 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |