| 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_MIPS64 | 10 #if V8_TARGET_ARCH_MIPS64 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 // SScanF not being implemented in a platform independent was through | 59 // SScanF not being implemented in a platform independent was through |
| 60 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time | 60 // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time |
| 61 // Library does not provide vsscanf. | 61 // Library does not provide vsscanf. |
| 62 #define SScanF sscanf // NOLINT | 62 #define SScanF sscanf // NOLINT |
| 63 | 63 |
| 64 // The MipsDebugger class is used by the simulator while debugging simulated | 64 // The MipsDebugger class is used by the simulator while debugging simulated |
| 65 // code. | 65 // code. |
| 66 class MipsDebugger { | 66 class MipsDebugger { |
| 67 public: | 67 public: |
| 68 explicit MipsDebugger(Simulator* sim) : sim_(sim) { } | 68 explicit MipsDebugger(Simulator* sim) : sim_(sim) { } |
| 69 ~MipsDebugger(); | |
| 70 | 69 |
| 71 void Stop(Instruction* instr); | 70 void Stop(Instruction* instr); |
| 72 void Debug(); | 71 void Debug(); |
| 73 // Print all registers with a nice formatting. | 72 // Print all registers with a nice formatting. |
| 74 void PrintAllRegs(); | 73 void PrintAllRegs(); |
| 75 void PrintAllRegsIncludingFPU(); | 74 void PrintAllRegsIncludingFPU(); |
| 76 | 75 |
| 77 private: | 76 private: |
| 78 // We set the breakpoint code to 0xfffff to easily recognize it. | 77 // We set the breakpoint code to 0xfffff to easily recognize it. |
| 79 static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6; | 78 static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 90 // Set or delete a breakpoint. Returns true if successful. | 89 // Set or delete a breakpoint. Returns true if successful. |
| 91 bool SetBreakpoint(Instruction* breakpc); | 90 bool SetBreakpoint(Instruction* breakpc); |
| 92 bool DeleteBreakpoint(Instruction* breakpc); | 91 bool DeleteBreakpoint(Instruction* breakpc); |
| 93 | 92 |
| 94 // Undo and redo all breakpoints. This is needed to bracket disassembly and | 93 // Undo and redo all breakpoints. This is needed to bracket disassembly and |
| 95 // execution to skip past breakpoints when run from the debugger. | 94 // execution to skip past breakpoints when run from the debugger. |
| 96 void UndoBreakpoints(); | 95 void UndoBreakpoints(); |
| 97 void RedoBreakpoints(); | 96 void RedoBreakpoints(); |
| 98 }; | 97 }; |
| 99 | 98 |
| 100 | 99 #define UNSUPPORTED() printf("Sim: Unsupported instruction.\n"); |
| 101 MipsDebugger::~MipsDebugger() { | |
| 102 } | |
| 103 | |
| 104 | |
| 105 #ifdef GENERATED_CODE_COVERAGE | |
| 106 static FILE* coverage_log = NULL; | |
| 107 | |
| 108 | |
| 109 static void InitializeCoverage() { | |
| 110 char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG"); | |
| 111 if (file_name != NULL) { | |
| 112 coverage_log = fopen(file_name, "aw+"); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 | 100 |
| 117 void MipsDebugger::Stop(Instruction* instr) { | 101 void MipsDebugger::Stop(Instruction* instr) { |
| 118 // Get the stop code. | 102 // Get the stop code. |
| 119 uint32_t code = instr->Bits(25, 6); | 103 uint32_t code = instr->Bits(25, 6); |
| 120 // Retrieve the encoded address, which comes just after this stop. | |
| 121 char** msg_address = | |
| 122 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); | |
| 123 char* msg = *msg_address; | |
| 124 DCHECK(msg != NULL); | |
| 125 | |
| 126 // Update this stop description. | |
| 127 if (!watched_stops_[code].desc) { | |
| 128 watched_stops_[code].desc = msg; | |
| 129 } | |
| 130 | |
| 131 if (strlen(msg) > 0) { | |
| 132 if (coverage_log != NULL) { | |
| 133 fprintf(coverage_log, "%s\n", str); | |
| 134 fflush(coverage_log); | |
| 135 } | |
| 136 // Overwrite the instruction and address with nops. | |
| 137 instr->SetInstructionBits(kNopInstr); | |
| 138 reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr); | |
| 139 } | |
| 140 // TODO(yuyin): 2 -> 3? | |
| 141 sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstructionSize); | |
| 142 } | |
| 143 | |
| 144 | |
| 145 #else // GENERATED_CODE_COVERAGE | |
| 146 | |
| 147 #define UNSUPPORTED() printf("Sim: Unsupported instruction.\n"); | |
| 148 | |
| 149 static void InitializeCoverage() {} | |
| 150 | |
| 151 | |
| 152 void MipsDebugger::Stop(Instruction* instr) { | |
| 153 // Get the stop code. | |
| 154 uint32_t code = instr->Bits(25, 6); | |
| 155 // Retrieve the encoded address, which comes just after this stop. | 104 // Retrieve the encoded address, which comes just after this stop. |
| 156 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + | 105 char* msg = *reinterpret_cast<char**>(sim_->get_pc() + |
| 157 Instruction::kInstrSize); | 106 Instruction::kInstrSize); |
| 158 // Update this stop description. | 107 // Update this stop description. |
| 159 if (!sim_->watched_stops_[code].desc) { | 108 if (!sim_->watched_stops_[code].desc) { |
| 160 sim_->watched_stops_[code].desc = msg; | 109 sim_->watched_stops_[code].desc = msg; |
| 161 } | 110 } |
| 162 PrintF("Simulator hit %s (%u)\n", msg, code); | 111 PrintF("Simulator hit %s (%u)\n", msg, code); |
| 163 // TODO(yuyin): 2 -> 3? | 112 // TODO(yuyin): 2 -> 3? |
| 164 sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstrSize); | 113 sim_->set_pc(sim_->get_pc() + 3 * Instruction::kInstrSize); |
| 165 Debug(); | 114 Debug(); |
| 166 } | 115 } |
| 167 #endif // GENERATED_CODE_COVERAGE | |
| 168 | |
| 169 | 116 |
| 170 int64_t MipsDebugger::GetRegisterValue(int regnum) { | 117 int64_t MipsDebugger::GetRegisterValue(int regnum) { |
| 171 if (regnum == kNumSimuRegisters) { | 118 if (regnum == kNumSimuRegisters) { |
| 172 return sim_->get_pc(); | 119 return sim_->get_pc(); |
| 173 } else { | 120 } else { |
| 174 return sim_->get_register(regnum); | 121 return sim_->get_register(regnum); |
| 175 } | 122 } |
| 176 } | 123 } |
| 177 | 124 |
| 178 | 125 |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 } | 856 } |
| 910 | 857 |
| 911 // The sp is initialized to point to the bottom (high address) of the | 858 // The sp is initialized to point to the bottom (high address) of the |
| 912 // allocated stack area. To be safe in potential stack underflows we leave | 859 // allocated stack area. To be safe in potential stack underflows we leave |
| 913 // some buffer below. | 860 // some buffer below. |
| 914 registers_[sp] = reinterpret_cast<int64_t>(stack_) + stack_size_ - 64; | 861 registers_[sp] = reinterpret_cast<int64_t>(stack_) + stack_size_ - 64; |
| 915 // The ra and pc are initialized to a known bad value that will cause an | 862 // The ra and pc are initialized to a known bad value that will cause an |
| 916 // access violation if the simulator ever tries to execute it. | 863 // access violation if the simulator ever tries to execute it. |
| 917 registers_[pc] = bad_ra; | 864 registers_[pc] = bad_ra; |
| 918 registers_[ra] = bad_ra; | 865 registers_[ra] = bad_ra; |
| 919 InitializeCoverage(); | |
| 920 | 866 |
| 921 last_debugger_input_ = NULL; | 867 last_debugger_input_ = NULL; |
| 922 } | 868 } |
| 923 | 869 |
| 924 | 870 |
| 925 Simulator::~Simulator() { free(stack_); } | 871 Simulator::~Simulator() { free(stack_); } |
| 926 | 872 |
| 927 | 873 |
| 928 // When the generated code calls an external reference we need to catch that in | 874 // When the generated code calls an external reference we need to catch that in |
| 929 // the simulator. The external reference will be a function compiled for the | 875 // the simulator. The external reference will be a function compiled for the |
| (...skipping 4064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4994 } | 4940 } |
| 4995 | 4941 |
| 4996 | 4942 |
| 4997 #undef UNSUPPORTED | 4943 #undef UNSUPPORTED |
| 4998 } // namespace internal | 4944 } // namespace internal |
| 4999 } // namespace v8 | 4945 } // namespace v8 |
| 5000 | 4946 |
| 5001 #endif // USE_SIMULATOR | 4947 #endif // USE_SIMULATOR |
| 5002 | 4948 |
| 5003 #endif // V8_TARGET_ARCH_MIPS64 | 4949 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |