PageRenderTime 168ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 2ms

/demos/simulator-mips-simulator-arm.html

http://github.com/yinwang0/ydiff
HTML | 6277 lines | 5625 code | 652 blank | 0 comment | 0 complexity | ec09f9745486a02c584340cef5075eec MD5 | raw file
Possible License(s): GPL-3.0
  1. <html>
  2. <head>
  3. <META http-equiv="Content-Type" content="text/html; charset=utf-8">
  4. <LINK href="diff-s.css" rel="stylesheet" type="text/css">
  5. <script type="text/javascript" src="nav-div.js"></script>
  6. </head>
  7. <body>
  8. <div id="left" class="src">
  9. <pre>
  10. <a id='leftstart' tid='rightstart'></a>
  11. // Copyright 2011 the V8 project authors. All rights reserved.
  12. // Redistribution and use in source and binary forms, with or without
  13. // modification, are permitted provided that the following conditions are
  14. // met:
  15. //
  16. // * Redistributions of source code must retain the above copyright
  17. // notice, this list of conditions and the following disclaimer.
  18. // * Redistributions in binary form must reproduce the above
  19. // copyright notice, this list of conditions and the following
  20. // disclaimer in the documentation and/or other materials provided
  21. // with the distribution.
  22. // * Neither the name of Google Inc. nor the names of its
  23. // contributors may be used to endorse or promote products derived
  24. // from this software without specific prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. // &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  29. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  30. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  31. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  32. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  33. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  34. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  36. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. #<a id='9613' tid='9614', class="m">include</a> <a id='9615' tid='9616', class="m">&lt;</a><a id='9617' tid='9618', class="m">stdlib</a><a id='9619' tid='9620', class="m">.</a><a id='9621' tid='9622', class="m">h</a><a id='9623' tid='9624', class="m">&gt;</a>
  38. #<a id='9601' tid='9602', class="m">include</a> <a id='9603' tid='9604', class="m">&lt;</a><a id='9605' tid='9606', class="m">math</a><a id='9607' tid='9608', class="m">.</a><a id='9609' tid='9610', class="m">h</a><a id='9611' tid='9612', class="m">&gt;</a>
  39. <span class="d">#include &lt;limits.h&gt;</span>
  40. <span class="d">#include &lt;cstdarg&gt;</span>
  41. <span class="d">#include &quot;v8.h&quot;</span>
  42. <span class="d">#if defined(V8_TARGET_ARCH_MIPS)</span>
  43. <span class="d">#include &quot;disasm.h&quot;</span>
  44. <span class="d">#include &quot;assembler.h&quot;</span>
  45. <span class="d">#include &quot;globals.h&quot;</span> // Need the BitCast.
  46. <span class="d">#include &quot;mips/constants-mips.h&quot;</span>
  47. <span class="d">#include &quot;mips/simulator-mips.h&quot;</span>
  48. // Only build the simulator if not compiling for real MIPS hardware.
  49. #<a id='9591' tid='9592', class="m">if</a> <a id='9593' tid='9594', class="m">defined</a><a id='9595' tid='9596', class="m">(</a><a id='9597' tid='9598', class="m">USE_SIMULATOR</a><a id='9599' tid='9600', class="m">)</a>
  50. namespace <span class="d">v8</span> {
  51. namespace <span class="d">internal</span> {
  52. // Utils functions.
  53. <span class="d">bool HaveSameSign(int32_t a, int32_t b) {
  54. return ((a ^ b) &gt;= 0);
  55. }</span>
  56. <span class="d">uint32_t get_fcsr_condition_bit(uint32_t cc) {
  57. if (cc == 0) {
  58. return 23;
  59. } else {
  60. return 24 + cc;
  61. }
  62. }</span>
  63. // This macro provides a platform independent use of sscanf. The reason for
  64. // SScanF not being implemented in a platform independent was through
  65. // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time
  66. // Library does not provide vsscanf.
  67. <span class="d">#define SScanF sscanf</span> // NOLINT
  68. // The MipsDebugger class is used by the simulator while debugging simulated
  69. // code.
  70. <span class="d">class</span> <span class="d">MipsDebugger</span> {
  71. <span class="d">public:</span>
  72. <span class="d">explicit MipsDebugger(Simulator* sim)</span>;
  73. <span class="d">~MipsDebugger();</span>
  74. <a id='9581' tid='9582', class="m">void</a> <a id='9583' tid='9584', class="m">Stop</a>(<a id='9585' tid='9586', class="m">Instruction</a><a id='9587' tid='9588', class="m">*</a> <a id='9589' tid='9590', class="m">instr</a>);
  75. <span class="d">void Debug()</span>;
  76. // Print all registers with a nice formatting.
  77. <span class="d">void PrintAllRegs()</span>;
  78. <span class="d">void PrintAllRegsIncludingFPU()</span>;
  79. <span class="d">private:</span>
  80. // We set the breakpoint code to 0xfffff to easily recognize it.
  81. <span class="d">static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff &lt;&lt; 6;</span>
  82. <span class="d">static const Instr kNopInstr = 0x0;</span>
  83. <span class="d">Simulator* sim_;</span>
  84. <span class="d">int32_t GetRegisterValue(int regnum)</span>;
  85. <span class="d">int32_t GetFPURegisterValueInt(int regnum)</span>;
  86. <span class="d">int64_t GetFPURegisterValueLong(int regnum)</span>;
  87. <span class="d">float GetFPURegisterValueFloat(int regnum)</span>;
  88. <span class="d">double GetFPURegisterValueDouble(int regnum)</span>;
  89. <a id='9563' tid='9564', class="m">bool</a> <a id='9565' tid='9566', class="m">GetValue</a>(<a id='9567' tid='9568', class="m">const</a> <a id='9569' tid='9570', class="m">char</a><a id='9571' tid='9572', class="m">*</a> <a id='9573' tid='9574', class="m">desc</a>, <a id='9575' tid='9576', class="m">int32_t</a><a id='9577' tid='9578', class="m">*</a> <a id='9579' tid='9580', class="m">value</a>);
  90. // Set or delete a breakpoint. Returns true if successful.
  91. <a id='9543' tid='9544', class="m">bool</a> <a id='9545' tid='9546', class="m">SetBreakpoint</a>(<a id='9547' tid='9548', class="m">Instruction</a><a id='9549' tid='9550', class="m">*</a> <a id='9551' tid='9552', class="m">breakpc</a>);
  92. <a id='9499' tid='9500', class="m">bool</a> <a id='9501' tid='9502', class="m">DeleteBreakpoint</a>(<a id='9503' tid='9504', class="m">Instruction</a><a id='9505' tid='9506', class="m">*</a> <a id='9507' tid='9508', class="m">breakpc</a>);
  93. // Undo and redo all breakpoints. This is needed to bracket disassembly and
  94. // execution to skip past breakpoints when run from the debugger.
  95. <span class="d">void UndoBreakpoints()</span>;
  96. <span class="d">void RedoBreakpoints()</span>;
  97. };
  98. <span class="d">MipsDebugger::MipsDebugger(Simulator* sim) {
  99. sim_ = sim;
  100. }</span>
  101. <span class="d">MipsDebugger::~MipsDebugger() {
  102. }</span>
  103. <span class="d">#ifdef GENERATED_CODE_COVERAGE</span>
  104. <a id='9553' tid='9554', class="m">static</a> <a id='9555' tid='9556', class="m">FILE</a><a id='9557' tid='9558', class="m">*</a> <a id='9559' tid='9560', class="m">coverage_log</a> = <a id='9561' tid='9562', class="m">NULL</a>;
  105. <a id='9509' tid='9510', class="m">static</a> <a id='9511' tid='9512', class="m">void</a> <a id='9513' tid='9514', class="m">InitializeCoverage</a>() {
  106. <a id='9515' tid='9516', class="m">char</a><a id='9517' tid='9518', class="m">*</a> <a id='9519' tid='9520', class="m">file_name</a> = <a id='9521' tid='9522', class="m">getenv</a>(<a id='9523' tid='9524', class="m">&quot;V8_GENERATED_CODE_COVERAGE_LOG&quot;</a>);
  107. <a id='9525' tid='9526', class="m">if</a> (<a id='9527' tid='9528', class="m">file_name</a> <a id='9529' tid='9530', class="m">!=</a> <a id='9531' tid='9532', class="m">NULL</a>) {
  108. <a id='9533' tid='9534', class="m">coverage_log</a> <a id='9535' tid='9536', class="m">=</a> <a id='9537' tid='9538', class="m">fopen</a>(<a id='9539' tid='9540', class="m">file_name</a>, <a id='9541' tid='9542', class="m">&quot;aw+&quot;</a>);
  109. }
  110. }
  111. <a id='9443' tid='9444', class="m">void</a> <span class="d">MipsDebugger::Stop</span>(<a id='9445' tid='9446', class="m">Instruction</a><a id='9447' tid='9448', class="m">*</a> <a id='9449' tid='9450', class="m">instr</a>) {
  112. // Get the stop code.
  113. <span class="d">uint32_t code = instr-&gt;Bits(25, 6);</span>
  114. // Retrieve the encoded address, which comes just after this stop.
  115. <span class="d">char** msg_address =
  116. reinterpret_cast&lt;char**&gt;(sim_-&gt;get_pc() + Instr::kInstrSize);</span>
  117. <a id='9489' tid='9490', class="m">char</a><a id='9491' tid='9492', class="m">*</a> <a id='9493' tid='9494', class="m">msg</a> = <a id='9495' tid='9496', class="m">*</a><a id='9497' tid='9498', class="m">msg_address</a>;
  118. <span class="d">ASSERT(msg != NULL);</span>
  119. // Update this stop description.
  120. <span class="d">if</span> <span class="d">(!watched_stops[code].desc)</span> {
  121. <a id='9479' tid='9480', class="m">watched_stops</a>[<a id='9481' tid='9482', class="m">code</a>].<a id='9483' tid='9484', class="m">desc</a> <a id='9485' tid='9486', class="m">=</a> <a id='9487' tid='9488', class="m">msg</a>;
  122. }
  123. <span class="d">if (strlen(msg) &gt; 0) {
  124. if (coverage_log != NULL) {
  125. fprintf(coverage_log, &quot;%s\n&quot;, str);
  126. fflush(coverage_log);
  127. }
  128. // Overwrite the instruction and address with nops.
  129. instr-&gt;SetInstructionBits(kNopInstr);
  130. reinterpret_cast&lt;Instr*&gt;(msg_address)-&gt;SetInstructionBits(kNopInstr);
  131. }</span>
  132. <span class="d">sim_-&gt;set_pc(sim_-&gt;get_pc() + 2 * Instruction::kInstructionSize);</span>
  133. }
  134. <span class="d">#else</span> // GENERATED_CODE_COVERAGE
  135. <span class="d">#define UNSUPPORTED() printf(&quot;Unsupported instruction.\n&quot;);</span>
  136. <span class="d">static void InitializeCoverage() {}</span>
  137. <a id='9405' tid='9406', class="m">void</a> <span class="d">MipsDebugger::Stop</span>(<a id='9407' tid='9408', class="m">Instruction</a><a id='9409' tid='9410', class="m">*</a> <a id='9411' tid='9412', class="m">instr</a>) {
  138. // Get the stop code.
  139. <span class="d">uint32_t code = instr-&gt;Bits(25, 6);</span>
  140. // Retrieve the encoded address, which comes just after this stop.
  141. <a id='9451' tid='9452', class="m">char</a><a id='9453' tid='9454', class="m">*</a> <a id='9455' tid='9456', class="m">msg</a> = <a id='9457' tid='9458', class="m">*</a><a id='9459' tid='9460', class="m">reinterpret_cast</a>&lt;<a id='9461' tid='9462', class="m">char</a><a id='9463' tid='9464', class="m">*</a><a id='9465' tid='9466', class="m">*</a>&gt;(<a id='9467' tid='9468', class="m">sim_</a>-&gt;<a id='9469' tid='9470', class="m">get_pc</a>() <a id='9471' tid='9472', class="m">+</a>
  142. <a id='9473' tid='9474', class="m">Instruction</a><a id='9475' tid='9476', class="m">::</a><a id='9477' tid='9478', class="m">kInstrSize</a>);
  143. // Update this stop description.
  144. <a id='9381' tid='9382', class="m">if</a> (<a id='9383' tid='9384', class="m">!</a><a id='9385' tid='9386', class="m">sim_</a>-&gt;<a id='9387' tid='9388', class="m">watched_stops</a>[<a id='9389' tid='9390', class="m">code</a>].<a id='9391' tid='9392', class="m">desc</a>) {
  145. <a id='9393' tid='9394', class="m">sim_</a>-&gt;<a id='9395' tid='9396', class="m">watched_stops</a>[<a id='9397' tid='9398', class="m">code</a>].<a id='9399' tid='9400', class="m">desc</a> <a id='9401' tid='9402', class="m">=</a> <a id='9403' tid='9404', class="m">msg</a>;
  146. }
  147. <span class="d">PrintF(&quot;Simulator hit %s (%u)\n&quot;, msg, code);</span>
  148. <a id='9423' tid='9424', class="m">sim_</a>-&gt;<a id='9425' tid='9426', class="m">set_pc</a>(<a id='9427' tid='9428', class="m">sim_</a>-&gt;<a id='9429' tid='9430', class="m">get_pc</a>() <a id='9431' tid='9432', class="m">+</a> <a id='9433' tid='9434', class="m">2</a> <a id='9435' tid='9436', class="m">*</a> <a id='9437' tid='9438', class="m">Instruction</a><a id='9439' tid='9440', class="m">::</a><a id='9441' tid='9442', class="m">kInstrSize</a>);
  149. <span class="d">Debug();</span>
  150. }
  151. <span class="d">#endif</span> // GENERATED_CODE_COVERAGE
  152. <a id='9361' tid='9362', class="m">int32_t</a> <span class="d">MipsDebugger::GetRegisterValue</span>(<a id='9363' tid='9364', class="m">int</a> <a id='9365' tid='9366', class="m">regnum</a>) {
  153. <span class="d">if</span> <span class="d">(regnum == kNumSimuRegisters)</span> <span class="d">{
  154. return sim_-&gt;get_pc();
  155. }</span> <a id='9413' tid='9414', class="m">else</a> {
  156. <a id='9415' tid='9416', class="m">return</a> <a id='9417' tid='9418', class="m">sim_</a>-&gt;<a id='9419' tid='9420', class="m">get_register</a>(<a id='9421' tid='9422', class="m">regnum</a>);
  157. }
  158. }
  159. <span class="d">int32_t MipsDebugger::GetFPURegisterValueInt(int regnum) {
  160. if (regnum == kNumFPURegisters) {
  161. return sim_-&gt;get_pc();
  162. } else {
  163. return sim_-&gt;get_fpu_register(regnum);
  164. }
  165. }</span>
  166. <span class="d">int64_t MipsDebugger::GetFPURegisterValueLong(int regnum) {
  167. if (regnum == kNumFPURegisters) {
  168. return sim_-&gt;get_pc();
  169. } else {
  170. return sim_-&gt;get_fpu_register_long(regnum);
  171. }
  172. }</span>
  173. <span class="d">float MipsDebugger::GetFPURegisterValueFloat(int regnum) {
  174. if (regnum == kNumFPURegisters) {
  175. return sim_-&gt;get_pc();
  176. } else {
  177. return sim_-&gt;get_fpu_register_float(regnum);
  178. }
  179. }</span>
  180. <span class="d">double MipsDebugger::GetFPURegisterValueDouble(int regnum) {
  181. if (regnum == kNumFPURegisters) {
  182. return sim_-&gt;get_pc();
  183. } else {
  184. return sim_-&gt;get_fpu_register_double(regnum);
  185. }
  186. }</span>
  187. <span class="d">bool</span> <span class="d">MipsDebugger::GetValue</span>(<a id='9367' tid='9368', class="m">const</a> <a id='9369' tid='9370', class="m">char</a><a id='9371' tid='9372', class="m">*</a> <a id='9373' tid='9374', class="m">desc</a>, <a id='9375' tid='9376', class="m">int32_t</a><a id='9377' tid='9378', class="m">*</a> <a id='9379' tid='9380', class="m">value</a>) {
  188. <a id='9313' tid='9314', class="m">int</a> <a id='9315' tid='9316', class="m">regnum</a> = <a id='9317' tid='9318', class="m">Registers</a><a id='9319' tid='9320', class="m">::</a><a id='9321' tid='9322', class="m">Number</a>(<a id='9323' tid='9324', class="m">desc</a>);
  189. <span class="d">int fpuregnum = FPURegisters::Number(desc);</span>
  190. <span class="d">if</span> <span class="d">(regnum != kInvalidRegister)</span> {
  191. <a id='9299' tid='9300', class="m">*</a><a id='9301' tid='9302', class="m">value</a> <a id='9303' tid='9304', class="m">=</a> <a id='9305' tid='9306', class="m">GetRegisterValue</a>(<a id='9307' tid='9308', class="m">regnum</a>);
  192. <a id='9309' tid='9310', class="m">return</a> <a id='9311' tid='9312', class="m">true</a>;
  193. } <span class="d">else</span> <span class="d">if</span> <span class="d">(fpuregnum != kInvalidFPURegister)</span> <span class="d">{
  194. *value = GetFPURegisterValueInt(fpuregnum);
  195. return true;
  196. }</span> <a id='9237' tid='9238', class="m">else</a> <span class="d">if</span> (<a id='9239' tid='9240', class="m">strncmp</a>(<a id='9241' tid='9242', class="m">desc</a>, <a id='9243' tid='9244', class="m">&quot;0x&quot;</a>, <a id='9245' tid='9246', class="m">2</a>) <a id='9247' tid='9248', class="m">==</a> <a id='9249' tid='9250', class="m">0</a>) <span class="d">{
  197. return SScanF(desc, &quot;%x&quot;, reinterpret_cast&lt;uint32_t*&gt;(value)) == 1;
  198. }</span> <span class="d">else {
  199. return SScanF(desc, &quot;%i&quot;, value) == 1;
  200. }</span>
  201. <span class="d">return false;</span>
  202. }
  203. <a id='9251' tid='9252', class="m">bool</a> <span class="d">MipsDebugger::SetBreakpoint</span>(<a id='9253' tid='9254', class="m">Instruction</a><a id='9255' tid='9256', class="m">*</a> <a id='9257' tid='9258', class="m">breakpc</a>) {
  204. // Check if a breakpoint can be set. If not return without any side-effects.
  205. <a id='9325' tid='9326', class="m">if</a> (<a id='9327' tid='9328', class="m">sim_</a>-&gt;<a id='9329' tid='9330', class="m">break_pc_</a> <a id='9331' tid='9332', class="m">!=</a> <a id='9333' tid='9334', class="m">NULL</a>) {
  206. <a id='9335' tid='9336', class="m">return</a> <a id='9337' tid='9338', class="m">false</a>;
  207. }
  208. // Set the breakpoint.
  209. <a id='9339' tid='9340', class="m">sim_</a>-&gt;<a id='9341' tid='9342', class="m">break_pc_</a> <a id='9343' tid='9344', class="m">=</a> <a id='9345' tid='9346', class="m">breakpc</a>;
  210. <a id='9347' tid='9348', class="m">sim_</a>-&gt;<a id='9349' tid='9350', class="m">break_instr_</a> <a id='9351' tid='9352', class="m">=</a> <a id='9353' tid='9354', class="m">breakpc</a>-&gt;<a id='9355' tid='9356', class="m">InstructionBits</a>();
  211. // Not setting the breakpoint instruction in the code itself. It will be set
  212. // when the debugger shell continues.
  213. <a id='9357' tid='9358', class="m">return</a> <a id='9359' tid='9360', class="m">true</a>;
  214. }
  215. <a id='9209' tid='9210', class="m">bool</a> <span class="d">MipsDebugger::DeleteBreakpoint</span>(<a id='9211' tid='9212', class="m">Instruction</a><a id='9213' tid='9214', class="m">*</a> <a id='9215' tid='9216', class="m">breakpc</a>) {
  216. <a id='9259' tid='9260', class="m">if</a> (<a id='9261' tid='9262', class="m">sim_</a>-&gt;<a id='9263' tid='9264', class="m">break_pc_</a> <a id='9265' tid='9266', class="m">!=</a> <a id='9267' tid='9268', class="m">NULL</a>) {
  217. <a id='9269' tid='9270', class="m">sim_</a>-&gt;<a id='9271' tid='9272', class="m">break_pc_</a>-&gt;<a id='9273' tid='9274', class="m">SetInstructionBits</a>(<a id='9275' tid='9276', class="m">sim_</a>-&gt;<a id='9277' tid='9278', class="m">break_instr_</a>);
  218. }
  219. <a id='9279' tid='9280', class="m">sim_</a>-&gt;<a id='9281' tid='9282', class="m">break_pc_</a> <a id='9283' tid='9284', class="m">=</a> <a id='9285' tid='9286', class="m">NULL</a>;
  220. <a id='9287' tid='9288', class="m">sim_</a>-&gt;<a id='9289' tid='9290', class="m">break_instr_</a> <a id='9291' tid='9292', class="m">=</a> <a id='9293' tid='9294', class="m">0</a>;
  221. <a id='9295' tid='9296', class="m">return</a> <a id='9297' tid='9298', class="m">true</a>;
  222. }
  223. <span class="d">void</span> <span class="d">MipsDebugger::UndoBreakpoints</span><span class="d">()</span> {
  224. <a id='9217' tid='9218', class="m">if</a> (<a id='9219' tid='9220', class="m">sim_</a>-&gt;<a id='9221' tid='9222', class="m">break_pc_</a> <a id='9223' tid='9224', class="m">!=</a> <a id='9225' tid='9226', class="m">NULL</a>) {
  225. <a id='9227' tid='9228', class="m">sim_</a>-&gt;<a id='9229' tid='9230', class="m">break_pc_</a>-&gt;<a id='9231' tid='9232', class="m">SetInstructionBits</a>(<a id='9233' tid='9234', class="m">sim_</a>-&gt;<a id='9235' tid='9236', class="m">break_instr_</a>);
  226. }
  227. }
  228. <span class="d">void</span> <span class="d">MipsDebugger::RedoBreakpoints</span><span class="d">()</span> {
  229. <a id='9191' tid='9192', class="m">if</a> (<a id='9193' tid='9194', class="m">sim_</a>-&gt;<a id='9195' tid='9196', class="m">break_pc_</a> <a id='9197' tid='9198', class="m">!=</a> <a id='9199' tid='9200', class="m">NULL</a>) {
  230. <a id='9201' tid='9202', class="m">sim_</a>-&gt;<a id='9203' tid='9204', class="m">break_pc_</a>-&gt;<a id='9205' tid='9206', class="m">SetInstructionBits</a>(<a id='9207' tid='9208', class="m">kBreakpointInstr</a>);
  231. }
  232. }
  233. <span class="d">void MipsDebugger::PrintAllRegs() {
  234. #define REG_INFO(n) Registers::Name(n), GetRegisterValue(n), GetRegisterValue(n)
  235. PrintF(&quot;\n&quot;);
  236. // at, v0, a0.
  237. PrintF(&quot;%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n&quot;,
  238. REG_INFO(1), REG_INFO(2), REG_INFO(4));
  239. // v1, a1.
  240. PrintF(&quot;%26s\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n&quot;,
  241. &quot;&quot;, REG_INFO(3), REG_INFO(5));
  242. // a2.
  243. PrintF(&quot;%26s\t%26s\t%3s: 0x%08x %10d\n&quot;, &quot;&quot;, &quot;&quot;, REG_INFO(6));
  244. // a3.
  245. PrintF(&quot;%26s\t%26s\t%3s: 0x%08x %10d\n&quot;, &quot;&quot;, &quot;&quot;, REG_INFO(7));
  246. PrintF(&quot;\n&quot;);
  247. // t0-t7, s0-s7
  248. for (int i = 0; i &lt; 8; i++) {
  249. PrintF(&quot;%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n&quot;,
  250. REG_INFO(8+i), REG_INFO(16+i));
  251. }
  252. PrintF(&quot;\n&quot;);
  253. // t8, k0, LO.
  254. PrintF(&quot;%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n&quot;,
  255. REG_INFO(24), REG_INFO(26), REG_INFO(32));
  256. // t9, k1, HI.
  257. PrintF(&quot;%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n&quot;,
  258. REG_INFO(25), REG_INFO(27), REG_INFO(33));
  259. // sp, fp, gp.
  260. PrintF(&quot;%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n&quot;,
  261. REG_INFO(29), REG_INFO(30), REG_INFO(28));
  262. // pc.
  263. PrintF(&quot;%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n&quot;,
  264. REG_INFO(31), REG_INFO(34));
  265. #undef REG_INFO
  266. #undef FPU_REG_INFO
  267. }</span>
  268. <span class="d">void MipsDebugger::PrintAllRegsIncludingFPU() {
  269. #define FPU_REG_INFO(n) FPURegisters::Name(n), FPURegisters::Name(n+1), \
  270. GetFPURegisterValueInt(n+1), \
  271. GetFPURegisterValueInt(n), \
  272. GetFPURegisterValueDouble(n)
  273. PrintAllRegs();
  274. PrintF(&quot;\n\n&quot;);
  275. // f0, f1, f2, ... f31.
  276. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(0) );
  277. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(2) );
  278. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(4) );
  279. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(6) );
  280. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(8) );
  281. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(10));
  282. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(12));
  283. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(14));
  284. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(16));
  285. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(18));
  286. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(20));
  287. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(22));
  288. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(24));
  289. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(26));
  290. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(28));
  291. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;, FPU_REG_INFO(30));
  292. #undef REG_INFO
  293. #undef FPU_REG_INFO
  294. }</span>
  295. <span class="d">void</span> <span class="d">MipsDebugger::Debug</span><span class="d">()</span> {
  296. <a id='8965' tid='8966', class="m">intptr_t</a> <a id='8967' tid='8968', class="m">last_pc</a> = <a id='8969' tid='8970', class="m">-</a><a id='8971' tid='8972', class="m">1</a>;
  297. <a id='8973' tid='8974', class="m">bool</a> <a id='8975' tid='8976', class="m">done</a> = <a id='8977' tid='8978', class="m">false</a>;
  298. #<a id='8979' tid='8980', class="m">define</a> <a id='8981' tid='8982', class="m">COMMAND_SIZE</a> <a id='8983' tid='8984', class="m">63</a>
  299. #<a id='8985' tid='8986', class="m">define</a> <a id='8987' tid='8988', class="m">ARG_SIZE</a> <a id='8989' tid='8990', class="m">255</a>
  300. #<a id='9177' tid='9178', class="m">define</a> <a id='9179' tid='9180', class="m">STR</a><a id='9181' tid='9182', class="m">(</a><a id='9183' tid='9184', class="m">a</a><a id='9185' tid='9186', class="m">)</a> <a id='9187' tid='9188', class="m">#</a><a id='9189' tid='9190', class="m">a</a>
  301. #<a id='8991' tid='8992', class="m">define</a> <a id='8993' tid='8994', class="m">XSTR</a><a id='8995' tid='8996', class="m">(</a><a id='8997' tid='8998', class="m">a</a><a id='8999' tid='9000', class="m">)</a> <a id='9001' tid='9002', class="m">STR</a><a id='9003' tid='9004', class="m">(</a><a id='9005' tid='9006', class="m">a</a><a id='9007' tid='9008', class="m">)</a>
  302. <a id='9009' tid='9010', class="m">char</a> <a id='9011' tid='9012', class="m">cmd</a>[<a id='9013' tid='9014', class="m">COMMAND_SIZE</a> <a id='9015' tid='9016', class="m">+</a> <a id='9017' tid='9018', class="m">1</a>];
  303. <a id='9019' tid='9020', class="m">char</a> <a id='9021' tid='9022', class="m">arg1</a>[<a id='9023' tid='9024', class="m">ARG_SIZE</a> <a id='9025' tid='9026', class="m">+</a> <a id='9027' tid='9028', class="m">1</a>];
  304. <a id='9029' tid='9030', class="m">char</a> <a id='9031' tid='9032', class="m">arg2</a>[<a id='9033' tid='9034', class="m">ARG_SIZE</a> <a id='9035' tid='9036', class="m">+</a> <a id='9037' tid='9038', class="m">1</a>];
  305. <a id='9039' tid='9040', class="m">char</a><a id='9041' tid='9042', class="m">*</a> <a id='9043' tid='9044', class="m">argv</a>[<a id='9045' tid='9046', class="m">3</a>] = { <a id='9047' tid='9048', class="m">cmd</a>, <a id='9049' tid='9050', class="m">arg1</a>, <a id='9051' tid='9052', class="m">arg2</a> };
  306. // Make sure to have a proper terminating character if reaching the limit.
  307. <a id='9053' tid='9054', class="m">cmd</a>[<a id='9055' tid='9056', class="m">COMMAND_SIZE</a>] <a id='9057' tid='9058', class="m">=</a> <a id='9059' tid='9060', class="m">0</a>;
  308. <a id='9061' tid='9062', class="m">arg1</a>[<a id='9063' tid='9064', class="m">ARG_SIZE</a>] <a id='9065' tid='9066', class="m">=</a> <a id='9067' tid='9068', class="m">0</a>;
  309. <a id='9069' tid='9070', class="m">arg2</a>[<a id='9071' tid='9072', class="m">ARG_SIZE</a>] <a id='9073' tid='9074', class="m">=</a> <a id='9075' tid='9076', class="m">0</a>;
  310. // Undo all set breakpoints while running in the debugger shell. This will
  311. // make them invisible to all commands.
  312. <a id='9077' tid='9078', class="m">UndoBreakpoints</a>();
  313. <span class="d">while</span> <span class="d">(!done && (sim_-&gt;get_pc() != Simulator::end_sim_pc))</span> {
  314. <a id='9079' tid='9080', class="m">if</a> (<a id='9081' tid='9082', class="m">last_pc</a> <a id='9083' tid='9084', class="m">!=</a> <a id='9085' tid='9086', class="m">sim_</a>-&gt;<a id='9087' tid='9088', class="m">get_pc</a>()) {
  315. <a id='9099' tid='9100', class="m">disasm</a><a id='9101' tid='9102', class="m">::</a><a id='9103' tid='9104', class="m">NameConverter</a> <a id='9105' tid='9106', class="m">converter</a>;
  316. <a id='9089' tid='9090', class="m">disasm</a><a id='9091' tid='9092', class="m">::</a><a id='9093' tid='9094', class="m">Disassembler</a> <a id='9095' tid='9096', class="m">dasm</a>(<a id='9097' tid='9098', class="m">converter</a>);
  317. // Use a reasonably large buffer.
  318. <a id='9107' tid='9108', class="m">v8</a><a id='9109' tid='9110', class="m">::</a><a id='9111' tid='9112', class="m">internal</a><a id='9113' tid='9114', class="m">::</a><a id='9115' tid='9116', class="m">EmbeddedVector</a>&lt;<a id='9117' tid='9118', class="m">char</a>, <a id='9119' tid='9120', class="m">256</a>&gt; <a id='9121' tid='9122', class="m">buffer</a>;
  319. <a id='9123' tid='9124', class="m">dasm</a>.<a id='9125' tid='9126', class="m">InstructionDecode</a>(<a id='9127' tid='9128', class="m">buffer</a>,
  320. <a id='9129' tid='9130', class="m">reinterpret_cast</a>&lt;<a id='9131' tid='9132', class="m">byte</a><a id='9133' tid='9134', class="m">*</a>&gt;(<a id='9135' tid='9136', class="m">sim_</a>-&gt;<a id='9137' tid='9138', class="m">get_pc</a>()));
  321. <a id='9139' tid='9140', class="m">PrintF</a>(<a id='9141' tid='9142', class="m">&quot; 0x%08x %s\n&quot;</a>, <a id='9143' tid='9144', class="m">sim_</a>-&gt;<a id='9145' tid='9146', class="m">get_pc</a>(), <a id='9147' tid='9148', class="m">buffer</a>.<a id='9149' tid='9150', class="m">start</a>());
  322. <a id='9151' tid='9152', class="m">last_pc</a> <a id='9153' tid='9154', class="m">=</a> <a id='9155' tid='9156', class="m">sim_</a>-&gt;<a id='9157' tid='9158', class="m">get_pc</a>();
  323. }
  324. <a id='8115' tid='8116', class="m">char</a><a id='8117' tid='8118', class="m">*</a> <a id='8119' tid='8120', class="m">line</a> = <a id='8121' tid='8122', class="m">ReadLine</a>(<a id='8123' tid='8124', class="m">&quot;sim&gt; &quot;</a>);
  325. <a id='8125' tid='8126', class="m">if</a> (<a id='8127' tid='8128', class="m">line</a> <a id='8129' tid='8130', class="m">==</a> <a id='8131' tid='8132', class="m">NULL</a>) {
  326. <a id='8133' tid='8134', class="m">break</a>;
  327. } <a id='8135' tid='8136', class="m">else</a> {
  328. // Use sscanf to parse the individual parts of the command line. At the
  329. // moment no command expects more than two parameters.
  330. <a id='8137' tid='8138', class="m">int</a> <a id='8139' tid='8140', class="m">argc</a> = <a id='8141' tid='8142', class="m">SScanF</a>(<a id='8143' tid='8144', class="m">line</a>,
  331. <a id='8145' tid='8146', class="m">&quot;%&quot;</a> <a id='8147' tid='8148', class="m">XSTR</a>(<a id='8149' tid='8150', class="m">COMMAND_SIZE</a>) <a id='8151' tid='8152', class="m">&quot;s &quot;</a>
  332. <a id='8153' tid='8154', class="m">&quot;%&quot;</a> <a id='8155' tid='8156', class="m">XSTR</a>(<a id='8157' tid='8158', class="m">ARG_SIZE</a>) <a id='8159' tid='8160', class="m">&quot;s &quot;</a>
  333. <a id='8161' tid='8162', class="m">&quot;%&quot;</a> <a id='8163' tid='8164', class="m">XSTR</a>(<a id='8165' tid='8166', class="m">ARG_SIZE</a>) <a id='8167' tid='8168', class="m">&quot;s&quot;</a>,
  334. <a id='8169' tid='8170', class="m">cmd</a>, <a id='8171' tid='8172', class="m">arg1</a>, <a id='8173' tid='8174', class="m">arg2</a>);
  335. <a id='8175' tid='8176', class="m">if</a> ((<a id='8177' tid='8178', class="m">strcmp</a>(<a id='8179' tid='8180', class="m">cmd</a>, <a id='8181' tid='8182', class="m">&quot;si&quot;</a>) <a id='8183' tid='8184', class="m">==</a> <a id='8185' tid='8186', class="m">0</a>) <a id='8187' tid='8188', class="m">||</a> (<a id='8189' tid='8190', class="m">strcmp</a>(<a id='8191' tid='8192', class="m">cmd</a>, <a id='8193' tid='8194', class="m">&quot;stepi&quot;</a>) <a id='8195' tid='8196', class="m">==</a> <a id='8197' tid='8198', class="m">0</a>)) {
  336. <span class="d">Instruction* instr = reinterpret_cast&lt;Instruction*&gt;(sim_-&gt;get_pc());</span>
  337. <span class="d">if</span> <span class="d">(!(instr-&gt;IsTrap()) ||
  338. instr-&gt;InstructionBits() == rtCallRedirInstr)</span> {
  339. <a id='8199' tid='8200', class="m">sim_</a>-&gt;<a id='8201' tid='8202', class="m">InstructionDecode</a>(
  340. <a id='8203' tid='8204', class="m">reinterpret_cast</a>&lt;<a id='8205' tid='8206', class="m">Instruction</a><a id='8207' tid='8208', class="m">*</a>&gt;(<a id='8209' tid='8210', class="m">sim_</a>-&gt;<a id='8211' tid='8212', class="m">get_pc</a>()));
  341. } <span class="d">else</span> {
  342. // Allow si to jump over generated breakpoints.
  343. <span class="d">PrintF(&quot;/!\\ Jumping over generated breakpoint.\n&quot;);</span>
  344. <span class="d">sim_-&gt;set_pc</span>(<a id='8037' tid='8038', class="m">sim_</a>-&gt;<a id='8039' tid='8040', class="m">get_pc</a>() <a id='8041' tid='8042', class="m">+</a> <a id='8043' tid='8044', class="m">Instruction</a><a id='8045' tid='8046', class="m">::</a><a id='8047' tid='8048', class="m">kInstrSize</a>);
  345. }
  346. } <a id='8213' tid='8214', class="m">else</a> <a id='8215' tid='8216', class="m">if</a> ((<a id='8217' tid='8218', class="m">strcmp</a>(<a id='8219' tid='8220', class="m">cmd</a>, <a id='8221' tid='8222', class="m">&quot;c&quot;</a>) <a id='8223' tid='8224', class="m">==</a> <a id='8225' tid='8226', class="m">0</a>) <a id='8227' tid='8228', class="m">||</a> (<a id='8229' tid='8230', class="m">strcmp</a>(<a id='8231' tid='8232', class="m">cmd</a>, <a id='8233' tid='8234', class="m">&quot;cont&quot;</a>) <a id='8235' tid='8236', class="m">==</a> <a id='8237' tid='8238', class="m">0</a>)) {
  347. // Execute the one instruction we broke at with breakpoints disabled.
  348. <a id='8239' tid='8240', class="m">sim_</a>-&gt;<a id='8241' tid='8242', class="m">InstructionDecode</a>(<a id='8243' tid='8244', class="m">reinterpret_cast</a>&lt;<a id='8245' tid='8246', class="m">Instruction</a><a id='8247' tid='8248', class="m">*</a>&gt;(<a id='8249' tid='8250', class="m">sim_</a>-&gt;<a id='8251' tid='8252', class="m">get_pc</a>()));
  349. // Leave the debugger shell.
  350. <a id='8253' tid='8254', class="m">done</a> <a id='8255' tid='8256', class="m">=</a> <a id='8257' tid='8258', class="m">true</a>;
  351. } <a id='8259' tid='8260', class="m">else</a> <a id='8261' tid='8262', class="m">if</a> ((<a id='8263' tid='8264', class="m">strcmp</a>(<a id='8265' tid='8266', class="m">cmd</a>, <a id='8267' tid='8268', class="m">&quot;p&quot;</a>) <a id='8269' tid='8270', class="m">==</a> <a id='8271' tid='8272', class="m">0</a>) <a id='8273' tid='8274', class="m">||</a> (<a id='8275' tid='8276', class="m">strcmp</a>(<a id='8277' tid='8278', class="m">cmd</a>, <a id='8279' tid='8280', class="m">&quot;print&quot;</a>) <a id='8281' tid='8282', class="m">==</a> <a id='8283' tid='8284', class="m">0</a>)) {
  352. <span class="d">if</span> <span class="d">(argc == 2)</span> {
  353. <span class="d">int32_t value;</span>
  354. <span class="d">float fvalue;</span>
  355. <span class="d">if</span> (<a id='8285' tid='8286', class="m">strcmp</a>(<a id='8287' tid='8288', class="m">arg1</a>, <a id='8289' tid='8290', class="m">&quot;all&quot;</a>) <a id='8291' tid='8292', class="m">==</a> <a id='8293' tid='8294', class="m">0</a>) <span class="d">{
  356. PrintAllRegs();
  357. }</span> <a id='8049' tid='8050', class="m">else</a> <span class="d">if</span> <span class="d">(strcmp(arg1, &quot;allf&quot;) == 0)</span> <span class="d">{
  358. PrintAllRegsIncludingFPU();
  359. }</span> <span class="d">else</span> {
  360. <span class="d">int regnum = Registers::Number(arg1);</span>
  361. <span class="d">int fpuregnum = FPURegisters::Number(arg1);</span>
  362. <span class="d">if</span> <span class="d">(regnum != kInvalidRegister)</span> {
  363. <span class="d">value = GetRegisterValue(regnum);</span>
  364. <a id='8051' tid='8052', class="m">PrintF</a>(<a id='8053' tid='8054', class="m">&quot;%s: 0x%08x %d \n&quot;</a>, <a id='8055' tid='8056', class="m">arg1</a>, <a id='8057' tid='8058', class="m">value</a>, <a id='8059' tid='8060', class="m">value</a>);
  365. } <span class="d">else if (fpuregnum != kInvalidFPURegister) {
  366. if (fpuregnum % 2 == 1) {
  367. value = GetFPURegisterValueInt(fpuregnum);
  368. fvalue = GetFPURegisterValueFloat(fpuregnum);
  369. PrintF(&quot;%s: 0x%08x %11.4e\n&quot;, arg1, value, fvalue);
  370. } else {
  371. double dfvalue;
  372. int32_t lvalue1 = GetFPURegisterValueInt(fpuregnum);
  373. int32_t lvalue2 = GetFPURegisterValueInt(fpuregnum + 1);
  374. dfvalue = GetFPURegisterValueDouble(fpuregnum);
  375. PrintF(&quot;%3s,%3s: 0x%08x%08x %16.4e\n&quot;,
  376. FPURegisters::Name(fpuregnum+1),
  377. FPURegisters::Name(fpuregnum),
  378. lvalue1,
  379. lvalue2,
  380. dfvalue);
  381. }
  382. } else {
  383. PrintF(&quot;%s unrecognized\n&quot;, arg1);
  384. }</span>
  385. }
  386. } <span class="d">else {
  387. if (argc == 3) {
  388. if (strcmp(arg2, &quot;single&quot;) == 0) {
  389. int32_t value;
  390. float fvalue;
  391. int fpuregnum = FPURegisters::Number(arg1);
  392. if (fpuregnum != kInvalidFPURegister) {
  393. value = GetFPURegisterValueInt(fpuregnum);
  394. fvalue = GetFPURegisterValueFloat(fpuregnum);
  395. PrintF(&quot;%s: 0x%08x %11.4e\n&quot;, arg1, value, fvalue);
  396. } else {
  397. PrintF(&quot;%s unrecognized\n&quot;, arg1);
  398. }
  399. } else {
  400. PrintF(&quot;print &lt;fpu register&gt; single\n&quot;);
  401. }
  402. } else {
  403. PrintF(&quot;print &lt;register&gt; or print &lt;fpu register&gt; single\n&quot;);
  404. }
  405. }</span>
  406. } <a id='8295' tid='8296', class="m">else</a> <a id='8297' tid='8298', class="m">if</a> ((<a id='8299' tid='8300', class="m">strcmp</a>(<a id='8301' tid='8302', class="m">cmd</a>, <a id='8303' tid='8304', class="m">&quot;po&quot;</a>) <a id='8305' tid='8306', class="m">==</a> <a id='8307' tid='8308', class="m">0</a>)
  407. <a id='8309' tid='8310', class="m">||</a> (<a id='8311' tid='8312', class="m">strcmp</a>(<a id='8313' tid='8314', class="m">cmd</a>, <a id='8315' tid='8316', class="m">&quot;printobject&quot;</a>) <a id='8317' tid='8318', class="m">==</a> <a id='8319' tid='8320', class="m">0</a>)) {
  408. <a id='8321' tid='8322', class="m">if</a> (<a id='8323' tid='8324', class="m">argc</a> <a id='8325' tid='8326', class="m">==</a> <a id='8327' tid='8328', class="m">2</a>) {
  409. <a id='8329' tid='8330', class="m">int32_t</a> <a id='8331' tid='8332', class="m">value</a>;
  410. <a id='8333' tid='8334', class="m">if</a> (<a id='8335' tid='8336', class="m">GetValue</a>(<a id='8337' tid='8338', class="m">arg1</a>, <a id='8339' tid='8340', class="m">&</a><a id='8341' tid='8342', class="m">value</a>)) {
  411. <a id='8343' tid='8344', class="m">Object</a><a id='8345' tid='8346', class="m">*</a> <a id='8347' tid='8348', class="m">obj</a> = <a id='8349' tid='8350', class="m">reinterpret_cast</a>&lt;<a id='8351' tid='8352', class="m">Object</a><a id='8353' tid='8354', class="m">*</a>&gt;(<a id='8355' tid='8356', class="m">value</a>);
  412. <a id='8357' tid='8358', class="m">PrintF</a>(<a id='8359' tid='8360', class="m">&quot;%s: \n&quot;</a>, <a id='8361' tid='8362', class="m">arg1</a>);
  413. #<a id='8363' tid='8364', class="m">ifdef</a> <a id='8365' tid='8366', class="m">DEBUG</a>
  414. <a id='8367' tid='8368', class="m">obj</a>-&gt;<a id='8369' tid='8370', class="m">PrintLn</a>();
  415. #<a id='8371' tid='8372', class="m">else</a>
  416. <a id='8373' tid='8374', class="m">obj</a>-&gt;<a id='8375' tid='8376', class="m">ShortPrint</a>();
  417. <a id='8377' tid='8378', class="m">PrintF</a>(<a id='8379' tid='8380', class="m">&quot;\n&quot;</a>);
  418. #<a id='8381' tid='8382', class="m">endif</a>
  419. } <a id='8383' tid='8384', class="m">else</a> {
  420. <a id='8385' tid='8386', class="m">PrintF</a>(<a id='8387' tid='8388', class="m">&quot;%s unrecognized\n&quot;</a>, <a id='8389' tid='8390', class="m">arg1</a>);
  421. }
  422. } <a id='8391' tid='8392', class="m">else</a> {
  423. <a id='8393' tid='8394', class="m">PrintF</a>(<a id='8395' tid='8396', class="m">&quot;printobject &lt;value&gt;\n&quot;</a>);
  424. }
  425. } <a id='8397' tid='8398', class="m">else</a> <a id='8399' tid='8400', class="m">if</a> (<a id='8401' tid='8402', class="m">strcmp</a>(<a id='8403' tid='8404', class="m">cmd</a>, <a id='8405' tid='8406', class="m">&quot;stack&quot;</a>) <a id='8407' tid='8408', class="m">==</a> <a id='8409' tid='8410', class="m">0</a> <a id='8411' tid='8412', class="m">||</a> <a id='8413' tid='8414', class="m">strcmp</a>(<a id='8415' tid='8416', class="m">cmd</a>, <a id='8417' tid='8418', class="m">&quot;mem&quot;</a>) <a id='8419' tid='8420', class="m">==</a> <a id='8421' tid='8422', class="m">0</a>) {
  426. <a id='8423' tid='8424', class="m">int32_t</a><a id='8425' tid='8426', class="m">*</a> <a id='8427' tid='8428', class="m">cur</a> = <a id='8429' tid='8430', class="m">NULL</a>;
  427. <a id='8431' tid='8432', class="m">int32_t</a><a id='8433' tid='8434', class="m">*</a> <a id='8435' tid='8436', class="m">end</a> = <a id='8437' tid='8438', class="m">NULL</a>;
  428. <a id='8439' tid='8440', class="m">int</a> <a id='8441' tid='8442', class="m">next_arg</a> = <a id='8443' tid='8444', class="m">1</a>;
  429. <a id='8445' tid='8446', class="m">if</a> (<a id='8447' tid='8448', class="m">strcmp</a>(<a id='8449' tid='8450', class="m">cmd</a>, <a id='8451' tid='8452', class="m">&quot;stack&quot;</a>) <a id='8453' tid='8454', class="m">==</a> <a id='8455' tid='8456', class="m">0</a>) {
  430. <a id='8457' tid='8458', class="m">cur</a> <a id='8459' tid='8460', class="m">=</a> <a id='8461' tid='8462', class="m">reinterpret_cast</a>&lt;<a id='8463' tid='8464', class="m">int32_t</a><a id='8465' tid='8466', class="m">*</a>&gt;(<a id='8467' tid='8468', class="m">sim_</a>-&gt;<a id='8469' tid='8470', class="m">get_register</a>(<a id='8471' tid='8472', class="m">Simulator</a><a id='8473' tid='8474', class="m">::</a><a id='8475' tid='8476', class="m">sp</a>));
  431. } <a id='8477' tid='8478', class="m">else</a> { // Command &quot;mem&quot;.
  432. <a id='8479' tid='8480', class="m">int32_t</a> <a id='8481' tid='8482', class="m">value</a>;
  433. <a id='8483' tid='8484', class="m">if</a> (<a id='8485' tid='8486', class="m">!</a><a id='8487' tid='8488', class="m">GetValue</a>(<a id='8489' tid='8490', class="m">arg1</a>, <a id='8491' tid='8492', class="m">&</a><a id='8493' tid='8494', class="m">value</a>)) {
  434. <a id='8495' tid='8496', class="m">PrintF</a>(<a id='8497' tid='8498', class="m">&quot;%s unrecognized\n&quot;</a>, <a id='8499' tid='8500', class="m">arg1</a>);
  435. <a id='8501' tid='8502', class="m">continue</a>;
  436. }
  437. <a id='8503' tid='8504', class="m">cur</a> <a id='8505' tid='8506', class="m">=</a> <a id='8507' tid='8508', class="m">reinterpret_cast</a>&lt;<a id='8509' tid='8510', class="m">int32_t</a><a id='8511' tid='8512', class="m">*</a>&gt;(<a id='8513' tid='8514', class="m">value</a>);
  438. <a id='8515' tid='8516', class="m">next_arg</a><a id='8517' tid='8518', class="m">++</a>;
  439. }
  440. <a id='8519' tid='8520', class="m">int32_t</a> <a id='8521' tid='8522', class="m">words</a>;
  441. <a id='8523' tid='8524', class="m">if</a> (<a id='8525' tid='8526', class="m">argc</a> <a id='8527' tid='8528', class="m">==</a> <a id='8529' tid='8530', class="m">next_arg</a>) {
  442. <a id='8531' tid='8532', class="m">words</a> <a id='8533' tid='8534', class="m">=</a> <a id='8535' tid='8536', class="m">10</a>;
  443. } <a id='8537' tid='8538', class="m">else</a> <a id='8539' tid='8540', class="m">if</a> (<a id='8541' tid='8542', class="m">argc</a> <a id='8543' tid='8544', class="m">==</a> <a id='8545' tid='8546', class="m">next_arg</a> <a id='8547' tid='8548', class="m">+</a> <a id='8549' tid='8550', class="m">1</a>) {
  444. <a id='8551' tid='8552', class="m">if</a> (<a id='8553' tid='8554', class="m">!</a><a id='8555' tid='8556', class="m">GetValue</a>(<a id='8557' tid='8558', class="m">argv</a>[<a id='8559' tid='8560', class="m">next_arg</a>], <a id='8561' tid='8562', class="m">&</a><a id='8563' tid='8564', class="m">words</a>)) {
  445. <a id='8565' tid='8566', class="m">words</a> <a id='8567' tid='8568', class="m">=</a> <a id='8569' tid='8570', class="m">10</a>;
  446. }
  447. }
  448. <a id='8571' tid='8572', class="m">end</a> <a id='8573' tid='8574', class="m">=</a> <a id='8575' tid='8576', class="m">cur</a> <a id='8577' tid='8578', class="m">+</a> <a id='8579' tid='8580', class="m">words</a>;
  449. <a id='8581' tid='8582', class="m">while</a> (<a id='8583' tid='8584', class="m">cur</a> <a id='8585' tid='8586', class="m">&lt;</a> <a id='8587' tid='8588', class="m">end</a>) {
  450. <a id='8589' tid='8590', class="m">PrintF</a>(<a id='8591' tid='8592', class="m">&quot; 0x%08x: 0x%08x %10d&quot;</a>,
  451. <a id='8593' tid='8594', class="m">reinterpret_cast</a>&lt;<a id='8595' tid='8596', class="m">intptr_t</a>&gt;(<a id='8597' tid='8598', class="m">cur</a>), <a id='8599' tid='8600', class="m">*</a><a id='8601' tid='8602', class="m">cur</a>, <a id='8603' tid='8604', class="m">*</a><a id='8605' tid='8606', class="m">cur</a>);
  452. <a id='8607' tid='8608', class="m">HeapObject</a><a id='8609' tid='8610', class="m">*</a> <a id='8611' tid='8612', class="m">obj</a> = <a id='8613' tid='8614', class="m">reinterpret_cast</a>&lt;<a id='8615' tid='8616', class="m">HeapObject</a><a id='8617' tid='8618', class="m">*</a>&gt;(<a id='8619' tid='8620', class="m">*</a><a id='8621' tid='8622', class="m">cur</a>);
  453. <a id='8623' tid='8624', class="m">int</a> <a id='8625' tid='8626', class="m">value</a> = <a id='8627' tid='8628', class="m">*</a><a id='8629' tid='8630', class="m">cur</a>;
  454. <a id='8631' tid='8632', class="m">Heap</a><a id='8633' tid='8634', class="m">*</a> <a id='8635' tid='8636', class="m">current_heap</a> = <a id='8637' tid='8638', class="m">v8</a><a id='8639' tid='8640', class="m">::</a><a id='8641' tid='8642', class="m">internal</a><a id='8643' tid='8644', class="m">::</a><a id='8645' tid='8646', class="m">Isolate</a><a id='8647' tid='8648', class="m">::</a><a id='8649' tid='8650', class="m">Current</a>()-&gt;<a id='8651' tid='8652', class="m">heap</a>();
  455. <a id='8653' tid='8654', class="m">if</a> (<a id='8655' tid='8656', class="m">current_heap</a>-&gt;<a id='8657' tid='8658', class="m">Contains</a>(<a id='8659' tid='8660', class="m">obj</a>) <a id='8661' tid='8662', class="m">||</a> ((<a id='8663' tid='8664', class="m">value</a> <a id='8665' tid='8666', class="m">&</a> <a id='8667' tid='8668', class="m">1</a>) <a id='8669' tid='8670', class="m">==</a> <a id='8671' tid='8672', class="m">0</a>)) {
  456. <a id='8673' tid='8674', class="m">PrintF</a>(<a id='8675' tid='8676', class="m">&quot; (&quot;</a>);
  457. <a id='8677' tid='8678', class="m">if</a> ((<a id='8679' tid='8680', class="m">value</a> <a id='8681' tid='8682', class="m">&</a> <a id='8683' tid='8684', class="m">1</a>) <a id='8685' tid='8686', class="m">==</a> <a id='8687' tid='8688', class="m">0</a>) {
  458. <a id='8689' tid='8690', class="m">PrintF</a>(<a id='8691' tid='8692', class="m">&quot;smi %d&quot;</a>, <a id='8693' tid='8694', class="m">value</a> <a id='8695' tid='8696', class="m">/</a> <a id='8697' tid='8698', class="m">2</a>);
  459. } <a id='8699' tid='8700', class="m">else</a> {
  460. <a id='8701' tid='8702', class="m">obj</a>-&gt;<a id='8703' tid='8704', class="m">ShortPrint</a>();
  461. }
  462. <a id='8705' tid='8706', class="m">PrintF</a>(<a id='8707' tid='8708', class="m">&quot;)&quot;</a>);
  463. }
  464. <a id='8709' tid='8710', class="m">PrintF</a>(<a id='8711' tid='8712', class="m">&quot;\n&quot;</a>);
  465. <a id='8713' tid='8714', class="m">cur</a><a id='8715' tid='8716', class="m">++</a>;
  466. }
  467. } <a id='8717' tid='8718', class="m">else</a> <a id='8719' tid='8720', class="m">if</a> ((<a id='8721' tid='8722', class="m">strcmp</a>(<a id='8723' tid='8724', class="m">cmd</a>, <a id='8725' tid='8726', class="m">&quot;disasm&quot;</a>) <a id='8727' tid='8728', class="m">==</a> <a id='8729' tid='8730', class="m">0</a>) <span class="d">||</span>
  468. (<span class="d">strcmp(cmd, &quot;dpc&quot;) == 0</span>) <a id='8731' tid='8732', class="m">||</a>
  469. (<a id='8733' tid='8734', class="m">strcmp</a>(<a id='8735' tid='8736', class="m">cmd</a>, <a id='8737' tid='8738', class="m">&quot;di&quot;</a>) <a id='8739' tid='8740', class="m">==</a> <a id='8741' tid='8742', class="m">0</a>)) {
  470. <span class="d">disasm::NameConverter converter;</span>
  471. <a id='8743' tid='8744', class="m">disasm</a><a id='8745' tid='8746', class="m">::</a><a id='8747' tid='8748', class="m">Disassembler</a> <a id='8749' tid='8750', class="m">dasm</a>(<a id='8751' tid='8752', class="m">converter</a>);
  472. // Use a reasonably large buffer.
  473. <a id='8061' tid='8062', class="m">v8</a><a id='8063' tid='8064', class="m">::</a><a id='8065' tid='8066', class="m">internal</a><a id='8067' tid='8068', class="m">::</a><a id='8069' tid='8070', class="m">EmbeddedVector</a>&lt;<a id='8071' tid='8072', class="m">char</a>, <a id='8073' tid='8074', class="m">256</a>&gt; <a id='8075' tid='8076', class="m">buffer</a>;
  474. <span class="d">byte* cur = NULL;</span>
  475. <span class="d">byte* end = NULL;</span>
  476. <a id='7545' tid='7546', class="m">if</a> (<a id='7547' tid='7548', class="m">argc</a> <a id='7549' tid='7550', class="m">==</a> <a id='7551' tid='7552', class="m">1</a>) {
  477. <a id='7553' tid='7554', class="m">cur</a> <a id='7555' tid='7556', class="m">=</a> <a id='7557' tid='7558', class="m">reinterpret_cast</a>&lt;<a id='7559' tid='7560', class="m">byte</a><a id='7561' tid='7562', class="m">*</a>&gt;(<a id='7563' tid='7564', class="m">sim_</a>-&gt;<a id='7565' tid='7566', class="m">get_pc</a>());
  478. <a id='7567' tid='7568', class="m">end</a> <a id='7569' tid='7570', class="m">=</a> <a id='7571' tid='7572', class="m">cur</a> <a id='7573' tid='7574', class="m">+</a> (<a id='7575' tid='7576', class="m">10</a> <a id='7577' tid='7578', class="m">*</a> <a id='7579' tid='7580', class="m">Instruction</a><a id='7581' tid='7582', class="m">::</a><a id='7583' tid='7584', class="m">kInstrSize</a>);
  479. } <a id='7585' tid='7586', class="m">else</a> <a id='7587' tid='7588', class="m">if</a> (<a id='7589' tid='7590', class="m">argc</a> <a id='7591' tid='7592', class="m">==</a> <a id='7593' tid='7594', class="m">2</a>) {
  480. <a id='7595' tid='7596', class="m">int</a> <a id='7597' tid='7598', class="m">regnum</a> = <a id='7599' tid='7600', class="m">Registers</a><a id='7601' tid='7602', class="m">::</a><a id='7603' tid='7604', class="m">Number</a>(<a id='7605' tid='7606', class="m">arg1</a>);
  481. <a id='7607' tid='7608', class="m">if</a> (<span class="d">regnum != kInvalidRegister</span> <span class="d">||</span> <a id='7609' tid='7610', class="m">strncmp</a>(<a id='7611' tid='7612', class="m">arg1</a>, <a id='7613' tid='7614', class="m">&quot;0x&quot;</a>, <a id='7615' tid='7616', class="m">2</a>) <a id='7617' tid='7618', class="m">==</a> <a id='7619' tid='7620', class="m">0</a>) {
  482. // The argument is an address or a register name.
  483. <a id='7621' tid='7622', class="m">int32_t</a> <a id='7623' tid='7624', class="m">value</a>;
  484. <a id='7625' tid='7626', class="m">if</a> (<a id='7627' tid='7628', class="m">GetValue</a>(<a id='7629' tid='7630', class="m">arg1</a>, <a id='7631' tid='7632', class="m">&</a><a id='7633' tid='7634', class="m">value</a>)) {
  485. <a id='7635' tid='7636', class="m">cur</a> <a id='7637' tid='7638', class="m">=</a> <a id='7639' tid='7640', class="m">reinterpret_cast</a>&lt;<a id='7641' tid='7642', class="m">byte</a><a id='7643' tid='7644', class="m">*</a>&gt;(<a id='7645' tid='7646', class="m">value</a>);
  486. // Disassemble 10 instructions at &lt;arg1&gt;.
  487. <a id='7647' tid='7648', class="m">end</a> <a id='7649' tid='7650', class="m">=</a> <a id='7651' tid='7652', class="m">cur</a> <a id='7653' tid='7654', class="m">+</a> (<a id='7655' tid='7656', class="m">10</a> <a id='7657' tid='7658', class="m">*</a> <a id='7659' tid='7660', class="m">Instruction</a><a id='7661' tid='7662', class="m">::</a><a id='7663' tid='7664', class="m">kInstrSize</a>);
  488. }
  489. } <a id='7665' tid='7666', class="m">else</a> {
  490. // The argument is the number of instructions.
  491. <a id='7667' tid='7668', class="m">int32_t</a> <a id='7669' tid='7670', class="m">value</a>;
  492. <a id='7671' tid='7672', class="m">if</a> (<a id='7673' tid='7674', class="m">GetValue</a>(<a id='7675' tid='7676', class="m">arg1</a>, <a id='7677' tid='7678', class="m">&</a><a id='7679' tid='7680', class="m">value</a>)) {
  493. <a id='7681' tid='7682', class="m">cur</a> <a id='7683' tid='7684', class="m">=</a> <a id='7685' tid='7686', class="m">reinterpret_cast</a>&lt;<a id='7687' tid='7688', class="m">byte</a><a id='7689' tid='7690', class="m">*</a>&gt;(<a id='7691' tid='7692', class="m">sim_</a>-&gt;<a id='7693' tid='7694', class="m">get_pc</a>());
  494. // Disassemble &lt;arg1&gt; instructions.
  495. <a id='7695' tid='7696', class="m">end</a> <a id='7697' tid='7698', class="m">=</a> <a id='7699' tid='7700', class="m">cur</a> <a id='7701' tid='7702', class="m">+</a> (<a id='7703' tid='7704', class="m">value</a> <a id='7705' tid='7706', class="m">*</a> <a id='7707' tid='7708', class="m">Instruction</a><a id='7709' tid='7710', class="m">::</a><a id='7711' tid='7712', class="m">kInstrSize</a>);
  496. }
  497. }
  498. } <a id='7713' tid='7714', class="m">else</a> {
  499. <a id='7715' tid='7716', class="m">int32_t</a> <a id='7717' tid='7718', class="m">value1</a>;
  500. <a id='7719' tid='7720', class="m">int32_t</a> <a id='7721' tid='7722', class="m">value2</a>;
  501. <a id='7723' tid='7724', class="m">if</a> (<a id='7725' tid='7726', class="m">GetValue</a>(<a id='7727' tid='7728', class="m">arg1</a>, <a id='7729' tid='7730', class="m">&</a><a id='7731' tid='7732', class="m">value1</a>) <a id='7733' tid='7734', class="m">&&</a> <a id='7735' tid='7736', class="m">GetValue</a>(<a id='7737' tid='7738', class="m">arg2</a>, <a id='7739' tid='7740', class="m">&</a><a id='7741' tid='7742', class="m">value2</a>)) {
  502. <a id='7743' tid='7744', class="m">cur</a> <a id='7745' tid='7746', class="m">=</a> <a id='7747' tid='7748', class="m">reinterpret_cast</a>&lt;<a id='7749' tid='7750', class="m">byte</a><a id='7751' tid='7752', class="m">*</a>&gt;(<a id='7753' tid='7754', class="m">value1</a>);
  503. <a id='7755' tid='7756', class="m">end</a> <a id='7757' tid='7758', class="m">=</a> <a id='7759' tid='7760', class="m">cur</a> <a id='7761' tid='7762', class="m">+</a> (<a id='7763' tid='7764', class="m">value2</a> <a id='7765' tid='7766', class="m">*</a> <a id='7767' tid='7768', class="m">Instruction</a><a id='7769' tid='7770', class="m">::</a><a id='7771' tid='7772', class="m">kInstrSize</a>);
  504. }
  505. }
  506. <span class="d">while (cur &lt; end) {
  507. dasm.InstructionDecode(buffer, cur);
  508. PrintF(&quot; 0x%08x %s\n&quot;,
  509. reinterpret_cast&lt;intptr_t&gt;(cur), buffer.start());
  510. cur += Instruction::kInstrSize;
  511. }</span>
  512. } <a id='8753' tid='8754', class="m">else</a> <a id='8755' tid='8756', class="m">if</a> (<a id='8757' tid='8758', class="m">strcmp</a>(<a id='8759' tid='8760', class="m">cmd</a>, <a id='8761' tid='8762', class="m">&quot;gdb&quot;</a>) <a id='8763' tid='8764', class="m">==</a> <a id='8765' tid='8766', class="m">0</a>) {
  513. <a id='8767' tid='8768', class="m">PrintF</a>(<a id='8769' tid='8770', class="m">&quot;relinquishing control to gdb\n&quot;</a>);
  514. <a id='8771' tid='8772', class="m">v8</a><a id='8773' tid='8774', class="m">::</a><a id='8775' tid='8776', class="m">internal</a><a id='8777' tid='8778', class="m">::</a><a id='8779' tid='8780', class="m">OS</a><a id='8781' tid='8782', class="m">::</a><a id='8783' tid='8784', class="m">DebugBreak</a>();
  515. <a id='8785' tid='8786', class="m">PrintF</a>(<a id='8787' tid='8788', class="m">&quot;regaining control from gdb\n&quot;</a>);
  516. } <a id='8789' tid='8790', class="m">else</a> <a id='8791' tid='8792', class="m">if</a> (<a id='8793' tid='8794', class="m">strcmp</a>(<a id='8795' tid='8796', class="m">cmd</a>, <a id='8797' tid='8798', class="m">&quot;break&quot;</a>) <a id='8799' tid='8800', class="m">==</a> <a id='8801' tid='8802', class="m">0</a>) {
  517. <a id='8803' tid='8804', class="m">if</a> (<a id='8805' tid='8806', class="m">argc</a> <a id='8807' tid='8808', class="m">==</a> <a id='8809' tid='8810', class="m">2</a>) {
  518. <a id='8811' tid='8812', class="m">int32_t</a> <a id='8813' tid='8814', class="m">value</a>;
  519. <a id='8815' tid='8816', class="m">if</a> (<a id='8817' tid='8818', class="m">GetValue</a>(<a id='8819' tid='8820', class="m">arg1</a>, <a id='8821' tid='8822', class="m">&</a><a id='8823' tid='8824', class="m">value</a>)) {
  520. <a id='8825' tid='8826', class="m">if</a> (<a id='8827' tid='8828', class="m">!</a><a id='8829' tid='8830', class="m">SetBreakpoint</a>(<a id='8831' tid='8832', class="m">reinterpret_cast</a>&lt;<a id='8833' tid='8834', class="m">Instruction</a><a id='8835' tid='8836', class="m">*</a>&gt;(<a id='8837' tid='8838', class="m">value</a>))) {
  521. <a id='8839' tid='8840', class="m">PrintF</a>(<a id='8841' tid='8842', class="m">&quot;setting breakpoint failed\n&quot;</a>);
  522. }
  523. } <a id='8843' tid='8844', class="m">else</a> {
  524. <a id='8845' tid='8846', class="m">PrintF</a>(<a id='8847' tid='8848', class="m">&quot;%s unrecognized\n&quot;</a>, <a id='8849' tid='8850', class="m">arg1</a>);
  525. }
  526. } <a id='8851' tid='8852', class="m">else</a> {
  527. <a id='8853' tid='8854', class="m">PrintF</a>(<a id='8855' tid='8856', class="m">&quot;break &lt;address&gt;\n&quot;</a>);
  528. }
  529. } <a id='8857' tid='8858', class="m">else</a> <a id='8859' tid='8860', class="m">if</a> (<a id='8861' tid='8862', class="m">strcmp</a>(<a id='8863' tid='8864', class="m">cmd</a>, <a id='8865' tid='8866', class="m">&quot;del&quot;</a>) <a id='8867' tid='8868', class="m">==</a> <a id='8869' tid='8870', class="m">0</a>) {
  530. <a id='8871' tid='8872', class="m">if</a> (<a id='8873' tid='8874', class="m">!</a><a id='8875' tid='8876', class="m">DeleteBreakpoint</a>(<a id='8877' tid='8878', class="m">NULL</a>)) {
  531. <a id='8879' tid='8880', class="m">PrintF</a>(<a id='8881' tid='8882', class="m">&quot;deleting breakpoint failed\n&quot;</a>);
  532. }
  533. } <a id='8883' tid='8884', class="m">else</a> <span class="d">if</span> (<a id='8885' tid='8886', class="m">strcmp</a>(<a id='8887' tid='8888', class="m">cmd</a>, <a id='8889' tid='8890', class="m">&quot;flags&quot;</a>) <a id='8891' tid='8892', class="m">==</a> <a id='8893' tid='8894', class="m">0</a>) <span class="d">{
  534. PrintF(&quot;No flags on MIPS !\n&quot;);
  535. }</span> <span class="d">else</span> <a id='7773' tid='7774', class="m">if</a> (<a id='8077' tid='8078', class="m">strcmp</a>(<a id='8079' tid='8080', class="m">cmd</a>, <a id='8081' tid='8082', class="m">&quot;stop&quot;</a>) <a id='8083' tid='8084', class="m">==</a> <a id='8085' tid='8086', class="m">0</a>) {
  536. <a id='7775' tid='7776', class="m">int32_t</a> <a id='7777' tid='7778', class="m">value</a>;
  537. <a id='7779' tid='7780', class="m">intptr_t</a> <a id='7781' tid='7782', class="m">stop_pc</a> = <a id='7783' tid='7784', class="m">sim_</a>-&gt;<a id='7785' tid='7786', class="m">get_pc</a>() <a id='7787' tid='7788', class="m">-</a>
  538. <a id='7789' tid='7790', class="m">2</a> <a id='7791' tid='7792', class="m">*</a> <a id='7793' tid='7794', class="m">Instruction</a><a id='7795' tid='7796', class="m">::</a><a id='7797' tid='7798', class="m">kInstrSize</a>;
  539. <a id='7799' tid='7800', class="m">Instruction</a><a id='7801' tid='7802', class="m">*</a> <a id='7803' tid='7804', class="m">stop_instr</a> = <a id='7805' tid='7806', class="m">reinterpret_cast</a>&lt;<a id='7807' tid='7808', class="m">Instruction</a><a id='7809' tid='7810', class="m">*</a>&gt;(<a id='7811' tid='7812', class="m">stop_pc</a>);
  540. <a id='7813' tid='7814', class="m">Instruction</a><a id='7815' tid='7816', class="m">*</a> <a id='7817' tid='7818', class="m">msg_address</a> =
  541. <a id='7819' tid='7820', class="m">reinterpret_cast</a>&lt;<a id='7821' tid='7822', class="m">Instruction</a><a id='7823' tid='7824', class="m">*</a>&gt;(<a id='7825' tid='7826', class="m">stop_pc</a> <a id='7827' tid='7828', class="m">+</a>
  542. <a id='7829' tid='7830', class="m">Instruction</a><a id='7831' tid='7832', class="m">::</a><a id='7833' tid='7834', class="m">kInstrSize</a>);
  543. <a id='7835' tid='7836', class="m">if</a> ((<a id='7837' tid='7838', class="m">argc</a> <a id='7839' tid='7840', class="m">==</a> <a id='7841' tid='7842', class="m">2</a>) <a id='7843' tid='7844', class="m">&&</a> (<a id='7845' tid='7846', class="m">strcmp</a>(<a id='7847' tid='7848', class="m">arg1</a>, <a id='7849' tid='7850', class="m">&quot;unstop&quot;</a>) <a id='7851' tid='7852', class="m">==</a> <a id='7853' tid='7854', class="m">0</a>)) {
  544. // Remove the current stop.
  545. <span class="d">if</span> <span class="d">(sim_-&gt;IsStopInstruction(stop_instr))</span> {
  546. <a id='7855' tid='7856', class="m">stop_instr</a>-&gt;<a id='7857' tid='7858', class="m">SetInstructionBits</a>(<a id='7859' tid='7860', class="m">kNopInstr</a>);
  547. <a id='7861' tid='7862', class="m">msg_address</a>-&gt;<a id='7863' tid='7864', class="m">SetInstructionBits</a>(<a id='7865' tid='7866', class="m">kNopInstr</a>);
  548. } <span class="d">else {
  549. PrintF(&quot;Not at debugger stop.\n&quot;);
  550. }</span>
  551. } <a id='7867' tid='7868', class="m">else</a> <a id='7869' tid='7870', class="m">if</a> (<a id='7871' tid='7872', class="m">argc</a> <a id='7873' tid='7874', class="m">==</a> <a id='7875' tid='7876', class="m">3</a>) {
  552. // Print information about all/the specified breakpoint(s).
  553. <a id='7877' tid='7878', class="m">if</a> (<a id='7879' tid='7880', class="m">strcmp</a>(<a id='7881' tid='7882', class="m">arg1</a>, <a id='7883' tid='7884', class="m">&quot;info&quot;</a>) <a id='7885' tid='7886', class="m">==</a> <a id='7887' tid='7888', class="m">0</a>) {
  554. <span class="d">if</span> (<a id='7889' tid='7890', class="m">strcmp</a>(<a id='7891' tid='7892', class="m">arg2</a>, <a id='7893' tid='7894', class="m">&quot;all&quot;</a>) <a id='7895' tid='7896', class="m">==</a> <a id='7897' tid='7898', class="m">0</a>) <span class="d">{
  555. PrintF(&quot;Stop information:\n&quot;);
  556. for (uint32_t i = kMaxWatchpointCode + 1;
  557. i &lt;= kMaxStopCode;
  558. i++) {
  559. sim_-&gt;PrintStopInfo(i);
  560. }
  561. }</span> <a id='7285' tid='7286', class="m">else</a> <a id='7287' tid='7288', class="m">if</a> (<a id='7289' tid='7290', class="m">GetValue</a>(<a id='7291' tid='7292', class="m">arg2</a>, <a id='7293' tid='7294', class="m">&</a><a id='7295' tid='7296', class="m">value</a>)) {
  562. <a id='7297' tid='7298', class="m">sim_</a>-&gt;<a id='7299' tid='7300', class="m">PrintStopInfo</a>(<a id='7301' tid='7302', class="m">value</a>);
  563. } <a id='7303' tid='7304', class="m">else</a> {
  564. <a id='7305' tid='7306', class="m">PrintF</a>(<a id='7307' tid='7308', class="m">&quot;Unrecognized argument.\n&quot;</a>);
  565. }
  566. } <a id='7899' tid='7900', class="m">else</a> <a id='7901' tid='7902', class="m">if</a> (<a id='7903' tid='7904', class="m">strcmp</a>(<a id='7905' tid='7906', class="m">arg1</a>, <a id='7907' tid='7908', class="m">&quot;enable&quot;</a>) <a id='7909' tid='7910', class="m">==</a> <a id='7911' tid='7912', class="m">0</a>) {
  567. // Enable all/the specified breakpoint(s).
  568. <span class="d">if</span> (<a id='7913' tid='7914', class="m">strcmp</a>(<a id='7915' tid='7916', class="m">arg2</a>, <a id='7917' tid='7918', class="m">&quot;all&quot;</a>) <a id='7919' tid='7920', class="m">==</a> <a id='7921' tid='7922', class="m">0</a>) <span class="d">{
  569. for (uint32_t i = kMaxWatchpointCode + 1;
  570. i &lt;= kMaxStopCode;
  571. i++) {
  572. sim_-&gt;EnableStop(i);
  573. }
  574. }</span> <a id='7309' tid='7310', class="m">else</a> <a id='7311' tid='7312', class="m">if</a> (<a id='7313' tid='7314', class="m">GetValue</a>(<a id='7315' tid='7316', class="m">arg2</a>, <a id='7317' tid='7318', class="m">&</a><a id='7319' tid='7320', class="m">value</a>)) {
  575. <a id='7321' tid='7322', class="m">sim_</a>-&gt;<a id='7323' tid='7324', class="m">EnableStop</a>(<a id='7325' tid='7326', class="m">value</a>);
  576. } <a id='7327' tid='7328', class="m">else</a> {
  577. <a id='7329' tid='7330', class="m">PrintF</a>(<a id='7331' tid='7332', class="m">&quot;Unrecognized argument.\n&quot;</a>);
  578. }
  579. } <a id='7923' tid='7924', class="m">else</a> <a id='7925' tid='7926', class="m">if</a> (<a id='7927' tid='7928', class="m">strcmp</a>(<a id='7929' tid='7930', class="m">arg1</a>, <a id='7931' tid='7932', class="m">&quot;disable&quot;</a>) <a id='7933' tid='7934', class="m">==</a> <a id='7935' tid='7936', class="m">0</a>) {
  580. // Disable all/the specified breakpoint(s).
  581. <span class="d">if</span> (<a id='7937' tid='7938', class="m">strcmp</a>(<a id='7939' tid='7940', class="m">arg2</a>, <a id='7941' tid='7942', class="m">&quot;all&quot;</a>) <a id='7943' tid='7944', class="m">==</a> <a id='7945' tid='7946', class="m">0</a>) <span class="d">{
  582. for (uint32_t i = kMaxWatchpointCode + 1;
  583. i &lt;= kMaxStopCode;
  584. i++) {
  585. sim_-&gt;DisableStop(i);
  586. }
  587. }</span> <a id='7333' tid='7334', class="m">else</a> <a id='7335' tid='7336', class="m">if</a> (<a id='7337' tid='7338', class="m">GetValue</a>(<a id='7339' tid='7340', class="m">arg2</a>, <a id='7341' tid='7342', class="m">&</a><a id='7343' tid='7344', class="m">value</a>)) {
  588. <a id='7345' tid='7346', class="m">sim_</a>-&gt;<a id='7347' tid='7348', class="m">DisableStop</a>(<a id='7349' tid='7350', class="m">value</a>);
  589. } <a id='7351' tid='7352', class="m">else</a> {
  590. <a id='7353' tid='7354', class="m">PrintF</a>(<a id='7355' tid='7356', class="m">&quot;Unrecognized argument.\n&quot;</a>);
  591. }
  592. }
  593. } <a id='7947' tid='7948', class="m">else</a> {
  594. <a id='7949' tid='7950', class="m">PrintF</a>(<a id='7951' tid='7952', class="m">&quot;Wrong usage. Use help command for more information.\n&quot;</a>);
  595. }
  596. } <a id='7953' tid='7954', class="m">else</a> <span class="d">if</span> <span class="d">((strcmp(cmd, &quot;stat&quot;) == 0) || (strcmp(cmd, &quot;st&quot;) == 0))</span> {
  597. // Print registers and disassemble.
  598. <span class="d">PrintAllRegs();</span>
  599. <span class="d">PrintF(&quot;\n&quot;);</span>
  600. <span class="d">disasm::NameConverter converter;</span>
  601. <a id='4845' tid='4846', class="m">disasm</a><a id='4847' tid='4848', class="m">::</a><a id='4849' tid='4850', class="m">Disassembler</a> <a id='4851' tid='4852', class="m">dasm</a>(<a id='4853' tid='4854', class="m">converter</a>);
  602. // Use a reasonably large buffer.
  603. <a id='4711' tid='4712', class="m">v8</a><a id='4713' tid='4714', class="m">::</a><a id='4715' tid='4716', class="m">internal</a><a id='4717' tid='4718', class="m">::</a><a id='4719' tid='4720', class="m">EmbeddedVector</a>&lt;<a id='4721' tid='4722', class="m">char</a>, <a id='4723' tid='4724', class="m">256</a>&gt; <a id='4725' tid='4726', class="m">buffer</a>;
  604. <span class="d">byte* cur = NULL;</span>
  605. <span class="d">byte* end = NULL;</span>
  606. <span class="d">if (argc == 1) {
  607. cur = reinterpret_cast&lt;byte*&gt;(sim_-&gt;get_pc());
  608. end = cur + (10 * Instruction::kInstrSize);
  609. } else if (argc == 2) {
  610. int32_t value;
  611. if (GetValue(arg1, &value)) {
  612. cur = reinterpret_cast&lt;byte*&gt;(value);
  613. // no length parameter passed, assume 10 instructions
  614. end = cur + (10 * Instruction::kInstrSize);
  615. }
  616. } else {
  617. int32_t value1;
  618. int32_t value2;
  619. if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
  620. cur = reinterpret_cast&lt;byte*&gt;(value1);
  621. end = cur + (value2 * Instruction::kInstrSize);
  622. }
  623. }</span>
  624. <span class="d">while (cur &lt; end) {
  625. dasm.InstructionDecode(buffer, cur);
  626. PrintF(&quot; 0x%08x %s\n&quot;,
  627. reinterpret_cast&lt;intptr_t&gt;(cur), buffer.start());
  628. cur += Instruction::kInstrSize;
  629. }</span>
  630. } <a id='7955' tid='7956', class="m">else</a> <span class="d">if</span> ((<a id='7957' tid='7958', class="m">strcmp</a>(<a id='7959' tid='7960', class="m">cmd</a>, <a id='7961' tid='7962', class="m">&quot;h&quot;</a>) <a id='7963' tid='7964', class="m">==</a> <a id='7965' tid='7966', class="m">0</a>) <a id='7967' tid='7968', class="m">||</a> (<a id='7969' tid='7970', class="m">strcmp</a>(<a id='7971' tid='7972', class="m">cmd</a>, <a id='7973' tid='7974', class="m">&quot;help&quot;</a>) <a id='7975' tid='7976', class="m">==</a> <a id='7977' tid='7978', class="m">0</a>)) <span class="d">{
  631. PrintF(&quot;cont\n&quot;);
  632. PrintF(&quot; continue execution (alias &#39;c&#39;)\n&quot;);
  633. PrintF(&quot;stepi\n&quot;);
  634. PrintF(&quot; step one instruction (alias &#39;si&#39;)\n&quot;);
  635. PrintF(&quot;print &lt;register&gt;\n&quot;);
  636. PrintF(&quot; print register content (alias &#39;p&#39;)\n&quot;);
  637. PrintF(&quot; use register name &#39;all&#39; to print all registers\n&quot;);
  638. PrintF(&quot;printobject &lt;register&gt;\n&quot;);
  639. PrintF(&quot; print an object from a register (alias &#39;po&#39;)\n&quot;);
  640. PrintF(&quot;stack [&lt;words&gt;]\n&quot;);
  641. PrintF(&quot; dump stack content, default dump 10 words)\n&quot;);
  642. PrintF(&quot;mem &lt;address&gt; [&lt;words&gt;]\n&quot;);
  643. PrintF(&quot; dump memory content, default dump 10 words)\n&quot;);
  644. PrintF(&quot;flags\n&quot;);
  645. PrintF(&quot; print flags\n&quot;);
  646. PrintF(&quot;disasm [&lt;instructions&gt;]\n&quot;);
  647. PrintF(&quot;disasm [&lt;address/register&gt;]\n&quot;);
  648. PrintF(&quot;disasm [[&lt;address/register&gt;] &lt;instructions&gt;]\n&quot;);
  649. PrintF(&quot; disassemble code, default is 10 instructions\n&quot;);
  650. PrintF(&quot; from pc (alias &#39;di&#39;)\n&quot;);
  651. PrintF(&quot;gdb\n&quot;);
  652. PrintF(&quot; enter gdb\n&quot;);
  653. PrintF(&quot;break &lt;address&gt;\n&quot;);
  654. PrintF(&quot; set a break point on the address\n&quot;);
  655. PrintF(&quot;del\n&quot;);
  656. PrintF(&quot; delete the breakpoint\n&quot;);
  657. PrintF(&quot;stop feature:\n&quot;);
  658. PrintF(&quot; Description:\n&quot;);
  659. PrintF(&quot; Stops are debug instructions inserted by\n&quot;);
  660. PrintF(&quot; the Assembler::stop() function.\n&quot;);
  661. PrintF(&quot; When hitting a stop, the Simulator will\n&quot;);
  662. PrintF(&quot; stop and and give control to the Debugger.\n&quot;);
  663. PrintF(&quot; All stop codes are watched:\n&quot;);
  664. PrintF(&quot; - They can be enabled / disabled: the Simulator\n&quot;);
  665. PrintF(&quot; will / won&#39;t stop when hitting them.\n&quot;);
  666. PrintF(&quot; - The Simulator keeps track of how many times they \n&quot;);
  667. PrintF(&quot; are met. (See the info command.) Going over a\n&quot;);
  668. PrintF(&quot; disabled stop still increases its counter. \n&quot;);
  669. PrintF(&quot; Commands:\n&quot;);
  670. PrintF(&quot; stop info all/&lt;code&gt; : print infos about number &lt;code&gt;\n&quot;);
  671. PrintF(&quot; or all stop(s).\n&quot;);
  672. PrintF(&quot; stop enable/disable all/&lt;code&gt; : enables / disables\n&quot;);
  673. PrintF(&quot; all or number &lt;code&gt; stop(s)\n&quot;);
  674. PrintF(&quot; stop unstop\n&quot;);
  675. PrintF(&quot; ignore the stop instruction at the current location\n&quot;);
  676. PrintF(&quot; from now on\n&quot;);
  677. }</span> <span class="d">else {
  678. PrintF(&quot;Unknown command: %s\n&quot;, cmd);
  679. }</span>
  680. }
  681. <a id='8895' tid='8896', class="m">DeleteArray</a>(<a id='8897' tid='8898', class="m">line</a>);
  682. }
  683. // Add all the breakpoints back to stop execution and enter the debugger
  684. // shell when hit.
  685. <a id='9159' tid='9160', class="m">RedoBreakpoints</a>();
  686. #<a id='9161' tid='9162', class="m">undef</a> <a id='9163' tid='9164', class="m">COMMAND_SIZE</a>
  687. #<a id='9165' tid='9166', class="m">undef</a> <a id='9167' tid='9168', class="m">ARG_SIZE</a>
  688. #<a id='9169' tid='9170', class="m">undef</a> <a id='9171' tid='9172', class="m">STR</a>
  689. #<a id='9173' tid='9174', class="m">undef</a> <a id='9175' tid='9176', class="m">XSTR</a>
  690. }
  691. <a id='8899' tid='8900', class="m">static</a> <a id='8901' tid='8902', class="m">bool</a> <a id='8903' tid='8904', class="m">ICacheMatch</a>(<a id='8905' tid='8906', class="m">void</a><a id='8907' tid='8908', class="m">*</a> <a id='8909' tid='8910', class="m">one</a>, <a id='8911' tid='8912', class="m">void</a><a id='8913' tid='8914', class="m">*</a> <a id='8915' tid='8916', class="m">two</a>) {
  692. <a id='8917' tid='8918', class="m">ASSERT</a>((<a id='8919' tid='8920', class="m">reinterpret_cast</a>&lt;<a id='8921' tid='8922', class="m">intptr_t</a>&gt;(<a id='8923' tid='8924', class="m">one</a>) <a id='8925' tid='8926', class="m">&</a> <a id='8927' tid='8928', class="m">CachePage</a><a id='8929' tid='8930', class="m">::</a><a id='8931' tid='8932', class="m">kPageMask</a>) <a id='8933' tid='8934', class="m">==</a> <a id='8935' tid='8936', class="m">0</a>);
  693. <a id='8937' tid='8938', class="m">ASSERT</a>((<a id='8939' tid='8940', class="m">reinterpret_cast</a>&lt;<a id='8941' tid='8942', class="m">intptr_t</a>&gt;(<a id='8943' tid='8944', class="m">two</a>) <a id='8945' tid='8946', class="m">&</a> <a id='8947' tid='8948', class="m">CachePage</a><a id='8949' tid='8950', class="m">::</a><a id='8951' tid='8952', class="m">kPageMask</a>) <a id='8953' tid='8954', class="m">==</a> <a id='8955' tid='8956', class="m">0</a>);
  694. <a id='8957' tid='8958', class="m">return</a> <a id='8959' tid='8960', class="m">one</a> <a id='8961' tid='8962', class="m">==</a> <a id='8963' tid='8964', class="m">two</a>;
  695. }
  696. <a id='8087' tid='8088', class="m">static</a> <a id='8089' tid='8090', class="m">uint32_t</a> <a id='8091' tid='8092', class="m">ICacheHash</a>(<a id='8093' tid='8094', class="m">void</a><a id='8095' tid='8096', class="m">*</a> <a id='8097' tid='8098', class="m">key</a>) {
  697. <a id='8099' tid='8100', class="m">return</a> <a id='8101' tid='8102', class="m">static_cast</a>&lt;<a id='8103' tid='8104', class="m">uint32_t</a>&gt;(<a id='8105' tid='8106', class="m">reinterpret_cast</a>&lt;<a id='8107' tid='8108', class="m">uintptr_t</a>&gt;(<a id='8109' tid='8110', class="m">key</a>)) <a id='8111' tid='8112', class="m">&gt;&gt;</a> <a id='8113' tid='8114', class="m">2</a>;
  698. }
  699. <a id='7979' tid='7980', class="m">static</a> <a id='7981' tid='7982', class="m">bool</a> <a id='7983' tid='7984', class="m">AllOnOnePage</a>(<a id='7985' tid='7986', class="m">uintptr_t</a> <a id='7987' tid='7988', class="m">start</a>, <a id='7989' tid='7990', class="m">int</a> <a id='7991' tid='7992', class="m">size</a>) {
  700. <a id='7993' tid='7994', class="m">intptr_t</a> <a id='7995' tid='7996', class="m">start_page</a> = (<a id='7997' tid='7998', class="m">start</a> <a id='7999' tid='8000', class="m">&</a> <a id='8001' tid='8002', class="m">~</a><a id='8003' tid='8004', class="m">CachePage</a><a id='8005' tid='8006', class="m">::</a><a id='8007' tid='8008', class="m">kPageMask</a>);
  701. <a id='8009' tid='8010', class="m">intptr_t</a> <a id='8011' tid='8012', class="m">end_page</a> = ((<a id='8013' tid='8014', class="m">start</a> <a id='8015' tid='8016', class="m">+</a> <a id='8017' tid='8018', class="m">size</a>) <a id='8019' tid='8020', class="m">&</a> <a id='8021' tid='8022', class="m">~</a><a id='8023' tid='8024', class="m">CachePage</a><a id='8025' tid='8026', class="m">::</a><a id='8027' tid='8028', class="m">kPageMask</a>);
  702. <a id='8029' tid='8030', class="m">return</a> <a id='8031' tid='8032', class="m">start_page</a> <a id='8033' tid='8034', class="m">==</a> <a id='8035' tid='8036', class="m">end_page</a>;
  703. }
  704. <a id='7357' tid='7358', class="m">void</a> <a id='7359' tid='7360', class="m">Simulator</a><a id='7361' tid='7362', class="m">::</a><a id='7363' tid='7364', class="m">FlushICache</a>(<a id='7365' tid='7366', class="m">v8</a><a id='7367' tid='7368', class="m">::</a><a id='7369' tid='7370', class="m">internal</a><a id='7371' tid='7372', class="m">::</a><a id='7373' tid='7374', class="m">HashMap</a><a id='7375' tid='7376', class="m">*</a> <a id='7377' tid='7378', class="m">i_cache</a>,
  705. <a id='7379' tid='7380', class="m">void</a><a id='7381' tid='7382', class="m">*</a> <a id='7383' tid='7384', class="m">start_addr</a>,
  706. <a id='7385' tid='7386', class="m">size_t</a> <a id='7387' tid='7388', class="m">size</a>) {
  707. <a id='7389' tid='7390', class="m">intptr_t</a> <a id='7391' tid='7392', class="m">start</a> = <a id='7393' tid='7394', class="m">reinterpret_cast</a>&lt;<a id='7395' tid='7396', class="m">intptr_t</a>&gt;(<a id='7397' tid='7398', class="m">start_addr</a>);
  708. <a id='7399' tid='7400', class="m">int</a> <a id='7401' tid='7402', class="m">intra_line</a> = (<a id='7403' tid='7404', class="m">start</a> <a id='7405' tid='7406', class="m">&</a> <a id='7407' tid='7408', class="m">CachePage</a><a id='7409' tid='7410', class="m">::</a><a id='7411' tid='7412', class="m">kLineMask</a>);
  709. <a id='7413' tid='7414', class="m">start</a> <a id='7415' tid='7416', class="m">-=</a> <a id='7417' tid='7418', class="m">intra_line</a>;
  710. <a id='7419' tid='7420', class="m">size</a> <a id='7421' tid='7422', class="m">+=</a> <a id='7423' tid='7424', class="m">intra_line</a>;
  711. <a id='7425' tid='7426', class="m">size</a> <a id='7427' tid='7428', class="m">=</a> ((<a id='7429' tid='7430', class="m">size</a> <a id='7431' tid='7432', class="m">-</a> <a id='7433' tid='7434', class="m">1</a>) <a id='7435' tid='7436', class="m">|</a> <a id='7437' tid='7438', class="m">CachePage</a><a id='7439' tid='7440', class="m">::</a><a id='7441' tid='7442', class="m">kLineMask</a>) <a id='7443' tid='7444', class="m">+</a> <a id='7445' tid='7446', class="m">1</a>;
  712. <a id='7447' tid='7448', class="m">int</a> <a id='7449' tid='7450', class="m">offset</a> = (<a id='7451' tid='7452', class="m">start</a> <a id='7453' tid='7454', class="m">&</a> <a id='7455' tid='7456', class="m">CachePage</a><a id='7457' tid='7458', class="m">::</a><a id='7459' tid='7460', class="m">kPageMask</a>);
  713. <a id='7461' tid='7462', class="m">while</a> (<a id='7463' tid='7464', class="m">!</a><a id='7465' tid='7466', class="m">AllOnOnePage</a>(<a id='7467' tid='7468', class="m">start</a>, <a id='7469' tid='7470', class="m">size</a> <a id='7471' tid='7472', class="m">-</a> <a id='7473' tid='7474', class="m">1</a>)) {
  714. <a id='7475' tid='7476', class="m">int</a> <a id='7477' tid='7478', class="m">bytes_to_flush</a> = <a id='7479' tid='7480', class="m">CachePage</a><a id='7481' tid='7482', class="m">::</a><a id='7483' tid='7484', class="m">kPageSize</a> <a id='7485' tid='7486', class="m">-</a> <a id='7487' tid='7488', class="m">offset</a>;
  715. <a id='7489' tid='7490', class="m">FlushOnePage</a>(<a id='7491' tid='7492', class="m">i_cache</a>, <a id='7493' tid='7494', class="m">start</a>, <a id='7495' tid='7496', class="m">bytes_to_flush</a>);
  716. <a id='7497' tid='7498', class="m">start</a> <a id='7499' tid='7500', class="m">+=</a> <a id='7501' tid='7502', class="m">bytes_to_flush</a>;
  717. <a id='7503' tid='7504', class="m">size</a> <a id='7505' tid='7506', class="m">-=</a> <a id='7507' tid='7508', class="m">bytes_to_flush</a>;
  718. <a id='7509' tid='7510', class="m">ASSERT_EQ</a>(<a id='7511' tid='7512', class="m">0</a>, <a id='7513' tid='7514', class="m">start</a> <a id='7515' tid='7516', class="m">&</a> <a id='7517' tid='7518', class="m">CachePage</a><a id='7519' tid='7520', class="m">::</a><a id='7521' tid='7522', class="m">kPageMask</a>);
  719. <a id='7523' tid='7524', class="m">offset</a> <a id='7525' tid='7526', class="m">=</a> <a id='7527' tid='7528', class="m">0</a>;
  720. }
  721. <a id='7529' tid='7530', class="m">if</a> (<a id='7531' tid='7532', class="m">size</a> <a id='7533' tid='7534', class="m">!=</a> <a id='7535' tid='7536', class="m">0</a>) {
  722. <a id='7537' tid='7538', class="m">FlushOnePage</a>(<a id='7539' tid='7540', class="m">i_cache</a>, <a id='7541' tid='7542', class="m">start</a>, <a id='7543' tid='7544', class="m">size</a>);
  723. }
  724. }
  725. <a id='7185' tid='7186', class="m">CachePage</a><a id='7187' tid='7188', class="m">*</a> <a id='7189' tid='7190', class="m">Simulator</a><a id='7191' tid='7192', class="m">::</a><a id='7193' tid='7194', class="m">GetCachePage</a>(<a id='7195' tid='7196', class="m">v8</a><a id='7197' tid='7198', class="m">::</a><a id='7199' tid='7200', class="m">internal</a><a id='7201' tid='7202', class="m">::</a><a id='7203' tid='7204', class="m">HashMap</a><a id='7205' tid='7206', class="m">*</a> <a id='7207' tid='7208', class="m">i_cache</a>, <a id='7209' tid='7210', class="m">void</a><a id='7211' tid='7212', class="m">*</a> <a id='7213' tid='7214', class="m">page</a>) {
  726. <a id='7215' tid='7216', class="m">v8</a><a id='7217' tid='7218', class="m">::</a><a id='7219' tid='7220', class="m">internal</a><a id='7221' tid='7222', class="m">::</a><a id='7223' tid='7224', class="m">HashMap</a><a id='7225' tid='7226', class="m">::</a><a id='7227' tid='7228', class="m">Entry</a><a id='7229' tid='7230', class="m">*</a> <a id='7231' tid='7232', class="m">entry</a> = <a id='7233' tid='7234', class="m">i_cache</a>-&gt;<a id='7235' tid='7236', class="m">Lookup</a>(<a id='7237' tid='7238', class="m">page</a>,
  727. <a id='7239' tid='7240', class="m">ICacheHash</a>(<a id='7241' tid='7242', class="m">page</a>),
  728. <a id='7243' tid='7244', class="m">true</a>);
  729. <a id='7245' tid='7246', class="m">if</a> (<a id='7247' tid='7248', class="m">entry</a>-&gt;<a id='7249' tid='7250', class="m">value</a> <a id='7251' tid='7252', class="m">==</a> <a id='7253' tid='7254', class="m">NULL</a>) {
  730. <a id='7255' tid='7256', class="m">CachePage</a><a id='7257' tid='7258', class="m">*</a> <a id='7259' tid='7260', class="m">new_page</a> = <a id='7261' tid='7262', class="m">new</a> <a id='7263' tid='7264', class="m">CachePage</a>();
  731. <a id='7265' tid='7266', class="m">entry</a>-&gt;<a id='7267' tid='7268', class="m">value</a> <a id='7269' tid='7270', class="m">=</a> <a id='7271' tid='7272', class="m">new_page</a>;
  732. }
  733. <a id='7273' tid='7274', class="m">return</a> <a id='7275' tid='7276', class="m">reinterpret_cast</a>&lt;<a id='7277' tid='7278', class="m">CachePage</a><a id='7279' tid='7280', class="m">*</a>&gt;(<a id='7281' tid='7282', class="m">entry</a>-&gt;<a id='7283' tid='7284', class="m">value</a>);
  734. }
  735. // Flush from start up to and not including start + size.
  736. <a id='7017' tid='7018', class="m">void</a> <a id='7019' tid='7020', class="m">Simulator</a><a id='7021' tid='7022', class="m">::</a><a id='7023' tid='7024', class="m">FlushOnePage</a>(<a id='7025' tid='7026', class="m">v8</a><a id='7027' tid='7028', class="m">::</a><a id='7029' tid='7030', class="m">internal</a><a id='7031' tid='7032', class="m">::</a><a id='7033' tid='7034', class="m">HashMap</a><a id='7035' tid='7036', class="m">*</a> <a id='7037' tid='7038', class="m">i_cache</a>,
  737. <a id='7039' tid='7040', class="m">intptr_t</a> <a id='7041' tid='7042', class="m">start</a>,
  738. <a id='7043' tid='7044', class="m">int</a> <a id='7045' tid='7046', class="m">size</a>) {
  739. <a id='7047' tid='7048', class="m">ASSERT</a>(<a id='7049' tid='7050', class="m">size</a> <a id='7051' tid='7052', class="m">&lt;=</a> <a id='7053' tid='7054', class="m">CachePage</a><a id='7055' tid='7056', class="m">::</a><a id='7057' tid='7058', class="m">kPageSize</a>);
  740. <a id='7059' tid='7060', class="m">ASSERT</a>(<a id='7061' tid='7062', class="m">AllOnOnePage</a>(<a id='7063' tid='7064', class="m">start</a>, <a id='7065' tid='7066', class="m">size</a> <a id='7067' tid='7068', class="m">-</a> <a id='7069' tid='7070', class="m">1</a>));
  741. <a id='7071' tid='7072', class="m">ASSERT</a>((<a id='7073' tid='7074', class="m">start</a> <a id='7075' tid='7076', class="m">&</a> <a id='7077' tid='7078', class="m">CachePage</a><a id='7079' tid='7080', class="m">::</a><a id='7081' tid='7082', class="m">kLineMask</a>) <a id='7083' tid='7084', class="m">==</a> <a id='7085' tid='7086', class="m">0</a>);
  742. <a id='7087' tid='7088', class="m">ASSERT</a>((<a id='7089' tid='7090', class="m">size</a> <a id='7091' tid='7092', class="m">&</a> <a id='7093' tid='7094', class="m">CachePage</a><a id='7095' tid='7096', class="m">::</a><a id='7097' tid='7098', class="m">kLineMask</a>) <a id='7099' tid='7100', class="m">==</a> <a id='7101' tid='7102', class="m">0</a>);
  743. <a id='7103' tid='7104', class="m">void</a><a id='7105' tid='7106', class="m">*</a> <a id='7107' tid='7108', class="m">page</a> = <a id='7109' tid='7110', class="m">reinterpret_cast</a>&lt;<a id='7111' tid='7112', class="m">void</a><a id='7113' tid='7114', class="m">*</a>&gt;(<a id='7115' tid='7116', class="m">start</a> <a id='7117' tid='7118', class="m">&</a> (<a id='7119' tid='7120', class="m">~</a><a id='7121' tid='7122', class="m">CachePage</a><a id='7123' tid='7124', class="m">::</a><a id='7125' tid='7126', class="m">kPageMask</a>));
  744. <a id='7127' tid='7128', class="m">int</a> <a id='7129' tid='7130', class="m">offset</a> = (<a id='7131' tid='7132', class="m">start</a> <a id='7133' tid='7134', class="m">&</a> <a id='7135' tid='7136', class="m">CachePage</a><a id='7137' tid='7138', class="m">::</a><a id='7139' tid='7140', class="m">kPageMask</a>);
  745. <a id='7141' tid='7142', class="m">CachePage</a><a id='7143' tid='7144', class="m">*</a> <a id='7145' tid='7146', class="m">cache_page</a> = <a id='7147' tid='7148', class="m">GetCachePage</a>(<a id='7149' tid='7150', class="m">i_cache</a>, <a id='7151' tid='7152', class="m">page</a>);
  746. <a id='7153' tid='7154', class="m">char</a><a id='7155' tid='7156', class="m">*</a> <a id='7157' tid='7158', class="m">valid_bytemap</a> = <a id='7159' tid='7160', class="m">cache_page</a>-&gt;<a id='7161' tid='7162', class="m">ValidityByte</a>(<a id='7163' tid='7164', class="m">offset</a>);
  747. <a id='7165' tid='7166', class="m">memset</a>(<a id='7167' tid='7168', class="m">valid_bytemap</a>, <a id='7169' tid='7170', class="m">CachePage</a><a id='7171' tid='7172', class="m">::</a><a id='7173' tid='7174', class="m">LINE_INVALID</a>, <a id='7175' tid='7176', class="m">size</a> <a id='7177' tid='7178', class="m">&gt;&gt;</a> <a id='7179' tid='7180', class="m">CachePage</a><a id='7181' tid='7182', class="m">::</a><a id='7183' tid='7184', class="m">kLineShift</a>);
  748. }
  749. <a id='6797' tid='6798', class="m">void</a> <a id='6799' tid='6800', class="m">Simulator</a><a id='6801' tid='6802', class="m">::</a><a id='6803' tid='6804', class="m">CheckICache</a>(<a id='6805' tid='6806', class="m">v8</a><a id='6807' tid='6808', class="m">::</a><a id='6809' tid='6810', class="m">internal</a><a id='6811' tid='6812', class="m">::</a><a id='6813' tid='6814', class="m">HashMap</a><a id='6815' tid='6816', class="m">*</a> <a id='6817' tid='6818', class="m">i_cache</a>,
  750. <a id='6819' tid='6820', class="m">Instruction</a><a id='6821' tid='6822', class="m">*</a> <a id='6823' tid='6824', class="m">instr</a>) {
  751. <a id='6825' tid='6826', class="m">intptr_t</a> <a id='6827' tid='6828', class="m">address</a> = <a id='6829' tid='6830', class="m">reinterpret_cast</a>&lt;<a id='6831' tid='6832', class="m">intptr_t</a>&gt;(<a id='6833' tid='6834', class="m">instr</a>);
  752. <a id='6835' tid='6836', class="m">void</a><a id='6837' tid='6838', class="m">*</a> <a id='6839' tid='6840', class="m">page</a> = <a id='6841' tid='6842', class="m">reinterpret_cast</a>&lt;<a id='6843' tid='6844', class="m">void</a><a id='6845' tid='6846', class="m">*</a>&gt;(<a id='6847' tid='6848', class="m">address</a> <a id='6849' tid='6850', class="m">&</a> (<a id='6851' tid='6852', class="m">~</a><a id='6853' tid='6854', class="m">CachePage</a><a id='6855' tid='6856', class="m">::</a><a id='6857' tid='6858', class="m">kPageMask</a>));
  753. <a id='6859' tid='6860', class="m">void</a><a id='6861' tid='6862', class="m">*</a> <a id='6863' tid='6864', class="m">line</a> = <a id='6865' tid='6866', class="m">reinterpret_cast</a>&lt;<a id='6867' tid='6868', class="m">void</a><a id='6869' tid='6870', class="m">*</a>&gt;(<a id='6871' tid='6872', class="m">address</a> <a id='6873' tid='6874', class="m">&</a> (<a id='6875' tid='6876', class="m">~</a><a id='6877' tid='6878', class="m">CachePage</a><a id='6879' tid='6880', class="m">::</a><a id='6881' tid='6882', class="m">kLineMask</a>));
  754. <a id='6883' tid='6884', class="m">int</a> <a id='6885' tid='6886', class="m">offset</a> = (<a id='6887' tid='6888', class="m">address</a> <a id='6889' tid='6890', class="m">&</a> <a id='6891' tid='6892', class="m">CachePage</a><a id='6893' tid='6894', class="m">::</a><a id='6895' tid='6896', class="m">kPageMask</a>);
  755. <a id='6897' tid='6898', class="m">CachePage</a><a id='6899' tid='6900', class="m">*</a> <a id='6901' tid='6902', class="m">cache_page</a> = <a id='6903' tid='6904', class="m">GetCachePage</a>(<a id='6905' tid='6906', class="m">i_cache</a>, <a id='6907' tid='6908', class="m">page</a>);
  756. <a id='6909' tid='6910', class="m">char</a><a id='6911' tid='6912', class="m">*</a> <a id='6913' tid='6914', class="m">cache_valid_byte</a> = <a id='6915' tid='6916', class="m">cache_page</a>-&gt;<a id='6917' tid='6918', class="m">ValidityByte</a>(<a id='6919' tid='6920', class="m">offset</a>);
  757. <a id='6921' tid='6922', class="m">bool</a> <a id='6923' tid='6924', class="m">cache_hit</a> = (<a id='6925' tid='6926', class="m">*</a><a id='6927' tid='6928', class="m">cache_valid_byte</a> <a id='6929' tid='6930', class="m">==</a> <a id='6931' tid='6932', class="m">CachePage</a><a id='6933' tid='6934', class="m">::</a><a id='6935' tid='6936', class="m">LINE_VALID</a>);
  758. <a id='6937' tid='6938', class="m">char</a><a id='6939' tid='6940', class="m">*</a> <a id='6941' tid='6942', class="m">cached_line</a> = <a id='6943' tid='6944', class="m">cache_page</a>-&gt;<a id='6945' tid='6946', class="m">CachedData</a>(<a id='6947' tid='6948', class="m">offset</a> <a id='6949' tid='6950', class="m">&</a> <a id='6951' tid='6952', class="m">~</a><a id='6953' tid='6954', class="m">CachePage</a><a id='6955' tid='6956', class="m">::</a><a id='6957' tid='6958', class="m">kLineMask</a>);
  759. <a id='6959' tid='6960', class="m">if</a> (<a id='6961' tid='6962', class="m">cache_hit</a>) {
  760. // Check that the data in memory matches the contents of the I-cache.
  761. <a id='6963' tid='6964', class="m">CHECK</a>(<a id='6965' tid='6966', class="m">memcmp</a>(<a id='6967' tid='6968', class="m">reinterpret_cast</a>&lt;<a id='6969' tid='6970', class="m">void</a><a id='6971' tid='6972', class="m">*</a>&gt;(<a id='6973' tid='6974', class="m">instr</a>),
  762. <a id='6975' tid='6976', class="m">cache_page</a>-&gt;<a id='6977' tid='6978', class="m">CachedData</a>(<a id='6979' tid='6980', class="m">offset</a>),
  763. <a id='6981' tid='6982', class="m">Instruction</a><a id='6983' tid='6984', class="m">::</a><a id='6985' tid='6986', class="m">kInstrSize</a>) <a id='6987' tid='6988', class="m">==</a> <a id='6989' tid='6990', class="m">0</a>);
  764. } <a id='6991' tid='6992', class="m">else</a> {
  765. // Cache miss. Load memory into the cache.
  766. <a id='6993' tid='6994', class="m">memcpy</a>(<a id='6995' tid='6996', class="m">cached_line</a>, <a id='6997' tid='6998', class="m">line</a>, <a id='6999' tid='7000', class="m">CachePage</a><a id='7001' tid='7002', class="m">::</a><a id='7003' tid='7004', class="m">kLineLength</a>);
  767. <a id='7005' tid='7006', class="m">*</a><a id='7007' tid='7008', class="m">cache_valid_byte</a> <a id='7009' tid='7010', class="m">=</a> <a id='7011' tid='7012', class="m">CachePage</a><a id='7013' tid='7014', class="m">::</a><a id='7015' tid='7016', class="m">LINE_VALID</a>;
  768. }
  769. }
  770. <a id='6747' tid='6748', class="m">void</a> <a id='6749' tid='6750', class="m">Simulator</a><a id='6751' tid='6752', class="m">::</a><a id='6753' tid='6754', class="m">Initialize</a>(<a id='6755' tid='6756', class="m">Isolate</a><a id='6757' tid='6758', class="m">*</a> <a id='6759' tid='6760', class="m">isolate</a>) {
  771. <a id='6761' tid='6762', class="m">if</a> (<a id='6763' tid='6764', class="m">isolate</a>-&gt;<a id='6765' tid='6766', class="m">simulator_initialized</a>()) <a id='6767' tid='6768', class="m">return</a>;
  772. <a id='6769' tid='6770', class="m">isolate</a>-&gt;<a id='6771' tid='6772', class="m">set_simulator_initialized</a>(<a id='6773' tid='6774', class="m">true</a>);
  773. <a id='6775' tid='6776', class="m">::</a><a id='6777' tid='6778', class="m">v8</a><a id='6779' tid='6780', class="m">::</a><a id='6781' tid='6782', class="m">internal</a><a id='6783' tid='6784', class="m">::</a><a id='6785' tid='6786', class="m">ExternalReference</a><a id='6787' tid='6788', class="m">::</a><a id='6789' tid='6790', class="m">set_redirector</a>(<a id='6791' tid='6792', class="m">isolate</a>,
  774. <a id='6793' tid='6794', class="m">&</a><a id='6795' tid='6796', class="m">RedirectExternalReference</a>);
  775. }
  776. <a id='6697' tid='6698', class="m">Simulator</a><a id='6699' tid='6700', class="m">::</a><a id='6701' tid='6702', class="m">Simulator</a>(<a id='6703' tid='6704', class="m">Isolate</a><a id='6705' tid='6706', class="m">*</a> <a id='6707' tid='6708', class="m">isolate</a>) : <a id='6709' tid='6710', class="m">isolate_</a>(<a id='6711' tid='6712', class="m">isolate</a>) {
  777. <span class="d">i_cache_ = isolate_-&gt;simulator_i_cache();</span>
  778. <a id='6713' tid='6714', class="m">if</a> (<a id='6715' tid='6716', class="m">i_cache_</a> <a id='6717' tid='6718', class="m">==</a> <a id='6719' tid='6720', class="m">NULL</a>) {
  779. <a id='6721' tid='6722', class="m">i_cache_</a> <a id='6723' tid='6724', class="m">=</a> <a id='6725' tid='6726', class="m">new</a> <a id='6727' tid='6728', class="m">v8</a><a id='6729' tid='6730', class="m">::</a><a id='6731' tid='6732', class="m">internal</a><a id='6733' tid='6734', class="m">::</a><a id='6735' tid='6736', class="m">HashMap</a>(<a id='6737' tid='6738', class="m">&</a><a id='6739' tid='6740', class="m">ICacheMatch</a>);
  780. <a id='6741' tid='6742', class="m">isolate_</a>-&gt;<a id='6743' tid='6744', class="m">set_simulator_i_cache</a>(<a id='6745' tid='6746', class="m">i_cache_</a>);
  781. }
  782. <span class="d">Initialize(isolate);</span>
  783. // Setup simulator support first. Some of this information is needed to
  784. // setup the architecture state.
  785. <span class="d">stack_ = reinterpret_cast&lt;char*&gt;(malloc(stack_size_));</span>
  786. <span class="d">pc_modified_ = false;</span>
  787. <span class="d">icount_ = 0;</span>
  788. <span class="d">break_count_ = 0;</span>
  789. <span class="d">break_pc_ = NULL;</span>
  790. <span class="d">break_instr_ = 0;</span>
  791. // Setup architecture state.
  792. // All registers are initialized to zero to start with.
  793. <span class="d">for (int i = 0; i &lt; kNumSimuRegisters; i++) {
  794. registers_[i] = 0;
  795. }</span>
  796. <span class="d">for (int i = 0; i &lt; kNumFPURegisters; i++) {
  797. FPUregisters_[i] = 0;
  798. }</span>
  799. <span class="d">FCSR_ = 0;</span>
  800. // The sp is initialized to point to the bottom (high address) of the
  801. // allocated stack area. To be safe in potential stack underflows we leave
  802. // some buffer below.
  803. <span class="d">registers_[sp] = reinterpret_cast&lt;int32_t&gt;(stack_) + stack_size_ - 64;</span>
  804. // The ra and pc are initialized to a known bad value that will cause an
  805. // access violation if the simulator ever tries to execute it.
  806. <span class="d">registers_[pc] = bad_ra;</span>
  807. <span class="d">registers_[ra] = bad_ra;</span>
  808. <span class="d">InitializeCoverage();</span>
  809. <span class="d">for (int i = 0; i &lt; kNumExceptions; i++) {
  810. exceptions[i] = 0;
  811. }</span>
  812. }
  813. // When the generated code calls an external reference we need to catch that in
  814. // the simulator. The external reference will be a function compiled for the
  815. // host architecture. We need to call that function instead of trying to
  816. // execute it with the simulator. We do that by redirecting the external
  817. // reference to a swi (software-interrupt) instruction that is handled by
  818. // the simulator. We write the original destination of the jump just at a known
  819. // offset from the swi instruction so the simulator knows what to call.
  820. <a id='6473' tid='6474', class="m">class</a> <a id='6475' tid='6476', class="m">Redirection</a> {
  821. <a id='6669' tid='6670', class="m">public</a>:
  822. <a id='6331' tid='6332', class="m">Redirection</a>(<a id='6615' tid='6616', class="m">void</a><a id='6617' tid='6618', class="m">*</a> <a id='6619' tid='6620', class="m">external_function</a>, <a id='6621' tid='6622', class="m">ExternalReference</a><a id='6623' tid='6624', class="m">::</a><a id='6625' tid='6626', class="m">Type</a> <a id='6627' tid='6628', class="m">type</a>)
  823. : <span class="d">external_function_(external_function),
  824. swi_instruction_(rtCallRedirInstr),
  825. type_(type),
  826. next_(NULL)</span> {
  827. <a id='6371' tid='6372', class="m">Isolate</a><a id='6373' tid='6374', class="m">*</a> <a id='6375' tid='6376', class="m">isolate</a> = <a id='6377' tid='6378', class="m">Isolate</a><a id='6379' tid='6380', class="m">::</a><a id='6381' tid='6382', class="m">Current</a>();
  828. <a id='6383' tid='6384', class="m">next_</a> <a id='6385' tid='6386', class="m">=</a> <a id='6387' tid='6388', class="m">isolate</a>-&gt;<a id='6389' tid='6390', class="m">simulator_redirection</a>();
  829. <a id='6391' tid='6392', class="m">Simulator</a><a id='6393' tid='6394', class="m">::</a><a id='6395' tid='6396', class="m">current</a>(<a id='6397' tid='6398', class="m">isolate</a>)-&gt;
  830. <a id='6399' tid='6400', class="m">FlushICache</a>(<a id='6401' tid='6402', class="m">isolate</a>-&gt;<a id='6403' tid='6404', class="m">simulator_i_cache</a>(),
  831. <a id='6405' tid='6406', class="m">reinterpret_cast</a>&lt;<a id='6407' tid='6408', class="m">void</a><a id='6409' tid='6410', class="m">*</a>&gt;(<a id='6411' tid='6412', class="m">&</a><a id='6413' tid='6414', class="m">swi_instruction_</a>),
  832. <a id='6415' tid='6416', class="m">Instruction</a><a id='6417' tid='6418', class="m">::</a><a id='6419' tid='6420', class="m">kInstrSize</a>);
  833. <a id='6421' tid='6422', class="m">isolate</a>-&gt;<a id='6423' tid='6424', class="m">set_simulator_redirection</a>(<a id='6425' tid='6426', class="m">this</a>);
  834. }
  835. <a id='6629' tid='6630', class="m">void</a><a id='6631' tid='6632', class="m">*</a> <a id='6633' tid='6634', class="m">address_of_swi_instruction</a>() {
  836. <a id='6635' tid='6636', class="m">return</a> <a id='6637' tid='6638', class="m">reinterpret_cast</a>&lt;<a id='6639' tid='6640', class="m">void</a><a id='6641' tid='6642', class="m">*</a>&gt;(<a id='6643' tid='6644', class="m">&</a><a id='6645' tid='6646', class="m">swi_instruction_</a>);
  837. }
  838. <a id='6647' tid='6648', class="m">void</a><a id='6649' tid='6650', class="m">*</a> <a id='6651' tid='6652', class="m">external_function</a>() { <a id='6653' tid='6654', class="m">return</a> <a id='6655' tid='6656', class="m">external_function_</a>; }
  839. <a id='6657' tid='6658', class="m">ExternalReference</a><a id='6659' tid='6660', class="m">::</a><a id='6661' tid='6662', class="m">Type</a> <a id='6663' tid='6664', class="m">type</a>() { <a id='6665' tid='6666', class="m">return</a> <a id='6667' tid='6668', class="m">type_</a>; }
  840. <a id='6531' tid='6532', class="m">static</a> <a id='6533' tid='6534', class="m">Redirection</a><a id='6535' tid='6536', class="m">*</a> <a id='6537' tid='6538', class="m">Get</a>(<a id='6539' tid='6540', class="m">void</a><a id='6541' tid='6542', class="m">*</a> <a id='6543' tid='6544', class="m">external_function</a>,
  841. <a id='6545' tid='6546', class="m">ExternalReference</a><a id='6547' tid='6548', class="m">::</a><a id='6549' tid='6550', class="m">Type</a> <a id='6551' tid='6552', class="m">type</a>) {
  842. <a id='6553' tid='6554', class="m">Isolate</a><a id='6555' tid='6556', class="m">*</a> <a id='6557' tid='6558', class="m">isolate</a> = <a id='6559' tid='6560', class="m">Isolate</a><a id='6561' tid='6562', class="m">::</a><a id='6563' tid='6564', class="m">Current</a>();
  843. <a id='6565' tid='6566', class="m">Redirection</a><a id='6567' tid='6568', class="m">*</a> <a id='6569' tid='6570', class="m">current</a> = <a id='6571' tid='6572', class="m">isolate</a>-&gt;<a id='6573' tid='6574', class="m">simulator_redirection</a>();
  844. <a id='6575' tid='6576', class="m">for</a> (; <a id='6577' tid='6578', class="m">current</a> <a id='6579' tid='6580', class="m">!=</a> <a id='6581' tid='6582', class="m">NULL</a>; <a id='6583' tid='6584', class="m">current</a> <a id='6585' tid='6586', class="m">=</a> <a id='6587' tid='6588', class="m">current</a>-&gt;<a id='6589' tid='6590', class="m">next_</a>) {
  845. <a id='6591' tid='6592', class="m">if</a> (<a id='6593' tid='6594', class="m">current</a>-&gt;<a id='6595' tid='6596', class="m">external_function_</a> <a id='6597' tid='6598', class="m">==</a> <a id='6599' tid='6600', class="m">external_function</a>) <a id='6601' tid='6602', class="m">return</a> <a id='6603' tid='6604', class="m">current</a>;
  846. }
  847. <a id='6605' tid='6606', class="m">return</a> <a id='6607' tid='6608', class="m">new</a> <a id='6609' tid='6610', class="m">Redirection</a>(<a id='6611' tid='6612', class="m">external_function</a>, <a id='6613' tid='6614', class="m">type</a>);
  848. }
  849. <a id='6477' tid='6478', class="m">static</a> <a id='6479' tid='6480', class="m">Redirection</a><a id='6481' tid='6482', class="m">*</a> <a id='6483' tid='6484', class="m">FromSwiInstruction</a>(<a id='6485' tid='6486', class="m">Instruction</a><a id='6487' tid='6488', class="m">*</a> <a id='6489' tid='6490', class="m">swi_instruction</a>) {
  850. <a id='6491' tid='6492', class="m">char</a><a id='6493' tid='6494', class="m">*</a> <a id='6495' tid='6496', class="m">addr_of_swi</a> = <a id='6497' tid='6498', class="m">reinterpret_cast</a>&lt;<a id='6499' tid='6500', class="m">char</a><a id='6501' tid='6502', class="m">*</a>&gt;(<a id='6503' tid='6504', class="m">swi_instruction</a>);
  851. <a id='6505' tid='6506', class="m">char</a><a id='6507' tid='6508', class="m">*</a> <a id='6509' tid='6510', class="m">addr_of_redirection</a> =
  852. <a id='6511' tid='6512', class="m">addr_of_swi</a> <a id='6513' tid='6514', class="m">-</a> <a id='6515' tid='6516', class="m">OFFSET_OF</a>(<a id='6517' tid='6518', class="m">Redirection</a>, <a id='6519' tid='6520', class="m">swi_instruction_</a>);
  853. <a id='6521' tid='6522', class="m">return</a> <a id='6523' tid='6524', class="m">reinterpret_cast</a>&lt;<a id='6525' tid='6526', class="m">Redirection</a><a id='6527' tid='6528', class="m">*</a>&gt;(<a id='6529' tid='6530', class="m">addr_of_redirection</a>);
  854. }
  855. <a id='6671' tid='6672', class="m">private</a>:
  856. <a id='6673' tid='6674', class="m">void</a><a id='6675' tid='6676', class="m">*</a> <a id='6677' tid='6678', class="m">external_function_</a>;
  857. <a id='6679' tid='6680', class="m">uint32_t</a> <a id='6681' tid='6682', class="m">swi_instruction_</a>;
  858. <a id='6683' tid='6684', class="m">ExternalReference</a><a id='6685' tid='6686', class="m">::</a><a id='6687' tid='6688', class="m">Type</a> <a id='6689' tid='6690', class="m">type_</a>;
  859. <a id='6691' tid='6692', class="m">Redirection</a><a id='6693' tid='6694', class="m">*</a> <a id='6695' tid='6696', class="m">next_</a>;
  860. };
  861. <a id='6427' tid='6428', class="m">void</a><a id='6429' tid='6430', class="m">*</a> <a id='6431' tid='6432', class="m">Simulator</a><a id='6433' tid='6434', class="m">::</a><a id='6435' tid='6436', class="m">RedirectExternalReference</a>(<a id='6437' tid='6438', class="m">void</a><a id='6439' tid='6440', class="m">*</a> <a id='6441' tid='6442', class="m">external_function</a>,
  862. <a id='6443' tid='6444', class="m">ExternalReference</a><a id='6445' tid='6446', class="m">::</a><a id='6447' tid='6448', class="m">Type</a> <a id='6449' tid='6450', class="m">type</a>) {
  863. <a id='6451' tid='6452', class="m">Redirection</a><a id='6453' tid='6454', class="m">*</a> <a id='6455' tid='6456', class="m">redirection</a> = <a id='6457' tid='6458', class="m">Redirection</a><a id='6459' tid='6460', class="m">::</a><a id='6461' tid='6462', class="m">Get</a>(<a id='6463' tid='6464', class="m">external_function</a>, <a id='6465' tid='6466', class="m">type</a>);
  864. <a id='6467' tid='6468', class="m">return</a> <a id='6469' tid='6470', class="m">redirection</a>-&gt;<a id='6471' tid='6472', class="m">address_of_swi_instruction</a>();
  865. }
  866. // Get the active Simulator for the current thread.
  867. <a id='6333' tid='6334', class="m">Simulator</a><a id='6335' tid='6336', class="m">*</a> <a id='6337' tid='6338', class="m">Simulator</a><a id='6339' tid='6340', class="m">::</a><a id='6341' tid='6342', class="m">current</a>(<a id='6343' tid='6344', class="m">Isolate</a><a id='6345' tid='6346', class="m">*</a> <a id='6347' tid='6348', class="m">isolate</a>) {
  868. <a id='6349' tid='6350', class="m">v8</a><a id='6351' tid='6352', class="m">::</a><a id='6353' tid='6354', class="m">internal</a><a id='6355' tid='6356', class="m">::</a><a id='6357' tid='6358', class="m">Isolate</a><a id='6359' tid='6360', class="m">::</a><a id='6361' tid='6362', class="m">PerIsolateThreadData</a><a id='6363' tid='6364', class="m">*</a> <a id='6365' tid='6366', class="m">isolate_data</a> =
  869. <a id='6367' tid='6368', class="m">isolate</a>-&gt;<a id='6369' tid='6370', class="m">FindOrAllocatePerThreadDataForThisThread</a>();
  870. <span class="d">ASSERT(isolate_data != NULL);</span>
  871. <span class="d">ASSERT(isolate_data != NULL);</span>
  872. <a id='6321' tid='6322', class="m">Simulator</a><a id='6323' tid='6324', class="m">*</a> <a id='6325' tid='6326', class="m">sim</a> = <a id='6327' tid='6328', class="m">isolate_data</a>-&gt;<a id='6329' tid='6330', class="m">simulator</a>();
  873. <a id='6267' tid='6268', class="m">if</a> (<a id='6269' tid='6270', class="m">sim</a> <a id='6271' tid='6272', class="m">==</a> <a id='6273' tid='6274', class="m">NULL</a>) {
  874. // TODO(146): delete the simulator object when a thread/isolate goes away.
  875. <a id='6275' tid='6276', class="m">sim</a> <a id='6277' tid='6278', class="m">=</a> <a id='6279' tid='6280', class="m">new</a> <a id='6281' tid='6282', class="m">Simulator</a>(<a id='6283' tid='6284', class="m">isolate</a>);
  876. <a id='6285' tid='6286', class="m">isolate_data</a>-&gt;<a id='6287' tid='6288', class="m">set_simulator</a>(<a id='6289' tid='6290', class="m">sim</a>);
  877. }
  878. <span class="d">return sim;</span>
  879. }
  880. // Sets the register in the architecture state. It will also deal with updating
  881. // Simulator internal state for special registers such as PC.
  882. <a id='6291' tid='6292', class="m">void</a> <a id='6293' tid='6294', class="m">Simulator</a><a id='6295' tid='6296', class="m">::</a><a id='6297' tid='6298', class="m">set_register</a>(<a id='6299' tid='6300', class="m">int</a> <a id='6301' tid='6302', class="m">reg</a>, <a id='6303' tid='6304', class="m">int32_t</a> <a id='6305' tid='6306', class="m">value</a>) {
  883. <span class="d">ASSERT((reg &gt;= 0) && (reg &lt; kNumSimuRegisters));</span>
  884. <a id='6307' tid='6308', class="m">if</a> (<a id='6309' tid='6310', class="m">reg</a> <a id='6311' tid='6312', class="m">==</a> <a id='6313' tid='6314', class="m">pc</a>) {
  885. <a id='6315' tid='6316', class="m">pc_modified_</a> <a id='6317' tid='6318', class="m">=</a> <a id='6319' tid='6320', class="m">true</a>;
  886. }
  887. // Zero register always holds 0.
  888. <span class="d">registers_[reg] = (reg == 0) ? 0 : value;</span>
  889. }
  890. <span class="d">void Simulator::set_fpu_register(int fpureg, int32_t value) {
  891. ASSERT((fpureg &gt;= 0) && (fpureg &lt; kNumFPURegisters));
  892. FPUregisters_[fpureg] = value;
  893. }</span>
  894. <span class="d">void Simulator::set_fpu_register_float(int fpureg, float value) {
  895. ASSERT((fpureg &gt;= 0) && (fpureg &lt; kNumFPURegisters));
  896. *BitCast&lt;float*&gt;(&FPUregisters_[fpureg]) = value;
  897. }</span>
  898. <span class="d">void Simulator::set_fpu_register_double(int fpureg, double value) {
  899. ASSERT((fpureg &gt;= 0) && (fpureg &lt; kNumFPURegisters) && ((fpureg % 2) == 0));
  900. *BitCast&lt;double*&gt;(&FPUregisters_[fpureg]) = value;
  901. }</span>
  902. // Get the register from the architecture state. This function does handle
  903. // the special case of accessing the PC register.
  904. <a id='6253' tid='6254', class="m">int32_t</a> <a id='6255' tid='6256', class="m">Simulator</a><a id='6257' tid='6258', class="m">::</a><a id='6259' tid='6260', class="m">get_register</a>(<a id='6261' tid='6262', class="m">int</a> <a id='6263' tid='6264', class="m">reg</a>) <a id='6265' tid='6266', class="m">const</a> {
  905. <span class="d">ASSERT((reg &gt;= 0) && (reg &lt; kNumSimuRegisters));</span>
  906. <span class="d">if</span> <span class="d">(reg == 0)</span>
  907. <span class="d">return 0;</span>
  908. <span class="d">else</span>
  909. <a id='6231' tid='6232', class="m">return</a> <a id='6233' tid='6234', class="m">registers_</a>[<a id='6235' tid='6236', class="m">reg</a>] <a id='6237' tid='6238', class="m">+</a> ((<a id='6239' tid='6240', class="m">reg</a> <a id='6241' tid='6242', class="m">==</a> <a id='6243' tid='6244', class="m">pc</a>) ? <a id='6245' tid='6246', class="m">Instruction</a><a id='6247' tid='6248', class="m">::</a><a id='6249' tid='6250', class="m">kPCReadOffset</a> : <a id='6251' tid='6252', class="m">0</a>);
  910. }
  911. <span class="d">int32_t Simulator::get_fpu_register(int fpureg) const</span> <span class="d">{
  912. ASSERT((fpureg &gt;= 0) && (fpureg &lt; kNumFPURegisters));
  913. return FPUregisters_[fpureg];
  914. }</span>
  915. <span class="d">int64_t Simulator::get_fpu_register_long(int fpureg) const</span> <span class="d">{
  916. ASSERT((fpureg &gt;= 0) && (fpureg &lt; kNumFPURegisters) && ((fpureg % 2) == 0));
  917. return *BitCast&lt;int64_t*&gt;(
  918. const_cast&lt;int32_t*&gt;(&FPUregisters_[fpureg]));
  919. }</span>
  920. <span class="d">float Simulator::get_fpu_register_float(int fpureg) const</span> <span class="d">{
  921. ASSERT((fpureg &gt;= 0) && (fpureg &lt; kNumFPURegisters));
  922. return *BitCast&lt;float*&gt;(
  923. const_cast&lt;int32_t*&gt;(&FPUregisters_[fpureg]));
  924. }</span>
  925. <span class="d">double Simulator::get_fpu_register_double(int fpureg) const</span> <span class="d">{
  926. ASSERT((fpureg &gt;= 0) && (fpureg &lt; kNumFPURegisters) && ((fpureg % 2) == 0));
  927. return *BitCast&lt;double*&gt;(const_cast&lt;int32_t*&gt;(&FPUregisters_[fpureg]));
  928. }</span>
  929. // For use in calls that take two double values, constructed either
  930. // from a0-a3 or f12 and f14.
  931. <a id='6153' tid='6154', class="m">void</a> <a id='6155' tid='6156', class="m">Simulator</a><a id='6157' tid='6158', class="m">::</a><a id='6159' tid='6160', class="m">GetFpArgs</a>(<a id='6161' tid='6162', class="m">double</a><a id='6163' tid='6164', class="m">*</a> <a id='6165' tid='6166', class="m">x</a>, <a id='6167' tid='6168', class="m">double</a><a id='6169' tid='6170', class="m">*</a> <a id='6171' tid='6172', class="m">y</a>) {
  932. <span class="d">if</span> <span class="d">(!IsMipsSoftFloatABI)</span> <span class="d">{
  933. *x = get_fpu_register_double(12);
  934. *y = get_fpu_register_double(14);
  935. }</span> <a id='6173' tid='6174', class="m">else</a> {
  936. // We use a char buffer to get around the strict-aliasing rules which
  937. // otherwise allow the compiler to optimize away the copy.
  938. <a id='6175' tid='6176', class="m">char</a> <a id='6177' tid='6178', class="m">buffer</a>[<a id='6179' tid='6180', class="m">sizeof</a>(<a id='6181' tid='6182', class="m">*</a><a id='6183' tid='6184', class="m">x</a>)];
  939. <span class="d">int32_t* reg_buffer = reinterpret_cast&lt;int32_t*&gt;(buffer);</span>
  940. // Registers a0 and a1 -&gt; x.
  941. <span class="d">reg_buffer[0] = get_register(a0);</span>
  942. <span class="d">reg_buffer[1] = get_register(a1);</span>
  943. <span class="d">memcpy(x, buffer, sizeof(buffer));</span>
  944. // Registers a2 and a3 -&gt; y.
  945. <span class="d">reg_buffer[0] = get_register(a2);</span>
  946. <span class="d">reg_buffer[1] = get_register(a3);</span>
  947. <span class="d">memcpy(y, buffer, sizeof(buffer));</span>
  948. }
  949. }
  950. // For use in calls that take one double value, constructed either
  951. // from a0 and a1 or f12.
  952. <a id='6129' tid='6130', class="m">void</a> <a id='6131' tid='6132', class="m">Simulator</a><a id='6133' tid='6134', class="m">::</a><a id='6135' tid='6136', class="m">GetFpArgs</a>(<a id='6137' tid='6138', class="m">double</a><a id='6139' tid='6140', class="m">*</a> <a id='6141' tid='6142', class="m">x</a>) {
  953. <span class="d">if</span> <span class="d">(!IsMipsSoftFloatABI)</span> <span class="d">{
  954. *x = get_fpu_register_double(12);
  955. }</span> <span class="d">else</span> {
  956. // We use a char buffer to get around the strict-aliasing rules which
  957. // otherwise allow the compiler to optimize away the copy.
  958. <a id='6143' tid='6144', class="m">char</a> <a id='6145' tid='6146', class="m">buffer</a>[<a id='6147' tid='6148', class="m">sizeof</a>(<a id='6149' tid='6150', class="m">*</a><a id='6151' tid='6152', class="m">x</a>)];
  959. <span class="d">int32_t* reg_buffer = reinterpret_cast&lt;int32_t*&gt;(buffer);</span>
  960. // Registers a0 and a1 -&gt; x.
  961. <span class="d">reg_buffer[0] = get_register(a0);</span>
  962. <span class="d">reg_buffer[1] = get_register(a1);</span>
  963. <span class="d">memcpy(x, buffer, sizeof(buffer));</span>
  964. }
  965. }
  966. // For use in calls that take one double value constructed either
  967. // from a0 and a1 or f12 and one integer value.
  968. <a id='6097' tid='6098', class="m">void</a> <a id='6099' tid='6100', class="m">Simulator</a><a id='6101' tid='6102', class="m">::</a><a id='6103' tid='6104', class="m">GetFpArgs</a>(<a id='6105' tid='6106', class="m">double</a><a id='6107' tid='6108', class="m">*</a> <a id='6109' tid='6110', class="m">x</a>, <a id='6111' tid='6112', class="m">int32_t</a><a id='6113' tid='6114', class="m">*</a> <a id='6115' tid='6116', class="m">y</a>) {
  969. <span class="d">if</span> <span class="d">(!IsMipsSoftFloatABI)</span> <span class="d">{
  970. *x = get_fpu_register_double(12);
  971. *y = get_register(a2);
  972. }</span> <a id='6117' tid='6118', class="m">else</a> {
  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. <a id='6119' tid='6120', class="m">char</a> <a id='6121' tid='6122', class="m">buffer</a>[<a id='6123' tid='6124', class="m">sizeof</a>(<a id='6125' tid='6126', class="m">*</a><a id='6127' tid='6128', class="m">x</a>)];
  976. <span class="d">int32_t* reg_buffer = reinterpret_cast&lt;int32_t*&gt;(buffer);</span>
  977. // Registers 0 and 1 -&gt; x.
  978. <span class="d">reg_buffer[0] = get_register(a0);</span>
  979. <span class="d">reg_buffer[1] = get_register(a1);</span>
  980. <span class="d">memcpy(x, buffer, sizeof(buffer));</span>
  981. // Register 2 -&gt; y.
  982. <span class="d">reg_buffer[0] = get_register(a2);</span>
  983. <a id='6085' tid='6086', class="m">memcpy</a>(<a id='6087' tid='6088', class="m">y</a>, <a id='6089' tid='6090', class="m">buffer</a>, <a id='6091' tid='6092', class="m">sizeof</a>(<a id='6093' tid='6094', class="m">*</a><a id='6095' tid='6096', class="m">y</a>));
  984. }
  985. }
  986. // The return value is either in v0/v1 or f0.
  987. <a id='6057' tid='6058', class="m">void</a> <a id='6059' tid='6060', class="m">Simulator</a><a id='6061' tid='6062', class="m">::</a><a id='6063' tid='6064', class="m">SetFpResult</a>(<a id='6065' tid='6066', class="m">const</a> <a id='6067' tid='6068', class="m">double</a><a id='6069' tid='6070', class="m">&</a> <a id='6071' tid='6072', class="m">result</a>) {
  988. <span class="d">if</span> <span class="d">(!IsMipsSoftFloatABI)</span> <span class="d">{
  989. set_fpu_register_double(0, result);
  990. }</span> <span class="d">else</span> {
  991. <a id='6043' tid='6044', class="m">char</a> <a id='6045' tid='6046', class="m">buffer</a>[<a id='6047' tid='6048', class="m">2</a> <a id='6049' tid='6050', class="m">*</a> <a id='6051' tid='6052', class="m">sizeof</a>(<a id='6053' tid='6054', class="m">registers_</a>[<a id='6055' tid='6056', class="m">0</a>])];
  992. <span class="d">int32_t* reg_buffer = reinterpret_cast&lt;int32_t*&gt;(buffer);</span>
  993. <a id='6073' tid='6074', class="m">memcpy</a>(<a id='6075' tid='6076', class="m">buffer</a>, <a id='6077' tid='6078', class="m">&</a><a id='6079' tid='6080', class="m">result</a>, <a id='6081' tid='6082', class="m">sizeof</a>(<a id='6083' tid='6084', class="m">buffer</a>));
  994. // Copy result to v0 and v1.
  995. <span class="d">set_register(v0, reg_buffer[0]);</span>
  996. <span class="d">set_register(v1, reg_buffer[1]);</span>
  997. }
  998. }
  999. // Helper functions for setting and testing the FCSR register&#39;s bits.
  1000. <span class="d">void Simulator::set_fcsr_bit(uint32_t cc, bool value) {
  1001. if (value) {
  1002. FCSR_ |= (1 &lt;&lt; cc);
  1003. } else {
  1004. FCSR_ &= ~(1 &lt;&lt; cc);
  1005. }
  1006. }</span>
  1007. <span class="d">bool Simulator::test_fcsr_bit(uint32_t cc) {
  1008. return FCSR_ & (1 &lt;&lt; cc);
  1009. }</span>
  1010. // Sets the rounding error codes in FCSR based on the result of the rounding.
  1011. // Returns true if the operation was invalid.
  1012. <span class="d">bool Simulator::set_fcsr_round_error(double original, double rounded) {
  1013. bool ret = false;
  1014. if (!isfinite(original) || !isfinite(rounded)) {
  1015. set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
  1016. ret = true;
  1017. }
  1018. if (original != rounded) {
  1019. set_fcsr_bit(kFCSRInexactFlagBit, true);
  1020. }
  1021. if (rounded &lt; DBL_MIN && rounded &gt; -DBL_MIN && rounded != 0) {
  1022. set_fcsr_bit(kFCSRUnderflowFlagBit, true);
  1023. ret = true;
  1024. }
  1025. if (rounded &gt; INT_MAX || rounded &lt; INT_MIN) {
  1026. set_fcsr_bit(kFCSROverflowFlagBit, true);
  1027. // The reference is not really clear but it seems this is required:
  1028. set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
  1029. ret = true;
  1030. }
  1031. return ret;
  1032. }</span>
  1033. // Raw access to the PC register.
  1034. <a id='6205' tid='6206', class="m">void</a> <a id='6207' tid='6208', class="m">Simulator</a><a id='6209' tid='6210', class="m">::</a><a id='6211' tid='6212', class="m">set_pc</a>(<a id='6213' tid='6214', class="m">int32_t</a> <a id='6215' tid='6216', class="m">value</a>) {
  1035. <a id='6217' tid='6218', class="m">pc_modified_</a> <a id='6219' tid='6220', class="m">=</a> <a id='6221' tid='6222', class="m">true</a>;
  1036. <a id='6223' tid='6224', class="m">registers_</a>[<a id='6225' tid='6226', class="m">pc</a>] <a id='6227' tid='6228', class="m">=</a> <a id='6229' tid='6230', class="m">value</a>;
  1037. }
  1038. <a id='6195' tid='6196', class="m">bool</a> <a id='6197' tid='6198', class="m">Simulator</a><a id='6199' tid='6200', class="m">::</a><a id='6201' tid='6202', class="m">has_bad_pc</a>() <a id='6203' tid='6204', class="m">const</a> <span class="d">{
  1039. return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc));
  1040. }</span>
  1041. // Raw access to the PC register without the special adjustment when reading.
  1042. <a id='6185' tid='6186', class="m">int32_t</a> <a id='6187' tid='6188', class="m">Simulator</a><a id='6189' tid='6190', class="m">::</a><a id='6191' tid='6192', class="m">get_pc</a>() <a id='6193' tid='6194', class="m">const</a> <span class="d">{
  1043. return registers_[pc];
  1044. }</span>
  1045. // The MIPS cannot do unaligned reads and writes. On some MIPS platforms an
  1046. // interrupt is caused. On others it does a funky rotation thing. For now we
  1047. // simply disallow unaligned reads, but at some point we may want to move to
  1048. // emulating the rotate behaviour. Note that simulator runs have the runtime
  1049. // system running directly on the host system and only generated code is
  1050. // executed in the simulator. Since the host is typically IA32 we will not
  1051. // get the correct MIPS-like behaviour on unaligned accesses.
  1052. <a id='6011' tid='6012', class="m">int</a> <a id='6013' tid='6014', class="m">Simulator</a><a id='6015' tid='6016', class="m">::</a><a id='6017' tid='6018', class="m">ReadW</a>(<a id='6019' tid='6020', class="m">int32_t</a> <a id='6021' tid='6022', class="m">addr</a>, <a id='6023' tid='6024', class="m">Instruction</a><a id='6025' tid='6026', class="m">*</a> <a id='6027' tid='6028', class="m">instr</a>) {
  1053. <span class="d">if (addr &gt;=0 && addr &lt; 0x400) {
  1054. // This has to be a NULL-dereference, drop into debugger.
  1055. MipsDebugger dbg(this);
  1056. dbg.Debug();
  1057. }</span>
  1058. <span class="d">if</span> <span class="d">((addr & kPointerAlignmentMask) == 0)</span> {
  1059. <a id='6029' tid='6030', class="m">intptr_t</a><a id='6031' tid='6032', class="m">*</a> <a id='6033' tid='6034', class="m">ptr</a> = <a id='6035' tid='6036', class="m">reinterpret_cast</a>&lt;<a id='6037' tid='6038', class="m">intptr_t</a><a id='6039' tid='6040', class="m">*</a>&gt;(<a id='6041' tid='6042', class="m">addr</a>);
  1060. <span class="d">return *ptr;</span>
  1061. }
  1062. <a id='5995' tid='5996', class="m">PrintF</a>(<a id='5997' tid='5998', class="m">&quot;Unaligned read at 0x%08x, pc=0x%08&quot;</a> <a id='5999' tid='6000', class="m">V8PRIxPTR</a> <a id='6001' tid='6002', class="m">&quot;\n&quot;</a>,
  1063. <a id='6003' tid='6004', class="m">addr</a>,
  1064. <a id='6005' tid='6006', class="m">reinterpret_cast</a>&lt;<a id='6007' tid='6008', class="m">intptr_t</a>&gt;(<a id='6009' tid='6010', class="m">instr</a>));
  1065. <span class="d">MipsDebugger dbg(this)</span>;
  1066. <span class="d">dbg.Debug();</span>
  1067. <span class="d">return 0;</span>
  1068. }
  1069. <a id='5959' tid='5960', class="m">void</a> <a id='5961' tid='5962', class="m">Simulator</a><a id='5963' tid='5964', class="m">::</a><a id='5965' tid='5966', class="m">WriteW</a>(<a id='5967' tid='5968', class="m">int32_t</a> <a id='5969' tid='5970', class="m">addr</a>, <a id='5971' tid='5972', class="m">int</a> <a id='5973' tid='5974', class="m">value</a>, <a id='5975' tid='5976', class="m">Instruction</a><a id='5977' tid='5978', class="m">*</a> <a id='5979' tid='5980', class="m">instr</a>) {
  1070. <span class="d">if (addr &gt;= 0 && addr &lt; 0x400) {
  1071. // This has to be a NULL-dereference, drop into debugger.
  1072. MipsDebugger dbg(this);
  1073. dbg.Debug();
  1074. }</span>
  1075. <span class="d">if</span> <span class="d">((addr & kPointerAlignmentMask) == 0)</span> {
  1076. <a id='5981' tid='5982', class="m">intptr_t</a><a id='5983' tid='5984', class="m">*</a> <a id='5985' tid='5986', class="m">ptr</a> = <a id='5987' tid='5988', class="m">reinterpret_cast</a>&lt;<a id='5989' tid='5990', class="m">intptr_t</a><a id='5991' tid='5992', class="m">*</a>&gt;(<a id='5993' tid='5994', class="m">addr</a>);
  1077. <span class="d">*ptr = value;</span>
  1078. <span class="d">return;</span>
  1079. }
  1080. <a id='5943' tid='5944', class="m">PrintF</a>(<a id='5945' tid='5946', class="m">&quot;Unaligned write at 0x%08x, pc=0x%08&quot;</a> <a id='5947' tid='5948', class="m">V8PRIxPTR</a> <a id='5949' tid='5950', class="m">&quot;\n&quot;</a>,
  1081. <a id='5951' tid='5952', class="m">addr</a>,
  1082. <a id='5953' tid='5954', class="m">reinterpret_cast</a>&lt;<a id='5955' tid='5956', class="m">intptr_t</a>&gt;(<a id='5957' tid='5958', class="m">instr</a>));
  1083. <span class="d">MipsDebugger dbg(this)</span>;
  1084. <span class="d">dbg.Debug();</span>
  1085. }
  1086. <span class="d">double</span> <span class="d">Simulator::ReadD</span>(<a id='5933' tid='5934', class="m">int32_t</a> <a id='5935' tid='5936', class="m">addr</a>, <a id='5937' tid='5938', class="m">Instruction</a><a id='5939' tid='5940', class="m">*</a> <a id='5941' tid='5942', class="m">instr</a>) <span class="d">{
  1087. if ((addr & kDoubleAlignmentMask) == 0) {
  1088. double* ptr = reinterpret_cast&lt;double*&gt;(addr);
  1089. return *ptr;
  1090. }
  1091. PrintF(&quot;Unaligned (double) read at 0x%08x, pc=0x%08&quot; V8PRIxPTR &quot;\n&quot;,
  1092. addr,
  1093. reinterpret_cast&lt;intptr_t&gt;(instr));
  1094. OS::Abort();
  1095. return 0;
  1096. }</span>
  1097. <span class="d">void Simulator::WriteD(int32_t addr, double value, Instruction* instr) {
  1098. if ((addr & kDoubleAlignmentMask) == 0) {
  1099. double* ptr = reinterpret_cast&lt;double*&gt;(addr);
  1100. *ptr = value;
  1101. return;
  1102. }
  1103. PrintF(&quot;Unaligned (double) write at 0x%08x, pc=0x%08&quot; V8PRIxPTR &quot;\n&quot;,
  1104. addr,
  1105. reinterpret_cast&lt;intptr_t&gt;(instr));
  1106. OS::Abort();
  1107. }</span>
  1108. <a id='5891' tid='5892', class="m">uint16_t</a> <a id='5893' tid='5894', class="m">Simulator</a><a id='5895' tid='5896', class="m">::</a><a id='5897' tid='5898', class="m">ReadHU</a>(<a id='5923' tid='5924', class="m">int32_t</a> <a id='5925' tid='5926', class="m">addr</a>, <a id='5927' tid='5928', class="m">Instruction</a><a id='5929' tid='5930', class="m">*</a> <a id='5931' tid='5932', class="m">instr</a>) {
  1109. <span class="d">if</span> ((<a id='5791' tid='5792', class="m">addr</a> <a id='5793' tid='5794', class="m">&</a> <a id='5795' tid='5796', class="m">1</a>) <a id='5797' tid='5798', class="m">==</a> <a id='5799' tid='5800', class="m">0</a>) {
  1110. <a id='5899' tid='5900', class="m">uint16_t</a><a id='5901' tid='5902', class="m">*</a> <a id='5903' tid='5904', class="m">ptr</a> = <a id='5905' tid='5906', class="m">reinterpret_cast</a>&lt;<a id='5907' tid='5908', class="m">uint16_t</a><a id='5909' tid='5910', class="m">*</a>&gt;(<a id='5911' tid='5912', class="m">addr</a>);
  1111. <span class="d">return *ptr;</span>
  1112. }
  1113. <a id='5875' tid='5876', class="m">PrintF</a>(<a id='5877' tid='5878', class="m">&quot;Unaligned unsigned halfword read at 0x%08x, pc=0x%08&quot;</a> <a id='5879' tid='5880', class="m">V8PRIxPTR</a> <a id='5881' tid='5882', class="m">&quot;\n&quot;</a>,
  1114. <a id='5883' tid='5884', class="m">addr</a>,
  1115. <a id='5885' tid='5886', class="m">reinterpret_cast</a>&lt;<a id='5887' tid='5888', class="m">intptr_t</a>&gt;(<a id='5889' tid='5890', class="m">instr</a>));
  1116. <span class="d">OS::Abort();</span>
  1117. <span class="d">return 0;</span>
  1118. }
  1119. <a id='5857' tid='5858', class="m">int16_t</a> <a id='5859' tid='5860', class="m">Simulator</a><a id='5861' tid='5862', class="m">::</a><a id='5863' tid='5864', class="m">ReadH</a><span class="d">(int32_t addr, Instruction* instr)</span> {
  1120. <span class="d">if</span> ((<a id='5913' tid='5914', class="m">addr</a> <a id='5915' tid='5916', class="m">&</a> <a id='5917' tid='5918', class="m">1</a>) <a id='5919' tid='5920', class="m">==</a> <a id='5921' tid='5922', class="m">0</a>) {
  1121. <a id='5801' tid='5802', class="m">int16_t</a><a id='5803' tid='5804', class="m">*</a> <a id='5805' tid='5806', class="m">ptr</a> = <a id='5807' tid='5808', class="m">reinterpret_cast</a>&lt;<a id='5809' tid='5810', class="m">int16_t</a><a id='5811' tid='5812', class="m">*</a>&gt;(<a id='5813' tid='5814', class="m">addr</a>);
  1122. <span class="d">return *ptr;</span>
  1123. }
  1124. <span class="d">PrintF(&quot;Unaligned signed halfword read at 0x%08x, pc=0x%08&quot; V8PRIxPTR &quot;\n&quot;,
  1125. addr,
  1126. reinterpret_cast&lt;intptr_t&gt;(instr));</span>
  1127. <span class="d">OS::Abort();</span>
  1128. <span class="d">return 0;</span>
  1129. }
  1130. <a id='5755' tid='5756', class="m">void</a> <a id='5757' tid='5758', class="m">Simulator</a><a id='5759' tid='5760', class="m">::</a><a id='5761' tid='5762', class="m">WriteH</a>(<a id='5763' tid='5764', class="m">int32_t</a> <a id='5765' tid='5766', class="m">addr</a>, <a id='5767' tid='5768', class="m">uint16_t</a> <a id='5769' tid='5770', class="m">value</a>, <a id='5771' tid='5772', class="m">Instruction</a><a id='5773' tid='5774', class="m">*</a> <a id='5775' tid='5776', class="m">instr</a>) {
  1131. <a id='5831' tid='5832', class="m">if</a> ((<a id='5865' tid='5866', class="m">addr</a> <a id='5867' tid='5868', class="m">&</a> <a id='5869' tid='5870', class="m">1</a>) <a id='5871' tid='5872', class="m">==</a> <a id='5873' tid='5874', class="m">0</a>) {
  1132. <a id='5833' tid='5834', class="m">uint16_t</a><a id='5835' tid='5836', class="m">*</a> <a id='5837' tid='5838', class="m">ptr</a> = <a id='5839' tid='5840', class="m">reinterpret_cast</a>&lt;<a id='5841' tid='5842', class="m">uint16_t</a><a id='5843' tid='5844', class="m">*</a>&gt;(<a id='5845' tid='5846', class="m">addr</a>);
  1133. <a id='5847' tid='5848', class="m">*</a><a id='5849' tid='5850', class="m">ptr</a> <a id='5851' tid='5852', class="m">=</a> <a id='5853' tid='5854', class="m">value</a>;
  1134. <a id='5855' tid='5856', class="m">return</a>;
  1135. }
  1136. <a id='5815' tid='5816', class="m">PrintF</a>(<a id='5817' tid='5818', class="m">&quot;Unaligned unsigned halfword write at 0x%08x, pc=0x%08&quot;</a> <a id='5819' tid='5820', class="m">V8PRIxPTR</a> <a id='5821' tid='5822', class="m">&quot;\n&quot;</a>,
  1137. <a id='5823' tid='5824', class="m">addr</a>,
  1138. <a id='5825' tid='5826', class="m">reinterpret_cast</a>&lt;<a id='5827' tid='5828', class="m">intptr_t</a>&gt;(<a id='5829' tid='5830', class="m">instr</a>));
  1139. <span class="d">OS::Abort();</span>
  1140. }
  1141. <a id='4299' tid='4300', class="m">void</a> <a id='4301' tid='4302', class="m">Simulator</a><a id='4303' tid='4304', class="m">::</a><a id='4305' tid='4306', class="m">WriteH</a>(<a id='4307' tid='4308', class="m">int32_t</a> <a id='4309' tid='4310', class="m">addr</a>, <a id='4311' tid='4312', class="m">int16_t</a> <a id='4313' tid='4314', class="m">value</a>, <a id='4315' tid='4316', class="m">Instruction</a><a id='4317' tid='4318', class="m">*</a> <a id='4319' tid='4320', class="m">instr</a>) {
  1142. <a id='4337' tid='4338', class="m">if</a> ((<a id='4339' tid='4340', class="m">addr</a> <a id='4341' tid='4342', class="m">&</a> <a id='4343' tid='4344', class="m">1</a>) <a id='4345' tid='4346', class="m">==</a> <a id='4347' tid='4348', class="m">0</a>) {
  1143. <a id='4349' tid='4350', class="m">int16_t</a><a id='4351' tid='4352', class="m">*</a> <a id='4353' tid='4354', class="m">ptr</a> = <a id='4355' tid='4356', class="m">reinterpret_cast</a>&lt;<a id='4357' tid='4358', class="m">int16_t</a><a id='4359' tid='4360', class="m">*</a>&gt;(<a id='4361' tid='4362', class="m">addr</a>);
  1144. <span class="d">*ptr = value;</span>
  1145. <span class="d">return;</span>
  1146. }
  1147. <a id='4321' tid='4322', class="m">PrintF</a>(<a id='4323' tid='4324', class="m">&quot;Unaligned halfword write at 0x%08x, pc=0x%08&quot;</a> <a id='4325' tid='4326', class="m">V8PRIxPTR</a> <a id='4327' tid='4328', class="m">&quot;\n&quot;</a>,
  1148. <a id='4329' tid='4330', class="m">addr</a>,
  1149. <a id='4331' tid='4332', class="m">reinterpret_cast</a>&lt;<a id='4333' tid='4334', class="m">intptr_t</a>&gt;(<a id='4335' tid='4336', class="m">instr</a>));
  1150. <span class="d">OS::Abort();</span>
  1151. }
  1152. <span class="d">uint32_t</span> <a id='5725' tid='5726', class="m">Simulator</a><a id='5727' tid='5728', class="m">::</a><a id='5729' tid='5730', class="m">ReadBU</a>(<a id='5731' tid='5732', class="m">int32_t</a> <a id='5733' tid='5734', class="m">addr</a>) {
  1153. <a id='5777' tid='5778', class="m">uint8_t</a><a id='5779' tid='5780', class="m">*</a> <a id='5781' tid='5782', class="m">ptr</a> = <a id='5783' tid='5784', class="m">reinterpret_cast</a>&lt;<a id='5785' tid='5786', class="m">uint8_t</a><a id='5787' tid='5788', class="m">*</a>&gt;(<a id='5789' tid='5790', class="m">addr</a>);
  1154. <span class="d">return *ptr & 0xff;</span>
  1155. }
  1156. <span class="d">int32_t</span> <a id='5677' tid='5678', class="m">Simulator</a><a id='5679' tid='5680', class="m">::</a><a id='5681' tid='5682', class="m">ReadB</a>(<a id='5683' tid='5684', class="m">int32_t</a> <a id='5685' tid='5686', class="m">addr</a>) {
  1157. <a id='5735' tid='5736', class="m">int8_t</a><a id='5737' tid='5738', class="m">*</a> <a id='5739' tid='5740', class="m">ptr</a> = <a id='5741' tid='5742', class="m">reinterpret_cast</a>&lt;<a id='5743' tid='5744', class="m">int8_t</a><a id='5745' tid='5746', class="m">*</a>&gt;(<a id='5747' tid='5748', class="m">addr</a>);
  1158. <a id='5749' tid='5750', class="m">return</a> <a id='5751' tid='5752', class="m">*</a><a id='5753' tid='5754', class="m">ptr</a>;
  1159. }
  1160. <a id='5687' tid='5688', class="m">void</a> <a id='5689' tid='5690', class="m">Simulator</a><a id='5691' tid='5692', class="m">::</a><a id='5693' tid='5694', class="m">WriteB</a>(<a id='5695' tid='5696', class="m">int32_t</a> <a id='5697' tid='5698', class="m">addr</a>, <a id='5699' tid='5700', class="m">uint8_t</a> <a id='5701' tid='5702', class="m">value</a>) {
  1161. <a id='5703' tid='5704', class="m">uint8_t</a><a id='5705' tid='5706', class="m">*</a> <a id='5707' tid='5708', class="m">ptr</a> = <a id='5709' tid='5710', class="m">reinterpret_cast</a>&lt;<a id='5711' tid='5712', class="m">uint8_t</a><a id='5713' tid='5714', class="m">*</a>&gt;(<a id='5715' tid='5716', class="m">addr</a>);
  1162. <a id='5717' tid='5718', class="m">*</a><a id='5719' tid='5720', class="m">ptr</a> <a id='5721' tid='5722', class="m">=</a> <a id='5723' tid='5724', class="m">value</a>;
  1163. }
  1164. <a id='5639' tid='5640', class="m">void</a> <a id='5641' tid='5642', class="m">Simulator</a><a id='5643' tid='5644', class="m">::</a><a id='5645' tid='5646', class="m">WriteB</a>(<a id='5647' tid='5648', class="m">int32_t</a> <a id='5649' tid='5650', class="m">addr</a>, <a id='5651' tid='5652', class="m">int8_t</a> <a id='5653' tid='5654', class="m">value</a>) {
  1165. <a id='5655' tid='5656', class="m">int8_t</a><a id='5657' tid='5658', class="m">*</a> <a id='5659' tid='5660', class="m">ptr</a> = <a id='5661' tid='5662', class="m">reinterpret_cast</a>&lt;<a id='5663' tid='5664', class="m">int8_t</a><a id='5665' tid='5666', class="m">*</a>&gt;(<a id='5667' tid='5668', class="m">addr</a>);
  1166. <a id='5669' tid='5670', class="m">*</a><a id='5671' tid='5672', class="m">ptr</a> <a id='5673' tid='5674', class="m">=</a> <a id='5675' tid='5676', class="m">value</a>;
  1167. }
  1168. // Returns the limit of the stack area to enable checking for stack overflows.
  1169. <a id='5629' tid='5630', class="m">uintptr_t</a> <a id='5631' tid='5632', class="m">Simulator</a><a id='5633' tid='5634', class="m">::</a><a id='5635' tid='5636', class="m">StackLimit</a>() <a id='5637' tid='5638', class="m">const</a> {
  1170. // Leave a safety margin of 256 bytes to prevent overrunning the stack when
  1171. // pushing values.
  1172. <a id='5617' tid='5618', class="m">return</a> <a id='5619' tid='5620', class="m">reinterpret_cast</a>&lt;<a id='5621' tid='5622', class="m">uintptr_t</a>&gt;(<a id='5623' tid='5624', class="m">stack_</a>) <a id='5625' tid='5626', class="m">+</a> <a id='5627' tid='5628', class="m">256</a>;
  1173. }
  1174. // Unsupported instructions use Format to print an error and stop execution.
  1175. <a id='5583' tid='5584', class="m">void</a> <a id='5585' tid='5586', class="m">Simulator</a><a id='5587' tid='5588', class="m">::</a><a id='5589' tid='5590', class="m">Format</a>(<a id='5591' tid='5592', class="m">Instruction</a><a id='5593' tid='5594', class="m">*</a> <a id='5595' tid='5596', class="m">instr</a>, <a id='5597' tid='5598', class="m">const</a> <a id='5599' tid='5600', class="m">char</a><a id='5601' tid='5602', class="m">*</a> <a id='5603' tid='5604', class="m">format</a>) {
  1176. <a id='5605' tid='5606', class="m">PrintF</a>(<a id='5607' tid='5608', class="m">&quot;Simulator found unsupported instruction:\n 0x%08x: %s\n&quot;</a>,
  1177. <a id='5609' tid='5610', class="m">reinterpret_cast</a>&lt;<a id='5611' tid='5612', class="m">intptr_t</a>&gt;(<a id='5613' tid='5614', class="m">instr</a>), <a id='5615' tid='5616', class="m">format</a>);
  1178. <span class="d">UNIMPLEMENTED_MIPS();</span>
  1179. }
  1180. // Calls into the V8 runtime are based on this very simple interface.
  1181. // Note: To be able to return two values from some calls the code in runtime.cc
  1182. // uses the ObjectPair which is essentially two 32-bit values stuffed into a
  1183. // 64-bit value. With the code below we assume that all runtime calls return
  1184. // 64 bits of result. If they don&#39;t, the v1 result register contains a bogus
  1185. // value, which is fine because it is caller-saved.
  1186. <a id='5551' tid='5552', class="m">typedef</a> <a id='5553' tid='5554', class="m">int64_t</a> (<a id='5555' tid='5556', class="m">*</a><a id='5557' tid='5558', class="m">SimulatorRuntimeCall</a>)(<a id='5559' tid='5560', class="m">int32_t</a> <a id='5561' tid='5562', class="m">arg0</a>,
  1187. <a id='5563' tid='5564', class="m">int32_t</a> <a id='5565' tid='5566', class="m">arg1</a>,
  1188. <a id='5567' tid='5568', class="m">int32_t</a> <a id='5569' tid='5570', class="m">arg2</a>,
  1189. <a id='5571' tid='5572', class="m">int32_t</a> <a id='5573' tid='5574', class="m">arg3</a>,
  1190. <a id='5575' tid='5576', class="m">int32_t</a> <a id='5577' tid='5578', class="m">arg4</a>,
  1191. <a id='5579' tid='5580', class="m">int32_t</a> <a id='5581' tid='5582', class="m">arg5</a>);
  1192. <a id='5527' tid='5528', class="m">typedef</a> <a id='5529' tid='5530', class="m">double</a> (<a id='5531' tid='5532', class="m">*</a><a id='5533' tid='5534', class="m">SimulatorRuntimeFPCall</a>)(<a id='5535' tid='5536', class="m">int32_t</a> <a id='5537' tid='5538', class="m">arg0</a>,
  1193. <a id='5539' tid='5540', class="m">int32_t</a> <a id='5541' tid='5542', class="m">arg1</a>,
  1194. <a id='5543' tid='5544', class="m">int32_t</a> <a id='5545' tid='5546', class="m">arg2</a>,
  1195. <a id='5547' tid='5548', class="m">int32_t</a> <a id='5549' tid='5550', class="m">arg3</a>);
  1196. // This signature supports direct call in to API function native callback
  1197. // (refer to InvocationCallback in v8.h).
  1198. <a id='5505' tid='5506', class="m">typedef</a> <a id='5507' tid='5508', class="m">v8</a><a id='5509' tid='5510', class="m">::</a><a id='5511' tid='5512', class="m">Handle</a>&lt;<a id='5513' tid='5514', class="m">v8</a><a id='5515' tid='5516', class="m">::</a><a id='5517' tid='5518', class="m">Value</a>&gt; (<a id='5519' tid='5520', class="m">*</a><a id='5521' tid='5522', class="m">SimulatorRuntimeDirectApiCall</a>)(<a id='5523' tid='5524', class="m">int32_t</a> <a id='5525' tid='5526', class="m">arg0</a>);
  1199. // This signature supports direct call to accessor getter callback.
  1200. <a id='5479' tid='5480', class="m">typedef</a> <a id='5481' tid='5482', class="m">v8</a><a id='5483' tid='5484', class="m">::</a><a id='5485' tid='5486', class="m">Handle</a>&lt;<a id='5487' tid='5488', class="m">v8</a><a id='5489' tid='5490', class="m">::</a><a id='5491' tid='5492', class="m">Value</a>&gt; (<a id='5493' tid='5494', class="m">*</a><a id='5495' tid='5496', class="m">SimulatorRuntimeDirectGetterCall</a>)(<a id='5497' tid='5498', class="m">int32_t</a> <a id='5499' tid='5500', class="m">arg0</a>,
  1201. <a id='5501' tid='5502', class="m">int32_t</a> <a id='5503' tid='5504', class="m">arg1</a>);
  1202. // Software interrupt instructions are used by the simulator to call into the
  1203. // C-based V8 runtime. They are also used for debugging with simulator.
  1204. <a id='5451' tid='5452', class="m">void</a> <a id='5453' tid='5454', class="m">Simulator</a><a id='5455' tid='5456', class="m">::</a><a id='5457' tid='5458', class="m">SoftwareInterrupt</a>(<a id='5459' tid='5460', class="m">Instruction</a><a id='5461' tid='5462', class="m">*</a> <a id='5463' tid='5464', class="m">instr</a>) {
  1205. // There are several instructions that could get us here,
  1206. // the break_ instruction, or several variants of traps. All
  1207. // Are &quot;SPECIAL&quot; class opcode, and are distinuished by function.
  1208. <span class="d">int32_t func = instr-&gt;FunctionFieldRaw();</span>
  1209. <span class="d">uint32_t code = (func == BREAK) ? instr-&gt;Bits(25, 6) : -1;</span>
  1210. // We first check if we met a call_rt_redirected.
  1211. <span class="d">if</span> <span class="d">(instr-&gt;InstructionBits() == rtCallRedirInstr)</span> {
  1212. <a id='5465' tid='5466', class="m">Redirection</a><a id='5467' tid='5468', class="m">*</a> <a id='5469' tid='5470', class="m">redirection</a> = <a id='5471' tid='5472', class="m">Redirection</a><a id='5473' tid='5474', class="m">::</a><a id='5475' tid='5476', class="m">FromSwiInstruction</a>(<a id='5477' tid='5478', class="m">instr</a>);
  1213. <span class="d">int32_t arg0 = get_register(a0);</span>
  1214. <span class="d">int32_t arg1 = get_register(a1);</span>
  1215. <span class="d">int32_t arg2 = get_register(a2);</span>
  1216. <span class="d">int32_t arg3 = get_register(a3);</span>
  1217. <span class="d">int32_t arg4 = 0;</span>
  1218. <span class="d">int32_t arg5 = 0;</span>
  1219. // Need to check if sp is valid before assigning arg4, arg5.
  1220. // This is a fix for cctest test-api/CatchStackOverflow which causes
  1221. // the stack to overflow. For some reason arm doesn&#39;t need this
  1222. // stack check here.
  1223. <a id='5435' tid='5436', class="m">int32_t</a><a id='5437' tid='5438', class="m">*</a> <a id='5439' tid='5440', class="m">stack_pointer</a> = <a id='5441' tid='5442', class="m">reinterpret_cast</a>&lt;<a id='5443' tid='5444', class="m">int32_t</a><a id='5445' tid='5446', class="m">*</a>&gt;(<a id='5447' tid='5448', class="m">get_register</a>(<a id='5449' tid='5450', class="m">sp</a>));
  1224. <span class="d">int32_t* stack = reinterpret_cast&lt;int32_t*&gt;(stack_);</span>
  1225. <span class="d">if (stack_pointer &gt;= stack && stack_pointer &lt; stack + stack_size_ - 5) {
  1226. // Args 4 and 5 are on the stack after the reserved space for args 0..3.
  1227. arg4 = stack_pointer[4];
  1228. arg5 = stack_pointer[5];
  1229. }</span>
  1230. <a id='5363' tid='5364', class="m">bool</a> <a id='5365' tid='5366', class="m">fp_call</a> =
  1231. (<a id='5367' tid='5368', class="m">redirection</a>-&gt;<a id='5369' tid='5370', class="m">type</a>() <a id='5371' tid='5372', class="m">==</a> <a id='5373' tid='5374', class="m">ExternalReference</a><a id='5375' tid='5376', class="m">::</a><a id='5377' tid='5378', class="m">BUILTIN_FP_FP_CALL</a>) <a id='5379' tid='5380', class="m">||</a>
  1232. (<a id='5381' tid='5382', class="m">redirection</a>-&gt;<a id='5383' tid='5384', class="m">type</a>() <a id='5385' tid='5386', class="m">==</a> <a id='5387' tid='5388', class="m">ExternalReference</a><a id='5389' tid='5390', class="m">::</a><a id='5391' tid='5392', class="m">BUILTIN_COMPARE_CALL</a>) <a id='5393' tid='5394', class="m">||</a>
  1233. (<a id='5395' tid='5396', class="m">redirection</a>-&gt;<a id='5397' tid='5398', class="m">type</a>() <a id='5399' tid='5400', class="m">==</a> <a id='5401' tid='5402', class="m">ExternalReference</a><a id='5403' tid='5404', class="m">::</a><a id='5405' tid='5406', class="m">BUILTIN_FP_CALL</a>) <a id='5407' tid='5408', class="m">||</a>
  1234. (<a id='5409' tid='5410', class="m">redirection</a>-&gt;<a id='5411' tid='5412', class="m">type</a>() <a id='5413' tid='5414', class="m">==</a> <a id='5415' tid='5416', class="m">ExternalReference</a><a id='5417' tid='5418', class="m">::</a><a id='5419' tid='5420', class="m">BUILTIN_FP_INT_CALL</a>);
  1235. <span class="d">if (!IsMipsSoftFloatABI) {
  1236. // With the hard floating point calling convention, double
  1237. // arguments are passed in FPU registers. Fetch the arguments
  1238. // from there and call the builtin using soft floating point
  1239. // convention.
  1240. switch (redirection-&gt;type()) {
  1241. case ExternalReference::BUILTIN_FP_FP_CALL:
  1242. case ExternalReference::BUILTIN_COMPARE_CALL:
  1243. arg0 = get_fpu_register(f12);
  1244. arg1 = get_fpu_register(f13);
  1245. arg2 = get_fpu_register(f14);
  1246. arg3 = get_fpu_register(f15);
  1247. break;
  1248. case ExternalReference::BUILTIN_FP_CALL:
  1249. arg0 = get_fpu_register(f12);
  1250. arg1 = get_fpu_register(f13);
  1251. break;
  1252. case ExternalReference::BUILTIN_FP_INT_CALL:
  1253. arg0 = get_fpu_register(f12);
  1254. arg1 = get_fpu_register(f13);
  1255. arg2 = get_register(a2);
  1256. break;
  1257. default:
  1258. break;
  1259. }
  1260. }</span>
  1261. // This is dodgy but it works because the C entry stubs are never moved.
  1262. // See comment in codegen-arm.cc and bug 1242173.
  1263. <span class="d">int32_t saved_ra = get_register(ra);</span>
  1264. <a id='5327' tid='5328', class="m">intptr_t</a> <a id='5329' tid='5330', class="m">external</a> =
  1265. <a id='5331' tid='5332', class="m">reinterpret_cast</a>&lt;<a id='5333' tid='5334', class="m">intptr_t</a>&gt;(<a id='5335' tid='5336', class="m">redirection</a>-&gt;<a id='5337' tid='5338', class="m">external_function</a>());
  1266. // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware
  1267. // FPU, or gcc soft-float routines. Hardware FPU is simulated in this
  1268. // simulator. Soft-float has additional abstraction of ExternalReference,
  1269. // to support serialization.
  1270. <a id='5227' tid='5228', class="m">if</a> (<a id='5229' tid='5230', class="m">fp_call</a>) {
  1271. <a id='5231' tid='5232', class="m">SimulatorRuntimeFPCall</a> <a id='5233' tid='5234', class="m">target</a> =
  1272. <a id='5235' tid='5236', class="m">reinterpret_cast</a>&lt;<a id='5237' tid='5238', class="m">SimulatorRuntimeFPCall</a>&gt;(<a id='5239' tid='5240', class="m">external</a>);
  1273. <span class="d">if</span> (<a id='4631' tid='4632', class="m">::</a><a id='4633' tid='4634', class="m">v8</a><a id='4635' tid='4636', class="m">::</a><a id='4637' tid='4638', class="m">internal</a><a id='4639' tid='4640', class="m">::</a><a id='4641' tid='4642', class="m">FLAG_trace_sim</a>) {
  1274. <span class="d">double dval0, dval1;</span>
  1275. <span class="d">int32_t ival;</span>
  1276. <a id='5015' tid='5016', class="m">switch</a> (<a id='5017' tid='5018', class="m">redirection</a>-&gt;<a id='5019' tid='5020', class="m">type</a>()) {
  1277. <a id='5021' tid='5022', class="m">case</a> <a id='5023' tid='5024', class="m">ExternalReference</a><a id='5025' tid='5026', class="m">::</a><a id='5027' tid='5028', class="m">BUILTIN_FP_FP_CALL</a>:
  1278. <a id='5029' tid='5030', class="m">case</a> <a id='5031' tid='5032', class="m">ExternalReference</a><a id='5033' tid='5034', class="m">::</a><a id='5035' tid='5036', class="m">BUILTIN_COMPARE_CALL</a>:
  1279. <a id='5037' tid='5038', class="m">GetFpArgs</a>(<a id='5039' tid='5040', class="m">&</a><a id='5041' tid='5042', class="m">dval0</a>, <a id='5043' tid='5044', class="m">&</a><a id='5045' tid='5046', class="m">dval1</a>);
  1280. <a id='5047' tid='5048', class="m">PrintF</a>(<a id='5049' tid='5050', class="m">&quot;Call to host function at %p with args %f, %f&quot;</a>,
  1281. <a id='5051' tid='5052', class="m">FUNCTION_ADDR</a>(<a id='5053' tid='5054', class="m">target</a>), <a id='5055' tid='5056', class="m">dval0</a>, <a id='5057' tid='5058', class="m">dval1</a>);
  1282. <a id='5059' tid='5060', class="m">break</a>;
  1283. <a id='5061' tid='5062', class="m">case</a> <a id='5063' tid='5064', class="m">ExternalReference</a><a id='5065' tid='5066', class="m">::</a><a id='5067' tid='5068', class="m">BUILTIN_FP_CALL</a>:
  1284. <a id='5069' tid='5070', class="m">GetFpArgs</a>(<a id='5071' tid='5072', class="m">&</a><a id='5073' tid='5074', class="m">dval0</a>);
  1285. <a id='5075' tid='5076', class="m">PrintF</a>(<a id='5077' tid='5078', class="m">&quot;Call to host function at %p with arg %f&quot;</a>,
  1286. <a id='5079' tid='5080', class="m">FUNCTION_ADDR</a>(<a id='5081' tid='5082', class="m">target</a>), <a id='5083' tid='5084', class="m">dval0</a>);
  1287. <a id='5085' tid='5086', class="m">break</a>;
  1288. <a id='5087' tid='5088', class="m">case</a> <a id='5089' tid='5090', class="m">ExternalReference</a><a id='5091' tid='5092', class="m">::</a><a id='5093' tid='5094', class="m">BUILTIN_FP_INT_CALL</a>:
  1289. <a id='5095' tid='5096', class="m">GetFpArgs</a>(<a id='5097' tid='5098', class="m">&</a><a id='5099' tid='5100', class="m">dval0</a>, <a id='5101' tid='5102', class="m">&</a><a id='5103' tid='5104', class="m">ival</a>);
  1290. <a id='5105' tid='5106', class="m">PrintF</a>(<a id='5107' tid='5108', class="m">&quot;Call to host function at %p with args %f, %d&quot;</a>,
  1291. <a id='5109' tid='5110', class="m">FUNCTION_ADDR</a>(<a id='5111' tid='5112', class="m">target</a>), <a id='5113' tid='5114', class="m">dval0</a>, <a id='5115' tid='5116', class="m">ival</a>);
  1292. <a id='5117' tid='5118', class="m">break</a>;
  1293. <a id='5119' tid='5120', class="m">default</a>:
  1294. <a id='5121' tid='5122', class="m">UNREACHABLE</a>();
  1295. <a id='5123' tid='5124', class="m">break</a>;
  1296. }
  1297. }
  1298. <span class="d">double</span> <a id='4619' tid='4620', class="m">result</a> = <a id='4621' tid='4622', class="m">target</a>(<a id='4623' tid='4624', class="m">arg0</a>, <a id='4625' tid='4626', class="m">arg1</a>, <a id='4627' tid='4628', class="m">arg2</a>, <a id='4629' tid='4630', class="m">arg3</a>);
  1299. <span class="d">if</span> (<a id='4873' tid='4874', class="m">redirection</a>-&gt;<a id='4875' tid='4876', class="m">type</a>() <a id='4877' tid='4878', class="m">!=</a> <a id='4879' tid='4880', class="m">ExternalReference</a><a id='4881' tid='4882', class="m">::</a><a id='4883' tid='4884', class="m">BUILTIN_COMPARE_CALL</a>) <span class="d">{
  1300. SetFpResult(result);
  1301. }</span> <span class="d">else {
  1302. int32_t gpreg_pair[2];
  1303. memcpy(&gpreg_pair[0], &result, 2 * sizeof(int32_t));
  1304. set_register(v0, gpreg_pair[0]);
  1305. set_register(v1, gpreg_pair[1]);
  1306. }</span>
  1307. } <a id='5241' tid='5242', class="m">else</a> <a id='5243' tid='5244', class="m">if</a> (<a id='5245' tid='5246', class="m">redirection</a>-&gt;<a id='5247' tid='5248', class="m">type</a>() <a id='5249' tid='5250', class="m">==</a> <a id='5251' tid='5252', class="m">ExternalReference</a><a id='5253' tid='5254', class="m">::</a><a id='5255' tid='5256', class="m">DIRECT_API_CALL</a>) {
  1308. // See DirectCEntryStub::GenerateCall for explanation of register usage.
  1309. <a id='5257' tid='5258', class="m">SimulatorRuntimeDirectApiCall</a> <a id='5259' tid='5260', class="m">target</a> =
  1310. <a id='5261' tid='5262', class="m">reinterpret_cast</a>&lt;<a id='5263' tid='5264', class="m">SimulatorRuntimeDirectApiCall</a>&gt;(<a id='5265' tid='5266', class="m">external</a>);
  1311. <span class="d">if</span> (<a id='5125' tid='5126', class="m">::</a><a id='5127' tid='5128', class="m">v8</a><a id='5129' tid='5130', class="m">::</a><a id='5131' tid='5132', class="m">internal</a><a id='5133' tid='5134', class="m">::</a><a id='5135' tid='5136', class="m">FLAG_trace_sim</a>) <span class="d">{
  1312. PrintF(&quot;Call to host function at %p args %08x\n&quot;,
  1313. FUNCTION_ADDR(target), arg1);
  1314. }</span>
  1315. <a id='4885' tid='4886', class="m">v8</a><a id='4887' tid='4888', class="m">::</a><a id='4889' tid='4890', class="m">Handle</a>&lt;<a id='4891' tid='4892', class="m">v8</a><a id='4893' tid='4894', class="m">::</a><a id='4895' tid='4896', class="m">Value</a>&gt; <span class="d">result = target(arg1)</span>;
  1316. <span class="d">*(reinterpret_cast&lt;int*&gt;(arg0)) = (int32_t) *result;</span>
  1317. <span class="d">set_register(v0, arg0);</span>
  1318. } <a id='5267' tid='5268', class="m">else</a> <a id='5269' tid='5270', class="m">if</a> (<a id='5271' tid='5272', class="m">redirection</a>-&gt;<a id='5273' tid='5274', class="m">type</a>() <a id='5275' tid='5276', class="m">==</a> <a id='5277' tid='5278', class="m">ExternalReference</a><a id='5279' tid='5280', class="m">::</a><a id='5281' tid='5282', class="m">DIRECT_GETTER_CALL</a>) {
  1319. // See DirectCEntryStub::GenerateCall for explanation of register usage.
  1320. <a id='5283' tid='5284', class="m">SimulatorRuntimeDirectGetterCall</a> <a id='5285' tid='5286', class="m">target</a> =
  1321. <a id='5287' tid='5288', class="m">reinterpret_cast</a>&lt;<a id='5289' tid='5290', class="m">SimulatorRuntimeDirectGetterCall</a>&gt;(<a id='5291' tid='5292', class="m">external</a>);
  1322. <span class="d">if</span> (<a id='5137' tid='5138', class="m">::</a><a id='5139' tid='5140', class="m">v8</a><a id='5141' tid='5142', class="m">::</a><a id='5143' tid='5144', class="m">internal</a><a id='5145' tid='5146', class="m">::</a><a id='5147' tid='5148', class="m">FLAG_trace_sim</a>) <span class="d">{
  1323. PrintF(&quot;Call to host function at %p args %08x %08x\n&quot;,
  1324. FUNCTION_ADDR(target), arg1, arg2);
  1325. }</span>
  1326. <a id='4897' tid='4898', class="m">v8</a><a id='4899' tid='4900', class="m">::</a><a id='4901' tid='4902', class="m">Handle</a>&lt;<a id='4903' tid='4904', class="m">v8</a><a id='4905' tid='4906', class="m">::</a><a id='4907' tid='4908', class="m">Value</a>&gt; <span class="d">result = target(arg1, arg2)</span>;
  1327. <span class="d">*(reinterpret_cast&lt;int*&gt;(arg0)) = (int32_t) *result;</span>
  1328. <span class="d">set_register(v0, arg0);</span>
  1329. } <a id='5293' tid='5294', class="m">else</a> {
  1330. <a id='5295' tid='5296', class="m">SimulatorRuntimeCall</a> <a id='5297' tid='5298', class="m">target</a> =
  1331. <a id='5299' tid='5300', class="m">reinterpret_cast</a>&lt;<a id='5301' tid='5302', class="m">SimulatorRuntimeCall</a>&gt;(<a id='5303' tid='5304', class="m">external</a>);
  1332. <span class="d">if</span> (<a id='5149' tid='5150', class="m">::</a><a id='5151' tid='5152', class="m">v8</a><a id='5153' tid='5154', class="m">::</a><a id='5155' tid='5156', class="m">internal</a><a id='5157' tid='5158', class="m">::</a><a id='5159' tid='5160', class="m">FLAG_trace_sim</a>) <span class="d">{
  1333. PrintF(
  1334. &quot;Call to host function at %p &quot;
  1335. &quot;args %08x, %08x, %08x, %08x, %08x, %08x\n&quot;,
  1336. FUNCTION_ADDR(target),
  1337. arg0,
  1338. arg1,
  1339. arg2,
  1340. arg3,
  1341. arg4,
  1342. arg5);
  1343. }</span>
  1344. <a id='4909' tid='4910', class="m">int64_t</a> <a id='4911' tid='4912', class="m">result</a> = <a id='4913' tid='4914', class="m">target</a>(<a id='4915' tid='4916', class="m">arg0</a>, <a id='4917' tid='4918', class="m">arg1</a>, <a id='4919' tid='4920', class="m">arg2</a>, <a id='4921' tid='4922', class="m">arg3</a>, <a id='4923' tid='4924', class="m">arg4</a>, <a id='4925' tid='4926', class="m">arg5</a>);
  1345. <span class="d">set_register(v0, static_cast&lt;int32_t&gt;(result));</span>
  1346. <span class="d">set_register</span>(<span class="d">v1</span>, <a id='4643' tid='4644', class="m">static_cast</a>&lt;<a id='4645' tid='4646', class="m">int32_t</a>&gt;(<a id='4647' tid='4648', class="m">result</a> <a id='4649' tid='4650', class="m">&gt;&gt;</a> <a id='4651' tid='4652', class="m">32</a>));
  1347. }
  1348. <span class="d">if</span> (<a id='5003' tid='5004', class="m">::</a><a id='5005' tid='5006', class="m">v8</a><a id='5007' tid='5008', class="m">::</a><a id='5009' tid='5010', class="m">internal</a><a id='5011' tid='5012', class="m">::</a><a id='5013' tid='5014', class="m">FLAG_trace_sim</a>) <span class="d">{
  1349. PrintF(&quot;Returned %08x : %08x\n&quot;, get_register(v1), get_register(v0));
  1350. }</span>
  1351. <span class="d">set_register(ra, saved_ra);</span>
  1352. <span class="d">set_pc(get_register(ra));</span>
  1353. } <span class="d">else if (func == BREAK && code &lt;= kMaxStopCode) {
  1354. if (IsWatchpoint(code)) {
  1355. PrintWatchpoint(code);
  1356. } else {
  1357. IncreaseStopCounter(code);
  1358. HandleStop(code, instr);
  1359. }
  1360. } else {
  1361. // All remaining break_ codes, and all traps are handled here.
  1362. MipsDebugger dbg(this);
  1363. dbg.Debug();
  1364. }</span>
  1365. }
  1366. // Stop helper functions.
  1367. <span class="d">bool Simulator::IsWatchpoint(uint32_t code) {
  1368. return (code &lt;= kMaxWatchpointCode);
  1369. }</span>
  1370. <span class="d">void Simulator::PrintWatchpoint(uint32_t code) {
  1371. MipsDebugger dbg(this);
  1372. ++break_count_;
  1373. PrintF(&quot;\n---- break %d marker: %3d (instr count: %8d) ----------&quot;
  1374. &quot;----------------------------------&quot;,
  1375. code, break_count_, icount_);
  1376. dbg.PrintAllRegs(); // Print registers and continue running.
  1377. }</span>
  1378. <span class="d">void</span> <span class="d">Simulator::HandleStop</span><span class="d">(uint32_t code, Instruction* instr)</span> {
  1379. // Stop if it is enabled, otherwise go on jumping over the stop
  1380. // and the message address.
  1381. <span class="d">if</span> <span class="d">(IsEnabledStop(code))</span> <span class="d">{
  1382. MipsDebugger dbg(this);
  1383. dbg.Stop(instr);
  1384. }</span> <a id='4855' tid='4856', class="m">else</a> {
  1385. <a id='4857' tid='4858', class="m">set_pc</a>(<a id='4859' tid='4860', class="m">get_pc</a>() <a id='4861' tid='4862', class="m">+</a> <a id='4863' tid='4864', class="m">2</a> <a id='4865' tid='4866', class="m">*</a> <a id='4867' tid='4868', class="m">Instruction</a><a id='4869' tid='4870', class="m">::</a><a id='4871' tid='4872', class="m">kInstrSize</a>);
  1386. }
  1387. }
  1388. <span class="d">bool Simulator::IsStopInstruction(Instruction* instr) {
  1389. int32_t func = instr-&gt;FunctionFieldRaw();
  1390. uint32_t code = static_cast&lt;uint32_t&gt;(instr-&gt;Bits(25, 6));
  1391. return (func == BREAK) && code &gt; kMaxWatchpointCode && code &lt;= kMaxStopCode;
  1392. }</span>
  1393. <span class="d">bool</span> <span class="d">Simulator::IsEnabledStop</span><span class="d">(uint32_t code)</span> {
  1394. <span class="d">ASSERT(code &lt;= kMaxStopCode);</span>
  1395. <span class="d">ASSERT(code &gt; kMaxWatchpointCode);</span>
  1396. <a id='5421' tid='5422', class="m">return</a> <a id='5423' tid='5424', class="m">!</a>(<a id='5425' tid='5426', class="m">watched_stops</a>[<a id='5427' tid='5428', class="m">code</a>].<a id='5429' tid='5430', class="m">count</a> <a id='5431' tid='5432', class="m">&</a> <a id='5433' tid='5434', class="m">kStopDisabledBit</a>);
  1397. }
  1398. <a id='5339' tid='5340', class="m">void</a> <a id='5341' tid='5342', class="m">Simulator</a><a id='5343' tid='5344', class="m">::</a><a id='5345' tid='5346', class="m">EnableStop</a>(<a id='5347' tid='5348', class="m">uint32_t</a> <a id='5349' tid='5350', class="m">code</a>) {
  1399. <span class="d">if</span> <span class="d">(!IsEnabledStop(code))</span> {
  1400. <a id='5351' tid='5352', class="m">watched_stops</a>[<a id='5353' tid='5354', class="m">code</a>].<a id='5355' tid='5356', class="m">count</a> <a id='5357' tid='5358', class="m">&=</a> <a id='5359' tid='5360', class="m">~</a><a id='5361' tid='5362', class="m">kStopDisabledBit</a>;
  1401. }
  1402. }
  1403. <a id='5305' tid='5306', class="m">void</a> <a id='5307' tid='5308', class="m">Simulator</a><a id='5309' tid='5310', class="m">::</a><a id='5311' tid='5312', class="m">DisableStop</a>(<a id='5313' tid='5314', class="m">uint32_t</a> <a id='5315' tid='5316', class="m">code</a>) {
  1404. <span class="d">if</span> <span class="d">(IsEnabledStop(code))</span> {
  1405. <a id='5317' tid='5318', class="m">watched_stops</a>[<a id='5319' tid='5320', class="m">code</a>].<a id='5321' tid='5322', class="m">count</a> <a id='5323' tid='5324', class="m">|=</a> <a id='5325' tid='5326', class="m">kStopDisabledBit</a>;
  1406. }
  1407. }
  1408. <a id='5161' tid='5162', class="m">void</a> <a id='5163' tid='5164', class="m">Simulator</a><a id='5165' tid='5166', class="m">::</a><a id='5167' tid='5168', class="m">IncreaseStopCounter</a>(<a id='5169' tid='5170', class="m">uint32_t</a> <a id='5171' tid='5172', class="m">code</a>) {
  1409. <span class="d">ASSERT(code &lt;= kMaxStopCode);</span>
  1410. <a id='5173' tid='5174', class="m">if</a> ((<a id='5175' tid='5176', class="m">watched_stops</a>[<a id='5177' tid='5178', class="m">code</a>].<a id='5179' tid='5180', class="m">count</a> <a id='5181' tid='5182', class="m">&</a> <a id='5183' tid='5184', class="m">~</a>(<a id='5185' tid='5186', class="m">1</a> <a id='5187' tid='5188', class="m">&lt;&lt;</a> <a id='5189' tid='5190', class="m">31</a>)) <a id='5191' tid='5192', class="m">==</a> <a id='5193' tid='5194', class="m">0x7fffffff</a>) {
  1411. <a id='5195' tid='5196', class="m">PrintF</a>(<a id='5197' tid='5198', class="m">&quot;Stop counter for code %i has overflowed.\n&quot;</a>
  1412. <a id='5199' tid='5200', class="m">&quot;Enabling this code and reseting the counter to 0.\n&quot;</a>, <a id='5201' tid='5202', class="m">code</a>);
  1413. <a id='5203' tid='5204', class="m">watched_stops</a>[<a id='5205' tid='5206', class="m">code</a>].<a id='5207' tid='5208', class="m">count</a> <a id='5209' tid='5210', class="m">=</a> <a id='5211' tid='5212', class="m">0</a>;
  1414. <a id='5213' tid='5214', class="m">EnableStop</a>(<a id='5215' tid='5216', class="m">code</a>);
  1415. } <a id='5217' tid='5218', class="m">else</a> {
  1416. <a id='5219' tid='5220', class="m">watched_stops</a>[<a id='5221' tid='5222', class="m">code</a>].<a id='5223' tid='5224', class="m">count</a><a id='5225' tid='5226', class="m">++</a>;
  1417. }
  1418. }
  1419. // Print a stop status.
  1420. <a id='4975' tid='4976', class="m">void</a> <a id='4977' tid='4978', class="m">Simulator</a><a id='4979' tid='4980', class="m">::</a><a id='4981' tid='4982', class="m">PrintStopInfo</a>(<a id='4983' tid='4984', class="m">uint32_t</a> <a id='4985' tid='4986', class="m">code</a>) {
  1421. <span class="d">if (code &lt;= kMaxWatchpointCode) {
  1422. PrintF(&quot;That is a watchpoint, not a stop.\n&quot;);
  1423. return;
  1424. } else if (code &gt; kMaxStopCode) {
  1425. PrintF(&quot;Code too large, only %u stops can be used\n&quot;, kMaxStopCode + 1);
  1426. return;
  1427. }</span>
  1428. <span class="d">const char* state = IsEnabledStop(code) ? &quot;Enabled&quot; : &quot;Disabled&quot;;</span>
  1429. <a id='4987' tid='4988', class="m">int32_t</a> <a id='4989' tid='4990', class="m">count</a> = <a id='4991' tid='4992', class="m">watched_stops</a>[<a id='4993' tid='4994', class="m">code</a>].<a id='4995' tid='4996', class="m">count</a> <a id='4997' tid='4998', class="m">&</a> <a id='4999' tid='5000', class="m">~</a><a id='5001' tid='5002', class="m">kStopDisabledBit</a>;
  1430. // Don&#39;t print the state of unused breakpoints.
  1431. <a id='4927' tid='4928', class="m">if</a> (<a id='4929' tid='4930', class="m">count</a> <a id='4931' tid='4932', class="m">!=</a> <a id='4933' tid='4934', class="m">0</a>) {
  1432. <a id='4935' tid='4936', class="m">if</a> (<a id='4937' tid='4938', class="m">watched_stops</a>[<a id='4939' tid='4940', class="m">code</a>].<a id='4941' tid='4942', class="m">desc</a>) {
  1433. <a id='4943' tid='4944', class="m">PrintF</a>(<a id='4945' tid='4946', class="m">&quot;stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n&quot;</a>,
  1434. <a id='4947' tid='4948', class="m">code</a>, <a id='4949' tid='4950', class="m">code</a>, <a id='4951' tid='4952', class="m">state</a>, <a id='4953' tid='4954', class="m">count</a>, <a id='4955' tid='4956', class="m">watched_stops</a>[<a id='4957' tid='4958', class="m">code</a>].<a id='4959' tid='4960', class="m">desc</a>);
  1435. } <a id='4961' tid='4962', class="m">else</a> {
  1436. <a id='4963' tid='4964', class="m">PrintF</a>(<a id='4965' tid='4966', class="m">&quot;stop %i - 0x%x: \t%s, \tcounter = %i\n&quot;</a>,
  1437. <a id='4967' tid='4968', class="m">code</a>, <a id='4969' tid='4970', class="m">code</a>, <a id='4971' tid='4972', class="m">state</a>, <a id='4973' tid='4974', class="m">count</a>);
  1438. }
  1439. }
  1440. }
  1441. <span class="d">void Simulator::SignalExceptions() {
  1442. for (int i = 1; i &lt; kNumExceptions; i++) {
  1443. if (exceptions[i] != 0) {
  1444. V8_Fatal(__FILE__, __LINE__, &quot;Error: Exception %i raised.&quot;, i);
  1445. }
  1446. }
  1447. }</span>
  1448. // Handle execution based on instruction types.
  1449. <span class="d">void Simulator::ConfigureTypeRegister(Instruction* instr,
  1450. int32_t& alu_out,
  1451. int64_t& i64hilo,
  1452. uint64_t& u64hilo,
  1453. int32_t& next_pc,
  1454. bool& do_interrupt) {
  1455. // Every local variable declared here needs to be const.
  1456. // This is to make sure that changed values are sent back to
  1457. // DecodeTypeRegister correctly.
  1458. // Instruction fields.
  1459. const Opcode op = instr-&gt;OpcodeFieldRaw();
  1460. const int32_t rs_reg = instr-&gt;RsValue();
  1461. const int32_t rs = get_register(rs_reg);
  1462. const uint32_t rs_u = static_cast&lt;uint32_t&gt;(rs);
  1463. const int32_t rt_reg = instr-&gt;RtValue();
  1464. const int32_t rt = get_register(rt_reg);
  1465. const uint32_t rt_u = static_cast&lt;uint32_t&gt;(rt);
  1466. const int32_t rd_reg = instr-&gt;RdValue();
  1467. const uint32_t sa = instr-&gt;SaValue();
  1468. const int32_t fs_reg = instr-&gt;FsValue();
  1469. // ---------- Configuration.
  1470. switch (op) {
  1471. case COP1: // Coprocessor instructions.
  1472. switch (instr-&gt;RsFieldRaw()) {
  1473. case BC1: // Handled in DecodeTypeImmed, should never come here.
  1474. UNREACHABLE();
  1475. break;
  1476. case CFC1:
  1477. // At the moment only FCSR is supported.
  1478. ASSERT(fs_reg == kFCSRRegister);
  1479. alu_out = FCSR_;
  1480. break;
  1481. case MFC1:
  1482. alu_out = get_fpu_register(fs_reg);
  1483. break;
  1484. case MFHC1:
  1485. UNIMPLEMENTED_MIPS();
  1486. break;
  1487. case CTC1:
  1488. case MTC1:
  1489. case MTHC1:
  1490. // Do the store in the execution step.
  1491. break;
  1492. case S:
  1493. case D:
  1494. case W:
  1495. case L:
  1496. case PS:
  1497. // Do everything in the execution step.
  1498. break;
  1499. default:
  1500. UNIMPLEMENTED_MIPS();
  1501. };
  1502. break;
  1503. case SPECIAL:
  1504. switch (instr-&gt;FunctionFieldRaw()) {
  1505. case JR:
  1506. case JALR:
  1507. next_pc = get_register(instr-&gt;RsValue());
  1508. break;
  1509. case SLL:
  1510. alu_out = rt &lt;&lt; sa;
  1511. break;
  1512. case SRL:
  1513. if (rs_reg == 0) {
  1514. // Regular logical right shift of a word by a fixed number of
  1515. // bits instruction. RS field is always equal to 0.
  1516. alu_out = rt_u &gt;&gt; sa;
  1517. } else {
  1518. // Logical right-rotate of a word by a fixed number of bits. This
  1519. // is special case of SRL instruction, added in MIPS32 Release 2.
  1520. // RS field is equal to 00001.
  1521. alu_out = (rt_u &gt;&gt; sa) | (rt_u &lt;&lt; (32 - sa));
  1522. }
  1523. break;
  1524. case SRA:
  1525. alu_out = rt &gt;&gt; sa;
  1526. break;
  1527. case SLLV:
  1528. alu_out = rt &lt;&lt; rs;
  1529. break;
  1530. case SRLV:
  1531. if (sa == 0) {
  1532. // Regular logical right-shift of a word by a variable number of
  1533. // bits instruction. SA field is always equal to 0.
  1534. alu_out = rt_u &gt;&gt; rs;
  1535. } else {
  1536. // Logical right-rotate of a word by a variable number of bits.
  1537. // This is special case od SRLV instruction, added in MIPS32
  1538. // Release 2. SA field is equal to 00001.
  1539. alu_out = (rt_u &gt;&gt; rs_u) | (rt_u &lt;&lt; (32 - rs_u));
  1540. }
  1541. break;
  1542. case SRAV:
  1543. alu_out = rt &gt;&gt; rs;
  1544. break;
  1545. case MFHI:
  1546. alu_out = get_register(HI);
  1547. break;
  1548. case MFLO:
  1549. alu_out = get_register(LO);
  1550. break;
  1551. case MULT:
  1552. i64hilo = static_cast&lt;int64_t&gt;(rs) * static_cast&lt;int64_t&gt;(rt);
  1553. break;
  1554. case MULTU:
  1555. u64hilo = static_cast&lt;uint64_t&gt;(rs_u) * static_cast&lt;uint64_t&gt;(rt_u);
  1556. break;
  1557. case ADD:
  1558. if (HaveSameSign(rs, rt)) {
  1559. if (rs &gt; 0) {
  1560. exceptions[kIntegerOverflow] = rs &gt; (Registers::kMaxValue - rt);
  1561. } else if (rs &lt; 0) {
  1562. exceptions[kIntegerUnderflow] = rs &lt; (Registers::kMinValue - rt);
  1563. }
  1564. }
  1565. alu_out = rs + rt;
  1566. break;
  1567. case ADDU:
  1568. alu_out = rs + rt;
  1569. break;
  1570. case SUB:
  1571. if (!HaveSameSign(rs, rt)) {
  1572. if (rs &gt; 0) {
  1573. exceptions[kIntegerOverflow] = rs &gt; (Registers::kMaxValue + rt);
  1574. } else if (rs &lt; 0) {
  1575. exceptions[kIntegerUnderflow] = rs &lt; (Registers::kMinValue + rt);
  1576. }
  1577. }
  1578. alu_out = rs - rt;
  1579. break;
  1580. case SUBU:
  1581. alu_out = rs - rt;
  1582. break;
  1583. case AND:
  1584. alu_out = rs & rt;
  1585. break;
  1586. case OR:
  1587. alu_out = rs | rt;
  1588. break;
  1589. case XOR:
  1590. alu_out = rs ^ rt;
  1591. break;
  1592. case NOR:
  1593. alu_out = ~(rs | rt);
  1594. break;
  1595. case SLT:
  1596. alu_out = rs &lt; rt ? 1 : 0;
  1597. break;
  1598. case SLTU:
  1599. alu_out = rs_u &lt; rt_u ? 1 : 0;
  1600. break;
  1601. // Break and trap instructions.
  1602. case BREAK:
  1603. do_interrupt = true;
  1604. break;
  1605. case TGE:
  1606. do_interrupt = rs &gt;= rt;
  1607. break;
  1608. case TGEU:
  1609. do_interrupt = rs_u &gt;= rt_u;
  1610. break;
  1611. case TLT:
  1612. do_interrupt = rs &lt; rt;
  1613. break;
  1614. case TLTU:
  1615. do_interrupt = rs_u &lt; rt_u;
  1616. break;
  1617. case TEQ:
  1618. do_interrupt = rs == rt;
  1619. break;
  1620. case TNE:
  1621. do_interrupt = rs != rt;
  1622. break;
  1623. case MOVN:
  1624. case MOVZ:
  1625. case MOVCI:
  1626. // No action taken on decode.
  1627. break;
  1628. case DIV:
  1629. case DIVU:
  1630. // div and divu never raise exceptions.
  1631. break;
  1632. default:
  1633. UNREACHABLE();
  1634. };
  1635. break;
  1636. case SPECIAL2:
  1637. switch (instr-&gt;FunctionFieldRaw()) {
  1638. case MUL:
  1639. alu_out = rs_u * rt_u; // Only the lower 32 bits are kept.
  1640. break;
  1641. case CLZ:
  1642. alu_out = __builtin_clz(rs_u);
  1643. break;
  1644. default:
  1645. UNREACHABLE();
  1646. };
  1647. break;
  1648. case SPECIAL3:
  1649. switch (instr-&gt;FunctionFieldRaw()) {
  1650. case INS: { // Mips32r2 instruction.
  1651. // Interpret rd field as 5-bit msb of insert.
  1652. uint16_t msb = rd_reg;
  1653. // Interpret sa field as 5-bit lsb of insert.
  1654. uint16_t lsb = sa;
  1655. uint16_t size = msb - lsb + 1;
  1656. uint32_t mask = (1 &lt;&lt; size) - 1;
  1657. alu_out = (rt_u & ~(mask &lt;&lt; lsb)) | ((rs_u & mask) &lt;&lt; lsb);
  1658. break;
  1659. }
  1660. case EXT: { // Mips32r2 instruction.
  1661. // Interpret rd field as 5-bit msb of extract.
  1662. uint16_t msb = rd_reg;
  1663. // Interpret sa field as 5-bit lsb of extract.
  1664. uint16_t lsb = sa;
  1665. uint16_t size = msb + 1;
  1666. uint32_t mask = (1 &lt;&lt; size) - 1;
  1667. alu_out = (rs_u & (mask &lt;&lt; lsb)) &gt;&gt; lsb;
  1668. break;
  1669. }
  1670. default:
  1671. UNREACHABLE();
  1672. };
  1673. break;
  1674. default:
  1675. UNREACHABLE();
  1676. };
  1677. }</span>
  1678. <span class="d">void</span> <span class="d">Simulator::DecodeTypeRegister</span><span class="d">(Instruction* instr)</span> {
  1679. // Instruction fields.
  1680. <span class="d">const Opcode op = instr-&gt;OpcodeFieldRaw();</span>
  1681. <span class="d">const int32_t rs_reg = instr-&gt;RsValue();</span>
  1682. <span class="d">const int32_t rs = get_register(rs_reg);</span>
  1683. <span class="d">const uint32_t rs_u = static_cast&lt;uint32_t&gt;(rs);</span>
  1684. <span class="d">const int32_t rt_reg = instr-&gt;RtValue();</span>
  1685. <span class="d">const int32_t rt = get_register(rt_reg);</span>
  1686. <span class="d">const uint32_t rt_u = static_cast&lt;uint32_t&gt;(rt);</span>
  1687. <span class="d">const int32_t rd_reg = instr-&gt;RdValue();</span>
  1688. <span class="d">const int32_t fs_reg = instr-&gt;FsValue();</span>
  1689. <span class="d">const int32_t ft_reg = instr-&gt;FtValue();</span>
  1690. <span class="d">const int32_t fd_reg = instr-&gt;FdValue();</span>
  1691. <span class="d">int64_t i64hilo = 0;</span>
  1692. <span class="d">uint64_t u64hilo = 0;</span>
  1693. // ALU output.
  1694. // It should not be used as is. Instructions using it should always
  1695. // initialize it first.
  1696. <span class="d">int32_t alu_out = 0x12345678;</span>
  1697. // For break and trap instructions.
  1698. <span class="d">bool do_interrupt = false;</span>
  1699. // For jr and jalr.
  1700. // Get current pc.
  1701. <span class="d">int32_t current_pc = get_pc();</span>
  1702. // Next pc
  1703. <span class="d">int32_t next_pc = 0;</span>
  1704. // Setup the variables if needed before executing the instruction.
  1705. <span class="d">ConfigureTypeRegister(instr,
  1706. alu_out,
  1707. i64hilo,
  1708. u64hilo,
  1709. next_pc,
  1710. do_interrupt);</span>
  1711. // ---------- Raise exceptions triggered.
  1712. <span class="d">SignalExceptions();</span>
  1713. // ---------- Execution.
  1714. <span class="d">switch</span> (<span class="d">op</span>) {
  1715. <span class="d">case COP1:
  1716. switch (instr-&gt;RsFieldRaw()) {
  1717. case BC1: // Branch on coprocessor condition.
  1718. UNREACHABLE();
  1719. break;
  1720. case CFC1:
  1721. set_register(rt_reg, alu_out);
  1722. case MFC1:
  1723. set_register(rt_reg, alu_out);
  1724. break;
  1725. case MFHC1:
  1726. UNIMPLEMENTED_MIPS();
  1727. break;
  1728. case CTC1:
  1729. // At the moment only FCSR is supported.
  1730. ASSERT(fs_reg == kFCSRRegister);
  1731. FCSR_ = registers_[rt_reg];
  1732. break;
  1733. case MTC1:
  1734. FPUregisters_[fs_reg] = registers_[rt_reg];
  1735. break;
  1736. case MTHC1:
  1737. UNIMPLEMENTED_MIPS();
  1738. break;
  1739. case S:
  1740. float f;
  1741. switch (instr-&gt;FunctionFieldRaw()) {
  1742. case CVT_D_S:
  1743. f = get_fpu_register_float(fs_reg);
  1744. set_fpu_register_double(fd_reg, static_cast&lt;double&gt;(f));
  1745. break;
  1746. case CVT_W_S:
  1747. case CVT_L_S:
  1748. case TRUNC_W_S:
  1749. case TRUNC_L_S:
  1750. case ROUND_W_S:
  1751. case ROUND_L_S:
  1752. case FLOOR_W_S:
  1753. case FLOOR_L_S:
  1754. case CEIL_W_S:
  1755. case CEIL_L_S:
  1756. case CVT_PS_S:
  1757. UNIMPLEMENTED_MIPS();
  1758. break;
  1759. default:
  1760. UNREACHABLE();
  1761. }
  1762. break;
  1763. case D:
  1764. double ft, fs;
  1765. uint32_t cc, fcsr_cc;
  1766. int64_t i64;
  1767. fs = get_fpu_register_double(fs_reg);
  1768. ft = get_fpu_register_double(ft_reg);
  1769. cc = instr-&gt;FCccValue();
  1770. fcsr_cc = get_fcsr_condition_bit(cc);
  1771. switch (instr-&gt;FunctionFieldRaw()) {
  1772. case ADD_D:
  1773. set_fpu_register_double(fd_reg, fs + ft);
  1774. break;
  1775. case SUB_D:
  1776. set_fpu_register_double(fd_reg, fs - ft);
  1777. break;
  1778. case MUL_D:
  1779. set_fpu_register_double(fd_reg, fs * ft);
  1780. break;
  1781. case DIV_D:
  1782. set_fpu_register_double(fd_reg, fs / ft);
  1783. break;
  1784. case ABS_D:
  1785. set_fpu_register_double(fd_reg, fs &lt; 0 ? -fs : fs);
  1786. break;
  1787. case MOV_D:
  1788. set_fpu_register_double(fd_reg, fs);
  1789. break;
  1790. case NEG_D:
  1791. set_fpu_register_double(fd_reg, -fs);
  1792. break;
  1793. case SQRT_D:
  1794. set_fpu_register_double(fd_reg, sqrt(fs));
  1795. break;
  1796. case C_UN_D:
  1797. set_fcsr_bit(fcsr_cc, isnan(fs) || isnan(ft));
  1798. break;
  1799. case C_EQ_D:
  1800. set_fcsr_bit(fcsr_cc, (fs == ft));
  1801. break;
  1802. case C_UEQ_D:
  1803. set_fcsr_bit(fcsr_cc, (fs == ft) || (isnan(fs) || isnan(ft)));
  1804. break;
  1805. case C_OLT_D:
  1806. set_fcsr_bit(fcsr_cc, (fs &lt; ft));
  1807. break;
  1808. case C_ULT_D:
  1809. set_fcsr_bit(fcsr_cc, (fs &lt; ft) || (isnan(fs) || isnan(ft)));
  1810. break;
  1811. case C_OLE_D:
  1812. set_fcsr_bit(fcsr_cc, (fs &lt;= ft));
  1813. break;
  1814. case C_ULE_D:
  1815. set_fcsr_bit(fcsr_cc, (fs &lt;= ft) || (isnan(fs) || isnan(ft)));
  1816. break;
  1817. case CVT_W_D: // Convert double to word.
  1818. // Rounding modes are not yet supported.
  1819. ASSERT((FCSR_ & 3) == 0);
  1820. // In rounding mode 0 it should behave like ROUND.
  1821. case ROUND_W_D: // Round double to word.
  1822. {
  1823. double rounded = fs &gt; 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
  1824. int32_t result = static_cast&lt;int32_t&gt;(rounded);
  1825. set_fpu_register(fd_reg, result);
  1826. if (set_fcsr_round_error(fs, rounded)) {
  1827. set_fpu_register(fd_reg, kFPUInvalidResult);
  1828. }
  1829. }
  1830. break;
  1831. case TRUNC_W_D: // Truncate double to word (round towards 0).
  1832. {
  1833. double rounded = trunc(fs);
  1834. int32_t result = static_cast&lt;int32_t&gt;(rounded);
  1835. set_fpu_register(fd_reg, result);
  1836. if (set_fcsr_round_error(fs, rounded)) {
  1837. set_fpu_register(fd_reg, kFPUInvalidResult);
  1838. }
  1839. }
  1840. break;
  1841. case FLOOR_W_D: // Round double to word towards negative infinity.
  1842. {
  1843. double rounded = floor(fs);
  1844. int32_t result = static_cast&lt;int32_t&gt;(rounded);
  1845. set_fpu_register(fd_reg, result);
  1846. if (set_fcsr_round_error(fs, rounded)) {
  1847. set_fpu_register(fd_reg, kFPUInvalidResult);
  1848. }
  1849. }
  1850. break;
  1851. case CEIL_W_D: // Round double to word towards positive infinity.
  1852. {
  1853. double rounded = ceil(fs);
  1854. int32_t result = static_cast&lt;int32_t&gt;(rounded);
  1855. set_fpu_register(fd_reg, result);
  1856. if (set_fcsr_round_error(fs, rounded)) {
  1857. set_fpu_register(fd_reg, kFPUInvalidResult);
  1858. }
  1859. }
  1860. break;
  1861. case CVT_S_D: // Convert double to float (single).
  1862. set_fpu_register_float(fd_reg, static_cast&lt;float&gt;(fs));
  1863. break;
  1864. case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word.
  1865. double rounded = trunc(fs);
  1866. i64 = static_cast&lt;int64_t&gt;(rounded);
  1867. set_fpu_register(fd_reg, i64 & 0xffffffff);
  1868. set_fpu_register(fd_reg + 1, i64 &gt;&gt; 32);
  1869. break;
  1870. }
  1871. case TRUNC_L_D: { // Mips32r2 instruction.
  1872. double rounded = trunc(fs);
  1873. i64 = static_cast&lt;int64_t&gt;(rounded);
  1874. set_fpu_register(fd_reg, i64 & 0xffffffff);
  1875. set_fpu_register(fd_reg + 1, i64 &gt;&gt; 32);
  1876. break;
  1877. }
  1878. case ROUND_L_D: { // Mips32r2 instruction.
  1879. double rounded = fs &gt; 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
  1880. i64 = static_cast&lt;int64_t&gt;(rounded);
  1881. set_fpu_register(fd_reg, i64 & 0xffffffff);
  1882. set_fpu_register(fd_reg + 1, i64 &gt;&gt; 32);
  1883. break;
  1884. }
  1885. case FLOOR_L_D: // Mips32r2 instruction.
  1886. i64 = static_cast&lt;int64_t&gt;(floor(fs));
  1887. set_fpu_register(fd_reg, i64 & 0xffffffff);
  1888. set_fpu_register(fd_reg + 1, i64 &gt;&gt; 32);
  1889. break;
  1890. case CEIL_L_D: // Mips32r2 instruction.
  1891. i64 = static_cast&lt;int64_t&gt;(ceil(fs));
  1892. set_fpu_register(fd_reg, i64 & 0xffffffff);
  1893. set_fpu_register(fd_reg + 1, i64 &gt;&gt; 32);
  1894. break;
  1895. case C_F_D:
  1896. UNIMPLEMENTED_MIPS();
  1897. break;
  1898. default:
  1899. UNREACHABLE();
  1900. }
  1901. break;
  1902. case W:
  1903. switch (instr-&gt;FunctionFieldRaw()) {
  1904. case CVT_S_W: // Convert word to float (single).
  1905. alu_out = get_fpu_register(fs_reg);
  1906. set_fpu_register_float(fd_reg, static_cast&lt;float&gt;(alu_out));
  1907. break;
  1908. case CVT_D_W: // Convert word to double.
  1909. alu_out = get_fpu_register(fs_reg);
  1910. set_fpu_register_double(fd_reg, static_cast&lt;double&gt;(alu_out));
  1911. break;
  1912. default:
  1913. UNREACHABLE();
  1914. };
  1915. break;
  1916. case L:
  1917. switch (instr-&gt;FunctionFieldRaw()) {
  1918. case CVT_D_L: // Mips32r2 instruction.
  1919. // Watch the signs here, we want 2 32-bit vals
  1920. // to make a sign-64.
  1921. i64 = (uint32_t) get_fpu_register(fs_reg);
  1922. i64 |= ((int64_t) get_fpu_register(fs_reg + 1) &lt;&lt; 32);
  1923. set_fpu_register_double(fd_reg, static_cast&lt;double&gt;(i64));
  1924. break;
  1925. case CVT_S_L:
  1926. UNIMPLEMENTED_MIPS();
  1927. break;
  1928. default:
  1929. UNREACHABLE();
  1930. }
  1931. break;
  1932. case PS:
  1933. break;
  1934. default:
  1935. UNREACHABLE();
  1936. };
  1937. break;</span>
  1938. <span class="d">case</span> <span class="d">SPECIAL</span>:
  1939. <span class="d">switch</span> (<span class="d">instr-&gt;FunctionFieldRaw()</span>) {
  1940. <span class="d">case JR: {
  1941. Instruction* branch_delay_instr = reinterpret_cast&lt;Instruction*&gt;(
  1942. current_pc+Instruction::kInstrSize);
  1943. BranchDelayInstructionDecode(branch_delay_instr);
  1944. set_pc(next_pc);
  1945. pc_modified_ = true;
  1946. break;
  1947. }</span>
  1948. <span class="d">case</span> <span class="d">JALR</span>: {
  1949. <span class="d">Instruction* branch_delay_instr = reinterpret_cast&lt;Instruction*&gt;(
  1950. current_pc+Instruction::kInstrSize);</span>
  1951. <span class="d">BranchDelayInstructionDecode(branch_delay_instr);</span>
  1952. <span class="d">set_register</span>(<span class="d">31</span>, <span class="d">current_pc</span> <span class="d">+</span> <a id='4471' tid='4472', class="m">2</a> <a id='4473' tid='4474', class="m">*</a> <a id='4475' tid='4476', class="m">Instruction</a><a id='4477' tid='4478', class="m">::</a><a id='4479' tid='4480', class="m">kInstrSize</a>);
  1953. <span class="d">set_pc(next_pc);</span>
  1954. <span class="d">pc_modified_ = true;</span>
  1955. <span class="d">break;</span>
  1956. }
  1957. // Instructions using HI and LO registers.
  1958. <span class="d">case MULT:
  1959. set_register(LO, static_cast&lt;int32_t&gt;(i64hilo & 0xffffffff));</span>
  1960. <span class="d">set_register(HI, static_cast&lt;int32_t&gt;(i64hilo &gt;&gt; 32));</span>
  1961. <span class="d">break;</span>
  1962. <span class="d">case MULTU:
  1963. set_register(LO, static_cast&lt;int32_t&gt;(u64hilo & 0xffffffff));</span>
  1964. <span class="d">set_register(HI, static_cast&lt;int32_t&gt;(u64hilo &gt;&gt; 32));</span>
  1965. <span class="d">break;</span>
  1966. <span class="d">case DIV:
  1967. // Divide by zero was not checked in the configuration step - div and
  1968. // divu do not raise exceptions. On division by 0, the result will
  1969. // be UNPREDICTABLE.
  1970. if (rt != 0) {
  1971. set_register(LO, rs / rt);
  1972. set_register(HI, rs % rt);
  1973. }
  1974. break;</span>
  1975. <span class="d">case DIVU:
  1976. if (rt_u != 0) {
  1977. set_register(LO, rs_u / rt_u);
  1978. set_register(HI, rs_u % rt_u);
  1979. }
  1980. break;</span>
  1981. // Break and trap instructions.
  1982. <span class="d">case BREAK</span>:
  1983. <span class="d">case TGE</span>:
  1984. <span class="d">case TGEU</span>:
  1985. <span class="d">case TLT</span>:
  1986. <span class="d">case TLTU</span>:
  1987. <span class="d">case TEQ</span>:
  1988. <span class="d">case TNE:
  1989. if (do_interrupt) {
  1990. SoftwareInterrupt(instr);
  1991. }
  1992. break;</span>
  1993. // Conditional moves.
  1994. <span class="d">case MOVN:
  1995. if (rt) set_register(rd_reg, rs);
  1996. break;</span>
  1997. <span class="d">case MOVCI: {
  1998. uint32_t cc = instr-&gt;FBccValue();
  1999. uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
  2000. if (instr-&gt;Bit(16)) { // Read Tf bit.
  2001. if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
  2002. } else {
  2003. if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
  2004. }
  2005. break;
  2006. }</span>
  2007. <span class="d">case MOVZ:
  2008. if (!rt) set_register(rd_reg, rs);
  2009. break;
  2010. default: // For other special opcodes we do the default operation.
  2011. set_register(rd_reg, alu_out);</span>
  2012. };
  2013. <span class="d">break;</span>
  2014. <span class="d">case SPECIAL2:
  2015. switch (instr-&gt;FunctionFieldRaw()) {
  2016. case MUL:
  2017. set_register(rd_reg, alu_out);
  2018. // HI and LO are UNPREDICTABLE after the operation.
  2019. set_register(LO, Unpredictable);
  2020. set_register(HI, Unpredictable);
  2021. break;
  2022. default: // For other special2 opcodes we do the default operation.
  2023. set_register(rd_reg, alu_out);
  2024. }
  2025. break;</span>
  2026. <span class="d">case SPECIAL3:
  2027. switch (instr-&gt;FunctionFieldRaw()) {
  2028. case INS:
  2029. // Ins instr leaves result in Rt, rather than Rd.
  2030. set_register(rt_reg, alu_out);
  2031. break;
  2032. case EXT:
  2033. // Ext instr leaves result in Rt, rather than Rd.
  2034. set_register(rt_reg, alu_out);
  2035. break;
  2036. default:
  2037. UNREACHABLE();
  2038. };
  2039. break;
  2040. // Unimplemented opcodes raised an error in the configuration step before,
  2041. // so we can use the default here to set the destination register in common
  2042. // cases.
  2043. default:
  2044. set_register(rd_reg, alu_out);</span>
  2045. };
  2046. }
  2047. // Type 2: instructions using a 16 bytes immediate. (eg: addi, beq).
  2048. <span class="d">void</span> <span class="d">Simulator::DecodeTypeImmediate</span><span class="d">(Instruction* instr)</span> {
  2049. // Instruction fields.
  2050. <span class="d">Opcode op = instr-&gt;OpcodeFieldRaw();</span>
  2051. <span class="d">int32_t rs = get_register(instr-&gt;RsValue());</span>
  2052. <span class="d">uint32_t rs_u = static_cast&lt;uint32_t&gt;(rs);</span>
  2053. <span class="d">int32_t rt_reg = instr-&gt;RtValue();</span> // Destination register.
  2054. <span class="d">int32_t rt = get_register(rt_reg);</span>
  2055. <span class="d">int16_t imm16 = instr-&gt;Imm16Value();</span>
  2056. <span class="d">int32_t ft_reg = instr-&gt;FtValue();</span> // Destination register.
  2057. // Zero extended immediate.
  2058. <span class="d">uint32_t oe_imm16 = 0xffff & imm16;</span>
  2059. // Sign extended immediate.
  2060. <span class="d">int32_t se_imm16 = imm16;</span>
  2061. // Get current pc.
  2062. <span class="d">int32_t current_pc = get_pc();</span>
  2063. // Next pc.
  2064. <span class="d">int32_t next_pc = bad_ra;</span>
  2065. // Used for conditional branch instructions.
  2066. <span class="d">bool do_branch = false;</span>
  2067. <span class="d">bool execute_branch_delay_instruction = false;</span>
  2068. // Used for arithmetic instructions.
  2069. <span class="d">int32_t alu_out = 0;</span>
  2070. // Floating point.
  2071. <span class="d">double fp_out = 0.0;</span>
  2072. <span class="d">uint32_t cc, cc_value, fcsr_cc;</span>
  2073. // Used for memory instructions.
  2074. <span class="d">int32_t addr = 0x0;</span>
  2075. // Value to be written in memory.
  2076. <span class="d">uint32_t mem_value = 0x0;</span>
  2077. // ---------- Configuration (and execution for REGIMM).
  2078. <span class="d">switch (op) {
  2079. // ------------- COP1. Coprocessor instructions.
  2080. case COP1:
  2081. switch (instr-&gt;RsFieldRaw()) {
  2082. case BC1: // Branch on coprocessor condition.
  2083. cc = instr-&gt;FBccValue();
  2084. fcsr_cc = get_fcsr_condition_bit(cc);
  2085. cc_value = test_fcsr_bit(fcsr_cc);
  2086. do_branch = (instr-&gt;FBtrueValue()) ? cc_value : !cc_value;
  2087. execute_branch_delay_instruction = true;
  2088. // Set next_pc.
  2089. if (do_branch) {
  2090. next_pc = current_pc + (imm16 &lt;&lt; 2) + Instruction::kInstrSize;
  2091. } else {
  2092. next_pc = current_pc + kBranchReturnOffset;
  2093. }
  2094. break;
  2095. default:
  2096. UNREACHABLE();
  2097. };
  2098. break;
  2099. // ------------- REGIMM class.
  2100. case REGIMM:
  2101. switch (instr-&gt;RtFieldRaw()) {
  2102. case BLTZ:
  2103. do_branch = (rs &lt; 0);
  2104. break;
  2105. case BLTZAL:
  2106. do_branch = rs &lt; 0;
  2107. break;
  2108. case BGEZ:
  2109. do_branch = rs &gt;= 0;
  2110. break;
  2111. case BGEZAL:
  2112. do_branch = rs &gt;= 0;
  2113. break;
  2114. default:
  2115. UNREACHABLE();
  2116. };
  2117. switch (instr-&gt;RtFieldRaw()) {
  2118. case BLTZ:
  2119. case BLTZAL:
  2120. case BGEZ:
  2121. case BGEZAL:
  2122. // Branch instructions common part.
  2123. execute_branch_delay_instruction = true;
  2124. // Set next_pc.
  2125. if (do_branch) {
  2126. next_pc = current_pc + (imm16 &lt;&lt; 2) + Instruction::kInstrSize;
  2127. if (instr-&gt;IsLinkingInstruction()) {
  2128. set_register(31, current_pc + kBranchReturnOffset);
  2129. }
  2130. } else {
  2131. next_pc = current_pc + kBranchReturnOffset;
  2132. }
  2133. default:
  2134. break;
  2135. };
  2136. break; // case REGIMM.
  2137. // ------------- Branch instructions.
  2138. // When comparing to zero, the encoding of rt field is always 0, so we don&#39;t
  2139. // need to replace rt with zero.
  2140. case BEQ:
  2141. do_branch = (rs == rt);
  2142. break;
  2143. case BNE:
  2144. do_branch = rs != rt;
  2145. break;
  2146. case BLEZ:
  2147. do_branch = rs &lt;= 0;
  2148. break;
  2149. case BGTZ:
  2150. do_branch = rs &gt; 0;
  2151. break;
  2152. // ------------- Arithmetic instructions.
  2153. case ADDI:
  2154. if (HaveSameSign(rs, se_imm16)) {
  2155. if (rs &gt; 0) {
  2156. exceptions[kIntegerOverflow] = rs &gt; (Registers::kMaxValue - se_imm16);
  2157. } else if (rs &lt; 0) {
  2158. exceptions[kIntegerUnderflow] =
  2159. rs &lt; (Registers::kMinValue - se_imm16);
  2160. }
  2161. }
  2162. alu_out = rs + se_imm16;
  2163. break;
  2164. case ADDIU:
  2165. alu_out = rs + se_imm16;
  2166. break;
  2167. case SLTI:
  2168. alu_out = (rs &lt; se_imm16) ? 1 : 0;
  2169. break;
  2170. case SLTIU:
  2171. alu_out = (rs_u &lt; static_cast&lt;uint32_t&gt;(se_imm16)) ? 1 : 0;
  2172. break;
  2173. case ANDI:
  2174. alu_out = rs & oe_imm16;
  2175. break;
  2176. case ORI:
  2177. alu_out = rs | oe_imm16;
  2178. break;
  2179. case XORI:
  2180. alu_out = rs ^ oe_imm16;
  2181. break;
  2182. case LUI:
  2183. alu_out = (oe_imm16 &lt;&lt; 16);
  2184. break;
  2185. // ------------- Memory instructions.
  2186. case LB:
  2187. addr = rs + se_imm16;
  2188. alu_out = ReadB(addr);
  2189. break;
  2190. case LH:
  2191. addr = rs + se_imm16;
  2192. alu_out = ReadH(addr, instr);
  2193. break;
  2194. case LWL: {
  2195. // al_offset is offset of the effective address within an aligned word.
  2196. uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
  2197. uint8_t byte_shift = kPointerAlignmentMask - al_offset;
  2198. uint32_t mask = (1 &lt;&lt; byte_shift * 8) - 1;
  2199. addr = rs + se_imm16 - al_offset;
  2200. alu_out = ReadW(addr, instr);
  2201. alu_out &lt;&lt;= byte_shift * 8;
  2202. alu_out |= rt & mask;
  2203. break;
  2204. }
  2205. case LW:
  2206. addr = rs + se_imm16;
  2207. alu_out = ReadW(addr, instr);
  2208. break;
  2209. case LBU:
  2210. addr = rs + se_imm16;
  2211. alu_out = ReadBU(addr);
  2212. break;
  2213. case LHU:
  2214. addr = rs + se_imm16;
  2215. alu_out = ReadHU(addr, instr);
  2216. break;
  2217. case LWR: {
  2218. // al_offset is offset of the effective address within an aligned word.
  2219. uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
  2220. uint8_t byte_shift = kPointerAlignmentMask - al_offset;
  2221. uint32_t mask = al_offset ? (~0 &lt;&lt; (byte_shift + 1) * 8) : 0;
  2222. addr = rs + se_imm16 - al_offset;
  2223. alu_out = ReadW(addr, instr);
  2224. alu_out = static_cast&lt;uint32_t&gt; (alu_out) &gt;&gt; al_offset * 8;
  2225. alu_out |= rt & mask;
  2226. break;
  2227. }
  2228. case SB:
  2229. addr = rs + se_imm16;
  2230. break;
  2231. case SH:
  2232. addr = rs + se_imm16;
  2233. break;
  2234. case SWL: {
  2235. uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
  2236. uint8_t byte_shift = kPointerAlignmentMask - al_offset;
  2237. uint32_t mask = byte_shift ? (~0 &lt;&lt; (al_offset + 1) * 8) : 0;
  2238. addr = rs + se_imm16 - al_offset;
  2239. mem_value = ReadW(addr, instr) & mask;
  2240. mem_value |= static_cast&lt;uint32_t&gt;(rt) &gt;&gt; byte_shift * 8;
  2241. break;
  2242. }
  2243. case SW:
  2244. addr = rs + se_imm16;
  2245. break;
  2246. case SWR: {
  2247. uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
  2248. uint32_t mask = (1 &lt;&lt; al_offset * 8) - 1;
  2249. addr = rs + se_imm16 - al_offset;
  2250. mem_value = ReadW(addr, instr);
  2251. mem_value = (rt &lt;&lt; al_offset * 8) | (mem_value & mask);
  2252. break;
  2253. }
  2254. case LWC1:
  2255. addr = rs + se_imm16;
  2256. alu_out = ReadW(addr, instr);
  2257. break;
  2258. case LDC1:
  2259. addr = rs + se_imm16;
  2260. fp_out = ReadD(addr, instr);
  2261. break;
  2262. case SWC1:
  2263. case SDC1:
  2264. addr = rs + se_imm16;
  2265. break;
  2266. default:
  2267. UNREACHABLE();
  2268. }</span>;
  2269. // ---------- Raise exceptions triggered.
  2270. <span class="d">SignalExceptions();</span>
  2271. // ---------- Execution.
  2272. <span class="d">switch</span> (<span class="d">op</span>) {
  2273. // ------------- Branch instructions.
  2274. <span class="d">case BEQ</span>:
  2275. <span class="d">case BNE</span>:
  2276. <span class="d">case</span> <span class="d">BLEZ</span>:
  2277. <span class="d">case BGTZ:
  2278. // Branch instructions common part.
  2279. execute_branch_delay_instruction = true;</span>
  2280. // Set next_pc.
  2281. <span class="d">if</span> <span class="d">(do_branch)</span> {
  2282. <span class="d">next_pc = current_pc + (imm16 &lt;&lt; 2) + Instruction::kInstrSize;</span>
  2283. <span class="d">if</span> <span class="d">(instr-&gt;IsLinkingInstruction())</span> {
  2284. <span class="d">set_register</span>(<span class="d">31</span>, <span class="d">current_pc</span> <span class="d">+</span> <a id='4415' tid='4416', class="m">2</a><a id='4417' tid='4418', class="m">*</a> <a id='4419' tid='4420', class="m">Instruction</a><a id='4421' tid='4422', class="m">::</a><a id='4423' tid='4424', class="m">kInstrSize</a>);
  2285. }
  2286. } <span class="d">else {
  2287. next_pc = current_pc + 2 * Instruction::kInstrSize;
  2288. }</span>
  2289. <span class="d">break;</span>
  2290. // ------------- Arithmetic instructions.
  2291. <span class="d">case ADDI</span>:
  2292. <span class="d">case ADDIU</span>:
  2293. <span class="d">case SLTI</span>:
  2294. <span class="d">case SLTIU</span>:
  2295. <span class="d">case ANDI</span>:
  2296. <span class="d">case ORI</span>:
  2297. <span class="d">case XORI:
  2298. case LUI:
  2299. set_register(rt_reg, alu_out);
  2300. break;</span>
  2301. // ------------- Memory instructions.
  2302. <span class="d">case LB</span>:
  2303. <span class="d">case LH</span>:
  2304. <span class="d">case LWL</span>:
  2305. <span class="d">case LW</span>:
  2306. <span class="d">case LBU</span>:
  2307. <span class="d">case LHU:
  2308. case LWR:
  2309. set_register(rt_reg, alu_out);
  2310. break;
  2311. case SB:
  2312. WriteB(addr, static_cast&lt;int8_t&gt;(rt));
  2313. break;
  2314. case SH:
  2315. WriteH(addr, static_cast&lt;uint16_t&gt;(rt), instr);
  2316. break;
  2317. case SWL:
  2318. WriteW(addr, mem_value, instr);
  2319. break;
  2320. case SW:
  2321. WriteW(addr, rt, instr);
  2322. break;
  2323. case SWR:
  2324. WriteW(addr, mem_value, instr);
  2325. break;
  2326. case LWC1:
  2327. set_fpu_register(ft_reg, alu_out);
  2328. break;
  2329. case LDC1:
  2330. set_fpu_register_double(ft_reg, fp_out);
  2331. break;
  2332. case SWC1:
  2333. addr = rs + se_imm16;
  2334. WriteW(addr, get_fpu_register(ft_reg), instr);
  2335. break;
  2336. case SDC1:
  2337. addr = rs + se_imm16;
  2338. WriteD(addr, get_fpu_register_double(ft_reg), instr);
  2339. break;
  2340. default:
  2341. break;</span>
  2342. };
  2343. <span class="d">if (execute_branch_delay_instruction) {
  2344. // Execute branch delay slot
  2345. // We don&#39;t check for end_sim_pc. First it should not be met as the current
  2346. // pc is valid. Secondly a jump should always execute its branch delay slot.
  2347. Instruction* branch_delay_instr =
  2348. reinterpret_cast&lt;Instruction*&gt;(current_pc+Instruction::kInstrSize);
  2349. BranchDelayInstructionDecode(branch_delay_instr);
  2350. }</span>
  2351. // If needed update pc after the branch delay execution.
  2352. <span class="d">if (next_pc != bad_ra) {
  2353. set_pc(next_pc);
  2354. }</span>
  2355. }
  2356. // Type 3: instructions using a 26 bytes immediate. (eg: j, jal).
  2357. <span class="d">void Simulator::DecodeTypeJump(Instruction* instr) {
  2358. // Get current pc.
  2359. int32_t current_pc = get_pc();
  2360. // Get unchanged bits of pc.
  2361. int32_t pc_high_bits = current_pc & 0xf0000000;
  2362. // Next pc.
  2363. int32_t next_pc = pc_high_bits | (instr-&gt;Imm26Value() &lt;&lt; 2);
  2364. // Execute branch delay slot.
  2365. // We don&#39;t check for end_sim_pc. First it should not be met as the current pc
  2366. // is valid. Secondly a jump should always execute its branch delay slot.
  2367. Instruction* branch_delay_instr =
  2368. reinterpret_cast&lt;Instruction*&gt;(current_pc + Instruction::kInstrSize);
  2369. BranchDelayInstructionDecode(branch_delay_instr);
  2370. // Update pc and ra if necessary.
  2371. // Do this after the branch delay execution.
  2372. if (instr-&gt;IsLinkingInstruction()) {
  2373. set_register(31, current_pc + 2 * Instruction::kInstrSize);
  2374. }
  2375. set_pc(next_pc);
  2376. pc_modified_ = true;
  2377. }</span>
  2378. // Executes the current instruction.
  2379. <a id='4401' tid='4402', class="m">void</a> <a id='4403' tid='4404', class="m">Simulator</a><a id='4405' tid='4406', class="m">::</a><a id='4407' tid='4408', class="m">InstructionDecode</a>(<a id='4409' tid='4410', class="m">Instruction</a><a id='4411' tid='4412', class="m">*</a> <a id='4413' tid='4414', class="m">instr</a>) {
  2380. <a id='4425' tid='4426', class="m">if</a> (<a id='4427' tid='4428', class="m">v8</a><a id='4429' tid='4430', class="m">::</a><a id='4431' tid='4432', class="m">internal</a><a id='4433' tid='4434', class="m">::</a><a id='4435' tid='4436', class="m">FLAG_check_icache</a>) {
  2381. <a id='4437' tid='4438', class="m">CheckICache</a>(<a id='4439' tid='4440', class="m">isolate_</a>-&gt;<a id='4441' tid='4442', class="m">simulator_i_cache</a>(), <a id='4443' tid='4444', class="m">instr</a>);
  2382. }
  2383. <span class="d">pc_modified_ = false;</span>
  2384. <span class="d">if</span> (<a id='4459' tid='4460', class="m">::</a><a id='4461' tid='4462', class="m">v8</a><a id='4463' tid='4464', class="m">::</a><a id='4465' tid='4466', class="m">internal</a><a id='4467' tid='4468', class="m">::</a><a id='4469' tid='4470', class="m">FLAG_trace_sim</a>) {
  2385. <span class="d">disasm::NameConverter converter;</span>
  2386. <span class="d">disasm::Disassembler dasm(converter)</span>;
  2387. // Use a reasonably large buffer.
  2388. <span class="d">v8::internal::EmbeddedVector&lt;char, 256&gt; buffer;</span>
  2389. <a id='4445' tid='4446', class="m">dasm</a>.<a id='4447' tid='4448', class="m">InstructionDecode</a>(<a id='4449' tid='4450', class="m">buffer</a>, <a id='4451' tid='4452', class="m">reinterpret_cast</a>&lt;<a id='4453' tid='4454', class="m">byte</a><a id='4455' tid='4456', class="m">*</a>&gt;(<a id='4457' tid='4458', class="m">instr</a>));
  2390. <a id='4387' tid='4388', class="m">PrintF</a>(<a id='4389' tid='4390', class="m">&quot; 0x%08x %s\n&quot;</a>, <a id='4391' tid='4392', class="m">reinterpret_cast</a>&lt;<a id='4393' tid='4394', class="m">intptr_t</a>&gt;(<a id='4395' tid='4396', class="m">instr</a>),
  2391. <a id='4397' tid='4398', class="m">buffer</a>.<a id='4399' tid='4400', class="m">start</a>());
  2392. }
  2393. <span class="d">switch (instr-&gt;InstructionType()) {
  2394. case Instruction::kRegisterType:
  2395. DecodeTypeRegister(instr);
  2396. break;
  2397. case Instruction::kImmediateType:
  2398. DecodeTypeImmediate(instr);
  2399. break;
  2400. case Instruction::kJumpType:
  2401. DecodeTypeJump(instr);
  2402. break;
  2403. default:
  2404. UNSUPPORTED();
  2405. }</span>
  2406. <a id='4363' tid='4364', class="m">if</a> (<a id='4365' tid='4366', class="m">!</a><a id='4367' tid='4368', class="m">pc_modified_</a>) {
  2407. <a id='4369' tid='4370', class="m">set_register</a>(<a id='4371' tid='4372', class="m">pc</a>, <a id='4373' tid='4374', class="m">reinterpret_cast</a>&lt;<a id='4375' tid='4376', class="m">int32_t</a>&gt;(<a id='4377' tid='4378', class="m">instr</a>) <a id='4379' tid='4380', class="m">+</a>
  2408. <a id='4381' tid='4382', class="m">Instruction</a><a id='4383' tid='4384', class="m">::</a><a id='4385' tid='4386', class="m">kInstrSize</a>);
  2409. }
  2410. }
  2411. <a id='4727' tid='4728', class="m">void</a> <a id='4729' tid='4730', class="m">Simulator</a><a id='4731' tid='4732', class="m">::</a><a id='4733' tid='4734', class="m">Execute</a>() {
  2412. // Get the PC to simulate. Cannot use the accessor here as we need the
  2413. // raw PC value and not the one used as input to arithmetic instructions.
  2414. <a id='4735' tid='4736', class="m">int</a> <a id='4737' tid='4738', class="m">program_counter</a> = <a id='4739' tid='4740', class="m">get_pc</a>();
  2415. <a id='4741' tid='4742', class="m">if</a> (<a id='4743' tid='4744', class="m">::</a><a id='4745' tid='4746', class="m">v8</a><a id='4747' tid='4748', class="m">::</a><a id='4749' tid='4750', class="m">internal</a><a id='4751' tid='4752', class="m">::</a><a id='4753' tid='4754', class="m">FLAG_stop_sim_at</a> <a id='4755' tid='4756', class="m">==</a> <a id='4757' tid='4758', class="m">0</a>) {
  2416. // Fast version of the dispatch loop without checking whether the simulator
  2417. // should be stopping at a particular executed instruction.
  2418. <a id='4759' tid='4760', class="m">while</a> (<a id='4761' tid='4762', class="m">program_counter</a> <a id='4763' tid='4764', class="m">!=</a> <a id='4765' tid='4766', class="m">end_sim_pc</a>) {
  2419. <a id='4767' tid='4768', class="m">Instruction</a><a id='4769' tid='4770', class="m">*</a> <a id='4771' tid='4772', class="m">instr</a> = <a id='4773' tid='4774', class="m">reinterpret_cast</a>&lt;<a id='4775' tid='4776', class="m">Instruction</a><a id='4777' tid='4778', class="m">*</a>&gt;(<a id='4779' tid='4780', class="m">program_counter</a>);
  2420. <a id='4781' tid='4782', class="m">icount_</a><a id='4783' tid='4784', class="m">++</a>;
  2421. <a id='4785' tid='4786', class="m">InstructionDecode</a>(<a id='4787' tid='4788', class="m">instr</a>);
  2422. <a id='4789' tid='4790', class="m">program_counter</a> <a id='4791' tid='4792', class="m">=</a> <a id='4793' tid='4794', class="m">get_pc</a>();
  2423. }
  2424. } <a id='4795' tid='4796', class="m">else</a> {
  2425. // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
  2426. // we reach the particular instuction count.
  2427. <a id='4797' tid='4798', class="m">while</a> (<a id='4799' tid='4800', class="m">program_counter</a> <a id='4801' tid='4802', class="m">!=</a> <a id='4803' tid='4804', class="m">end_sim_pc</a>) {
  2428. <a id='4805' tid='4806', class="m">Instruction</a><a id='4807' tid='4808', class="m">*</a> <a id='4809' tid='4810', class="m">instr</a> = <a id='4811' tid='4812', class="m">reinterpret_cast</a>&lt;<a id='4813' tid='4814', class="m">Instruction</a><a id='4815' tid='4816', class="m">*</a>&gt;(<a id='4817' tid='4818', class="m">program_counter</a>);
  2429. <a id='4819' tid='4820', class="m">icount_</a><a id='4821' tid='4822', class="m">++</a>;
  2430. <span class="d">if</span> (<a id='4823' tid='4824', class="m">icount_</a> <a id='4825' tid='4826', class="m">==</a> <a id='4827' tid='4828', class="m">::</a><a id='4829' tid='4830', class="m">v8</a><a id='4831' tid='4832', class="m">::</a><a id='4833' tid='4834', class="m">internal</a><a id='4835' tid='4836', class="m">::</a><a id='4837' tid='4838', class="m">FLAG_stop_sim_at</a>) <span class="d">{
  2431. MipsDebugger dbg(this);
  2432. dbg.Debug();
  2433. }</span> <span class="d">else {
  2434. InstructionDecode(instr);
  2435. }</span>
  2436. <a id='4839' tid='4840', class="m">program_counter</a> <a id='4841' tid='4842', class="m">=</a> <a id='4843' tid='4844', class="m">get_pc</a>();
  2437. }
  2438. }
  2439. }
  2440. <a id='4667' tid='4668', class="m">int32_t</a> <a id='4669' tid='4670', class="m">Simulator</a><a id='4671' tid='4672', class="m">::</a><a id='4673' tid='4674', class="m">Call</a>(<a id='4675' tid='4676', class="m">byte</a><a id='4677' tid='4678', class="m">*</a> <a id='4679' tid='4680', class="m">entry</a>, <a id='4681' tid='4682', class="m">int</a> <a id='4683' tid='4684', class="m">argument_count</a>, <a id='4685' tid='4686', class="m">...</a>) {
  2441. <span class="d">va_list parameters;</span>
  2442. <span class="d">va_start(parameters, argument_count);</span>
  2443. // Setup arguments.
  2444. // First four arguments passed in registers.
  2445. <span class="d">ASSERT(argument_count &gt;= 4);</span>
  2446. <span class="d">set_register(a0, va_arg(parameters, int32_t));</span>
  2447. <span class="d">set_register(a1, va_arg(parameters, int32_t));</span>
  2448. <span class="d">set_register(a2, va_arg(parameters, int32_t));</span>
  2449. <span class="d">set_register(a3, va_arg(parameters, int32_t));</span>
  2450. // Remaining arguments passed on stack.
  2451. <span class="d">int original_stack = get_register(sp);</span>
  2452. // Compute position of stack on entry to generated code.
  2453. <span class="d">int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t)
  2454. - kCArgsSlotsSize);</span>
  2455. <a id='4687' tid='4688', class="m">if</a> (<a id='4689' tid='4690', class="m">OS</a><a id='4691' tid='4692', class="m">::</a><a id='4693' tid='4694', class="m">ActivationFrameAlignment</a>() <a id='4695' tid='4696', class="m">!=</a> <a id='4697' tid='4698', class="m">0</a>) {
  2456. <a id='4699' tid='4700', class="m">entry_stack</a> <a id='4701' tid='4702', class="m">&=</a> <a id='4703' tid='4704', class="m">-</a><a id='4705' tid='4706', class="m">OS</a><a id='4707' tid='4708', class="m">::</a><a id='4709' tid='4710', class="m">ActivationFrameAlignment</a>();
  2457. }
  2458. // Store remaining arguments on stack, from low to high memory.
  2459. <a id='4653' tid='4654', class="m">intptr_t</a><a id='4655' tid='4656', class="m">*</a> <a id='4657' tid='4658', class="m">stack_argument</a> = <a id='4659' tid='4660', class="m">reinterpret_cast</a>&lt;<a id='4661' tid='4662', class="m">intptr_t</a><a id='4663' tid='4664', class="m">*</a>&gt;(<a id='4665' tid='4666', class="m">entry_stack</a>);
  2460. <span class="d">for</span> (<a id='4545' tid='4546', class="m">int</a> <a id='4547' tid='4548', class="m">i</a> = <a id='4549' tid='4550', class="m">4</a>; <a id='4551' tid='4552', class="m">i</a> <a id='4553' tid='4554', class="m">&lt;</a> <a id='4555' tid='4556', class="m">argument_count</a>; <a id='4557' tid='4558', class="m">i</a><a id='4559' tid='4560', class="m">++</a>) <span class="d">{
  2461. stack_argument[i - 4 + kArgsSlotsNum] = va_arg(parameters, int32_t);
  2462. }</span>
  2463. <span class="d">va_end(parameters);</span>
  2464. <span class="d">set_register(sp, entry_stack);</span>
  2465. // Prepare to execute the code at entry.
  2466. <a id='4481' tid='4482', class="m">set_register</a>(<a id='4483' tid='4484', class="m">pc</a>, <a id='4485' tid='4486', class="m">reinterpret_cast</a>&lt;<a id='4487' tid='4488', class="m">int32_t</a>&gt;(<a id='4489' tid='4490', class="m">entry</a>));
  2467. // Put down marker for end of simulation. The simulator will stop simulation
  2468. // when the PC reaches this value. By saving the &quot;end simulation&quot; value into
  2469. // the LR the simulation stops when returning to this call point.
  2470. <span class="d">set_register(ra, end_sim_pc);</span>
  2471. // Remember the values of callee-saved registers.
  2472. // The code below assumes that r9 is not used as sb (static base) in
  2473. // simulator code and therefore is regarded as a callee-saved register.
  2474. <span class="d">int32_t s0_val = get_register(s0);</span>
  2475. <span class="d">int32_t s1_val = get_register(s1);</span>
  2476. <span class="d">int32_t s2_val = get_register(s2);</span>
  2477. <span class="d">int32_t s3_val = get_register(s3);</span>
  2478. <span class="d">int32_t s4_val = get_register(s4);</span>
  2479. <span class="d">int32_t s5_val = get_register(s5);</span>
  2480. <span class="d">int32_t s6_val = get_register(s6);</span>
  2481. <span class="d">int32_t s7_val = get_register(s7);</span>
  2482. <span class="d">int32_t gp_val = get_register(gp);</span>
  2483. <span class="d">int32_t sp_val = get_register(sp);</span>
  2484. <span class="d">int32_t fp_val = get_register(fp);</span>
  2485. // Setup the callee-saved registers with a known value. To be able to check
  2486. // that they are preserved properly across JS execution.
  2487. <span class="d">int32_t callee_saved_value = icount_;</span>
  2488. <span class="d">set_register(s0, callee_saved_value);</span>
  2489. <span class="d">set_register(s1, callee_saved_value);</span>
  2490. <span class="d">set_register(s2, callee_saved_value);</span>
  2491. <span class="d">set_register(s3, callee_saved_value);</span>
  2492. <span class="d">set_register(s4, callee_saved_value);</span>
  2493. <span class="d">set_register(s5, callee_saved_value);</span>
  2494. <span class="d">set_register(s6, callee_saved_value);</span>
  2495. <span class="d">set_register(s7, callee_saved_value);</span>
  2496. <span class="d">set_register(gp, callee_saved_value);</span>
  2497. <span class="d">set_register(fp, callee_saved_value);</span>
  2498. // Start the simulation.
  2499. <span class="d">Execute();</span>
  2500. // Check that the callee-saved registers have been preserved.
  2501. <span class="d">CHECK_EQ(callee_saved_value, get_register(s0));</span>
  2502. <span class="d">CHECK_EQ(callee_saved_value, get_register(s1));</span>
  2503. <span class="d">CHECK_EQ(callee_saved_value, get_register(s2));</span>
  2504. <span class="d">CHECK_EQ(callee_saved_value, get_register(s3));</span>
  2505. <span class="d">CHECK_EQ(callee_saved_value, get_register(s4));</span>
  2506. <span class="d">CHECK_EQ(callee_saved_value, get_register(s5));</span>
  2507. <span class="d">CHECK_EQ(callee_saved_value, get_register(s6));</span>
  2508. <span class="d">CHECK_EQ(callee_saved_value, get_register(s7));</span>
  2509. <span class="d">CHECK_EQ(callee_saved_value, get_register(gp));</span>
  2510. <span class="d">CHECK_EQ(callee_saved_value, get_register(fp));</span>
  2511. // Restore callee-saved registers with the original value.
  2512. <span class="d">set_register(s0, s0_val);</span>
  2513. <span class="d">set_register(s1, s1_val);</span>
  2514. <span class="d">set_register(s2, s2_val);</span>
  2515. <span class="d">set_register(s3, s3_val);</span>
  2516. <span class="d">set_register(s4, s4_val);</span>
  2517. <span class="d">set_register(s5, s5_val);</span>
  2518. <span class="d">set_register(s6, s6_val);</span>
  2519. <span class="d">set_register(s7, s7_val);</span>
  2520. <span class="d">set_register(gp, gp_val);</span>
  2521. <span class="d">set_register(sp, sp_val);</span>
  2522. <span class="d">set_register(fp, fp_val);</span>
  2523. // Pop stack passed arguments.
  2524. <span class="d">CHECK_EQ(entry_stack, get_register(sp));</span>
  2525. <span class="d">set_register(sp, original_stack);</span>
  2526. <span class="d">int32_t result = get_register(v0);</span>
  2527. <span class="d">return result;</span>
  2528. }
  2529. <a id='4561' tid='4562', class="m">uintptr_t</a> <a id='4563' tid='4564', class="m">Simulator</a><a id='4565' tid='4566', class="m">::</a><a id='4567' tid='4568', class="m">PushAddress</a>(<a id='4569' tid='4570', class="m">uintptr_t</a> <a id='4571' tid='4572', class="m">address</a>) {
  2530. <a id='4573' tid='4574', class="m">int</a> <a id='4575' tid='4576', class="m">new_sp</a> = <a id='4577' tid='4578', class="m">get_register</a>(<a id='4579' tid='4580', class="m">sp</a>) <a id='4581' tid='4582', class="m">-</a> <a id='4583' tid='4584', class="m">sizeof</a>(<a id='4585' tid='4586', class="m">uintptr_t</a>);
  2531. <a id='4587' tid='4588', class="m">uintptr_t</a><a id='4589' tid='4590', class="m">*</a> <a id='4591' tid='4592', class="m">stack_slot</a> = <a id='4593' tid='4594', class="m">reinterpret_cast</a>&lt;<a id='4595' tid='4596', class="m">uintptr_t</a><a id='4597' tid='4598', class="m">*</a>&gt;(<a id='4599' tid='4600', class="m">new_sp</a>);
  2532. <a id='4601' tid='4602', class="m">*</a><a id='4603' tid='4604', class="m">stack_slot</a> <a id='4605' tid='4606', class="m">=</a> <a id='4607' tid='4608', class="m">address</a>;
  2533. <a id='4609' tid='4610', class="m">set_register</a>(<a id='4611' tid='4612', class="m">sp</a>, <a id='4613' tid='4614', class="m">new_sp</a>);
  2534. <a id='4615' tid='4616', class="m">return</a> <a id='4617' tid='4618', class="m">new_sp</a>;
  2535. }
  2536. <a id='4491' tid='4492', class="m">uintptr_t</a> <a id='4493' tid='4494', class="m">Simulator</a><a id='4495' tid='4496', class="m">::</a><a id='4497' tid='4498', class="m">PopAddress</a>() {
  2537. <a id='4499' tid='4500', class="m">int</a> <a id='4501' tid='4502', class="m">current_sp</a> = <a id='4503' tid='4504', class="m">get_register</a>(<a id='4505' tid='4506', class="m">sp</a>);
  2538. <a id='4507' tid='4508', class="m">uintptr_t</a><a id='4509' tid='4510', class="m">*</a> <a id='4511' tid='4512', class="m">stack_slot</a> = <a id='4513' tid='4514', class="m">reinterpret_cast</a>&lt;<a id='4515' tid='4516', class="m">uintptr_t</a><a id='4517' tid='4518', class="m">*</a>&gt;(<a id='4519' tid='4520', class="m">current_sp</a>);
  2539. <a id='4521' tid='4522', class="m">uintptr_t</a> <a id='4523' tid='4524', class="m">address</a> = <a id='4525' tid='4526', class="m">*</a><a id='4527' tid='4528', class="m">stack_slot</a>;
  2540. <a id='4529' tid='4530', class="m">set_register</a>(<a id='4531' tid='4532', class="m">sp</a>, <a id='4533' tid='4534', class="m">current_sp</a> <a id='4535' tid='4536', class="m">+</a> <a id='4537' tid='4538', class="m">sizeof</a>(<a id='4539' tid='4540', class="m">uintptr_t</a>));
  2541. <a id='4541' tid='4542', class="m">return</a> <a id='4543' tid='4544', class="m">address</a>;
  2542. }
  2543. <span class="d">#undef UNSUPPORTED</span>
  2544. } } // namespace v8::internal
  2545. <span class="d">#endif</span> // USE_SIMULATOR
  2546. <span class="d">#endif</span> // V8_TARGET_ARCH_MIPS
  2547. </pre>
  2548. </div>
  2549. <div id="right" class="src">
  2550. <pre>
  2551. <a id='rightstart' tid='leftstart'></a>
  2552. // Copyright 2011 the V8 project authors. All rights reserved.
  2553. // Redistribution and use in source and binary forms, with or without
  2554. // modification, are permitted provided that the following conditions are
  2555. // met:
  2556. //
  2557. // * Redistributions of source code must retain the above copyright
  2558. // notice, this list of conditions and the following disclaimer.
  2559. // * Redistributions in binary form must reproduce the above
  2560. // copyright notice, this list of conditions and the following
  2561. // disclaimer in the documentation and/or other materials provided
  2562. // with the distribution.
  2563. // * Neither the name of Google Inc. nor the names of its
  2564. // contributors may be used to endorse or promote products derived
  2565. // from this software without specific prior written permission.
  2566. //
  2567. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  2568. // &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  2569. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  2570. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  2571. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  2572. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  2573. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2574. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  2575. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2576. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  2577. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2578. #<a id='9614' tid='9613', class="m">include</a> <a id='9616' tid='9615', class="m">&lt;</a><a id='9618' tid='9617', class="m">stdlib</a><a id='9620' tid='9619', class="m">.</a><a id='9622' tid='9621', class="m">h</a><a id='9624' tid='9623', class="m">&gt;</a>
  2579. #<a id='9602' tid='9601', class="m">include</a> <a id='9604' tid='9603', class="m">&lt;</a><a id='9606' tid='9605', class="m">math</a><a id='9608' tid='9607', class="m">.</a><a id='9610' tid='9609', class="m">h</a><a id='9612' tid='9611', class="m">&gt;</a>
  2580. <span class="i">#include &lt;cstdarg&gt;</span>
  2581. <span class="i">#include &quot;v8.h&quot;</span>
  2582. <span class="i">#if defined(V8_TARGET_ARCH_ARM)</span>
  2583. <span class="i">#include &quot;disasm.h&quot;</span>
  2584. <span class="i">#include &quot;assembler.h&quot;</span>
  2585. <span class="i">#include &quot;arm/constants-arm.h&quot;</span>
  2586. <span class="i">#include &quot;arm/simulator-arm.h&quot;</span>
  2587. #<a id='9592' tid='9591', class="m">if</a> <a id='9594' tid='9593', class="m">defined</a><a id='9596' tid='9595', class="m">(</a><a id='9598' tid='9597', class="m">USE_SIMULATOR</a><a id='9600' tid='9599', class="m">)</a>
  2588. // Only build the simulator if not compiling for real ARM hardware.
  2589. namespace <span class="i">v8</span> {
  2590. namespace <span class="i">internal</span> {
  2591. // This macro provides a platform independent use of sscanf. The reason for
  2592. // SScanF not being implemented in a platform independent way through
  2593. // ::v8::internal::OS in the same way as SNPrintF is that the
  2594. // Windows C Run-Time Library does not provide vsscanf.
  2595. <span class="i">#define SScanF sscanf</span> // NOLINT
  2596. // The ArmDebugger class is used by the simulator while debugging simulated ARM
  2597. // code.
  2598. <span class="i">class</span> <span class="i">ArmDebugger</span> {
  2599. <span class="i">public:</span>
  2600. <span class="i">explicit ArmDebugger(Simulator* sim)</span>;
  2601. <span class="i">~ArmDebugger();</span>
  2602. <a id='9582' tid='9581', class="m">void</a> <a id='9584' tid='9583', class="m">Stop</a>(<a id='9586' tid='9585', class="m">Instruction</a><a id='9588' tid='9587', class="m">*</a> <a id='9590' tid='9589', class="m">instr</a>);
  2603. <span class="i">void Debug()</span>;
  2604. <span class="i">private:</span>
  2605. <span class="i">static const Instr kBreakpointInstr =
  2606. (al | (7*B25) | (1*B24) | kBreakpoint);</span>
  2607. <span class="i">static const Instr kNopInstr = (al | (13*B21));</span>
  2608. <span class="i">Simulator* sim_;</span>
  2609. <span class="i">int32_t GetRegisterValue(int regnum)</span>;
  2610. <span class="i">double GetRegisterPairDoubleValue(int regnum)</span>;
  2611. <span class="i">double GetVFPDoubleRegisterValue(int regnum)</span>;
  2612. <a id='9564' tid='9563', class="m">bool</a> <a id='9566' tid='9565', class="m">GetValue</a>(<a id='9568' tid='9567', class="m">const</a> <a id='9570' tid='9569', class="m">char</a><a id='9572' tid='9571', class="m">*</a> <a id='9574' tid='9573', class="m">desc</a>, <a id='9576' tid='9575', class="m">int32_t</a><a id='9578' tid='9577', class="m">*</a> <a id='9580' tid='9579', class="m">value</a>);
  2613. <span class="i">bool GetVFPSingleValue(const char* desc, float* value)</span>;
  2614. <span class="i">bool GetVFPDoubleValue(const char* desc, double* value)</span>;
  2615. // Set or delete a breakpoint. Returns true if successful.
  2616. <a id='9544' tid='9543', class="m">bool</a> <a id='9546' tid='9545', class="m">SetBreakpoint</a>(<a id='9548' tid='9547', class="m">Instruction</a><a id='9550' tid='9549', class="m">*</a> <a id='9552' tid='9551', class="m">breakpc</a>);
  2617. <a id='9500' tid='9499', class="m">bool</a> <a id='9502' tid='9501', class="m">DeleteBreakpoint</a>(<a id='9504' tid='9503', class="m">Instruction</a><a id='9506' tid='9505', class="m">*</a> <a id='9508' tid='9507', class="m">breakpc</a>);
  2618. // Undo and redo all breakpoints. This is needed to bracket disassembly and
  2619. // execution to skip past breakpoints when run from the debugger.
  2620. <span class="i">void UndoBreakpoints()</span>;
  2621. <span class="i">void RedoBreakpoints()</span>;
  2622. };
  2623. <span class="i">ArmDebugger::ArmDebugger(Simulator* sim) {
  2624. sim_ = sim;
  2625. }</span>
  2626. <span class="i">ArmDebugger::~ArmDebugger() {
  2627. }</span>
  2628. <span class="i">#ifdef GENERATED_CODE_COVERAGE</span>
  2629. <a id='9554' tid='9553', class="m">static</a> <a id='9556' tid='9555', class="m">FILE</a><a id='9558' tid='9557', class="m">*</a> <a id='9560' tid='9559', class="m">coverage_log</a> = <a id='9562' tid='9561', class="m">NULL</a>;
  2630. <a id='9510' tid='9509', class="m">static</a> <a id='9512' tid='9511', class="m">void</a> <a id='9514' tid='9513', class="m">InitializeCoverage</a>() {
  2631. <a id='9516' tid='9515', class="m">char</a><a id='9518' tid='9517', class="m">*</a> <a id='9520' tid='9519', class="m">file_name</a> = <a id='9522' tid='9521', class="m">getenv</a>(<a id='9524' tid='9523', class="m">&quot;V8_GENERATED_CODE_COVERAGE_LOG&quot;</a>);
  2632. <a id='9526' tid='9525', class="m">if</a> (<a id='9528' tid='9527', class="m">file_name</a> <a id='9530' tid='9529', class="m">!=</a> <a id='9532' tid='9531', class="m">NULL</a>) {
  2633. <a id='9534' tid='9533', class="m">coverage_log</a> <a id='9536' tid='9535', class="m">=</a> <a id='9538' tid='9537', class="m">fopen</a>(<a id='9540' tid='9539', class="m">file_name</a>, <a id='9542' tid='9541', class="m">&quot;aw+&quot;</a>);
  2634. }
  2635. }
  2636. <a id='9444' tid='9443', class="m">void</a> <span class="i">ArmDebugger::Stop</span>(<a id='9446' tid='9445', class="m">Instruction</a><a id='9448' tid='9447', class="m">*</a> <a id='9450' tid='9449', class="m">instr</a>) {
  2637. // Get the stop code.
  2638. <span class="i">uint32_t code = instr-&gt;SvcValue() & kStopCodeMask;</span>
  2639. // Retrieve the encoded address, which comes just after this stop.
  2640. <span class="i">char**</span> <span class="i">msg_address</span> =
  2641. <span class="i">reinterpret_cast&lt;char**&gt;</span>(<a id='8038' tid='8037', class="m">sim_</a>-&gt;<a id='8040' tid='8039', class="m">get_pc</a>() <a id='8042' tid='8041', class="m">+</a> <a id='8044' tid='8043', class="m">Instruction</a><a id='8046' tid='8045', class="m">::</a><a id='8048' tid='8047', class="m">kInstrSize</a>);
  2642. <a id='9490' tid='9489', class="m">char</a><a id='9492' tid='9491', class="m">*</a> <a id='9494' tid='9493', class="m">msg</a> = <a id='9496' tid='9495', class="m">*</a><a id='9498' tid='9497', class="m">msg_address</a>;
  2643. <span class="i">ASSERT(msg != NULL);</span>
  2644. // Update this stop description.
  2645. <span class="i">if</span> <span class="i">(isWatchedStop(code) && !watched_stops[code].desc)</span> {
  2646. <a id='9480' tid='9479', class="m">watched_stops</a>[<a id='9482' tid='9481', class="m">code</a>].<a id='9484' tid='9483', class="m">desc</a> <a id='9486' tid='9485', class="m">=</a> <a id='9488' tid='9487', class="m">msg</a>;
  2647. }
  2648. <span class="i">if (strlen(msg) &gt; 0) {
  2649. if (coverage_log != NULL) {
  2650. fprintf(coverage_log, &quot;%s\n&quot;, msg);
  2651. fflush(coverage_log);
  2652. }
  2653. // Overwrite the instruction and address with nops.
  2654. instr-&gt;SetInstructionBits(kNopInstr);
  2655. reinterpret_cast&lt;Instruction*&gt;(msg_address)-&gt;SetInstructionBits(kNopInstr);
  2656. }</span>
  2657. <a id='9424' tid='9423', class="m">sim_</a>-&gt;<a id='9426' tid='9425', class="m">set_pc</a>(<a id='9428' tid='9427', class="m">sim_</a>-&gt;<a id='9430' tid='9429', class="m">get_pc</a>() <a id='9432' tid='9431', class="m">+</a> <a id='9434' tid='9433', class="m">2</a> <a id='9436' tid='9435', class="m">*</a> <a id='9438' tid='9437', class="m">Instruction</a><a id='9440' tid='9439', class="m">::</a><a id='9442' tid='9441', class="m">kInstrSize</a>);
  2658. }
  2659. <span class="i">#else</span> // ndef GENERATED_CODE_COVERAGE
  2660. <span class="i">static void InitializeCoverage() {
  2661. }</span>
  2662. <a id='9406' tid='9405', class="m">void</a> <span class="i">ArmDebugger::Stop</span>(<a id='9408' tid='9407', class="m">Instruction</a><a id='9410' tid='9409', class="m">*</a> <a id='9412' tid='9411', class="m">instr</a>) {
  2663. // Get the stop code.
  2664. <span class="i">uint32_t code = instr-&gt;SvcValue() & kStopCodeMask;</span>
  2665. // Retrieve the encoded address, which comes just after this stop.
  2666. <a id='9452' tid='9451', class="m">char</a><a id='9454' tid='9453', class="m">*</a> <a id='9456' tid='9455', class="m">msg</a> = <a id='9458' tid='9457', class="m">*</a><a id='9460' tid='9459', class="m">reinterpret_cast</a>&lt;<a id='9462' tid='9461', class="m">char</a><a id='9464' tid='9463', class="m">*</a><a id='9466' tid='9465', class="m">*</a>&gt;(<a id='9468' tid='9467', class="m">sim_</a>-&gt;<a id='9470' tid='9469', class="m">get_pc</a>()
  2667. <a id='9472' tid='9471', class="m">+</a> <a id='9474' tid='9473', class="m">Instruction</a><a id='9476' tid='9475', class="m">::</a><a id='9478' tid='9477', class="m">kInstrSize</a>);
  2668. // Update this stop description.
  2669. <a id='9382' tid='9381', class="m">if</a> (<span class="i">sim_-&gt;isWatchedStop(code)</span> <span class="i">&&</span> <a id='9384' tid='9383', class="m">!</a><a id='9386' tid='9385', class="m">sim_</a>-&gt;<a id='9388' tid='9387', class="m">watched_stops</a>[<a id='9390' tid='9389', class="m">code</a>].<a id='9392' tid='9391', class="m">desc</a>) {
  2670. <a id='9394' tid='9393', class="m">sim_</a>-&gt;<a id='9396' tid='9395', class="m">watched_stops</a>[<a id='9398' tid='9397', class="m">code</a>].<a id='9400' tid='9399', class="m">desc</a> <a id='9402' tid='9401', class="m">=</a> <a id='9404' tid='9403', class="m">msg</a>;
  2671. }
  2672. // Print the stop message and code if it is not the default code.
  2673. <span class="i">if (code != kMaxStopCode) {
  2674. PrintF(&quot;Simulator hit stop %u: %s\n&quot;, code, msg);
  2675. } else {
  2676. PrintF(&quot;Simulator hit %s\n&quot;, msg);
  2677. }</span>
  2678. <span class="i">sim_-&gt;set_pc</span>(<span class="i">sim_-&gt;get_pc()</span> <span class="i">+</span> <a id='4416' tid='4415', class="m">2</a> <a id='4418' tid='4417', class="m">*</a> <a id='4420' tid='4419', class="m">Instruction</a><a id='4422' tid='4421', class="m">::</a><a id='4424' tid='4423', class="m">kInstrSize</a>);
  2679. <span class="i">Debug();</span>
  2680. }
  2681. <span class="i">#endif</span>
  2682. <a id='9362' tid='9361', class="m">int32_t</a> <span class="i">ArmDebugger::GetRegisterValue</span>(<a id='9364' tid='9363', class="m">int</a> <a id='9366' tid='9365', class="m">regnum</a>) {
  2683. <span class="i">if</span> <span class="i">(regnum == kPCRegister)</span> <span class="i">{
  2684. return sim_-&gt;get_pc();
  2685. }</span> <a id='9414' tid='9413', class="m">else</a> {
  2686. <a id='9416' tid='9415', class="m">return</a> <a id='9418' tid='9417', class="m">sim_</a>-&gt;<a id='9420' tid='9419', class="m">get_register</a>(<a id='9422' tid='9421', class="m">regnum</a>);
  2687. }
  2688. }
  2689. <span class="i">double ArmDebugger::GetRegisterPairDoubleValue(int regnum) {
  2690. return sim_-&gt;get_double_from_register_pair(regnum);
  2691. }</span>
  2692. <span class="i">double ArmDebugger::GetVFPDoubleRegisterValue(int regnum) {
  2693. return sim_-&gt;get_double_from_d_register(regnum);
  2694. }</span>
  2695. <span class="i">bool</span> <span class="i">ArmDebugger::GetValue</span>(<a id='9368' tid='9367', class="m">const</a> <a id='9370' tid='9369', class="m">char</a><a id='9372' tid='9371', class="m">*</a> <a id='9374' tid='9373', class="m">desc</a>, <a id='9376' tid='9375', class="m">int32_t</a><a id='9378' tid='9377', class="m">*</a> <a id='9380' tid='9379', class="m">value</a>) {
  2696. <a id='9314' tid='9313', class="m">int</a> <a id='9316' tid='9315', class="m">regnum</a> = <a id='9318' tid='9317', class="m">Registers</a><a id='9320' tid='9319', class="m">::</a><a id='9322' tid='9321', class="m">Number</a>(<a id='9324' tid='9323', class="m">desc</a>);
  2697. <span class="i">if</span> <span class="i">(regnum != kNoRegister)</span> {
  2698. <a id='9300' tid='9299', class="m">*</a><a id='9302' tid='9301', class="m">value</a> <a id='9304' tid='9303', class="m">=</a> <a id='9306' tid='9305', class="m">GetRegisterValue</a>(<a id='9308' tid='9307', class="m">regnum</a>);
  2699. <a id='9310' tid='9309', class="m">return</a> <a id='9312' tid='9311', class="m">true</a>;
  2700. } <a id='9238' tid='9237', class="m">else</a> {
  2701. <span class="i">if</span> (<a id='9240' tid='9239', class="m">strncmp</a>(<a id='9242' tid='9241', class="m">desc</a>, <a id='9244' tid='9243', class="m">&quot;0x&quot;</a>, <a id='9246' tid='9245', class="m">2</a>) <a id='9248' tid='9247', class="m">==</a> <a id='9250' tid='9249', class="m">0</a>) <span class="i">{
  2702. return SScanF(desc + 2, &quot;%x&quot;, reinterpret_cast&lt;uint32_t*&gt;(value)) == 1;
  2703. }</span> <span class="i">else {
  2704. return SScanF(desc, &quot;%u&quot;, reinterpret_cast&lt;uint32_t*&gt;(value)) == 1;
  2705. }</span>
  2706. }
  2707. <span class="i">return false;</span>
  2708. }
  2709. <span class="i">bool ArmDebugger::GetVFPSingleValue(const char* desc, float* value) {
  2710. bool is_double;
  2711. int regnum = VFPRegisters::Number(desc, &is_double);
  2712. if (regnum != kNoRegister && !is_double) {
  2713. *value = sim_-&gt;get_float_from_s_register(regnum);
  2714. return true;
  2715. }
  2716. return false;
  2717. }</span>
  2718. <span class="i">bool ArmDebugger::GetVFPDoubleValue(const char* desc, double* value) {
  2719. bool is_double;
  2720. int regnum = VFPRegisters::Number(desc, &is_double);
  2721. if (regnum != kNoRegister && is_double) {
  2722. *value = sim_-&gt;get_double_from_d_register(regnum);
  2723. return true;
  2724. }
  2725. return false;
  2726. }</span>
  2727. <a id='9252' tid='9251', class="m">bool</a> <span class="i">ArmDebugger::SetBreakpoint</span>(<a id='9254' tid='9253', class="m">Instruction</a><a id='9256' tid='9255', class="m">*</a> <a id='9258' tid='9257', class="m">breakpc</a>) {
  2728. // Check if a breakpoint can be set. If not return without any side-effects.
  2729. <a id='9326' tid='9325', class="m">if</a> (<a id='9328' tid='9327', class="m">sim_</a>-&gt;<a id='9330' tid='9329', class="m">break_pc_</a> <a id='9332' tid='9331', class="m">!=</a> <a id='9334' tid='9333', class="m">NULL</a>) {
  2730. <a id='9336' tid='9335', class="m">return</a> <a id='9338' tid='9337', class="m">false</a>;
  2731. }
  2732. // Set the breakpoint.
  2733. <a id='9340' tid='9339', class="m">sim_</a>-&gt;<a id='9342' tid='9341', class="m">break_pc_</a> <a id='9344' tid='9343', class="m">=</a> <a id='9346' tid='9345', class="m">breakpc</a>;
  2734. <a id='9348' tid='9347', class="m">sim_</a>-&gt;<a id='9350' tid='9349', class="m">break_instr_</a> <a id='9352' tid='9351', class="m">=</a> <a id='9354' tid='9353', class="m">breakpc</a>-&gt;<a id='9356' tid='9355', class="m">InstructionBits</a>();
  2735. // Not setting the breakpoint instruction in the code itself. It will be set
  2736. // when the debugger shell continues.
  2737. <a id='9358' tid='9357', class="m">return</a> <a id='9360' tid='9359', class="m">true</a>;
  2738. }
  2739. <a id='9210' tid='9209', class="m">bool</a> <span class="i">ArmDebugger::DeleteBreakpoint</span>(<a id='9212' tid='9211', class="m">Instruction</a><a id='9214' tid='9213', class="m">*</a> <a id='9216' tid='9215', class="m">breakpc</a>) {
  2740. <a id='9260' tid='9259', class="m">if</a> (<a id='9262' tid='9261', class="m">sim_</a>-&gt;<a id='9264' tid='9263', class="m">break_pc_</a> <a id='9266' tid='9265', class="m">!=</a> <a id='9268' tid='9267', class="m">NULL</a>) {
  2741. <a id='9270' tid='9269', class="m">sim_</a>-&gt;<a id='9272' tid='9271', class="m">break_pc_</a>-&gt;<a id='9274' tid='9273', class="m">SetInstructionBits</a>(<a id='9276' tid='9275', class="m">sim_</a>-&gt;<a id='9278' tid='9277', class="m">break_instr_</a>);
  2742. }
  2743. <a id='9280' tid='9279', class="m">sim_</a>-&gt;<a id='9282' tid='9281', class="m">break_pc_</a> <a id='9284' tid='9283', class="m">=</a> <a id='9286' tid='9285', class="m">NULL</a>;
  2744. <a id='9288' tid='9287', class="m">sim_</a>-&gt;<a id='9290' tid='9289', class="m">break_instr_</a> <a id='9292' tid='9291', class="m">=</a> <a id='9294' tid='9293', class="m">0</a>;
  2745. <a id='9296' tid='9295', class="m">return</a> <a id='9298' tid='9297', class="m">true</a>;
  2746. }
  2747. <span class="i">void</span> <span class="i">ArmDebugger::UndoBreakpoints</span><span class="i">()</span> {
  2748. <a id='9218' tid='9217', class="m">if</a> (<a id='9220' tid='9219', class="m">sim_</a>-&gt;<a id='9222' tid='9221', class="m">break_pc_</a> <a id='9224' tid='9223', class="m">!=</a> <a id='9226' tid='9225', class="m">NULL</a>) {
  2749. <a id='9228' tid='9227', class="m">sim_</a>-&gt;<a id='9230' tid='9229', class="m">break_pc_</a>-&gt;<a id='9232' tid='9231', class="m">SetInstructionBits</a>(<a id='9234' tid='9233', class="m">sim_</a>-&gt;<a id='9236' tid='9235', class="m">break_instr_</a>);
  2750. }
  2751. }
  2752. <span class="i">void</span> <span class="i">ArmDebugger::RedoBreakpoints</span><span class="i">()</span> {
  2753. <a id='9192' tid='9191', class="m">if</a> (<a id='9194' tid='9193', class="m">sim_</a>-&gt;<a id='9196' tid='9195', class="m">break_pc_</a> <a id='9198' tid='9197', class="m">!=</a> <a id='9200' tid='9199', class="m">NULL</a>) {
  2754. <a id='9202' tid='9201', class="m">sim_</a>-&gt;<a id='9204' tid='9203', class="m">break_pc_</a>-&gt;<a id='9206' tid='9205', class="m">SetInstructionBits</a>(<a id='9208' tid='9207', class="m">kBreakpointInstr</a>);
  2755. }
  2756. }
  2757. <span class="i">void</span> <span class="i">ArmDebugger::Debug</span><span class="i">()</span> {
  2758. <a id='8966' tid='8965', class="m">intptr_t</a> <a id='8968' tid='8967', class="m">last_pc</a> = <a id='8970' tid='8969', class="m">-</a><a id='8972' tid='8971', class="m">1</a>;
  2759. <a id='8974' tid='8973', class="m">bool</a> <a id='8976' tid='8975', class="m">done</a> = <a id='8978' tid='8977', class="m">false</a>;
  2760. #<a id='8980' tid='8979', class="m">define</a> <a id='8982' tid='8981', class="m">COMMAND_SIZE</a> <a id='8984' tid='8983', class="m">63</a>
  2761. #<a id='8986' tid='8985', class="m">define</a> <a id='8988' tid='8987', class="m">ARG_SIZE</a> <a id='8990' tid='8989', class="m">255</a>
  2762. #<a id='9178' tid='9177', class="m">define</a> <a id='9180' tid='9179', class="m">STR</a><a id='9182' tid='9181', class="m">(</a><a id='9184' tid='9183', class="m">a</a><a id='9186' tid='9185', class="m">)</a> <a id='9188' tid='9187', class="m">#</a><a id='9190' tid='9189', class="m">a</a>
  2763. #<a id='8992' tid='8991', class="m">define</a> <a id='8994' tid='8993', class="m">XSTR</a><a id='8996' tid='8995', class="m">(</a><a id='8998' tid='8997', class="m">a</a><a id='9000' tid='8999', class="m">)</a> <a id='9002' tid='9001', class="m">STR</a><a id='9004' tid='9003', class="m">(</a><a id='9006' tid='9005', class="m">a</a><a id='9008' tid='9007', class="m">)</a>
  2764. <a id='9010' tid='9009', class="m">char</a> <a id='9012' tid='9011', class="m">cmd</a>[<a id='9014' tid='9013', class="m">COMMAND_SIZE</a> <a id='9016' tid='9015', class="m">+</a> <a id='9018' tid='9017', class="m">1</a>];
  2765. <a id='9020' tid='9019', class="m">char</a> <a id='9022' tid='9021', class="m">arg1</a>[<a id='9024' tid='9023', class="m">ARG_SIZE</a> <a id='9026' tid='9025', class="m">+</a> <a id='9028' tid='9027', class="m">1</a>];
  2766. <a id='9030' tid='9029', class="m">char</a> <a id='9032' tid='9031', class="m">arg2</a>[<a id='9034' tid='9033', class="m">ARG_SIZE</a> <a id='9036' tid='9035', class="m">+</a> <a id='9038' tid='9037', class="m">1</a>];
  2767. <a id='9040' tid='9039', class="m">char</a><a id='9042' tid='9041', class="m">*</a> <a id='9044' tid='9043', class="m">argv</a>[<a id='9046' tid='9045', class="m">3</a>] = { <a id='9048' tid='9047', class="m">cmd</a>, <a id='9050' tid='9049', class="m">arg1</a>, <a id='9052' tid='9051', class="m">arg2</a> };
  2768. // make sure to have a proper terminating character if reaching the limit
  2769. <a id='9054' tid='9053', class="m">cmd</a>[<a id='9056' tid='9055', class="m">COMMAND_SIZE</a>] <a id='9058' tid='9057', class="m">=</a> <a id='9060' tid='9059', class="m">0</a>;
  2770. <a id='9062' tid='9061', class="m">arg1</a>[<a id='9064' tid='9063', class="m">ARG_SIZE</a>] <a id='9066' tid='9065', class="m">=</a> <a id='9068' tid='9067', class="m">0</a>;
  2771. <a id='9070' tid='9069', class="m">arg2</a>[<a id='9072' tid='9071', class="m">ARG_SIZE</a>] <a id='9074' tid='9073', class="m">=</a> <a id='9076' tid='9075', class="m">0</a>;
  2772. // Undo all set breakpoints while running in the debugger shell. This will
  2773. // make them invisible to all commands.
  2774. <a id='9078' tid='9077', class="m">UndoBreakpoints</a>();
  2775. <span class="i">while</span> <span class="i">(!done)</span> {
  2776. <a id='9080' tid='9079', class="m">if</a> (<a id='9082' tid='9081', class="m">last_pc</a> <a id='9084' tid='9083', class="m">!=</a> <a id='9086' tid='9085', class="m">sim_</a>-&gt;<a id='9088' tid='9087', class="m">get_pc</a>()) {
  2777. <a id='9100' tid='9099', class="m">disasm</a><a id='9102' tid='9101', class="m">::</a><a id='9104' tid='9103', class="m">NameConverter</a> <a id='9106' tid='9105', class="m">converter</a>;
  2778. <a id='9090' tid='9089', class="m">disasm</a><a id='9092' tid='9091', class="m">::</a><a id='9094' tid='9093', class="m">Disassembler</a> <a id='9096' tid='9095', class="m">dasm</a>(<a id='9098' tid='9097', class="m">converter</a>);
  2779. // use a reasonably large buffer
  2780. <a id='9108' tid='9107', class="m">v8</a><a id='9110' tid='9109', class="m">::</a><a id='9112' tid='9111', class="m">internal</a><a id='9114' tid='9113', class="m">::</a><a id='9116' tid='9115', class="m">EmbeddedVector</a>&lt;<a id='9118' tid='9117', class="m">char</a>, <a id='9120' tid='9119', class="m">256</a>&gt; <a id='9122' tid='9121', class="m">buffer</a>;
  2781. <a id='9124' tid='9123', class="m">dasm</a>.<a id='9126' tid='9125', class="m">InstructionDecode</a>(<a id='9128' tid='9127', class="m">buffer</a>,
  2782. <a id='9130' tid='9129', class="m">reinterpret_cast</a>&lt;<a id='9132' tid='9131', class="m">byte</a><a id='9134' tid='9133', class="m">*</a>&gt;(<a id='9136' tid='9135', class="m">sim_</a>-&gt;<a id='9138' tid='9137', class="m">get_pc</a>()));
  2783. <a id='9140' tid='9139', class="m">PrintF</a>(<a id='9142' tid='9141', class="m">&quot; 0x%08x %s\n&quot;</a>, <a id='9144' tid='9143', class="m">sim_</a>-&gt;<a id='9146' tid='9145', class="m">get_pc</a>(), <a id='9148' tid='9147', class="m">buffer</a>.<a id='9150' tid='9149', class="m">start</a>());
  2784. <a id='9152' tid='9151', class="m">last_pc</a> <a id='9154' tid='9153', class="m">=</a> <a id='9156' tid='9155', class="m">sim_</a>-&gt;<a id='9158' tid='9157', class="m">get_pc</a>();
  2785. }
  2786. <a id='8116' tid='8115', class="m">char</a><a id='8118' tid='8117', class="m">*</a> <a id='8120' tid='8119', class="m">line</a> = <a id='8122' tid='8121', class="m">ReadLine</a>(<a id='8124' tid='8123', class="m">&quot;sim&gt; &quot;</a>);
  2787. <a id='8126' tid='8125', class="m">if</a> (<a id='8128' tid='8127', class="m">line</a> <a id='8130' tid='8129', class="m">==</a> <a id='8132' tid='8131', class="m">NULL</a>) {
  2788. <a id='8134' tid='8133', class="m">break</a>;
  2789. } <a id='8136' tid='8135', class="m">else</a> {
  2790. // Use sscanf to parse the individual parts of the command line. At the
  2791. // moment no command expects more than two parameters.
  2792. <a id='8138' tid='8137', class="m">int</a> <a id='8140' tid='8139', class="m">argc</a> = <a id='8142' tid='8141', class="m">SScanF</a>(<a id='8144' tid='8143', class="m">line</a>,
  2793. <a id='8146' tid='8145', class="m">&quot;%&quot;</a> <a id='8148' tid='8147', class="m">XSTR</a>(<a id='8150' tid='8149', class="m">COMMAND_SIZE</a>) <a id='8152' tid='8151', class="m">&quot;s &quot;</a>
  2794. <a id='8154' tid='8153', class="m">&quot;%&quot;</a> <a id='8156' tid='8155', class="m">XSTR</a>(<a id='8158' tid='8157', class="m">ARG_SIZE</a>) <a id='8160' tid='8159', class="m">&quot;s &quot;</a>
  2795. <a id='8162' tid='8161', class="m">&quot;%&quot;</a> <a id='8164' tid='8163', class="m">XSTR</a>(<a id='8166' tid='8165', class="m">ARG_SIZE</a>) <a id='8168' tid='8167', class="m">&quot;s&quot;</a>,
  2796. <a id='8170' tid='8169', class="m">cmd</a>, <a id='8172' tid='8171', class="m">arg1</a>, <a id='8174' tid='8173', class="m">arg2</a>);
  2797. <a id='8176' tid='8175', class="m">if</a> ((<a id='8178' tid='8177', class="m">strcmp</a>(<a id='8180' tid='8179', class="m">cmd</a>, <a id='8182' tid='8181', class="m">&quot;si&quot;</a>) <a id='8184' tid='8183', class="m">==</a> <a id='8186' tid='8185', class="m">0</a>) <a id='8188' tid='8187', class="m">||</a> (<a id='8190' tid='8189', class="m">strcmp</a>(<a id='8192' tid='8191', class="m">cmd</a>, <a id='8194' tid='8193', class="m">&quot;stepi&quot;</a>) <a id='8196' tid='8195', class="m">==</a> <a id='8198' tid='8197', class="m">0</a>)) {
  2798. <a id='8200' tid='8199', class="m">sim_</a>-&gt;<a id='8202' tid='8201', class="m">InstructionDecode</a>(<a id='8204' tid='8203', class="m">reinterpret_cast</a>&lt;<a id='8206' tid='8205', class="m">Instruction</a><a id='8208' tid='8207', class="m">*</a>&gt;(<a id='8210' tid='8209', class="m">sim_</a>-&gt;<a id='8212' tid='8211', class="m">get_pc</a>()));
  2799. } <a id='8214' tid='8213', class="m">else</a> <a id='8216' tid='8215', class="m">if</a> ((<a id='8218' tid='8217', class="m">strcmp</a>(<a id='8220' tid='8219', class="m">cmd</a>, <a id='8222' tid='8221', class="m">&quot;c&quot;</a>) <a id='8224' tid='8223', class="m">==</a> <a id='8226' tid='8225', class="m">0</a>) <a id='8228' tid='8227', class="m">||</a> (<a id='8230' tid='8229', class="m">strcmp</a>(<a id='8232' tid='8231', class="m">cmd</a>, <a id='8234' tid='8233', class="m">&quot;cont&quot;</a>) <a id='8236' tid='8235', class="m">==</a> <a id='8238' tid='8237', class="m">0</a>)) {
  2800. // Execute the one instruction we broke at with breakpoints disabled.
  2801. <a id='8240' tid='8239', class="m">sim_</a>-&gt;<a id='8242' tid='8241', class="m">InstructionDecode</a>(<a id='8244' tid='8243', class="m">reinterpret_cast</a>&lt;<a id='8246' tid='8245', class="m">Instruction</a><a id='8248' tid='8247', class="m">*</a>&gt;(<a id='8250' tid='8249', class="m">sim_</a>-&gt;<a id='8252' tid='8251', class="m">get_pc</a>()));
  2802. // Leave the debugger shell.
  2803. <a id='8254' tid='8253', class="m">done</a> <a id='8256' tid='8255', class="m">=</a> <a id='8258' tid='8257', class="m">true</a>;
  2804. } <a id='8260' tid='8259', class="m">else</a> <a id='8262' tid='8261', class="m">if</a> ((<a id='8264' tid='8263', class="m">strcmp</a>(<a id='8266' tid='8265', class="m">cmd</a>, <a id='8268' tid='8267', class="m">&quot;p&quot;</a>) <a id='8270' tid='8269', class="m">==</a> <a id='8272' tid='8271', class="m">0</a>) <a id='8274' tid='8273', class="m">||</a> (<a id='8276' tid='8275', class="m">strcmp</a>(<a id='8278' tid='8277', class="m">cmd</a>, <a id='8280' tid='8279', class="m">&quot;print&quot;</a>) <a id='8282' tid='8281', class="m">==</a> <a id='8284' tid='8283', class="m">0</a>)) {
  2805. <span class="i">if</span> <span class="i">(argc == 2 || (argc == 3 && strcmp(arg2, &quot;fp&quot;) == 0))</span> {
  2806. <span class="i">int32_t value;</span>
  2807. <span class="i">float svalue;</span>
  2808. <span class="i">double dvalue;</span>
  2809. <span class="i">if</span> (<a id='8286' tid='8285', class="m">strcmp</a>(<a id='8288' tid='8287', class="m">arg1</a>, <a id='8290' tid='8289', class="m">&quot;all&quot;</a>) <a id='8292' tid='8291', class="m">==</a> <a id='8294' tid='8293', class="m">0</a>) <span class="i">{
  2810. for (int i = 0; i &lt; kNumRegisters; i++) {
  2811. value = GetRegisterValue(i);
  2812. PrintF(&quot;%3s: 0x%08x %10d&quot;, Registers::Name(i), value, value);
  2813. if ((argc == 3 && strcmp(arg2, &quot;fp&quot;) == 0) &&
  2814. i &lt; 8 &&
  2815. (i % 2) == 0) {
  2816. dvalue = GetRegisterPairDoubleValue(i);
  2817. PrintF(&quot; (%f)\n&quot;, dvalue);
  2818. } else {
  2819. PrintF(&quot;\n&quot;);
  2820. }
  2821. }
  2822. for (int i = 0; i &lt; kNumVFPDoubleRegisters; i++) {
  2823. dvalue = GetVFPDoubleRegisterValue(i);
  2824. uint64_t as_words = BitCast&lt;uint64_t&gt;(dvalue);
  2825. PrintF(&quot;%3s: %f 0x%08x %08x\n&quot;,
  2826. VFPRegisters::Name(i, true),
  2827. dvalue,
  2828. static_cast&lt;uint32_t&gt;(as_words &gt;&gt; 32),
  2829. static_cast&lt;uint32_t&gt;(as_words & 0xffffffff));
  2830. }
  2831. }</span> <a id='8050' tid='8049', class="m">else</a> {
  2832. <span class="i">if</span> <span class="i">(GetValue(arg1, &value))</span> {
  2833. <a id='8052' tid='8051', class="m">PrintF</a>(<a id='8054' tid='8053', class="m">&quot;%s: 0x%08x %d \n&quot;</a>, <a id='8056' tid='8055', class="m">arg1</a>, <a id='8058' tid='8057', class="m">value</a>, <a id='8060' tid='8059', class="m">value</a>);
  2834. } <span class="i">else if (GetVFPSingleValue(arg1, &svalue)) {
  2835. uint32_t as_word = BitCast&lt;uint32_t&gt;(svalue);
  2836. PrintF(&quot;%s: %f 0x%08x\n&quot;, arg1, svalue, as_word);
  2837. } else if (GetVFPDoubleValue(arg1, &dvalue)) {
  2838. uint64_t as_words = BitCast&lt;uint64_t&gt;(dvalue);
  2839. PrintF(&quot;%s: %f 0x%08x %08x\n&quot;,
  2840. arg1,
  2841. dvalue,
  2842. static_cast&lt;uint32_t&gt;(as_words &gt;&gt; 32),
  2843. static_cast&lt;uint32_t&gt;(as_words & 0xffffffff));
  2844. } else {
  2845. PrintF(&quot;%s unrecognized\n&quot;, arg1);
  2846. }</span>
  2847. }
  2848. } <span class="i">else {
  2849. PrintF(&quot;print &lt;register&gt;\n&quot;);
  2850. }</span>
  2851. } <a id='8296' tid='8295', class="m">else</a> <a id='8298' tid='8297', class="m">if</a> ((<a id='8300' tid='8299', class="m">strcmp</a>(<a id='8302' tid='8301', class="m">cmd</a>, <a id='8304' tid='8303', class="m">&quot;po&quot;</a>) <a id='8306' tid='8305', class="m">==</a> <a id='8308' tid='8307', class="m">0</a>)
  2852. <a id='8310' tid='8309', class="m">||</a> (<a id='8312' tid='8311', class="m">strcmp</a>(<a id='8314' tid='8313', class="m">cmd</a>, <a id='8316' tid='8315', class="m">&quot;printobject&quot;</a>) <a id='8318' tid='8317', class="m">==</a> <a id='8320' tid='8319', class="m">0</a>)) {
  2853. <a id='8322' tid='8321', class="m">if</a> (<a id='8324' tid='8323', class="m">argc</a> <a id='8326' tid='8325', class="m">==</a> <a id='8328' tid='8327', class="m">2</a>) {
  2854. <a id='8330' tid='8329', class="m">int32_t</a> <a id='8332' tid='8331', class="m">value</a>;
  2855. <a id='8334' tid='8333', class="m">if</a> (<a id='8336' tid='8335', class="m">GetValue</a>(<a id='8338' tid='8337', class="m">arg1</a>, <a id='8340' tid='8339', class="m">&</a><a id='8342' tid='8341', class="m">value</a>)) {
  2856. <a id='8344' tid='8343', class="m">Object</a><a id='8346' tid='8345', class="m">*</a> <a id='8348' tid='8347', class="m">obj</a> = <a id='8350' tid='8349', class="m">reinterpret_cast</a>&lt;<a id='8352' tid='8351', class="m">Object</a><a id='8354' tid='8353', class="m">*</a>&gt;(<a id='8356' tid='8355', class="m">value</a>);
  2857. <a id='8358' tid='8357', class="m">PrintF</a>(<a id='8360' tid='8359', class="m">&quot;%s: \n&quot;</a>, <a id='8362' tid='8361', class="m">arg1</a>);
  2858. #<a id='8364' tid='8363', class="m">ifdef</a> <a id='8366' tid='8365', class="m">DEBUG</a>
  2859. <a id='8368' tid='8367', class="m">obj</a>-&gt;<a id='8370' tid='8369', class="m">PrintLn</a>();
  2860. #<a id='8372' tid='8371', class="m">else</a>
  2861. <a id='8374' tid='8373', class="m">obj</a>-&gt;<a id='8376' tid='8375', class="m">ShortPrint</a>();
  2862. <a id='8378' tid='8377', class="m">PrintF</a>(<a id='8380' tid='8379', class="m">&quot;\n&quot;</a>);
  2863. #<a id='8382' tid='8381', class="m">endif</a>
  2864. } <a id='8384' tid='8383', class="m">else</a> {
  2865. <a id='8386' tid='8385', class="m">PrintF</a>(<a id='8388' tid='8387', class="m">&quot;%s unrecognized\n&quot;</a>, <a id='8390' tid='8389', class="m">arg1</a>);
  2866. }
  2867. } <a id='8392' tid='8391', class="m">else</a> {
  2868. <a id='8394' tid='8393', class="m">PrintF</a>(<a id='8396' tid='8395', class="m">&quot;printobject &lt;value&gt;\n&quot;</a>);
  2869. }
  2870. } <a id='8398' tid='8397', class="m">else</a> <a id='8400' tid='8399', class="m">if</a> (<a id='8402' tid='8401', class="m">strcmp</a>(<a id='8404' tid='8403', class="m">cmd</a>, <a id='8406' tid='8405', class="m">&quot;stack&quot;</a>) <a id='8408' tid='8407', class="m">==</a> <a id='8410' tid='8409', class="m">0</a> <a id='8412' tid='8411', class="m">||</a> <a id='8414' tid='8413', class="m">strcmp</a>(<a id='8416' tid='8415', class="m">cmd</a>, <a id='8418' tid='8417', class="m">&quot;mem&quot;</a>) <a id='8420' tid='8419', class="m">==</a> <a id='8422' tid='8421', class="m">0</a>) {
  2871. <a id='8424' tid='8423', class="m">int32_t</a><a id='8426' tid='8425', class="m">*</a> <a id='8428' tid='8427', class="m">cur</a> = <a id='8430' tid='8429', class="m">NULL</a>;
  2872. <a id='8432' tid='8431', class="m">int32_t</a><a id='8434' tid='8433', class="m">*</a> <a id='8436' tid='8435', class="m">end</a> = <a id='8438' tid='8437', class="m">NULL</a>;
  2873. <a id='8440' tid='8439', class="m">int</a> <a id='8442' tid='8441', class="m">next_arg</a> = <a id='8444' tid='8443', class="m">1</a>;
  2874. <a id='8446' tid='8445', class="m">if</a> (<a id='8448' tid='8447', class="m">strcmp</a>(<a id='8450' tid='8449', class="m">cmd</a>, <a id='8452' tid='8451', class="m">&quot;stack&quot;</a>) <a id='8454' tid='8453', class="m">==</a> <a id='8456' tid='8455', class="m">0</a>) {
  2875. <a id='8458' tid='8457', class="m">cur</a> <a id='8460' tid='8459', class="m">=</a> <a id='8462' tid='8461', class="m">reinterpret_cast</a>&lt;<a id='8464' tid='8463', class="m">int32_t</a><a id='8466' tid='8465', class="m">*</a>&gt;(<a id='8468' tid='8467', class="m">sim_</a>-&gt;<a id='8470' tid='8469', class="m">get_register</a>(<a id='8472' tid='8471', class="m">Simulator</a><a id='8474' tid='8473', class="m">::</a><a id='8476' tid='8475', class="m">sp</a>));
  2876. } <a id='8478' tid='8477', class="m">else</a> { // &quot;mem&quot;
  2877. <a id='8480' tid='8479', class="m">int32_t</a> <a id='8482' tid='8481', class="m">value</a>;
  2878. <a id='8484' tid='8483', class="m">if</a> (<a id='8486' tid='8485', class="m">!</a><a id='8488' tid='8487', class="m">GetValue</a>(<a id='8490' tid='8489', class="m">arg1</a>, <a id='8492' tid='8491', class="m">&</a><a id='8494' tid='8493', class="m">value</a>)) {
  2879. <a id='8496' tid='8495', class="m">PrintF</a>(<a id='8498' tid='8497', class="m">&quot;%s unrecognized\n&quot;</a>, <a id='8500' tid='8499', class="m">arg1</a>);
  2880. <a id='8502' tid='8501', class="m">continue</a>;
  2881. }
  2882. <a id='8504' tid='8503', class="m">cur</a> <a id='8506' tid='8505', class="m">=</a> <a id='8508' tid='8507', class="m">reinterpret_cast</a>&lt;<a id='8510' tid='8509', class="m">int32_t</a><a id='8512' tid='8511', class="m">*</a>&gt;(<a id='8514' tid='8513', class="m">value</a>);
  2883. <a id='8516' tid='8515', class="m">next_arg</a><a id='8518' tid='8517', class="m">++</a>;
  2884. }
  2885. <a id='8520' tid='8519', class="m">int32_t</a> <a id='8522' tid='8521', class="m">words</a>;
  2886. <a id='8524' tid='8523', class="m">if</a> (<a id='8526' tid='8525', class="m">argc</a> <a id='8528' tid='8527', class="m">==</a> <a id='8530' tid='8529', class="m">next_arg</a>) {
  2887. <a id='8532' tid='8531', class="m">words</a> <a id='8534' tid='8533', class="m">=</a> <a id='8536' tid='8535', class="m">10</a>;
  2888. } <a id='8538' tid='8537', class="m">else</a> <a id='8540' tid='8539', class="m">if</a> (<a id='8542' tid='8541', class="m">argc</a> <a id='8544' tid='8543', class="m">==</a> <a id='8546' tid='8545', class="m">next_arg</a> <a id='8548' tid='8547', class="m">+</a> <a id='8550' tid='8549', class="m">1</a>) {
  2889. <a id='8552' tid='8551', class="m">if</a> (<a id='8554' tid='8553', class="m">!</a><a id='8556' tid='8555', class="m">GetValue</a>(<a id='8558' tid='8557', class="m">argv</a>[<a id='8560' tid='8559', class="m">next_arg</a>], <a id='8562' tid='8561', class="m">&</a><a id='8564' tid='8563', class="m">words</a>)) {
  2890. <a id='8566' tid='8565', class="m">words</a> <a id='8568' tid='8567', class="m">=</a> <a id='8570' tid='8569', class="m">10</a>;
  2891. }
  2892. }
  2893. <a id='8572' tid='8571', class="m">end</a> <a id='8574' tid='8573', class="m">=</a> <a id='8576' tid='8575', class="m">cur</a> <a id='8578' tid='8577', class="m">+</a> <a id='8580' tid='8579', class="m">words</a>;
  2894. <a id='8582' tid='8581', class="m">while</a> (<a id='8584' tid='8583', class="m">cur</a> <a id='8586' tid='8585', class="m">&lt;</a> <a id='8588' tid='8587', class="m">end</a>) {
  2895. <a id='8590' tid='8589', class="m">PrintF</a>(<a id='8592' tid='8591', class="m">&quot; 0x%08x: 0x%08x %10d&quot;</a>,
  2896. <a id='8594' tid='8593', class="m">reinterpret_cast</a>&lt;<a id='8596' tid='8595', class="m">intptr_t</a>&gt;(<a id='8598' tid='8597', class="m">cur</a>), <a id='8600' tid='8599', class="m">*</a><a id='8602' tid='8601', class="m">cur</a>, <a id='8604' tid='8603', class="m">*</a><a id='8606' tid='8605', class="m">cur</a>);
  2897. <a id='8608' tid='8607', class="m">HeapObject</a><a id='8610' tid='8609', class="m">*</a> <a id='8612' tid='8611', class="m">obj</a> = <a id='8614' tid='8613', class="m">reinterpret_cast</a>&lt;<a id='8616' tid='8615', class="m">HeapObject</a><a id='8618' tid='8617', class="m">*</a>&gt;(<a id='8620' tid='8619', class="m">*</a><a id='8622' tid='8621', class="m">cur</a>);
  2898. <a id='8624' tid='8623', class="m">int</a> <a id='8626' tid='8625', class="m">value</a> = <a id='8628' tid='8627', class="m">*</a><a id='8630' tid='8629', class="m">cur</a>;
  2899. <a id='8632' tid='8631', class="m">Heap</a><a id='8634' tid='8633', class="m">*</a> <a id='8636' tid='8635', class="m">current_heap</a> = <a id='8638' tid='8637', class="m">v8</a><a id='8640' tid='8639', class="m">::</a><a id='8642' tid='8641', class="m">internal</a><a id='8644' tid='8643', class="m">::</a><a id='8646' tid='8645', class="m">Isolate</a><a id='8648' tid='8647', class="m">::</a><a id='8650' tid='8649', class="m">Current</a>()-&gt;<a id='8652' tid='8651', class="m">heap</a>();
  2900. <a id='8654' tid='8653', class="m">if</a> (<a id='8656' tid='8655', class="m">current_heap</a>-&gt;<a id='8658' tid='8657', class="m">Contains</a>(<a id='8660' tid='8659', class="m">obj</a>) <a id='8662' tid='8661', class="m">||</a> ((<a id='8664' tid='8663', class="m">value</a> <a id='8666' tid='8665', class="m">&</a> <a id='8668' tid='8667', class="m">1</a>) <a id='8670' tid='8669', class="m">==</a> <a id='8672' tid='8671', class="m">0</a>)) {
  2901. <a id='8674' tid='8673', class="m">PrintF</a>(<a id='8676' tid='8675', class="m">&quot; (&quot;</a>);
  2902. <a id='8678' tid='8677', class="m">if</a> ((<a id='8680' tid='8679', class="m">value</a> <a id='8682' tid='8681', class="m">&</a> <a id='8684' tid='8683', class="m">1</a>) <a id='8686' tid='8685', class="m">==</a> <a id='8688' tid='8687', class="m">0</a>) {
  2903. <a id='8690' tid='8689', class="m">PrintF</a>(<a id='8692' tid='8691', class="m">&quot;smi %d&quot;</a>, <a id='8694' tid='8693', class="m">value</a> <a id='8696' tid='8695', class="m">/</a> <a id='8698' tid='8697', class="m">2</a>);
  2904. } <a id='8700' tid='8699', class="m">else</a> {
  2905. <a id='8702' tid='8701', class="m">obj</a>-&gt;<a id='8704' tid='8703', class="m">ShortPrint</a>();
  2906. }
  2907. <a id='8706' tid='8705', class="m">PrintF</a>(<a id='8708' tid='8707', class="m">&quot;)&quot;</a>);
  2908. }
  2909. <a id='8710' tid='8709', class="m">PrintF</a>(<a id='8712' tid='8711', class="m">&quot;\n&quot;</a>);
  2910. <a id='8714' tid='8713', class="m">cur</a><a id='8716' tid='8715', class="m">++</a>;
  2911. }
  2912. } <a id='8718' tid='8717', class="m">else</a> <a id='8720' tid='8719', class="m">if</a> (<a id='8722' tid='8721', class="m">strcmp</a>(<a id='8724' tid='8723', class="m">cmd</a>, <a id='8726' tid='8725', class="m">&quot;disasm&quot;</a>) <a id='8728' tid='8727', class="m">==</a> <a id='8730' tid='8729', class="m">0</a> <a id='8732' tid='8731', class="m">||</a> <a id='8734' tid='8733', class="m">strcmp</a>(<a id='8736' tid='8735', class="m">cmd</a>, <a id='8738' tid='8737', class="m">&quot;di&quot;</a>) <a id='8740' tid='8739', class="m">==</a> <a id='8742' tid='8741', class="m">0</a>) {
  2913. <span class="i">disasm::NameConverter converter;</span>
  2914. <a id='8744' tid='8743', class="m">disasm</a><a id='8746' tid='8745', class="m">::</a><a id='8748' tid='8747', class="m">Disassembler</a> <a id='8750' tid='8749', class="m">dasm</a>(<a id='8752' tid='8751', class="m">converter</a>);
  2915. // use a reasonably large buffer
  2916. <a id='8062' tid='8061', class="m">v8</a><a id='8064' tid='8063', class="m">::</a><a id='8066' tid='8065', class="m">internal</a><a id='8068' tid='8067', class="m">::</a><a id='8070' tid='8069', class="m">EmbeddedVector</a>&lt;<a id='8072' tid='8071', class="m">char</a>, <a id='8074' tid='8073', class="m">256</a>&gt; <a id='8076' tid='8075', class="m">buffer</a>;
  2917. <span class="i">byte* prev = NULL;</span>
  2918. <span class="i">byte* cur = NULL;</span>
  2919. <span class="i">byte* end = NULL;</span>
  2920. <a id='7546' tid='7545', class="m">if</a> (<a id='7548' tid='7547', class="m">argc</a> <a id='7550' tid='7549', class="m">==</a> <a id='7552' tid='7551', class="m">1</a>) {
  2921. <a id='7554' tid='7553', class="m">cur</a> <a id='7556' tid='7555', class="m">=</a> <a id='7558' tid='7557', class="m">reinterpret_cast</a>&lt;<a id='7560' tid='7559', class="m">byte</a><a id='7562' tid='7561', class="m">*</a>&gt;(<a id='7564' tid='7563', class="m">sim_</a>-&gt;<a id='7566' tid='7565', class="m">get_pc</a>());
  2922. <a id='7568' tid='7567', class="m">end</a> <a id='7570' tid='7569', class="m">=</a> <a id='7572' tid='7571', class="m">cur</a> <a id='7574' tid='7573', class="m">+</a> (<a id='7576' tid='7575', class="m">10</a> <a id='7578' tid='7577', class="m">*</a> <a id='7580' tid='7579', class="m">Instruction</a><a id='7582' tid='7581', class="m">::</a><a id='7584' tid='7583', class="m">kInstrSize</a>);
  2923. } <a id='7586' tid='7585', class="m">else</a> <a id='7588' tid='7587', class="m">if</a> (<a id='7590' tid='7589', class="m">argc</a> <a id='7592' tid='7591', class="m">==</a> <a id='7594' tid='7593', class="m">2</a>) {
  2924. <a id='7596' tid='7595', class="m">int</a> <a id='7598' tid='7597', class="m">regnum</a> = <a id='7600' tid='7599', class="m">Registers</a><a id='7602' tid='7601', class="m">::</a><a id='7604' tid='7603', class="m">Number</a>(<a id='7606' tid='7605', class="m">arg1</a>);
  2925. <a id='7608' tid='7607', class="m">if</a> (<span class="i">regnum != kNoRegister</span> <span class="i">||</span> <a id='7610' tid='7609', class="m">strncmp</a>(<a id='7612' tid='7611', class="m">arg1</a>, <a id='7614' tid='7613', class="m">&quot;0x&quot;</a>, <a id='7616' tid='7615', class="m">2</a>) <a id='7618' tid='7617', class="m">==</a> <a id='7620' tid='7619', class="m">0</a>) {
  2926. // The argument is an address or a register name.
  2927. <a id='7622' tid='7621', class="m">int32_t</a> <a id='7624' tid='7623', class="m">value</a>;
  2928. <a id='7626' tid='7625', class="m">if</a> (<a id='7628' tid='7627', class="m">GetValue</a>(<a id='7630' tid='7629', class="m">arg1</a>, <a id='7632' tid='7631', class="m">&</a><a id='7634' tid='7633', class="m">value</a>)) {
  2929. <a id='7636' tid='7635', class="m">cur</a> <a id='7638' tid='7637', class="m">=</a> <a id='7640' tid='7639', class="m">reinterpret_cast</a>&lt;<a id='7642' tid='7641', class="m">byte</a><a id='7644' tid='7643', class="m">*</a>&gt;(<a id='7646' tid='7645', class="m">value</a>);
  2930. // Disassemble 10 instructions at &lt;arg1&gt;.
  2931. <a id='7648' tid='7647', class="m">end</a> <a id='7650' tid='7649', class="m">=</a> <a id='7652' tid='7651', class="m">cur</a> <a id='7654' tid='7653', class="m">+</a> (<a id='7656' tid='7655', class="m">10</a> <a id='7658' tid='7657', class="m">*</a> <a id='7660' tid='7659', class="m">Instruction</a><a id='7662' tid='7661', class="m">::</a><a id='7664' tid='7663', class="m">kInstrSize</a>);
  2932. }
  2933. } <a id='7666' tid='7665', class="m">else</a> {
  2934. // The argument is the number of instructions.
  2935. <a id='7668' tid='7667', class="m">int32_t</a> <a id='7670' tid='7669', class="m">value</a>;
  2936. <a id='7672' tid='7671', class="m">if</a> (<a id='7674' tid='7673', class="m">GetValue</a>(<a id='7676' tid='7675', class="m">arg1</a>, <a id='7678' tid='7677', class="m">&</a><a id='7680' tid='7679', class="m">value</a>)) {
  2937. <a id='7682' tid='7681', class="m">cur</a> <a id='7684' tid='7683', class="m">=</a> <a id='7686' tid='7685', class="m">reinterpret_cast</a>&lt;<a id='7688' tid='7687', class="m">byte</a><a id='7690' tid='7689', class="m">*</a>&gt;(<a id='7692' tid='7691', class="m">sim_</a>-&gt;<a id='7694' tid='7693', class="m">get_pc</a>());
  2938. // Disassemble &lt;arg1&gt; instructions.
  2939. <a id='7696' tid='7695', class="m">end</a> <a id='7698' tid='7697', class="m">=</a> <a id='7700' tid='7699', class="m">cur</a> <a id='7702' tid='7701', class="m">+</a> (<a id='7704' tid='7703', class="m">value</a> <a id='7706' tid='7705', class="m">*</a> <a id='7708' tid='7707', class="m">Instruction</a><a id='7710' tid='7709', class="m">::</a><a id='7712' tid='7711', class="m">kInstrSize</a>);
  2940. }
  2941. }
  2942. } <a id='7714' tid='7713', class="m">else</a> {
  2943. <a id='7716' tid='7715', class="m">int32_t</a> <a id='7718' tid='7717', class="m">value1</a>;
  2944. <a id='7720' tid='7719', class="m">int32_t</a> <a id='7722' tid='7721', class="m">value2</a>;
  2945. <a id='7724' tid='7723', class="m">if</a> (<a id='7726' tid='7725', class="m">GetValue</a>(<a id='7728' tid='7727', class="m">arg1</a>, <a id='7730' tid='7729', class="m">&</a><a id='7732' tid='7731', class="m">value1</a>) <a id='7734' tid='7733', class="m">&&</a> <a id='7736' tid='7735', class="m">GetValue</a>(<a id='7738' tid='7737', class="m">arg2</a>, <a id='7740' tid='7739', class="m">&</a><a id='7742' tid='7741', class="m">value2</a>)) {
  2946. <a id='7744' tid='7743', class="m">cur</a> <a id='7746' tid='7745', class="m">=</a> <a id='7748' tid='7747', class="m">reinterpret_cast</a>&lt;<a id='7750' tid='7749', class="m">byte</a><a id='7752' tid='7751', class="m">*</a>&gt;(<a id='7754' tid='7753', class="m">value1</a>);
  2947. <a id='7756' tid='7755', class="m">end</a> <a id='7758' tid='7757', class="m">=</a> <a id='7760' tid='7759', class="m">cur</a> <a id='7762' tid='7761', class="m">+</a> (<a id='7764' tid='7763', class="m">value2</a> <a id='7766' tid='7765', class="m">*</a> <a id='7768' tid='7767', class="m">Instruction</a><a id='7770' tid='7769', class="m">::</a><a id='7772' tid='7771', class="m">kInstrSize</a>);
  2948. }
  2949. }
  2950. <span class="i">while (cur &lt; end) {
  2951. prev = cur;
  2952. cur += dasm.InstructionDecode(buffer, cur);
  2953. PrintF(&quot; 0x%08x %s\n&quot;,
  2954. reinterpret_cast&lt;intptr_t&gt;(prev), buffer.start());
  2955. }</span>
  2956. } <a id='8754' tid='8753', class="m">else</a> <a id='8756' tid='8755', class="m">if</a> (<a id='8758' tid='8757', class="m">strcmp</a>(<a id='8760' tid='8759', class="m">cmd</a>, <a id='8762' tid='8761', class="m">&quot;gdb&quot;</a>) <a id='8764' tid='8763', class="m">==</a> <a id='8766' tid='8765', class="m">0</a>) {
  2957. <a id='8768' tid='8767', class="m">PrintF</a>(<a id='8770' tid='8769', class="m">&quot;relinquishing control to gdb\n&quot;</a>);
  2958. <a id='8772' tid='8771', class="m">v8</a><a id='8774' tid='8773', class="m">::</a><a id='8776' tid='8775', class="m">internal</a><a id='8778' tid='8777', class="m">::</a><a id='8780' tid='8779', class="m">OS</a><a id='8782' tid='8781', class="m">::</a><a id='8784' tid='8783', class="m">DebugBreak</a>();
  2959. <a id='8786' tid='8785', class="m">PrintF</a>(<a id='8788' tid='8787', class="m">&quot;regaining control from gdb\n&quot;</a>);
  2960. } <a id='8790' tid='8789', class="m">else</a> <a id='8792' tid='8791', class="m">if</a> (<a id='8794' tid='8793', class="m">strcmp</a>(<a id='8796' tid='8795', class="m">cmd</a>, <a id='8798' tid='8797', class="m">&quot;break&quot;</a>) <a id='8800' tid='8799', class="m">==</a> <a id='8802' tid='8801', class="m">0</a>) {
  2961. <a id='8804' tid='8803', class="m">if</a> (<a id='8806' tid='8805', class="m">argc</a> <a id='8808' tid='8807', class="m">==</a> <a id='8810' tid='8809', class="m">2</a>) {
  2962. <a id='8812' tid='8811', class="m">int32_t</a> <a id='8814' tid='8813', class="m">value</a>;
  2963. <a id='8816' tid='8815', class="m">if</a> (<a id='8818' tid='8817', class="m">GetValue</a>(<a id='8820' tid='8819', class="m">arg1</a>, <a id='8822' tid='8821', class="m">&</a><a id='8824' tid='8823', class="m">value</a>)) {
  2964. <a id='8826' tid='8825', class="m">if</a> (<a id='8828' tid='8827', class="m">!</a><a id='8830' tid='8829', class="m">SetBreakpoint</a>(<a id='8832' tid='8831', class="m">reinterpret_cast</a>&lt;<a id='8834' tid='8833', class="m">Instruction</a><a id='8836' tid='8835', class="m">*</a>&gt;(<a id='8838' tid='8837', class="m">value</a>))) {
  2965. <a id='8840' tid='8839', class="m">PrintF</a>(<a id='8842' tid='8841', class="m">&quot;setting breakpoint failed\n&quot;</a>);
  2966. }
  2967. } <a id='8844' tid='8843', class="m">else</a> {
  2968. <a id='8846' tid='8845', class="m">PrintF</a>(<a id='8848' tid='8847', class="m">&quot;%s unrecognized\n&quot;</a>, <a id='8850' tid='8849', class="m">arg1</a>);
  2969. }
  2970. } <a id='8852' tid='8851', class="m">else</a> {
  2971. <a id='8854' tid='8853', class="m">PrintF</a>(<a id='8856' tid='8855', class="m">&quot;break &lt;address&gt;\n&quot;</a>);
  2972. }
  2973. } <a id='8858' tid='8857', class="m">else</a> <a id='8860' tid='8859', class="m">if</a> (<a id='8862' tid='8861', class="m">strcmp</a>(<a id='8864' tid='8863', class="m">cmd</a>, <a id='8866' tid='8865', class="m">&quot;del&quot;</a>) <a id='8868' tid='8867', class="m">==</a> <a id='8870' tid='8869', class="m">0</a>) {
  2974. <a id='8872' tid='8871', class="m">if</a> (<a id='8874' tid='8873', class="m">!</a><a id='8876' tid='8875', class="m">DeleteBreakpoint</a>(<a id='8878' tid='8877', class="m">NULL</a>)) {
  2975. <a id='8880' tid='8879', class="m">PrintF</a>(<a id='8882' tid='8881', class="m">&quot;deleting breakpoint failed\n&quot;</a>);
  2976. }
  2977. } <a id='8884' tid='8883', class="m">else</a> <span class="i">if</span> (<a id='8886' tid='8885', class="m">strcmp</a>(<a id='8888' tid='8887', class="m">cmd</a>, <a id='8890' tid='8889', class="m">&quot;flags&quot;</a>) <a id='8892' tid='8891', class="m">==</a> <a id='8894' tid='8893', class="m">0</a>) <span class="i">{
  2978. PrintF(&quot;N flag: %d; &quot;, sim_-&gt;n_flag_);
  2979. PrintF(&quot;Z flag: %d; &quot;, sim_-&gt;z_flag_);
  2980. PrintF(&quot;C flag: %d; &quot;, sim_-&gt;c_flag_);
  2981. PrintF(&quot;V flag: %d\n&quot;, sim_-&gt;v_flag_);
  2982. PrintF(&quot;INVALID OP flag: %d; &quot;, sim_-&gt;inv_op_vfp_flag_);
  2983. PrintF(&quot;DIV BY ZERO flag: %d; &quot;, sim_-&gt;div_zero_vfp_flag_);
  2984. PrintF(&quot;OVERFLOW flag: %d; &quot;, sim_-&gt;overflow_vfp_flag_);
  2985. PrintF(&quot;UNDERFLOW flag: %d; &quot;, sim_-&gt;underflow_vfp_flag_);
  2986. PrintF(&quot;INEXACT flag: %d;\n&quot;, sim_-&gt;inexact_vfp_flag_);
  2987. }</span> <span class="i">else</span> <a id='7774' tid='7773', class="m">if</a> (<a id='8078' tid='8077', class="m">strcmp</a>(<a id='8080' tid='8079', class="m">cmd</a>, <a id='8082' tid='8081', class="m">&quot;stop&quot;</a>) <a id='8084' tid='8083', class="m">==</a> <a id='8086' tid='8085', class="m">0</a>) {
  2988. <a id='7776' tid='7775', class="m">int32_t</a> <a id='7778' tid='7777', class="m">value</a>;
  2989. <a id='7780' tid='7779', class="m">intptr_t</a> <a id='7782' tid='7781', class="m">stop_pc</a> = <a id='7784' tid='7783', class="m">sim_</a>-&gt;<a id='7786' tid='7785', class="m">get_pc</a>() <a id='7788' tid='7787', class="m">-</a> <a id='7790' tid='7789', class="m">2</a> <a id='7792' tid='7791', class="m">*</a> <a id='7794' tid='7793', class="m">Instruction</a><a id='7796' tid='7795', class="m">::</a><a id='7798' tid='7797', class="m">kInstrSize</a>;
  2990. <a id='7800' tid='7799', class="m">Instruction</a><a id='7802' tid='7801', class="m">*</a> <a id='7804' tid='7803', class="m">stop_instr</a> = <a id='7806' tid='7805', class="m">reinterpret_cast</a>&lt;<a id='7808' tid='7807', class="m">Instruction</a><a id='7810' tid='7809', class="m">*</a>&gt;(<a id='7812' tid='7811', class="m">stop_pc</a>);
  2991. <a id='7814' tid='7813', class="m">Instruction</a><a id='7816' tid='7815', class="m">*</a> <a id='7818' tid='7817', class="m">msg_address</a> =
  2992. <a id='7820' tid='7819', class="m">reinterpret_cast</a>&lt;<a id='7822' tid='7821', class="m">Instruction</a><a id='7824' tid='7823', class="m">*</a>&gt;(<a id='7826' tid='7825', class="m">stop_pc</a> <a id='7828' tid='7827', class="m">+</a> <a id='7830' tid='7829', class="m">Instruction</a><a id='7832' tid='7831', class="m">::</a><a id='7834' tid='7833', class="m">kInstrSize</a>);
  2993. <a id='7836' tid='7835', class="m">if</a> ((<a id='7838' tid='7837', class="m">argc</a> <a id='7840' tid='7839', class="m">==</a> <a id='7842' tid='7841', class="m">2</a>) <a id='7844' tid='7843', class="m">&&</a> (<a id='7846' tid='7845', class="m">strcmp</a>(<a id='7848' tid='7847', class="m">arg1</a>, <a id='7850' tid='7849', class="m">&quot;unstop&quot;</a>) <a id='7852' tid='7851', class="m">==</a> <a id='7854' tid='7853', class="m">0</a>)) {
  2994. // Remove the current stop.
  2995. <span class="i">if</span> <span class="i">(sim_-&gt;isStopInstruction(stop_instr))</span> {
  2996. <a id='7856' tid='7855', class="m">stop_instr</a>-&gt;<a id='7858' tid='7857', class="m">SetInstructionBits</a>(<a id='7860' tid='7859', class="m">kNopInstr</a>);
  2997. <a id='7862' tid='7861', class="m">msg_address</a>-&gt;<a id='7864' tid='7863', class="m">SetInstructionBits</a>(<a id='7866' tid='7865', class="m">kNopInstr</a>);
  2998. } <span class="i">else {
  2999. PrintF(&quot;Not at debugger stop.\n&quot;);
  3000. }</span>
  3001. } <a id='7868' tid='7867', class="m">else</a> <a id='7870' tid='7869', class="m">if</a> (<a id='7872' tid='7871', class="m">argc</a> <a id='7874' tid='7873', class="m">==</a> <a id='7876' tid='7875', class="m">3</a>) {
  3002. // Print information about all/the specified breakpoint(s).
  3003. <a id='7878' tid='7877', class="m">if</a> (<a id='7880' tid='7879', class="m">strcmp</a>(<a id='7882' tid='7881', class="m">arg1</a>, <a id='7884' tid='7883', class="m">&quot;info&quot;</a>) <a id='7886' tid='7885', class="m">==</a> <a id='7888' tid='7887', class="m">0</a>) {
  3004. <span class="i">if</span> (<a id='7890' tid='7889', class="m">strcmp</a>(<a id='7892' tid='7891', class="m">arg2</a>, <a id='7894' tid='7893', class="m">&quot;all&quot;</a>) <a id='7896' tid='7895', class="m">==</a> <a id='7898' tid='7897', class="m">0</a>) <span class="i">{
  3005. PrintF(&quot;Stop information:\n&quot;);
  3006. for (uint32_t i = 0; i &lt; sim_-&gt;kNumOfWatchedStops; i++) {
  3007. sim_-&gt;PrintStopInfo(i);
  3008. }
  3009. }</span> <a id='7286' tid='7285', class="m">else</a> <a id='7288' tid='7287', class="m">if</a> (<a id='7290' tid='7289', class="m">GetValue</a>(<a id='7292' tid='7291', class="m">arg2</a>, <a id='7294' tid='7293', class="m">&</a><a id='7296' tid='7295', class="m">value</a>)) {
  3010. <a id='7298' tid='7297', class="m">sim_</a>-&gt;<a id='7300' tid='7299', class="m">PrintStopInfo</a>(<a id='7302' tid='7301', class="m">value</a>);
  3011. } <a id='7304' tid='7303', class="m">else</a> {
  3012. <a id='7306' tid='7305', class="m">PrintF</a>(<a id='7308' tid='7307', class="m">&quot;Unrecognized argument.\n&quot;</a>);
  3013. }
  3014. } <a id='7900' tid='7899', class="m">else</a> <a id='7902' tid='7901', class="m">if</a> (<a id='7904' tid='7903', class="m">strcmp</a>(<a id='7906' tid='7905', class="m">arg1</a>, <a id='7908' tid='7907', class="m">&quot;enable&quot;</a>) <a id='7910' tid='7909', class="m">==</a> <a id='7912' tid='7911', class="m">0</a>) {
  3015. // Enable all/the specified breakpoint(s).
  3016. <span class="i">if</span> (<a id='7914' tid='7913', class="m">strcmp</a>(<a id='7916' tid='7915', class="m">arg2</a>, <a id='7918' tid='7917', class="m">&quot;all&quot;</a>) <a id='7920' tid='7919', class="m">==</a> <a id='7922' tid='7921', class="m">0</a>) <span class="i">{
  3017. for (uint32_t i = 0; i &lt; sim_-&gt;kNumOfWatchedStops; i++) {
  3018. sim_-&gt;EnableStop(i);
  3019. }
  3020. }</span> <a id='7310' tid='7309', class="m">else</a> <a id='7312' tid='7311', class="m">if</a> (<a id='7314' tid='7313', class="m">GetValue</a>(<a id='7316' tid='7315', class="m">arg2</a>, <a id='7318' tid='7317', class="m">&</a><a id='7320' tid='7319', class="m">value</a>)) {
  3021. <a id='7322' tid='7321', class="m">sim_</a>-&gt;<a id='7324' tid='7323', class="m">EnableStop</a>(<a id='7326' tid='7325', class="m">value</a>);
  3022. } <a id='7328' tid='7327', class="m">else</a> {
  3023. <a id='7330' tid='7329', class="m">PrintF</a>(<a id='7332' tid='7331', class="m">&quot;Unrecognized argument.\n&quot;</a>);
  3024. }
  3025. } <a id='7924' tid='7923', class="m">else</a> <a id='7926' tid='7925', class="m">if</a> (<a id='7928' tid='7927', class="m">strcmp</a>(<a id='7930' tid='7929', class="m">arg1</a>, <a id='7932' tid='7931', class="m">&quot;disable&quot;</a>) <a id='7934' tid='7933', class="m">==</a> <a id='7936' tid='7935', class="m">0</a>) {
  3026. // Disable all/the specified breakpoint(s).
  3027. <span class="i">if</span> (<a id='7938' tid='7937', class="m">strcmp</a>(<a id='7940' tid='7939', class="m">arg2</a>, <a id='7942' tid='7941', class="m">&quot;all&quot;</a>) <a id='7944' tid='7943', class="m">==</a> <a id='7946' tid='7945', class="m">0</a>) <span class="i">{
  3028. for (uint32_t i = 0; i &lt; sim_-&gt;kNumOfWatchedStops; i++) {
  3029. sim_-&gt;DisableStop(i);
  3030. }
  3031. }</span> <a id='7334' tid='7333', class="m">else</a> <a id='7336' tid='7335', class="m">if</a> (<a id='7338' tid='7337', class="m">GetValue</a>(<a id='7340' tid='7339', class="m">arg2</a>, <a id='7342' tid='7341', class="m">&</a><a id='7344' tid='7343', class="m">value</a>)) {
  3032. <a id='7346' tid='7345', class="m">sim_</a>-&gt;<a id='7348' tid='7347', class="m">DisableStop</a>(<a id='7350' tid='7349', class="m">value</a>);
  3033. } <a id='7352' tid='7351', class="m">else</a> {
  3034. <a id='7354' tid='7353', class="m">PrintF</a>(<a id='7356' tid='7355', class="m">&quot;Unrecognized argument.\n&quot;</a>);
  3035. }
  3036. }
  3037. } <a id='7948' tid='7947', class="m">else</a> {
  3038. <a id='7950' tid='7949', class="m">PrintF</a>(<a id='7952' tid='7951', class="m">&quot;Wrong usage. Use help command for more information.\n&quot;</a>);
  3039. }
  3040. } <a id='7954' tid='7953', class="m">else</a> <span class="i">if</span> <span class="i">((strcmp(cmd, &quot;t&quot;) == 0) || strcmp(cmd, &quot;trace&quot;) == 0)</span> <span class="i">{
  3041. ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
  3042. PrintF(&quot;Trace of executed instructions is %s\n&quot;,
  3043. ::v8::internal::FLAG_trace_sim ? &quot;on&quot; : &quot;off&quot;);
  3044. }</span> <a id='7956' tid='7955', class="m">else</a> <span class="i">if</span> ((<a id='7958' tid='7957', class="m">strcmp</a>(<a id='7960' tid='7959', class="m">cmd</a>, <a id='7962' tid='7961', class="m">&quot;h&quot;</a>) <a id='7964' tid='7963', class="m">==</a> <a id='7966' tid='7965', class="m">0</a>) <a id='7968' tid='7967', class="m">||</a> (<a id='7970' tid='7969', class="m">strcmp</a>(<a id='7972' tid='7971', class="m">cmd</a>, <a id='7974' tid='7973', class="m">&quot;help&quot;</a>) <a id='7976' tid='7975', class="m">==</a> <a id='7978' tid='7977', class="m">0</a>)) <span class="i">{
  3045. PrintF(&quot;cont\n&quot;);
  3046. PrintF(&quot; continue execution (alias &#39;c&#39;)\n&quot;);
  3047. PrintF(&quot;stepi\n&quot;);
  3048. PrintF(&quot; step one instruction (alias &#39;si&#39;)\n&quot;);
  3049. PrintF(&quot;print &lt;register&gt;\n&quot;);
  3050. PrintF(&quot; print register content (alias &#39;p&#39;)\n&quot;);
  3051. PrintF(&quot; use register name &#39;all&#39; to print all registers\n&quot;);
  3052. PrintF(&quot; add argument &#39;fp&#39; to print register pair double values\n&quot;);
  3053. PrintF(&quot;printobject &lt;register&gt;\n&quot;);
  3054. PrintF(&quot; print an object from a register (alias &#39;po&#39;)\n&quot;);
  3055. PrintF(&quot;flags\n&quot;);
  3056. PrintF(&quot; print flags\n&quot;);
  3057. PrintF(&quot;stack [&lt;words&gt;]\n&quot;);
  3058. PrintF(&quot; dump stack content, default dump 10 words)\n&quot;);
  3059. PrintF(&quot;mem &lt;address&gt; [&lt;words&gt;]\n&quot;);
  3060. PrintF(&quot; dump memory content, default dump 10 words)\n&quot;);
  3061. PrintF(&quot;disasm [&lt;instructions&gt;]\n&quot;);
  3062. PrintF(&quot;disasm [&lt;address/register&gt;]\n&quot;);
  3063. PrintF(&quot;disasm [[&lt;address/register&gt;] &lt;instructions&gt;]\n&quot;);
  3064. PrintF(&quot; disassemble code, default is 10 instructions\n&quot;);
  3065. PrintF(&quot; from pc (alias &#39;di&#39;)\n&quot;);
  3066. PrintF(&quot;gdb\n&quot;);
  3067. PrintF(&quot; enter gdb\n&quot;);
  3068. PrintF(&quot;break &lt;address&gt;\n&quot;);
  3069. PrintF(&quot; set a break point on the address\n&quot;);
  3070. PrintF(&quot;del\n&quot;);
  3071. PrintF(&quot; delete the breakpoint\n&quot;);
  3072. PrintF(&quot;trace (alias &#39;t&#39;)\n&quot;);
  3073. PrintF(&quot; toogle the tracing of all executed statements\n&quot;);
  3074. PrintF(&quot;stop feature:\n&quot;);
  3075. PrintF(&quot; Description:\n&quot;);
  3076. PrintF(&quot; Stops are debug instructions inserted by\n&quot;);
  3077. PrintF(&quot; the Assembler::stop() function.\n&quot;);
  3078. PrintF(&quot; When hitting a stop, the Simulator will\n&quot;);
  3079. PrintF(&quot; stop and and give control to the ArmDebugger.\n&quot;);
  3080. PrintF(&quot; The first %d stop codes are watched:\n&quot;,
  3081. Simulator::kNumOfWatchedStops);
  3082. PrintF(&quot; - They can be enabled / disabled: the Simulator\n&quot;);
  3083. PrintF(&quot; will / won&#39;t stop when hitting them.\n&quot;);
  3084. PrintF(&quot; - The Simulator keeps track of how many times they \n&quot;);
  3085. PrintF(&quot; are met. (See the info command.) Going over a\n&quot;);
  3086. PrintF(&quot; disabled stop still increases its counter. \n&quot;);
  3087. PrintF(&quot; Commands:\n&quot;);
  3088. PrintF(&quot; stop info all/&lt;code&gt; : print infos about number &lt;code&gt;\n&quot;);
  3089. PrintF(&quot; or all stop(s).\n&quot;);
  3090. PrintF(&quot; stop enable/disable all/&lt;code&gt; : enables / disables\n&quot;);
  3091. PrintF(&quot; all or number &lt;code&gt; stop(s)\n&quot;);
  3092. PrintF(&quot; stop unstop\n&quot;);
  3093. PrintF(&quot; ignore the stop instruction at the current location\n&quot;);
  3094. PrintF(&quot; from now on\n&quot;);
  3095. }</span> <span class="i">else {
  3096. PrintF(&quot;Unknown command: %s\n&quot;, cmd);
  3097. }</span>
  3098. }
  3099. <a id='8896' tid='8895', class="m">DeleteArray</a>(<a id='8898' tid='8897', class="m">line</a>);
  3100. }
  3101. // Add all the breakpoints back to stop execution and enter the debugger
  3102. // shell when hit.
  3103. <a id='9160' tid='9159', class="m">RedoBreakpoints</a>();
  3104. #<a id='9162' tid='9161', class="m">undef</a> <a id='9164' tid='9163', class="m">COMMAND_SIZE</a>
  3105. #<a id='9166' tid='9165', class="m">undef</a> <a id='9168' tid='9167', class="m">ARG_SIZE</a>
  3106. #<a id='9170' tid='9169', class="m">undef</a> <a id='9172' tid='9171', class="m">STR</a>
  3107. #<a id='9174' tid='9173', class="m">undef</a> <a id='9176' tid='9175', class="m">XSTR</a>
  3108. }
  3109. <a id='8900' tid='8899', class="m">static</a> <a id='8902' tid='8901', class="m">bool</a> <a id='8904' tid='8903', class="m">ICacheMatch</a>(<a id='8906' tid='8905', class="m">void</a><a id='8908' tid='8907', class="m">*</a> <a id='8910' tid='8909', class="m">one</a>, <a id='8912' tid='8911', class="m">void</a><a id='8914' tid='8913', class="m">*</a> <a id='8916' tid='8915', class="m">two</a>) {
  3110. <a id='8918' tid='8917', class="m">ASSERT</a>((<a id='8920' tid='8919', class="m">reinterpret_cast</a>&lt;<a id='8922' tid='8921', class="m">intptr_t</a>&gt;(<a id='8924' tid='8923', class="m">one</a>) <a id='8926' tid='8925', class="m">&</a> <a id='8928' tid='8927', class="m">CachePage</a><a id='8930' tid='8929', class="m">::</a><a id='8932' tid='8931', class="m">kPageMask</a>) <a id='8934' tid='8933', class="m">==</a> <a id='8936' tid='8935', class="m">0</a>);
  3111. <a id='8938' tid='8937', class="m">ASSERT</a>((<a id='8940' tid='8939', class="m">reinterpret_cast</a>&lt;<a id='8942' tid='8941', class="m">intptr_t</a>&gt;(<a id='8944' tid='8943', class="m">two</a>) <a id='8946' tid='8945', class="m">&</a> <a id='8948' tid='8947', class="m">CachePage</a><a id='8950' tid='8949', class="m">::</a><a id='8952' tid='8951', class="m">kPageMask</a>) <a id='8954' tid='8953', class="m">==</a> <a id='8956' tid='8955', class="m">0</a>);
  3112. <a id='8958' tid='8957', class="m">return</a> <a id='8960' tid='8959', class="m">one</a> <a id='8962' tid='8961', class="m">==</a> <a id='8964' tid='8963', class="m">two</a>;
  3113. }
  3114. <a id='8088' tid='8087', class="m">static</a> <a id='8090' tid='8089', class="m">uint32_t</a> <a id='8092' tid='8091', class="m">ICacheHash</a>(<a id='8094' tid='8093', class="m">void</a><a id='8096' tid='8095', class="m">*</a> <a id='8098' tid='8097', class="m">key</a>) {
  3115. <a id='8100' tid='8099', class="m">return</a> <a id='8102' tid='8101', class="m">static_cast</a>&lt;<a id='8104' tid='8103', class="m">uint32_t</a>&gt;(<a id='8106' tid='8105', class="m">reinterpret_cast</a>&lt;<a id='8108' tid='8107', class="m">uintptr_t</a>&gt;(<a id='8110' tid='8109', class="m">key</a>)) <a id='8112' tid='8111', class="m">&gt;&gt;</a> <a id='8114' tid='8113', class="m">2</a>;
  3116. }
  3117. <a id='7980' tid='7979', class="m">static</a> <a id='7982' tid='7981', class="m">bool</a> <a id='7984' tid='7983', class="m">AllOnOnePage</a>(<a id='7986' tid='7985', class="m">uintptr_t</a> <a id='7988' tid='7987', class="m">start</a>, <a id='7990' tid='7989', class="m">int</a> <a id='7992' tid='7991', class="m">size</a>) {
  3118. <a id='7994' tid='7993', class="m">intptr_t</a> <a id='7996' tid='7995', class="m">start_page</a> = (<a id='7998' tid='7997', class="m">start</a> <a id='8000' tid='7999', class="m">&</a> <a id='8002' tid='8001', class="m">~</a><a id='8004' tid='8003', class="m">CachePage</a><a id='8006' tid='8005', class="m">::</a><a id='8008' tid='8007', class="m">kPageMask</a>);
  3119. <a id='8010' tid='8009', class="m">intptr_t</a> <a id='8012' tid='8011', class="m">end_page</a> = ((<a id='8014' tid='8013', class="m">start</a> <a id='8016' tid='8015', class="m">+</a> <a id='8018' tid='8017', class="m">size</a>) <a id='8020' tid='8019', class="m">&</a> <a id='8022' tid='8021', class="m">~</a><a id='8024' tid='8023', class="m">CachePage</a><a id='8026' tid='8025', class="m">::</a><a id='8028' tid='8027', class="m">kPageMask</a>);
  3120. <a id='8030' tid='8029', class="m">return</a> <a id='8032' tid='8031', class="m">start_page</a> <a id='8034' tid='8033', class="m">==</a> <a id='8036' tid='8035', class="m">end_page</a>;
  3121. }
  3122. <a id='7358' tid='7357', class="m">void</a> <a id='7360' tid='7359', class="m">Simulator</a><a id='7362' tid='7361', class="m">::</a><a id='7364' tid='7363', class="m">FlushICache</a>(<a id='7366' tid='7365', class="m">v8</a><a id='7368' tid='7367', class="m">::</a><a id='7370' tid='7369', class="m">internal</a><a id='7372' tid='7371', class="m">::</a><a id='7374' tid='7373', class="m">HashMap</a><a id='7376' tid='7375', class="m">*</a> <a id='7378' tid='7377', class="m">i_cache</a>,
  3123. <a id='7380' tid='7379', class="m">void</a><a id='7382' tid='7381', class="m">*</a> <a id='7384' tid='7383', class="m">start_addr</a>,
  3124. <a id='7386' tid='7385', class="m">size_t</a> <a id='7388' tid='7387', class="m">size</a>) {
  3125. <a id='7390' tid='7389', class="m">intptr_t</a> <a id='7392' tid='7391', class="m">start</a> = <a id='7394' tid='7393', class="m">reinterpret_cast</a>&lt;<a id='7396' tid='7395', class="m">intptr_t</a>&gt;(<a id='7398' tid='7397', class="m">start_addr</a>);
  3126. <a id='7400' tid='7399', class="m">int</a> <a id='7402' tid='7401', class="m">intra_line</a> = (<a id='7404' tid='7403', class="m">start</a> <a id='7406' tid='7405', class="m">&</a> <a id='7408' tid='7407', class="m">CachePage</a><a id='7410' tid='7409', class="m">::</a><a id='7412' tid='7411', class="m">kLineMask</a>);
  3127. <a id='7414' tid='7413', class="m">start</a> <a id='7416' tid='7415', class="m">-=</a> <a id='7418' tid='7417', class="m">intra_line</a>;
  3128. <a id='7420' tid='7419', class="m">size</a> <a id='7422' tid='7421', class="m">+=</a> <a id='7424' tid='7423', class="m">intra_line</a>;
  3129. <a id='7426' tid='7425', class="m">size</a> <a id='7428' tid='7427', class="m">=</a> ((<a id='7430' tid='7429', class="m">size</a> <a id='7432' tid='7431', class="m">-</a> <a id='7434' tid='7433', class="m">1</a>) <a id='7436' tid='7435', class="m">|</a> <a id='7438' tid='7437', class="m">CachePage</a><a id='7440' tid='7439', class="m">::</a><a id='7442' tid='7441', class="m">kLineMask</a>) <a id='7444' tid='7443', class="m">+</a> <a id='7446' tid='7445', class="m">1</a>;
  3130. <a id='7448' tid='7447', class="m">int</a> <a id='7450' tid='7449', class="m">offset</a> = (<a id='7452' tid='7451', class="m">start</a> <a id='7454' tid='7453', class="m">&</a> <a id='7456' tid='7455', class="m">CachePage</a><a id='7458' tid='7457', class="m">::</a><a id='7460' tid='7459', class="m">kPageMask</a>);
  3131. <a id='7462' tid='7461', class="m">while</a> (<a id='7464' tid='7463', class="m">!</a><a id='7466' tid='7465', class="m">AllOnOnePage</a>(<a id='7468' tid='7467', class="m">start</a>, <a id='7470' tid='7469', class="m">size</a> <a id='7472' tid='7471', class="m">-</a> <a id='7474' tid='7473', class="m">1</a>)) {
  3132. <a id='7476' tid='7475', class="m">int</a> <a id='7478' tid='7477', class="m">bytes_to_flush</a> = <a id='7480' tid='7479', class="m">CachePage</a><a id='7482' tid='7481', class="m">::</a><a id='7484' tid='7483', class="m">kPageSize</a> <a id='7486' tid='7485', class="m">-</a> <a id='7488' tid='7487', class="m">offset</a>;
  3133. <a id='7490' tid='7489', class="m">FlushOnePage</a>(<a id='7492' tid='7491', class="m">i_cache</a>, <a id='7494' tid='7493', class="m">start</a>, <a id='7496' tid='7495', class="m">bytes_to_flush</a>);
  3134. <a id='7498' tid='7497', class="m">start</a> <a id='7500' tid='7499', class="m">+=</a> <a id='7502' tid='7501', class="m">bytes_to_flush</a>;
  3135. <a id='7504' tid='7503', class="m">size</a> <a id='7506' tid='7505', class="m">-=</a> <a id='7508' tid='7507', class="m">bytes_to_flush</a>;
  3136. <a id='7510' tid='7509', class="m">ASSERT_EQ</a>(<a id='7512' tid='7511', class="m">0</a>, <a id='7514' tid='7513', class="m">start</a> <a id='7516' tid='7515', class="m">&</a> <a id='7518' tid='7517', class="m">CachePage</a><a id='7520' tid='7519', class="m">::</a><a id='7522' tid='7521', class="m">kPageMask</a>);
  3137. <a id='7524' tid='7523', class="m">offset</a> <a id='7526' tid='7525', class="m">=</a> <a id='7528' tid='7527', class="m">0</a>;
  3138. }
  3139. <a id='7530' tid='7529', class="m">if</a> (<a id='7532' tid='7531', class="m">size</a> <a id='7534' tid='7533', class="m">!=</a> <a id='7536' tid='7535', class="m">0</a>) {
  3140. <a id='7538' tid='7537', class="m">FlushOnePage</a>(<a id='7540' tid='7539', class="m">i_cache</a>, <a id='7542' tid='7541', class="m">start</a>, <a id='7544' tid='7543', class="m">size</a>);
  3141. }
  3142. }
  3143. <a id='7186' tid='7185', class="m">CachePage</a><a id='7188' tid='7187', class="m">*</a> <a id='7190' tid='7189', class="m">Simulator</a><a id='7192' tid='7191', class="m">::</a><a id='7194' tid='7193', class="m">GetCachePage</a>(<a id='7196' tid='7195', class="m">v8</a><a id='7198' tid='7197', class="m">::</a><a id='7200' tid='7199', class="m">internal</a><a id='7202' tid='7201', class="m">::</a><a id='7204' tid='7203', class="m">HashMap</a><a id='7206' tid='7205', class="m">*</a> <a id='7208' tid='7207', class="m">i_cache</a>, <a id='7210' tid='7209', class="m">void</a><a id='7212' tid='7211', class="m">*</a> <a id='7214' tid='7213', class="m">page</a>) {
  3144. <a id='7216' tid='7215', class="m">v8</a><a id='7218' tid='7217', class="m">::</a><a id='7220' tid='7219', class="m">internal</a><a id='7222' tid='7221', class="m">::</a><a id='7224' tid='7223', class="m">HashMap</a><a id='7226' tid='7225', class="m">::</a><a id='7228' tid='7227', class="m">Entry</a><a id='7230' tid='7229', class="m">*</a> <a id='7232' tid='7231', class="m">entry</a> = <a id='7234' tid='7233', class="m">i_cache</a>-&gt;<a id='7236' tid='7235', class="m">Lookup</a>(<a id='7238' tid='7237', class="m">page</a>,
  3145. <a id='7240' tid='7239', class="m">ICacheHash</a>(<a id='7242' tid='7241', class="m">page</a>),
  3146. <a id='7244' tid='7243', class="m">true</a>);
  3147. <a id='7246' tid='7245', class="m">if</a> (<a id='7248' tid='7247', class="m">entry</a>-&gt;<a id='7250' tid='7249', class="m">value</a> <a id='7252' tid='7251', class="m">==</a> <a id='7254' tid='7253', class="m">NULL</a>) {
  3148. <a id='7256' tid='7255', class="m">CachePage</a><a id='7258' tid='7257', class="m">*</a> <a id='7260' tid='7259', class="m">new_page</a> = <a id='7262' tid='7261', class="m">new</a> <a id='7264' tid='7263', class="m">CachePage</a>();
  3149. <a id='7266' tid='7265', class="m">entry</a>-&gt;<a id='7268' tid='7267', class="m">value</a> <a id='7270' tid='7269', class="m">=</a> <a id='7272' tid='7271', class="m">new_page</a>;
  3150. }
  3151. <a id='7274' tid='7273', class="m">return</a> <a id='7276' tid='7275', class="m">reinterpret_cast</a>&lt;<a id='7278' tid='7277', class="m">CachePage</a><a id='7280' tid='7279', class="m">*</a>&gt;(<a id='7282' tid='7281', class="m">entry</a>-&gt;<a id='7284' tid='7283', class="m">value</a>);
  3152. }
  3153. // Flush from start up to and not including start + size.
  3154. <a id='7018' tid='7017', class="m">void</a> <a id='7020' tid='7019', class="m">Simulator</a><a id='7022' tid='7021', class="m">::</a><a id='7024' tid='7023', class="m">FlushOnePage</a>(<a id='7026' tid='7025', class="m">v8</a><a id='7028' tid='7027', class="m">::</a><a id='7030' tid='7029', class="m">internal</a><a id='7032' tid='7031', class="m">::</a><a id='7034' tid='7033', class="m">HashMap</a><a id='7036' tid='7035', class="m">*</a> <a id='7038' tid='7037', class="m">i_cache</a>,
  3155. <a id='7040' tid='7039', class="m">intptr_t</a> <a id='7042' tid='7041', class="m">start</a>,
  3156. <a id='7044' tid='7043', class="m">int</a> <a id='7046' tid='7045', class="m">size</a>) {
  3157. <a id='7048' tid='7047', class="m">ASSERT</a>(<a id='7050' tid='7049', class="m">size</a> <a id='7052' tid='7051', class="m">&lt;=</a> <a id='7054' tid='7053', class="m">CachePage</a><a id='7056' tid='7055', class="m">::</a><a id='7058' tid='7057', class="m">kPageSize</a>);
  3158. <a id='7060' tid='7059', class="m">ASSERT</a>(<a id='7062' tid='7061', class="m">AllOnOnePage</a>(<a id='7064' tid='7063', class="m">start</a>, <a id='7066' tid='7065', class="m">size</a> <a id='7068' tid='7067', class="m">-</a> <a id='7070' tid='7069', class="m">1</a>));
  3159. <a id='7072' tid='7071', class="m">ASSERT</a>((<a id='7074' tid='7073', class="m">start</a> <a id='7076' tid='7075', class="m">&</a> <a id='7078' tid='7077', class="m">CachePage</a><a id='7080' tid='7079', class="m">::</a><a id='7082' tid='7081', class="m">kLineMask</a>) <a id='7084' tid='7083', class="m">==</a> <a id='7086' tid='7085', class="m">0</a>);
  3160. <a id='7088' tid='7087', class="m">ASSERT</a>((<a id='7090' tid='7089', class="m">size</a> <a id='7092' tid='7091', class="m">&</a> <a id='7094' tid='7093', class="m">CachePage</a><a id='7096' tid='7095', class="m">::</a><a id='7098' tid='7097', class="m">kLineMask</a>) <a id='7100' tid='7099', class="m">==</a> <a id='7102' tid='7101', class="m">0</a>);
  3161. <a id='7104' tid='7103', class="m">void</a><a id='7106' tid='7105', class="m">*</a> <a id='7108' tid='7107', class="m">page</a> = <a id='7110' tid='7109', class="m">reinterpret_cast</a>&lt;<a id='7112' tid='7111', class="m">void</a><a id='7114' tid='7113', class="m">*</a>&gt;(<a id='7116' tid='7115', class="m">start</a> <a id='7118' tid='7117', class="m">&</a> (<a id='7120' tid='7119', class="m">~</a><a id='7122' tid='7121', class="m">CachePage</a><a id='7124' tid='7123', class="m">::</a><a id='7126' tid='7125', class="m">kPageMask</a>));
  3162. <a id='7128' tid='7127', class="m">int</a> <a id='7130' tid='7129', class="m">offset</a> = (<a id='7132' tid='7131', class="m">start</a> <a id='7134' tid='7133', class="m">&</a> <a id='7136' tid='7135', class="m">CachePage</a><a id='7138' tid='7137', class="m">::</a><a id='7140' tid='7139', class="m">kPageMask</a>);
  3163. <a id='7142' tid='7141', class="m">CachePage</a><a id='7144' tid='7143', class="m">*</a> <a id='7146' tid='7145', class="m">cache_page</a> = <a id='7148' tid='7147', class="m">GetCachePage</a>(<a id='7150' tid='7149', class="m">i_cache</a>, <a id='7152' tid='7151', class="m">page</a>);
  3164. <a id='7154' tid='7153', class="m">char</a><a id='7156' tid='7155', class="m">*</a> <a id='7158' tid='7157', class="m">valid_bytemap</a> = <a id='7160' tid='7159', class="m">cache_page</a>-&gt;<a id='7162' tid='7161', class="m">ValidityByte</a>(<a id='7164' tid='7163', class="m">offset</a>);
  3165. <a id='7166' tid='7165', class="m">memset</a>(<a id='7168' tid='7167', class="m">valid_bytemap</a>, <a id='7170' tid='7169', class="m">CachePage</a><a id='7172' tid='7171', class="m">::</a><a id='7174' tid='7173', class="m">LINE_INVALID</a>, <a id='7176' tid='7175', class="m">size</a> <a id='7178' tid='7177', class="m">&gt;&gt;</a> <a id='7180' tid='7179', class="m">CachePage</a><a id='7182' tid='7181', class="m">::</a><a id='7184' tid='7183', class="m">kLineShift</a>);
  3166. }
  3167. <a id='6798' tid='6797', class="m">void</a> <a id='6800' tid='6799', class="m">Simulator</a><a id='6802' tid='6801', class="m">::</a><a id='6804' tid='6803', class="m">CheckICache</a>(<a id='6806' tid='6805', class="m">v8</a><a id='6808' tid='6807', class="m">::</a><a id='6810' tid='6809', class="m">internal</a><a id='6812' tid='6811', class="m">::</a><a id='6814' tid='6813', class="m">HashMap</a><a id='6816' tid='6815', class="m">*</a> <a id='6818' tid='6817', class="m">i_cache</a>,
  3168. <a id='6820' tid='6819', class="m">Instruction</a><a id='6822' tid='6821', class="m">*</a> <a id='6824' tid='6823', class="m">instr</a>) {
  3169. <a id='6826' tid='6825', class="m">intptr_t</a> <a id='6828' tid='6827', class="m">address</a> = <a id='6830' tid='6829', class="m">reinterpret_cast</a>&lt;<a id='6832' tid='6831', class="m">intptr_t</a>&gt;(<a id='6834' tid='6833', class="m">instr</a>);
  3170. <a id='6836' tid='6835', class="m">void</a><a id='6838' tid='6837', class="m">*</a> <a id='6840' tid='6839', class="m">page</a> = <a id='6842' tid='6841', class="m">reinterpret_cast</a>&lt;<a id='6844' tid='6843', class="m">void</a><a id='6846' tid='6845', class="m">*</a>&gt;(<a id='6848' tid='6847', class="m">address</a> <a id='6850' tid='6849', class="m">&</a> (<a id='6852' tid='6851', class="m">~</a><a id='6854' tid='6853', class="m">CachePage</a><a id='6856' tid='6855', class="m">::</a><a id='6858' tid='6857', class="m">kPageMask</a>));
  3171. <a id='6860' tid='6859', class="m">void</a><a id='6862' tid='6861', class="m">*</a> <a id='6864' tid='6863', class="m">line</a> = <a id='6866' tid='6865', class="m">reinterpret_cast</a>&lt;<a id='6868' tid='6867', class="m">void</a><a id='6870' tid='6869', class="m">*</a>&gt;(<a id='6872' tid='6871', class="m">address</a> <a id='6874' tid='6873', class="m">&</a> (<a id='6876' tid='6875', class="m">~</a><a id='6878' tid='6877', class="m">CachePage</a><a id='6880' tid='6879', class="m">::</a><a id='6882' tid='6881', class="m">kLineMask</a>));
  3172. <a id='6884' tid='6883', class="m">int</a> <a id='6886' tid='6885', class="m">offset</a> = (<a id='6888' tid='6887', class="m">address</a> <a id='6890' tid='6889', class="m">&</a> <a id='6892' tid='6891', class="m">CachePage</a><a id='6894' tid='6893', class="m">::</a><a id='6896' tid='6895', class="m">kPageMask</a>);
  3173. <a id='6898' tid='6897', class="m">CachePage</a><a id='6900' tid='6899', class="m">*</a> <a id='6902' tid='6901', class="m">cache_page</a> = <a id='6904' tid='6903', class="m">GetCachePage</a>(<a id='6906' tid='6905', class="m">i_cache</a>, <a id='6908' tid='6907', class="m">page</a>);
  3174. <a id='6910' tid='6909', class="m">char</a><a id='6912' tid='6911', class="m">*</a> <a id='6914' tid='6913', class="m">cache_valid_byte</a> = <a id='6916' tid='6915', class="m">cache_page</a>-&gt;<a id='6918' tid='6917', class="m">ValidityByte</a>(<a id='6920' tid='6919', class="m">offset</a>);
  3175. <a id='6922' tid='6921', class="m">bool</a> <a id='6924' tid='6923', class="m">cache_hit</a> = (<a id='6926' tid='6925', class="m">*</a><a id='6928' tid='6927', class="m">cache_valid_byte</a> <a id='6930' tid='6929', class="m">==</a> <a id='6932' tid='6931', class="m">CachePage</a><a id='6934' tid='6933', class="m">::</a><a id='6936' tid='6935', class="m">LINE_VALID</a>);
  3176. <a id='6938' tid='6937', class="m">char</a><a id='6940' tid='6939', class="m">*</a> <a id='6942' tid='6941', class="m">cached_line</a> = <a id='6944' tid='6943', class="m">cache_page</a>-&gt;<a id='6946' tid='6945', class="m">CachedData</a>(<a id='6948' tid='6947', class="m">offset</a> <a id='6950' tid='6949', class="m">&</a> <a id='6952' tid='6951', class="m">~</a><a id='6954' tid='6953', class="m">CachePage</a><a id='6956' tid='6955', class="m">::</a><a id='6958' tid='6957', class="m">kLineMask</a>);
  3177. <a id='6960' tid='6959', class="m">if</a> (<a id='6962' tid='6961', class="m">cache_hit</a>) {
  3178. // Check that the data in memory matches the contents of the I-cache.
  3179. <a id='6964' tid='6963', class="m">CHECK</a>(<a id='6966' tid='6965', class="m">memcmp</a>(<a id='6968' tid='6967', class="m">reinterpret_cast</a>&lt;<a id='6970' tid='6969', class="m">void</a><a id='6972' tid='6971', class="m">*</a>&gt;(<a id='6974' tid='6973', class="m">instr</a>),
  3180. <a id='6976' tid='6975', class="m">cache_page</a>-&gt;<a id='6978' tid='6977', class="m">CachedData</a>(<a id='6980' tid='6979', class="m">offset</a>),
  3181. <a id='6982' tid='6981', class="m">Instruction</a><a id='6984' tid='6983', class="m">::</a><a id='6986' tid='6985', class="m">kInstrSize</a>) <a id='6988' tid='6987', class="m">==</a> <a id='6990' tid='6989', class="m">0</a>);
  3182. } <a id='6992' tid='6991', class="m">else</a> {
  3183. // Cache miss. Load memory into the cache.
  3184. <a id='6994' tid='6993', class="m">memcpy</a>(<a id='6996' tid='6995', class="m">cached_line</a>, <a id='6998' tid='6997', class="m">line</a>, <a id='7000' tid='6999', class="m">CachePage</a><a id='7002' tid='7001', class="m">::</a><a id='7004' tid='7003', class="m">kLineLength</a>);
  3185. <a id='7006' tid='7005', class="m">*</a><a id='7008' tid='7007', class="m">cache_valid_byte</a> <a id='7010' tid='7009', class="m">=</a> <a id='7012' tid='7011', class="m">CachePage</a><a id='7014' tid='7013', class="m">::</a><a id='7016' tid='7015', class="m">LINE_VALID</a>;
  3186. }
  3187. }
  3188. <a id='6748' tid='6747', class="m">void</a> <a id='6750' tid='6749', class="m">Simulator</a><a id='6752' tid='6751', class="m">::</a><a id='6754' tid='6753', class="m">Initialize</a>(<a id='6756' tid='6755', class="m">Isolate</a><a id='6758' tid='6757', class="m">*</a> <a id='6760' tid='6759', class="m">isolate</a>) {
  3189. <a id='6762' tid='6761', class="m">if</a> (<a id='6764' tid='6763', class="m">isolate</a>-&gt;<a id='6766' tid='6765', class="m">simulator_initialized</a>()) <a id='6768' tid='6767', class="m">return</a>;
  3190. <a id='6770' tid='6769', class="m">isolate</a>-&gt;<a id='6772' tid='6771', class="m">set_simulator_initialized</a>(<a id='6774' tid='6773', class="m">true</a>);
  3191. <a id='6776' tid='6775', class="m">::</a><a id='6778' tid='6777', class="m">v8</a><a id='6780' tid='6779', class="m">::</a><a id='6782' tid='6781', class="m">internal</a><a id='6784' tid='6783', class="m">::</a><a id='6786' tid='6785', class="m">ExternalReference</a><a id='6788' tid='6787', class="m">::</a><a id='6790' tid='6789', class="m">set_redirector</a>(<a id='6792' tid='6791', class="m">isolate</a>,
  3192. <a id='6794' tid='6793', class="m">&</a><a id='6796' tid='6795', class="m">RedirectExternalReference</a>);
  3193. }
  3194. <a id='6698' tid='6697', class="m">Simulator</a><a id='6700' tid='6699', class="m">::</a><a id='6702' tid='6701', class="m">Simulator</a>(<a id='6704' tid='6703', class="m">Isolate</a><a id='6706' tid='6705', class="m">*</a> <a id='6708' tid='6707', class="m">isolate</a>) : <a id='6710' tid='6709', class="m">isolate_</a>(<a id='6712' tid='6711', class="m">isolate</a>) {
  3195. <span class="i">i_cache_ = isolate_-&gt;simulator_i_cache();</span>
  3196. <a id='6714' tid='6713', class="m">if</a> (<a id='6716' tid='6715', class="m">i_cache_</a> <a id='6718' tid='6717', class="m">==</a> <a id='6720' tid='6719', class="m">NULL</a>) {
  3197. <a id='6722' tid='6721', class="m">i_cache_</a> <a id='6724' tid='6723', class="m">=</a> <a id='6726' tid='6725', class="m">new</a> <a id='6728' tid='6727', class="m">v8</a><a id='6730' tid='6729', class="m">::</a><a id='6732' tid='6731', class="m">internal</a><a id='6734' tid='6733', class="m">::</a><a id='6736' tid='6735', class="m">HashMap</a>(<a id='6738' tid='6737', class="m">&</a><a id='6740' tid='6739', class="m">ICacheMatch</a>);
  3198. <a id='6742' tid='6741', class="m">isolate_</a>-&gt;<a id='6744' tid='6743', class="m">set_simulator_i_cache</a>(<a id='6746' tid='6745', class="m">i_cache_</a>);
  3199. }
  3200. <span class="i">Initialize(isolate);</span>
  3201. // Setup simulator support first. Some of this information is needed to
  3202. // setup the architecture state.
  3203. <span class="i">size_t stack_size = 1 * 1024*1024;</span> // allocate 1MB for stack
  3204. <span class="i">stack_ = reinterpret_cast&lt;char*&gt;(malloc(stack_size));</span>
  3205. <span class="i">pc_modified_ = false;</span>
  3206. <span class="i">icount_ = 0;</span>
  3207. <span class="i">break_pc_ = NULL;</span>
  3208. <span class="i">break_instr_ = 0;</span>
  3209. // Setup architecture state.
  3210. // All registers are initialized to zero to start with.
  3211. <span class="i">for (int i = 0; i &lt; num_registers; i++) {
  3212. registers_[i] = 0;
  3213. }</span>
  3214. <span class="i">n_flag_ = false;</span>
  3215. <span class="i">z_flag_ = false;</span>
  3216. <span class="i">c_flag_ = false;</span>
  3217. <span class="i">v_flag_ = false;</span>
  3218. // Initializing VFP registers.
  3219. // All registers are initialized to zero to start with
  3220. // even though s_registers_ & d_registers_ share the same
  3221. // physical registers in the target.
  3222. <span class="i">for (int i = 0; i &lt; num_s_registers; i++) {
  3223. vfp_register[i] = 0;
  3224. }</span>
  3225. <span class="i">n_flag_FPSCR_ = false;</span>
  3226. <span class="i">z_flag_FPSCR_ = false;</span>
  3227. <span class="i">c_flag_FPSCR_ = false;</span>
  3228. <span class="i">v_flag_FPSCR_ = false;</span>
  3229. <span class="i">FPSCR_rounding_mode_ = RZ;</span>
  3230. <span class="i">inv_op_vfp_flag_ = false;</span>
  3231. <span class="i">div_zero_vfp_flag_ = false;</span>
  3232. <span class="i">overflow_vfp_flag_ = false;</span>
  3233. <span class="i">underflow_vfp_flag_ = false;</span>
  3234. <span class="i">inexact_vfp_flag_ = false;</span>
  3235. // The sp is initialized to point to the bottom (high address) of the
  3236. // allocated stack area. To be safe in potential stack underflows we leave
  3237. // some buffer below.
  3238. <span class="i">registers_[sp] = reinterpret_cast&lt;int32_t&gt;(stack_) + stack_size - 64;</span>
  3239. // The lr and pc are initialized to a known bad value that will cause an
  3240. // access violation if the simulator ever tries to execute it.
  3241. <span class="i">registers_[pc] = bad_lr;</span>
  3242. <span class="i">registers_[lr] = bad_lr;</span>
  3243. <span class="i">InitializeCoverage();</span>
  3244. }
  3245. // When the generated code calls an external reference we need to catch that in
  3246. // the simulator. The external reference will be a function compiled for the
  3247. // host architecture. We need to call that function instead of trying to
  3248. // execute it with the simulator. We do that by redirecting the external
  3249. // reference to a svc (Supervisor Call) instruction that is handled by
  3250. // the simulator. We write the original destination of the jump just at a known
  3251. // offset from the svc instruction so the simulator knows what to call.
  3252. <a id='6474' tid='6473', class="m">class</a> <a id='6476' tid='6475', class="m">Redirection</a> {
  3253. <a id='6670' tid='6669', class="m">public</a>:
  3254. <a id='6332' tid='6331', class="m">Redirection</a>(<a id='6616' tid='6615', class="m">void</a><a id='6618' tid='6617', class="m">*</a> <a id='6620' tid='6619', class="m">external_function</a>, <a id='6622' tid='6621', class="m">ExternalReference</a><a id='6624' tid='6623', class="m">::</a><a id='6626' tid='6625', class="m">Type</a> <a id='6628' tid='6627', class="m">type</a>)
  3255. : <span class="i">external_function_(external_function),
  3256. swi_instruction_(al | (0xf*B24) | kCallRtRedirected),
  3257. type_(type),
  3258. next_(NULL)</span> {
  3259. <a id='6372' tid='6371', class="m">Isolate</a><a id='6374' tid='6373', class="m">*</a> <a id='6376' tid='6375', class="m">isolate</a> = <a id='6378' tid='6377', class="m">Isolate</a><a id='6380' tid='6379', class="m">::</a><a id='6382' tid='6381', class="m">Current</a>();
  3260. <a id='6384' tid='6383', class="m">next_</a> <a id='6386' tid='6385', class="m">=</a> <a id='6388' tid='6387', class="m">isolate</a>-&gt;<a id='6390' tid='6389', class="m">simulator_redirection</a>();
  3261. <a id='6392' tid='6391', class="m">Simulator</a><a id='6394' tid='6393', class="m">::</a><a id='6396' tid='6395', class="m">current</a>(<a id='6398' tid='6397', class="m">isolate</a>)-&gt;
  3262. <a id='6400' tid='6399', class="m">FlushICache</a>(<a id='6402' tid='6401', class="m">isolate</a>-&gt;<a id='6404' tid='6403', class="m">simulator_i_cache</a>(),
  3263. <a id='6406' tid='6405', class="m">reinterpret_cast</a>&lt;<a id='6408' tid='6407', class="m">void</a><a id='6410' tid='6409', class="m">*</a>&gt;(<a id='6412' tid='6411', class="m">&</a><a id='6414' tid='6413', class="m">swi_instruction_</a>),
  3264. <a id='6416' tid='6415', class="m">Instruction</a><a id='6418' tid='6417', class="m">::</a><a id='6420' tid='6419', class="m">kInstrSize</a>);
  3265. <a id='6422' tid='6421', class="m">isolate</a>-&gt;<a id='6424' tid='6423', class="m">set_simulator_redirection</a>(<a id='6426' tid='6425', class="m">this</a>);
  3266. }
  3267. <a id='6630' tid='6629', class="m">void</a><a id='6632' tid='6631', class="m">*</a> <a id='6634' tid='6633', class="m">address_of_swi_instruction</a>() {
  3268. <a id='6636' tid='6635', class="m">return</a> <a id='6638' tid='6637', class="m">reinterpret_cast</a>&lt;<a id='6640' tid='6639', class="m">void</a><a id='6642' tid='6641', class="m">*</a>&gt;(<a id='6644' tid='6643', class="m">&</a><a id='6646' tid='6645', class="m">swi_instruction_</a>);
  3269. }
  3270. <a id='6648' tid='6647', class="m">void</a><a id='6650' tid='6649', class="m">*</a> <a id='6652' tid='6651', class="m">external_function</a>() { <a id='6654' tid='6653', class="m">return</a> <a id='6656' tid='6655', class="m">external_function_</a>; }
  3271. <a id='6658' tid='6657', class="m">ExternalReference</a><a id='6660' tid='6659', class="m">::</a><a id='6662' tid='6661', class="m">Type</a> <a id='6664' tid='6663', class="m">type</a>() { <a id='6666' tid='6665', class="m">return</a> <a id='6668' tid='6667', class="m">type_</a>; }
  3272. <a id='6532' tid='6531', class="m">static</a> <a id='6534' tid='6533', class="m">Redirection</a><a id='6536' tid='6535', class="m">*</a> <a id='6538' tid='6537', class="m">Get</a>(<a id='6540' tid='6539', class="m">void</a><a id='6542' tid='6541', class="m">*</a> <a id='6544' tid='6543', class="m">external_function</a>,
  3273. <a id='6546' tid='6545', class="m">ExternalReference</a><a id='6548' tid='6547', class="m">::</a><a id='6550' tid='6549', class="m">Type</a> <a id='6552' tid='6551', class="m">type</a>) {
  3274. <a id='6554' tid='6553', class="m">Isolate</a><a id='6556' tid='6555', class="m">*</a> <a id='6558' tid='6557', class="m">isolate</a> = <a id='6560' tid='6559', class="m">Isolate</a><a id='6562' tid='6561', class="m">::</a><a id='6564' tid='6563', class="m">Current</a>();
  3275. <a id='6566' tid='6565', class="m">Redirection</a><a id='6568' tid='6567', class="m">*</a> <a id='6570' tid='6569', class="m">current</a> = <a id='6572' tid='6571', class="m">isolate</a>-&gt;<a id='6574' tid='6573', class="m">simulator_redirection</a>();
  3276. <a id='6576' tid='6575', class="m">for</a> (; <a id='6578' tid='6577', class="m">current</a> <a id='6580' tid='6579', class="m">!=</a> <a id='6582' tid='6581', class="m">NULL</a>; <a id='6584' tid='6583', class="m">current</a> <a id='6586' tid='6585', class="m">=</a> <a id='6588' tid='6587', class="m">current</a>-&gt;<a id='6590' tid='6589', class="m">next_</a>) {
  3277. <a id='6592' tid='6591', class="m">if</a> (<a id='6594' tid='6593', class="m">current</a>-&gt;<a id='6596' tid='6595', class="m">external_function_</a> <a id='6598' tid='6597', class="m">==</a> <a id='6600' tid='6599', class="m">external_function</a>) <a id='6602' tid='6601', class="m">return</a> <a id='6604' tid='6603', class="m">current</a>;
  3278. }
  3279. <a id='6606' tid='6605', class="m">return</a> <a id='6608' tid='6607', class="m">new</a> <a id='6610' tid='6609', class="m">Redirection</a>(<a id='6612' tid='6611', class="m">external_function</a>, <a id='6614' tid='6613', class="m">type</a>);
  3280. }
  3281. <a id='6478' tid='6477', class="m">static</a> <a id='6480' tid='6479', class="m">Redirection</a><a id='6482' tid='6481', class="m">*</a> <a id='6484' tid='6483', class="m">FromSwiInstruction</a>(<a id='6486' tid='6485', class="m">Instruction</a><a id='6488' tid='6487', class="m">*</a> <a id='6490' tid='6489', class="m">swi_instruction</a>) {
  3282. <a id='6492' tid='6491', class="m">char</a><a id='6494' tid='6493', class="m">*</a> <a id='6496' tid='6495', class="m">addr_of_swi</a> = <a id='6498' tid='6497', class="m">reinterpret_cast</a>&lt;<a id='6500' tid='6499', class="m">char</a><a id='6502' tid='6501', class="m">*</a>&gt;(<a id='6504' tid='6503', class="m">swi_instruction</a>);
  3283. <a id='6506' tid='6505', class="m">char</a><a id='6508' tid='6507', class="m">*</a> <a id='6510' tid='6509', class="m">addr_of_redirection</a> =
  3284. <a id='6512' tid='6511', class="m">addr_of_swi</a> <a id='6514' tid='6513', class="m">-</a> <a id='6516' tid='6515', class="m">OFFSET_OF</a>(<a id='6518' tid='6517', class="m">Redirection</a>, <a id='6520' tid='6519', class="m">swi_instruction_</a>);
  3285. <a id='6522' tid='6521', class="m">return</a> <a id='6524' tid='6523', class="m">reinterpret_cast</a>&lt;<a id='6526' tid='6525', class="m">Redirection</a><a id='6528' tid='6527', class="m">*</a>&gt;(<a id='6530' tid='6529', class="m">addr_of_redirection</a>);
  3286. }
  3287. <a id='6672' tid='6671', class="m">private</a>:
  3288. <a id='6674' tid='6673', class="m">void</a><a id='6676' tid='6675', class="m">*</a> <a id='6678' tid='6677', class="m">external_function_</a>;
  3289. <a id='6680' tid='6679', class="m">uint32_t</a> <a id='6682' tid='6681', class="m">swi_instruction_</a>;
  3290. <a id='6684' tid='6683', class="m">ExternalReference</a><a id='6686' tid='6685', class="m">::</a><a id='6688' tid='6687', class="m">Type</a> <a id='6690' tid='6689', class="m">type_</a>;
  3291. <a id='6692' tid='6691', class="m">Redirection</a><a id='6694' tid='6693', class="m">*</a> <a id='6696' tid='6695', class="m">next_</a>;
  3292. };
  3293. <a id='6428' tid='6427', class="m">void</a><a id='6430' tid='6429', class="m">*</a> <a id='6432' tid='6431', class="m">Simulator</a><a id='6434' tid='6433', class="m">::</a><a id='6436' tid='6435', class="m">RedirectExternalReference</a>(<a id='6438' tid='6437', class="m">void</a><a id='6440' tid='6439', class="m">*</a> <a id='6442' tid='6441', class="m">external_function</a>,
  3294. <a id='6444' tid='6443', class="m">ExternalReference</a><a id='6446' tid='6445', class="m">::</a><a id='6448' tid='6447', class="m">Type</a> <a id='6450' tid='6449', class="m">type</a>) {
  3295. <a id='6452' tid='6451', class="m">Redirection</a><a id='6454' tid='6453', class="m">*</a> <a id='6456' tid='6455', class="m">redirection</a> = <a id='6458' tid='6457', class="m">Redirection</a><a id='6460' tid='6459', class="m">::</a><a id='6462' tid='6461', class="m">Get</a>(<a id='6464' tid='6463', class="m">external_function</a>, <a id='6466' tid='6465', class="m">type</a>);
  3296. <a id='6468' tid='6467', class="m">return</a> <a id='6470' tid='6469', class="m">redirection</a>-&gt;<a id='6472' tid='6471', class="m">address_of_swi_instruction</a>();
  3297. }
  3298. // Get the active Simulator for the current thread.
  3299. <a id='6334' tid='6333', class="m">Simulator</a><a id='6336' tid='6335', class="m">*</a> <a id='6338' tid='6337', class="m">Simulator</a><a id='6340' tid='6339', class="m">::</a><a id='6342' tid='6341', class="m">current</a>(<a id='6344' tid='6343', class="m">Isolate</a><a id='6346' tid='6345', class="m">*</a> <a id='6348' tid='6347', class="m">isolate</a>) {
  3300. <a id='6350' tid='6349', class="m">v8</a><a id='6352' tid='6351', class="m">::</a><a id='6354' tid='6353', class="m">internal</a><a id='6356' tid='6355', class="m">::</a><a id='6358' tid='6357', class="m">Isolate</a><a id='6360' tid='6359', class="m">::</a><a id='6362' tid='6361', class="m">PerIsolateThreadData</a><a id='6364' tid='6363', class="m">*</a> <a id='6366' tid='6365', class="m">isolate_data</a> =
  3301. <a id='6368' tid='6367', class="m">isolate</a>-&gt;<a id='6370' tid='6369', class="m">FindOrAllocatePerThreadDataForThisThread</a>();
  3302. <span class="i">ASSERT(isolate_data != NULL);</span>
  3303. <a id='6322' tid='6321', class="m">Simulator</a><a id='6324' tid='6323', class="m">*</a> <a id='6326' tid='6325', class="m">sim</a> = <a id='6328' tid='6327', class="m">isolate_data</a>-&gt;<a id='6330' tid='6329', class="m">simulator</a>();
  3304. <a id='6268' tid='6267', class="m">if</a> (<a id='6270' tid='6269', class="m">sim</a> <a id='6272' tid='6271', class="m">==</a> <a id='6274' tid='6273', class="m">NULL</a>) {
  3305. // TODO(146): delete the simulator object when a thread/isolate goes away.
  3306. <a id='6276' tid='6275', class="m">sim</a> <a id='6278' tid='6277', class="m">=</a> <a id='6280' tid='6279', class="m">new</a> <a id='6282' tid='6281', class="m">Simulator</a>(<a id='6284' tid='6283', class="m">isolate</a>);
  3307. <a id='6286' tid='6285', class="m">isolate_data</a>-&gt;<a id='6288' tid='6287', class="m">set_simulator</a>(<a id='6290' tid='6289', class="m">sim</a>);
  3308. }
  3309. <span class="i">return sim;</span>
  3310. }
  3311. // Sets the register in the architecture state. It will also deal with updating
  3312. // Simulator internal state for special registers such as PC.
  3313. <a id='6292' tid='6291', class="m">void</a> <a id='6294' tid='6293', class="m">Simulator</a><a id='6296' tid='6295', class="m">::</a><a id='6298' tid='6297', class="m">set_register</a>(<a id='6300' tid='6299', class="m">int</a> <a id='6302' tid='6301', class="m">reg</a>, <a id='6304' tid='6303', class="m">int32_t</a> <a id='6306' tid='6305', class="m">value</a>) {
  3314. <span class="i">ASSERT((reg &gt;= 0) && (reg &lt; num_registers));</span>
  3315. <a id='6308' tid='6307', class="m">if</a> (<a id='6310' tid='6309', class="m">reg</a> <a id='6312' tid='6311', class="m">==</a> <a id='6314' tid='6313', class="m">pc</a>) {
  3316. <a id='6316' tid='6315', class="m">pc_modified_</a> <a id='6318' tid='6317', class="m">=</a> <a id='6320' tid='6319', class="m">true</a>;
  3317. }
  3318. <span class="i">registers_[reg] = value;</span>
  3319. }
  3320. // Get the register from the architecture state. This function does handle
  3321. // the special case of accessing the PC register.
  3322. <a id='6254' tid='6253', class="m">int32_t</a> <a id='6256' tid='6255', class="m">Simulator</a><a id='6258' tid='6257', class="m">::</a><a id='6260' tid='6259', class="m">get_register</a>(<a id='6262' tid='6261', class="m">int</a> <a id='6264' tid='6263', class="m">reg</a>) <a id='6266' tid='6265', class="m">const</a> {
  3323. <span class="i">ASSERT((reg &gt;= 0) && (reg &lt; num_registers));</span>
  3324. // Stupid code added to avoid bug in GCC.
  3325. // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
  3326. <span class="i">if (reg &gt;= num_registers) return 0;</span>
  3327. // End stupid code.
  3328. <a id='6232' tid='6231', class="m">return</a> <a id='6234' tid='6233', class="m">registers_</a>[<a id='6236' tid='6235', class="m">reg</a>] <a id='6238' tid='6237', class="m">+</a> ((<a id='6240' tid='6239', class="m">reg</a> <a id='6242' tid='6241', class="m">==</a> <a id='6244' tid='6243', class="m">pc</a>) ? <a id='6246' tid='6245', class="m">Instruction</a><a id='6248' tid='6247', class="m">::</a><a id='6250' tid='6249', class="m">kPCReadOffset</a> : <a id='6252' tid='6251', class="m">0</a>);
  3329. }
  3330. <span class="i">double Simulator::get_double_from_register_pair(int reg) {
  3331. ASSERT((reg &gt;= 0) && (reg &lt; num_registers) && ((reg % 2) == 0));
  3332. double dm_val = 0.0;
  3333. // Read the bits from the unsigned integer register_[] array
  3334. // into the double precision floating point value and return it.
  3335. char buffer[2 * sizeof(vfp_register[0])];
  3336. memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
  3337. memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
  3338. return(dm_val);
  3339. }</span>
  3340. <span class="i">void Simulator::set_dw_register(int dreg, const int* dbl) {
  3341. ASSERT((dreg &gt;= 0) && (dreg &lt; num_d_registers));
  3342. registers_[dreg] = dbl[0];
  3343. registers_[dreg + 1] = dbl[1];
  3344. }</span>
  3345. // Raw access to the PC register.
  3346. <a id='6206' tid='6205', class="m">void</a> <a id='6208' tid='6207', class="m">Simulator</a><a id='6210' tid='6209', class="m">::</a><a id='6212' tid='6211', class="m">set_pc</a>(<a id='6214' tid='6213', class="m">int32_t</a> <a id='6216' tid='6215', class="m">value</a>) {
  3347. <a id='6218' tid='6217', class="m">pc_modified_</a> <a id='6220' tid='6219', class="m">=</a> <a id='6222' tid='6221', class="m">true</a>;
  3348. <a id='6224' tid='6223', class="m">registers_</a>[<a id='6226' tid='6225', class="m">pc</a>] <a id='6228' tid='6227', class="m">=</a> <a id='6230' tid='6229', class="m">value</a>;
  3349. }
  3350. <a id='6196' tid='6195', class="m">bool</a> <a id='6198' tid='6197', class="m">Simulator</a><a id='6200' tid='6199', class="m">::</a><a id='6202' tid='6201', class="m">has_bad_pc</a>() <a id='6204' tid='6203', class="m">const</a> <span class="i">{
  3351. return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc));
  3352. }</span>
  3353. // Raw access to the PC register without the special adjustment when reading.
  3354. <a id='6186' tid='6185', class="m">int32_t</a> <a id='6188' tid='6187', class="m">Simulator</a><a id='6190' tid='6189', class="m">::</a><a id='6192' tid='6191', class="m">get_pc</a>() <a id='6194' tid='6193', class="m">const</a> <span class="i">{
  3355. return registers_[pc];
  3356. }</span>
  3357. // Getting from and setting into VFP registers.
  3358. <span class="i">void Simulator::set_s_register(int sreg, unsigned int value) {
  3359. ASSERT((sreg &gt;= 0) && (sreg &lt; num_s_registers));
  3360. vfp_register[sreg] = value;
  3361. }</span>
  3362. <span class="i">unsigned int Simulator::get_s_register(int sreg) const</span> <span class="i">{
  3363. ASSERT((sreg &gt;= 0) && (sreg &lt; num_s_registers));
  3364. return vfp_register[sreg];
  3365. }</span>
  3366. <span class="i">void Simulator::set_s_register_from_float(int sreg, const float flt) {
  3367. ASSERT((sreg &gt;= 0) && (sreg &lt; num_s_registers));
  3368. // Read the bits from the single precision floating point value
  3369. // into the unsigned integer element of vfp_register[] given by index=sreg.
  3370. char buffer[sizeof(vfp_register[0])];
  3371. memcpy(buffer, &flt, sizeof(vfp_register[0]));
  3372. memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
  3373. }</span>
  3374. <span class="i">void Simulator::set_s_register_from_sinteger(int sreg, const int sint) {
  3375. ASSERT((sreg &gt;= 0) && (sreg &lt; num_s_registers));
  3376. // Read the bits from the integer value into the unsigned integer element of
  3377. // vfp_register[] given by index=sreg.
  3378. char buffer[sizeof(vfp_register[0])];
  3379. memcpy(buffer, &sint, sizeof(vfp_register[0]));
  3380. memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
  3381. }</span>
  3382. <span class="i">void Simulator::set_d_register_from_double(int dreg, const double& dbl) {
  3383. ASSERT((dreg &gt;= 0) && (dreg &lt; num_d_registers));
  3384. // Read the bits from the double precision floating point value into the two
  3385. // consecutive unsigned integer elements of vfp_register[] given by index
  3386. // 2*sreg and 2*sreg+1.
  3387. char buffer[2 * sizeof(vfp_register[0])];
  3388. memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0]));
  3389. memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0]));
  3390. }</span>
  3391. <span class="i">float Simulator::get_float_from_s_register(int sreg) {
  3392. ASSERT((sreg &gt;= 0) && (sreg &lt; num_s_registers));
  3393. float sm_val = 0.0;
  3394. // Read the bits from the unsigned integer vfp_register[] array
  3395. // into the single precision floating point value and return it.
  3396. char buffer[sizeof(vfp_register[0])];
  3397. memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
  3398. memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
  3399. return(sm_val);
  3400. }</span>
  3401. <span class="i">int Simulator::get_sinteger_from_s_register(int sreg) {
  3402. ASSERT((sreg &gt;= 0) && (sreg &lt; num_s_registers));
  3403. int sm_val = 0;
  3404. // Read the bits from the unsigned integer vfp_register[] array
  3405. // into the single precision floating point value and return it.
  3406. char buffer[sizeof(vfp_register[0])];
  3407. memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
  3408. memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
  3409. return(sm_val);
  3410. }</span>
  3411. <span class="i">double Simulator::get_double_from_d_register(int dreg) {
  3412. ASSERT((dreg &gt;= 0) && (dreg &lt; num_d_registers));
  3413. double dm_val = 0.0;
  3414. // Read the bits from the unsigned integer vfp_register[] array
  3415. // into the double precision floating point value and return it.
  3416. char buffer[2 * sizeof(vfp_register[0])];
  3417. memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0]));
  3418. memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0]));
  3419. return(dm_val);
  3420. }</span>
  3421. // For use in calls that take two double values, constructed either
  3422. // from r0-r3 or d0 and d1.
  3423. <a id='6154' tid='6153', class="m">void</a> <a id='6156' tid='6155', class="m">Simulator</a><a id='6158' tid='6157', class="m">::</a><a id='6160' tid='6159', class="m">GetFpArgs</a>(<a id='6162' tid='6161', class="m">double</a><a id='6164' tid='6163', class="m">*</a> <a id='6166' tid='6165', class="m">x</a>, <a id='6168' tid='6167', class="m">double</a><a id='6170' tid='6169', class="m">*</a> <a id='6172' tid='6171', class="m">y</a>) {
  3424. <span class="i">if</span> <span class="i">(use_eabi_hardfloat())</span> <span class="i">{
  3425. *x = vfp_register[0];
  3426. *y = vfp_register[1];
  3427. }</span> <a id='6174' tid='6173', class="m">else</a> {
  3428. // We use a char buffer to get around the strict-aliasing rules which
  3429. // otherwise allow the compiler to optimize away the copy.
  3430. <a id='6176' tid='6175', class="m">char</a> <a id='6178' tid='6177', class="m">buffer</a>[<a id='6180' tid='6179', class="m">sizeof</a>(<a id='6182' tid='6181', class="m">*</a><a id='6184' tid='6183', class="m">x</a>)];
  3431. // Registers 0 and 1 -&gt; x.
  3432. <span class="i">memcpy(buffer, registers_, sizeof(*x));</span>
  3433. <span class="i">memcpy(x, buffer, sizeof(*x));</span>
  3434. // Registers 2 and 3 -&gt; y.
  3435. <span class="i">memcpy(buffer, registers_ + 2, sizeof(*y));</span>
  3436. <a id='6086' tid='6085', class="m">memcpy</a>(<a id='6088' tid='6087', class="m">y</a>, <a id='6090' tid='6089', class="m">buffer</a>, <a id='6092' tid='6091', class="m">sizeof</a>(<a id='6094' tid='6093', class="m">*</a><a id='6096' tid='6095', class="m">y</a>));
  3437. }
  3438. }
  3439. // For use in calls that take one double value, constructed either
  3440. // from r0 and r1 or d0.
  3441. <a id='6130' tid='6129', class="m">void</a> <a id='6132' tid='6131', class="m">Simulator</a><a id='6134' tid='6133', class="m">::</a><a id='6136' tid='6135', class="m">GetFpArgs</a>(<a id='6138' tid='6137', class="m">double</a><a id='6140' tid='6139', class="m">*</a> <a id='6142' tid='6141', class="m">x</a>) {
  3442. <span class="i">if</span> <span class="i">(use_eabi_hardfloat())</span> <span class="i">{
  3443. *x = vfp_register[0];
  3444. }</span> <span class="i">else</span> {
  3445. // We use a char buffer to get around the strict-aliasing rules which
  3446. // otherwise allow the compiler to optimize away the copy.
  3447. <a id='6144' tid='6143', class="m">char</a> <a id='6146' tid='6145', class="m">buffer</a>[<a id='6148' tid='6147', class="m">sizeof</a>(<a id='6150' tid='6149', class="m">*</a><a id='6152' tid='6151', class="m">x</a>)];
  3448. // Registers 0 and 1 -&gt; x.
  3449. <span class="i">memcpy(buffer, registers_, sizeof(*x));</span>
  3450. <span class="i">memcpy(x, buffer, sizeof(*x));</span>
  3451. }
  3452. }
  3453. // For use in calls that take one double value constructed either
  3454. // from r0 and r1 or d0 and one integer value.
  3455. <a id='6098' tid='6097', class="m">void</a> <a id='6100' tid='6099', class="m">Simulator</a><a id='6102' tid='6101', class="m">::</a><a id='6104' tid='6103', class="m">GetFpArgs</a>(<a id='6106' tid='6105', class="m">double</a><a id='6108' tid='6107', class="m">*</a> <a id='6110' tid='6109', class="m">x</a>, <a id='6112' tid='6111', class="m">int32_t</a><a id='6114' tid='6113', class="m">*</a> <a id='6116' tid='6115', class="m">y</a>) {
  3456. <span class="i">if</span> <span class="i">(use_eabi_hardfloat())</span> <span class="i">{
  3457. *x = vfp_register[0];
  3458. *y = registers_[1];
  3459. }</span> <a id='6118' tid='6117', class="m">else</a> {
  3460. // We use a char buffer to get around the strict-aliasing rules which
  3461. // otherwise allow the compiler to optimize away the copy.
  3462. <a id='6120' tid='6119', class="m">char</a> <a id='6122' tid='6121', class="m">buffer</a>[<a id='6124' tid='6123', class="m">sizeof</a>(<a id='6126' tid='6125', class="m">*</a><a id='6128' tid='6127', class="m">x</a>)];
  3463. // Registers 0 and 1 -&gt; x.
  3464. <span class="i">memcpy(buffer, registers_, sizeof(*x));</span>
  3465. <span class="i">memcpy(x, buffer, sizeof(*x));</span>
  3466. // Register 2 -&gt; y.
  3467. <span class="i">memcpy(buffer, registers_ + 2, sizeof(*y));</span>
  3468. <span class="i">memcpy(y, buffer, sizeof(*y));</span>
  3469. }
  3470. }
  3471. // The return value is either in r0/r1 or d0.
  3472. <a id='6058' tid='6057', class="m">void</a> <a id='6060' tid='6059', class="m">Simulator</a><a id='6062' tid='6061', class="m">::</a><a id='6064' tid='6063', class="m">SetFpResult</a>(<a id='6066' tid='6065', class="m">const</a> <a id='6068' tid='6067', class="m">double</a><a id='6070' tid='6069', class="m">&</a> <a id='6072' tid='6071', class="m">result</a>) {
  3473. <span class="i">if</span> <span class="i">(use_eabi_hardfloat())</span> {
  3474. <span class="i">char buffer[2 * sizeof(vfp_register[0])];</span>
  3475. <a id='6074' tid='6073', class="m">memcpy</a>(<a id='6076' tid='6075', class="m">buffer</a>, <a id='6078' tid='6077', class="m">&</a><a id='6080' tid='6079', class="m">result</a>, <a id='6082' tid='6081', class="m">sizeof</a>(<a id='6084' tid='6083', class="m">buffer</a>));
  3476. // Copy result to d0.
  3477. <span class="i">memcpy(vfp_register, buffer, sizeof(buffer));</span>
  3478. } <span class="i">else</span> {
  3479. <a id='6044' tid='6043', class="m">char</a> <a id='6046' tid='6045', class="m">buffer</a>[<a id='6048' tid='6047', class="m">2</a> <a id='6050' tid='6049', class="m">*</a> <a id='6052' tid='6051', class="m">sizeof</a>(<a id='6054' tid='6053', class="m">registers_</a>[<a id='6056' tid='6055', class="m">0</a>])];
  3480. <span class="i">memcpy(buffer, &result, sizeof(buffer));</span>
  3481. // Copy result to r0 and r1.
  3482. <span class="i">memcpy(registers_, buffer, sizeof(buffer));</span>
  3483. }
  3484. }
  3485. <span class="i">void Simulator::TrashCallerSaveRegisters() {
  3486. // We don&#39;t trash the registers with the return value.
  3487. registers_[2] = 0x50Bad4U;
  3488. registers_[3] = 0x50Bad4U;
  3489. registers_[12] = 0x50Bad4U;
  3490. }</span>
  3491. // Some Operating Systems allow unaligned access on ARMv7 targets. We
  3492. // assume that unaligned accesses are not allowed unless the v8 build system
  3493. // defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero.
  3494. // The following statements below describes the behavior of the ARM CPUs
  3495. // that don&#39;t support unaligned access.
  3496. // Some ARM platforms raise an interrupt on detecting unaligned access.
  3497. // On others it does a funky rotation thing. For now we
  3498. // simply disallow unaligned reads. Note that simulator runs have the runtime
  3499. // system running directly on the host system and only generated code is
  3500. // executed in the simulator. Since the host is typically IA32 we will not
  3501. // get the correct ARM-like behaviour on unaligned accesses for those ARM
  3502. // targets that don&#39;t support unaligned loads and stores.
  3503. <a id='6012' tid='6011', class="m">int</a> <a id='6014' tid='6013', class="m">Simulator</a><a id='6016' tid='6015', class="m">::</a><a id='6018' tid='6017', class="m">ReadW</a>(<a id='6020' tid='6019', class="m">int32_t</a> <a id='6022' tid='6021', class="m">addr</a>, <a id='6024' tid='6023', class="m">Instruction</a><a id='6026' tid='6025', class="m">*</a> <a id='6028' tid='6027', class="m">instr</a>) {
  3504. <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
  3505. <a id='6030' tid='6029', class="m">intptr_t</a><a id='6032' tid='6031', class="m">*</a> <a id='6034' tid='6033', class="m">ptr</a> = <a id='6036' tid='6035', class="m">reinterpret_cast</a>&lt;<a id='6038' tid='6037', class="m">intptr_t</a><a id='6040' tid='6039', class="m">*</a>&gt;(<a id='6042' tid='6041', class="m">addr</a>);
  3506. <span class="i">return *ptr;</span>
  3507. <span class="i">#else</span>
  3508. <span class="i">if ((addr & 3) == 0) {
  3509. intptr_t* ptr = reinterpret_cast&lt;intptr_t*&gt;(addr);
  3510. return *ptr;
  3511. }</span>
  3512. <a id='5996' tid='5995', class="m">PrintF</a>(<a id='5998' tid='5997', class="m">&quot;Unaligned read at 0x%08x, pc=0x%08&quot;</a> <a id='6000' tid='5999', class="m">V8PRIxPTR</a> <a id='6002' tid='6001', class="m">&quot;\n&quot;</a>,
  3513. <a id='6004' tid='6003', class="m">addr</a>,
  3514. <a id='6006' tid='6005', class="m">reinterpret_cast</a>&lt;<a id='6008' tid='6007', class="m">intptr_t</a>&gt;(<a id='6010' tid='6009', class="m">instr</a>));
  3515. <span class="i">UNIMPLEMENTED();</span>
  3516. <span class="i">return 0;</span>
  3517. <span class="i">#endif</span>
  3518. }
  3519. <a id='5960' tid='5959', class="m">void</a> <a id='5962' tid='5961', class="m">Simulator</a><a id='5964' tid='5963', class="m">::</a><a id='5966' tid='5965', class="m">WriteW</a>(<a id='5968' tid='5967', class="m">int32_t</a> <a id='5970' tid='5969', class="m">addr</a>, <a id='5972' tid='5971', class="m">int</a> <a id='5974' tid='5973', class="m">value</a>, <a id='5976' tid='5975', class="m">Instruction</a><a id='5978' tid='5977', class="m">*</a> <a id='5980' tid='5979', class="m">instr</a>) {
  3520. <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
  3521. <a id='5982' tid='5981', class="m">intptr_t</a><a id='5984' tid='5983', class="m">*</a> <a id='5986' tid='5985', class="m">ptr</a> = <a id='5988' tid='5987', class="m">reinterpret_cast</a>&lt;<a id='5990' tid='5989', class="m">intptr_t</a><a id='5992' tid='5991', class="m">*</a>&gt;(<a id='5994' tid='5993', class="m">addr</a>);
  3522. <span class="i">*ptr = value;</span>
  3523. <span class="i">return;</span>
  3524. <span class="i">#else</span>
  3525. <span class="i">if ((addr & 3) == 0) {
  3526. intptr_t* ptr = reinterpret_cast&lt;intptr_t*&gt;(addr);
  3527. *ptr = value;
  3528. return;
  3529. }</span>
  3530. <a id='5944' tid='5943', class="m">PrintF</a>(<a id='5946' tid='5945', class="m">&quot;Unaligned write at 0x%08x, pc=0x%08&quot;</a> <a id='5948' tid='5947', class="m">V8PRIxPTR</a> <a id='5950' tid='5949', class="m">&quot;\n&quot;</a>,
  3531. <a id='5952' tid='5951', class="m">addr</a>,
  3532. <a id='5954' tid='5953', class="m">reinterpret_cast</a>&lt;<a id='5956' tid='5955', class="m">intptr_t</a>&gt;(<a id='5958' tid='5957', class="m">instr</a>));
  3533. <span class="i">UNIMPLEMENTED();</span>
  3534. <span class="i">#endif</span>
  3535. }
  3536. <a id='5892' tid='5891', class="m">uint16_t</a> <a id='5894' tid='5893', class="m">Simulator</a><a id='5896' tid='5895', class="m">::</a><a id='5898' tid='5897', class="m">ReadHU</a>(<a id='5934' tid='5933', class="m">int32_t</a> <a id='5936' tid='5935', class="m">addr</a>, <a id='5938' tid='5937', class="m">Instruction</a><a id='5940' tid='5939', class="m">*</a> <a id='5942' tid='5941', class="m">instr</a>) {
  3537. <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
  3538. <a id='5900' tid='5899', class="m">uint16_t</a><a id='5902' tid='5901', class="m">*</a> <a id='5904' tid='5903', class="m">ptr</a> = <a id='5906' tid='5905', class="m">reinterpret_cast</a>&lt;<a id='5908' tid='5907', class="m">uint16_t</a><a id='5910' tid='5909', class="m">*</a>&gt;(<a id='5912' tid='5911', class="m">addr</a>);
  3539. <span class="i">return *ptr;</span>
  3540. <span class="i">#else</span>
  3541. <span class="i">if</span> ((<a id='5792' tid='5791', class="m">addr</a> <a id='5794' tid='5793', class="m">&</a> <a id='5796' tid='5795', class="m">1</a>) <a id='5798' tid='5797', class="m">==</a> <a id='5800' tid='5799', class="m">0</a>) <span class="i">{
  3542. uint16_t* ptr = reinterpret_cast&lt;uint16_t*&gt;(addr);
  3543. return *ptr;
  3544. }</span>
  3545. <a id='5876' tid='5875', class="m">PrintF</a>(<a id='5878' tid='5877', class="m">&quot;Unaligned unsigned halfword read at 0x%08x, pc=0x%08&quot;</a> <a id='5880' tid='5879', class="m">V8PRIxPTR</a> <a id='5882' tid='5881', class="m">&quot;\n&quot;</a>,
  3546. <a id='5884' tid='5883', class="m">addr</a>,
  3547. <a id='5886' tid='5885', class="m">reinterpret_cast</a>&lt;<a id='5888' tid='5887', class="m">intptr_t</a>&gt;(<a id='5890' tid='5889', class="m">instr</a>));
  3548. <span class="i">UNIMPLEMENTED();</span>
  3549. <span class="i">return 0;</span>
  3550. <span class="i">#endif</span>
  3551. }
  3552. <a id='5858' tid='5857', class="m">int16_t</a> <a id='5860' tid='5859', class="m">Simulator</a><a id='5862' tid='5861', class="m">::</a><a id='5864' tid='5863', class="m">ReadH</a>(<a id='5924' tid='5923', class="m">int32_t</a> <a id='5926' tid='5925', class="m">addr</a>, <a id='5928' tid='5927', class="m">Instruction</a><a id='5930' tid='5929', class="m">*</a> <a id='5932' tid='5931', class="m">instr</a>) {
  3553. <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
  3554. <a id='5802' tid='5801', class="m">int16_t</a><a id='5804' tid='5803', class="m">*</a> <a id='5806' tid='5805', class="m">ptr</a> = <a id='5808' tid='5807', class="m">reinterpret_cast</a>&lt;<a id='5810' tid='5809', class="m">int16_t</a><a id='5812' tid='5811', class="m">*</a>&gt;(<a id='5814' tid='5813', class="m">addr</a>);
  3555. <span class="i">return *ptr;</span>
  3556. <span class="i">#else</span>
  3557. <a id='4338' tid='4337', class="m">if</a> ((<a id='4340' tid='4339', class="m">addr</a> <a id='4342' tid='4341', class="m">&</a> <a id='4344' tid='4343', class="m">1</a>) <a id='4346' tid='4345', class="m">==</a> <a id='4348' tid='4347', class="m">0</a>) {
  3558. <a id='4350' tid='4349', class="m">int16_t</a><a id='4352' tid='4351', class="m">*</a> <a id='4354' tid='4353', class="m">ptr</a> = <a id='4356' tid='4355', class="m">reinterpret_cast</a>&lt;<a id='4358' tid='4357', class="m">int16_t</a><a id='4360' tid='4359', class="m">*</a>&gt;(<a id='4362' tid='4361', class="m">addr</a>);
  3559. <span class="i">return *ptr;</span>
  3560. }
  3561. <span class="i">PrintF(&quot;Unaligned signed halfword read at 0x%08x\n&quot;, addr);</span>
  3562. <span class="i">UNIMPLEMENTED();</span>
  3563. <span class="i">return 0;</span>
  3564. <span class="i">#endif</span>
  3565. }
  3566. <a id='5756' tid='5755', class="m">void</a> <a id='5758' tid='5757', class="m">Simulator</a><a id='5760' tid='5759', class="m">::</a><a id='5762' tid='5761', class="m">WriteH</a>(<a id='5764' tid='5763', class="m">int32_t</a> <a id='5766' tid='5765', class="m">addr</a>, <a id='5768' tid='5767', class="m">uint16_t</a> <a id='5770' tid='5769', class="m">value</a>, <a id='5772' tid='5771', class="m">Instruction</a><a id='5774' tid='5773', class="m">*</a> <a id='5776' tid='5775', class="m">instr</a>) {
  3567. <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
  3568. <span class="i">uint16_t* ptr = reinterpret_cast&lt;uint16_t*&gt;(addr);</span>
  3569. <span class="i">*ptr = value;</span>
  3570. <span class="i">return;</span>
  3571. <span class="i">#else</span>
  3572. <a id='5832' tid='5831', class="m">if</a> ((<a id='5914' tid='5913', class="m">addr</a> <a id='5916' tid='5915', class="m">&</a> <a id='5918' tid='5917', class="m">1</a>) <a id='5920' tid='5919', class="m">==</a> <a id='5922' tid='5921', class="m">0</a>) {
  3573. <a id='5834' tid='5833', class="m">uint16_t</a><a id='5836' tid='5835', class="m">*</a> <a id='5838' tid='5837', class="m">ptr</a> = <a id='5840' tid='5839', class="m">reinterpret_cast</a>&lt;<a id='5842' tid='5841', class="m">uint16_t</a><a id='5844' tid='5843', class="m">*</a>&gt;(<a id='5846' tid='5845', class="m">addr</a>);
  3574. <a id='5848' tid='5847', class="m">*</a><a id='5850' tid='5849', class="m">ptr</a> <a id='5852' tid='5851', class="m">=</a> <a id='5854' tid='5853', class="m">value</a>;
  3575. <a id='5856' tid='5855', class="m">return</a>;
  3576. }
  3577. <a id='5816' tid='5815', class="m">PrintF</a>(<a id='5818' tid='5817', class="m">&quot;Unaligned unsigned halfword write at 0x%08x, pc=0x%08&quot;</a> <a id='5820' tid='5819', class="m">V8PRIxPTR</a> <a id='5822' tid='5821', class="m">&quot;\n&quot;</a>,
  3578. <a id='5824' tid='5823', class="m">addr</a>,
  3579. <a id='5826' tid='5825', class="m">reinterpret_cast</a>&lt;<a id='5828' tid='5827', class="m">intptr_t</a>&gt;(<a id='5830' tid='5829', class="m">instr</a>));
  3580. <span class="i">UNIMPLEMENTED();</span>
  3581. <span class="i">#endif</span>
  3582. }
  3583. <a id='4300' tid='4299', class="m">void</a> <a id='4302' tid='4301', class="m">Simulator</a><a id='4304' tid='4303', class="m">::</a><a id='4306' tid='4305', class="m">WriteH</a>(<a id='4308' tid='4307', class="m">int32_t</a> <a id='4310' tid='4309', class="m">addr</a>, <a id='4312' tid='4311', class="m">int16_t</a> <a id='4314' tid='4313', class="m">value</a>, <a id='4316' tid='4315', class="m">Instruction</a><a id='4318' tid='4317', class="m">*</a> <a id='4320' tid='4319', class="m">instr</a>) {
  3584. <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
  3585. <span class="i">int16_t* ptr = reinterpret_cast&lt;int16_t*&gt;(addr);</span>
  3586. <span class="i">*ptr = value;</span>
  3587. <span class="i">return;</span>
  3588. <span class="i">#else</span>
  3589. <span class="i">if</span> ((<a id='5866' tid='5865', class="m">addr</a> <a id='5868' tid='5867', class="m">&</a> <a id='5870' tid='5869', class="m">1</a>) <a id='5872' tid='5871', class="m">==</a> <a id='5874' tid='5873', class="m">0</a>) <span class="i">{
  3590. int16_t* ptr = reinterpret_cast&lt;int16_t*&gt;(addr);
  3591. *ptr = value;
  3592. return;
  3593. }</span>
  3594. <a id='4322' tid='4321', class="m">PrintF</a>(<a id='4324' tid='4323', class="m">&quot;Unaligned halfword write at 0x%08x, pc=0x%08&quot;</a> <a id='4326' tid='4325', class="m">V8PRIxPTR</a> <a id='4328' tid='4327', class="m">&quot;\n&quot;</a>,
  3595. <a id='4330' tid='4329', class="m">addr</a>,
  3596. <a id='4332' tid='4331', class="m">reinterpret_cast</a>&lt;<a id='4334' tid='4333', class="m">intptr_t</a>&gt;(<a id='4336' tid='4335', class="m">instr</a>));
  3597. <span class="i">UNIMPLEMENTED();</span>
  3598. <span class="i">#endif</span>
  3599. }
  3600. <span class="i">uint8_t</span> <a id='5726' tid='5725', class="m">Simulator</a><a id='5728' tid='5727', class="m">::</a><a id='5730' tid='5729', class="m">ReadBU</a>(<a id='5732' tid='5731', class="m">int32_t</a> <a id='5734' tid='5733', class="m">addr</a>) {
  3601. <a id='5778' tid='5777', class="m">uint8_t</a><a id='5780' tid='5779', class="m">*</a> <a id='5782' tid='5781', class="m">ptr</a> = <a id='5784' tid='5783', class="m">reinterpret_cast</a>&lt;<a id='5786' tid='5785', class="m">uint8_t</a><a id='5788' tid='5787', class="m">*</a>&gt;(<a id='5790' tid='5789', class="m">addr</a>);
  3602. <span class="i">return *ptr;</span>
  3603. }
  3604. <span class="i">int8_t</span> <a id='5678' tid='5677', class="m">Simulator</a><a id='5680' tid='5679', class="m">::</a><a id='5682' tid='5681', class="m">ReadB</a>(<a id='5684' tid='5683', class="m">int32_t</a> <a id='5686' tid='5685', class="m">addr</a>) {
  3605. <a id='5736' tid='5735', class="m">int8_t</a><a id='5738' tid='5737', class="m">*</a> <a id='5740' tid='5739', class="m">ptr</a> = <a id='5742' tid='5741', class="m">reinterpret_cast</a>&lt;<a id='5744' tid='5743', class="m">int8_t</a><a id='5746' tid='5745', class="m">*</a>&gt;(<a id='5748' tid='5747', class="m">addr</a>);
  3606. <a id='5750' tid='5749', class="m">return</a> <a id='5752' tid='5751', class="m">*</a><a id='5754' tid='5753', class="m">ptr</a>;
  3607. }
  3608. <a id='5688' tid='5687', class="m">void</a> <a id='5690' tid='5689', class="m">Simulator</a><a id='5692' tid='5691', class="m">::</a><a id='5694' tid='5693', class="m">WriteB</a>(<a id='5696' tid='5695', class="m">int32_t</a> <a id='5698' tid='5697', class="m">addr</a>, <a id='5700' tid='5699', class="m">uint8_t</a> <a id='5702' tid='5701', class="m">value</a>) {
  3609. <a id='5704' tid='5703', class="m">uint8_t</a><a id='5706' tid='5705', class="m">*</a> <a id='5708' tid='5707', class="m">ptr</a> = <a id='5710' tid='5709', class="m">reinterpret_cast</a>&lt;<a id='5712' tid='5711', class="m">uint8_t</a><a id='5714' tid='5713', class="m">*</a>&gt;(<a id='5716' tid='5715', class="m">addr</a>);
  3610. <a id='5718' tid='5717', class="m">*</a><a id='5720' tid='5719', class="m">ptr</a> <a id='5722' tid='5721', class="m">=</a> <a id='5724' tid='5723', class="m">value</a>;
  3611. }
  3612. <a id='5640' tid='5639', class="m">void</a> <a id='5642' tid='5641', class="m">Simulator</a><a id='5644' tid='5643', class="m">::</a><a id='5646' tid='5645', class="m">WriteB</a>(<a id='5648' tid='5647', class="m">int32_t</a> <a id='5650' tid='5649', class="m">addr</a>, <a id='5652' tid='5651', class="m">int8_t</a> <a id='5654' tid='5653', class="m">value</a>) {
  3613. <a id='5656' tid='5655', class="m">int8_t</a><a id='5658' tid='5657', class="m">*</a> <a id='5660' tid='5659', class="m">ptr</a> = <a id='5662' tid='5661', class="m">reinterpret_cast</a>&lt;<a id='5664' tid='5663', class="m">int8_t</a><a id='5666' tid='5665', class="m">*</a>&gt;(<a id='5668' tid='5667', class="m">addr</a>);
  3614. <a id='5670' tid='5669', class="m">*</a><a id='5672' tid='5671', class="m">ptr</a> <a id='5674' tid='5673', class="m">=</a> <a id='5676' tid='5675', class="m">value</a>;
  3615. }
  3616. <span class="i">int32_t* Simulator::ReadDW(int32_t addr) {
  3617. #if V8_TARGET_CAN_READ_UNALIGNED
  3618. int32_t* ptr = reinterpret_cast&lt;int32_t*&gt;(addr);
  3619. return ptr;
  3620. #else
  3621. if ((addr & 3) == 0) {
  3622. int32_t* ptr = reinterpret_cast&lt;int32_t*&gt;(addr);
  3623. return ptr;
  3624. }
  3625. PrintF(&quot;Unaligned read at 0x%08x\n&quot;, addr);
  3626. UNIMPLEMENTED();
  3627. return 0;
  3628. #endif
  3629. }</span>
  3630. <span class="i">void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) {
  3631. #if V8_TARGET_CAN_READ_UNALIGNED
  3632. int32_t* ptr = reinterpret_cast&lt;int32_t*&gt;(addr);
  3633. *ptr++ = value1;
  3634. *ptr = value2;
  3635. return;
  3636. #else
  3637. if ((addr & 3) == 0) {
  3638. int32_t* ptr = reinterpret_cast&lt;int32_t*&gt;(addr);
  3639. *ptr++ = value1;
  3640. *ptr = value2;
  3641. return;
  3642. }
  3643. PrintF(&quot;Unaligned write at 0x%08x\n&quot;, addr);
  3644. UNIMPLEMENTED();
  3645. #endif
  3646. }</span>
  3647. // Returns the limit of the stack area to enable checking for stack overflows.
  3648. <a id='5630' tid='5629', class="m">uintptr_t</a> <a id='5632' tid='5631', class="m">Simulator</a><a id='5634' tid='5633', class="m">::</a><a id='5636' tid='5635', class="m">StackLimit</a>() <a id='5638' tid='5637', class="m">const</a> {
  3649. // Leave a safety margin of 256 bytes to prevent overrunning the stack when
  3650. // pushing values.
  3651. <a id='5618' tid='5617', class="m">return</a> <a id='5620' tid='5619', class="m">reinterpret_cast</a>&lt;<a id='5622' tid='5621', class="m">uintptr_t</a>&gt;(<a id='5624' tid='5623', class="m">stack_</a>) <a id='5626' tid='5625', class="m">+</a> <a id='5628' tid='5627', class="m">256</a>;
  3652. }
  3653. // Unsupported instructions use Format to print an error and stop execution.
  3654. <a id='5584' tid='5583', class="m">void</a> <a id='5586' tid='5585', class="m">Simulator</a><a id='5588' tid='5587', class="m">::</a><a id='5590' tid='5589', class="m">Format</a>(<a id='5592' tid='5591', class="m">Instruction</a><a id='5594' tid='5593', class="m">*</a> <a id='5596' tid='5595', class="m">instr</a>, <a id='5598' tid='5597', class="m">const</a> <a id='5600' tid='5599', class="m">char</a><a id='5602' tid='5601', class="m">*</a> <a id='5604' tid='5603', class="m">format</a>) {
  3655. <a id='5606' tid='5605', class="m">PrintF</a>(<a id='5608' tid='5607', class="m">&quot;Simulator found unsupported instruction:\n 0x%08x: %s\n&quot;</a>,
  3656. <a id='5610' tid='5609', class="m">reinterpret_cast</a>&lt;<a id='5612' tid='5611', class="m">intptr_t</a>&gt;(<a id='5614' tid='5613', class="m">instr</a>), <a id='5616' tid='5615', class="m">format</a>);
  3657. <span class="i">UNIMPLEMENTED();</span>
  3658. }
  3659. // Checks if the current instruction should be executed based on its
  3660. // condition bits.
  3661. <span class="i">bool Simulator::ConditionallyExecute(Instruction* instr) {
  3662. switch (instr-&gt;ConditionField()) {
  3663. case eq: return z_flag_;
  3664. case ne: return !z_flag_;
  3665. case cs: return c_flag_;
  3666. case cc: return !c_flag_;
  3667. case mi: return n_flag_;
  3668. case pl: return !n_flag_;
  3669. case vs: return v_flag_;
  3670. case vc: return !v_flag_;
  3671. case hi: return c_flag_ && !z_flag_;
  3672. case ls: return !c_flag_ || z_flag_;
  3673. case ge: return n_flag_ == v_flag_;
  3674. case lt: return n_flag_ != v_flag_;
  3675. case gt: return !z_flag_ && (n_flag_ == v_flag_);
  3676. case le: return z_flag_ || (n_flag_ != v_flag_);
  3677. case al: return true;
  3678. default: UNREACHABLE();
  3679. }
  3680. return false;
  3681. }</span>
  3682. // Calculate and set the Negative and Zero flags.
  3683. <span class="i">void Simulator::SetNZFlags(int32_t val) {
  3684. n_flag_ = (val &lt; 0);
  3685. z_flag_ = (val == 0);
  3686. }</span>
  3687. // Set the Carry flag.
  3688. <span class="i">void Simulator::SetCFlag(bool val) {
  3689. c_flag_ = val;
  3690. }</span>
  3691. // Set the oVerflow flag.
  3692. <span class="i">void Simulator::SetVFlag(bool val) {
  3693. v_flag_ = val;
  3694. }</span>
  3695. // Calculate C flag value for additions.
  3696. <span class="i">bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
  3697. uint32_t uleft = static_cast&lt;uint32_t&gt;(left);
  3698. uint32_t uright = static_cast&lt;uint32_t&gt;(right);
  3699. uint32_t urest = 0xffffffffU - uleft;
  3700. return (uright &gt; urest) ||
  3701. (carry && (((uright + 1) &gt; urest) || (uright &gt; (urest - 1))));
  3702. }</span>
  3703. // Calculate C flag value for subtractions.
  3704. <span class="i">bool Simulator::BorrowFrom(int32_t left, int32_t right) {
  3705. uint32_t uleft = static_cast&lt;uint32_t&gt;(left);
  3706. uint32_t uright = static_cast&lt;uint32_t&gt;(right);
  3707. return (uright &gt; uleft);
  3708. }</span>
  3709. // Calculate V flag value for additions and subtractions.
  3710. <span class="i">bool Simulator::OverflowFrom(int32_t alu_out,
  3711. int32_t left, int32_t right, bool addition) {
  3712. bool overflow;
  3713. if (addition) {
  3714. // operands have the same sign
  3715. overflow = ((left &gt;= 0 && right &gt;= 0) || (left &lt; 0 && right &lt; 0))
  3716. // and operands and result have different sign
  3717. && ((left &lt; 0 && alu_out &gt;= 0) || (left &gt;= 0 && alu_out &lt; 0));
  3718. } else {
  3719. // operands have different signs
  3720. overflow = ((left &lt; 0 && right &gt;= 0) || (left &gt;= 0 && right &lt; 0))
  3721. // and first operand and result have different signs
  3722. && ((left &lt; 0 && alu_out &gt;= 0) || (left &gt;= 0 && alu_out &lt; 0));
  3723. }
  3724. return overflow;
  3725. }</span>
  3726. // Support for VFP comparisons.
  3727. <span class="i">void Simulator::Compute_FPSCR_Flags(double val1, double val2) {
  3728. if (isnan(val1) || isnan(val2)) {
  3729. n_flag_FPSCR_ = false;
  3730. z_flag_FPSCR_ = false;
  3731. c_flag_FPSCR_ = true;
  3732. v_flag_FPSCR_ = true;
  3733. // All non-NaN cases.
  3734. } else if (val1 == val2) {
  3735. n_flag_FPSCR_ = false;
  3736. z_flag_FPSCR_ = true;
  3737. c_flag_FPSCR_ = true;
  3738. v_flag_FPSCR_ = false;
  3739. } else if (val1 &lt; val2) {
  3740. n_flag_FPSCR_ = true;
  3741. z_flag_FPSCR_ = false;
  3742. c_flag_FPSCR_ = false;
  3743. v_flag_FPSCR_ = false;
  3744. } else {
  3745. // Case when (val1 &gt; val2).
  3746. n_flag_FPSCR_ = false;
  3747. z_flag_FPSCR_ = false;
  3748. c_flag_FPSCR_ = true;
  3749. v_flag_FPSCR_ = false;
  3750. }
  3751. }</span>
  3752. <span class="i">void Simulator::Copy_FPSCR_to_APSR() {
  3753. n_flag_ = n_flag_FPSCR_;
  3754. z_flag_ = z_flag_FPSCR_;
  3755. c_flag_ = c_flag_FPSCR_;
  3756. v_flag_ = v_flag_FPSCR_;
  3757. }</span>
  3758. // Addressing Mode 1 - Data-processing operands:
  3759. // Get the value based on the shifter_operand with register.
  3760. <span class="i">int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) {
  3761. ShiftOp shift = instr-&gt;ShiftField();
  3762. int shift_amount = instr-&gt;ShiftAmountValue();
  3763. int32_t result = get_register(instr-&gt;RmValue());
  3764. if (instr-&gt;Bit(4) == 0) {
  3765. // by immediate
  3766. if ((shift == ROR) && (shift_amount == 0)) {
  3767. UNIMPLEMENTED();
  3768. return result;
  3769. } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
  3770. shift_amount = 32;
  3771. }
  3772. switch (shift) {
  3773. case ASR: {
  3774. if (shift_amount == 0) {
  3775. if (result &lt; 0) {
  3776. result = 0xffffffff;
  3777. *carry_out = true;
  3778. } else {
  3779. result = 0;
  3780. *carry_out = false;
  3781. }
  3782. } else {
  3783. result &gt;&gt;= (shift_amount - 1);
  3784. *carry_out = (result & 1) == 1;
  3785. result &gt;&gt;= 1;
  3786. }
  3787. break;
  3788. }
  3789. case LSL: {
  3790. if (shift_amount == 0) {
  3791. *carry_out = c_flag_;
  3792. } else {
  3793. result &lt;&lt;= (shift_amount - 1);
  3794. *carry_out = (result &lt; 0);
  3795. result &lt;&lt;= 1;
  3796. }
  3797. break;
  3798. }
  3799. case LSR: {
  3800. if (shift_amount == 0) {
  3801. result = 0;
  3802. *carry_out = c_flag_;
  3803. } else {
  3804. uint32_t uresult = static_cast&lt;uint32_t&gt;(result);
  3805. uresult &gt;&gt;= (shift_amount - 1);
  3806. *carry_out = (uresult & 1) == 1;
  3807. uresult &gt;&gt;= 1;
  3808. result = static_cast&lt;int32_t&gt;(uresult);
  3809. }
  3810. break;
  3811. }
  3812. case ROR: {
  3813. UNIMPLEMENTED();
  3814. break;
  3815. }
  3816. default: {
  3817. UNREACHABLE();
  3818. break;
  3819. }
  3820. }
  3821. } else {
  3822. // by register
  3823. int rs = instr-&gt;RsValue();
  3824. shift_amount = get_register(rs) &0xff;
  3825. switch (shift) {
  3826. case ASR: {
  3827. if (shift_amount == 0) {
  3828. *carry_out = c_flag_;
  3829. } else if (shift_amount &lt; 32) {
  3830. result &gt;&gt;= (shift_amount - 1);
  3831. *carry_out = (result & 1) == 1;
  3832. result &gt;&gt;= 1;
  3833. } else {
  3834. ASSERT(shift_amount &gt;= 32);
  3835. if (result &lt; 0) {
  3836. *carry_out = true;
  3837. result = 0xffffffff;
  3838. } else {
  3839. *carry_out = false;
  3840. result = 0;
  3841. }
  3842. }
  3843. break;
  3844. }
  3845. case LSL: {
  3846. if (shift_amount == 0) {
  3847. *carry_out = c_flag_;
  3848. } else if (shift_amount &lt; 32) {
  3849. result &lt;&lt;= (shift_amount - 1);
  3850. *carry_out = (result &lt; 0);
  3851. result &lt;&lt;= 1;
  3852. } else if (shift_amount == 32) {
  3853. *carry_out = (result & 1) == 1;
  3854. result = 0;
  3855. } else {
  3856. ASSERT(shift_amount &gt; 32);
  3857. *carry_out = false;
  3858. result = 0;
  3859. }
  3860. break;
  3861. }
  3862. case LSR: {
  3863. if (shift_amount == 0) {
  3864. *carry_out = c_flag_;
  3865. } else if (shift_amount &lt; 32) {
  3866. uint32_t uresult = static_cast&lt;uint32_t&gt;(result);
  3867. uresult &gt;&gt;= (shift_amount - 1);
  3868. *carry_out = (uresult & 1) == 1;
  3869. uresult &gt;&gt;= 1;
  3870. result = static_cast&lt;int32_t&gt;(uresult);
  3871. } else if (shift_amount == 32) {
  3872. *carry_out = (result &lt; 0);
  3873. result = 0;
  3874. } else {
  3875. *carry_out = false;
  3876. result = 0;
  3877. }
  3878. break;
  3879. }
  3880. case ROR: {
  3881. UNIMPLEMENTED();
  3882. break;
  3883. }
  3884. default: {
  3885. UNREACHABLE();
  3886. break;
  3887. }
  3888. }
  3889. }
  3890. return result;
  3891. }</span>
  3892. // Addressing Mode 1 - Data-processing operands:
  3893. // Get the value based on the shifter_operand with immediate.
  3894. <span class="i">int32_t Simulator::GetImm(Instruction* instr, bool* carry_out) {
  3895. int rotate = instr-&gt;RotateValue() * 2;
  3896. int immed8 = instr-&gt;Immed8Value();
  3897. int imm = (immed8 &gt;&gt; rotate) | (immed8 &lt;&lt; (32 - rotate));
  3898. *carry_out = (rotate == 0) ? c_flag_ : (imm &lt; 0);
  3899. return imm;
  3900. }</span>
  3901. <span class="i">static int count_bits(int bit_vector) {
  3902. int count = 0;
  3903. while (bit_vector != 0) {
  3904. if ((bit_vector & 1) != 0) {
  3905. count++;
  3906. }
  3907. bit_vector &gt;&gt;= 1;
  3908. }
  3909. return count;
  3910. }</span>
  3911. <span class="i">void Simulator::ProcessPUW(Instruction* instr,
  3912. int num_regs,
  3913. int reg_size,
  3914. intptr_t* start_address,
  3915. intptr_t* end_address) {
  3916. int rn = instr-&gt;RnValue();
  3917. int32_t rn_val = get_register(rn);
  3918. switch (instr-&gt;PUField()) {
  3919. case da_x: {
  3920. UNIMPLEMENTED();
  3921. break;
  3922. }
  3923. case ia_x: {
  3924. *start_address = rn_val;
  3925. *end_address = rn_val + (num_regs * reg_size) - reg_size;
  3926. rn_val = rn_val + (num_regs * reg_size);
  3927. break;
  3928. }
  3929. case db_x: {
  3930. *start_address = rn_val - (num_regs * reg_size);
  3931. *end_address = rn_val - reg_size;
  3932. rn_val = *start_address;
  3933. break;
  3934. }
  3935. case ib_x: {
  3936. *start_address = rn_val + reg_size;
  3937. *end_address = rn_val + (num_regs * reg_size);
  3938. rn_val = *end_address;
  3939. break;
  3940. }
  3941. default: {
  3942. UNREACHABLE();
  3943. break;
  3944. }
  3945. }
  3946. if (instr-&gt;HasW()) {
  3947. set_register(rn, rn_val);
  3948. }
  3949. }</span>
  3950. // Addressing Mode 4 - Load and Store Multiple
  3951. <span class="i">void Simulator::HandleRList(Instruction* instr, bool load) {
  3952. int rlist = instr-&gt;RlistValue();
  3953. int num_regs = count_bits(rlist);
  3954. intptr_t start_address = 0;
  3955. intptr_t end_address = 0;
  3956. ProcessPUW(instr, num_regs, kPointerSize, &start_address, &end_address);
  3957. intptr_t* address = reinterpret_cast&lt;intptr_t*&gt;(start_address);
  3958. int reg = 0;
  3959. while (rlist != 0) {
  3960. if ((rlist & 1) != 0) {
  3961. if (load) {
  3962. set_register(reg, *address);
  3963. } else {
  3964. *address = get_register(reg);
  3965. }
  3966. address += 1;
  3967. }
  3968. reg++;
  3969. rlist &gt;&gt;= 1;
  3970. }
  3971. ASSERT(end_address == ((intptr_t)address) - 4);
  3972. }</span>
  3973. // Addressing Mode 6 - Load and Store Multiple Coprocessor registers.
  3974. <span class="i">void Simulator::HandleVList(Instruction* instr) {
  3975. VFPRegPrecision precision =
  3976. (instr-&gt;SzValue() == 0) ? kSinglePrecision : kDoublePrecision;
  3977. int operand_size = (precision == kSinglePrecision) ? 4 : 8;
  3978. bool load = (instr-&gt;VLValue() == 0x1);
  3979. int vd;
  3980. int num_regs;
  3981. vd = instr-&gt;VFPDRegValue(precision);
  3982. if (precision == kSinglePrecision) {
  3983. num_regs = instr-&gt;Immed8Value();
  3984. } else {
  3985. num_regs = instr-&gt;Immed8Value() / 2;
  3986. }
  3987. intptr_t start_address = 0;
  3988. intptr_t end_address = 0;
  3989. ProcessPUW(instr, num_regs, operand_size, &start_address, &end_address);
  3990. intptr_t* address = reinterpret_cast&lt;intptr_t*&gt;(start_address);
  3991. for (int reg = vd; reg &lt; vd + num_regs; reg++) {
  3992. if (precision == kSinglePrecision) {
  3993. if (load) {
  3994. set_s_register_from_sinteger(
  3995. reg, ReadW(reinterpret_cast&lt;int32_t&gt;(address), instr));
  3996. } else {
  3997. WriteW(reinterpret_cast&lt;int32_t&gt;(address),
  3998. get_sinteger_from_s_register(reg), instr);
  3999. }
  4000. address += 1;
  4001. } else {
  4002. if (load) {
  4003. set_s_register_from_sinteger(
  4004. 2 * reg, ReadW(reinterpret_cast&lt;int32_t&gt;(address), instr));
  4005. set_s_register_from_sinteger(
  4006. 2 * reg + 1, ReadW(reinterpret_cast&lt;int32_t&gt;(address + 1), instr));
  4007. } else {
  4008. WriteW(reinterpret_cast&lt;int32_t&gt;(address),
  4009. get_sinteger_from_s_register(2 * reg), instr);
  4010. WriteW(reinterpret_cast&lt;int32_t&gt;(address + 1),
  4011. get_sinteger_from_s_register(2 * reg + 1), instr);
  4012. }
  4013. address += 2;
  4014. }
  4015. }
  4016. ASSERT(reinterpret_cast&lt;intptr_t&gt;(address) - operand_size == end_address);
  4017. }</span>
  4018. // Calls into the V8 runtime are based on this very simple interface.
  4019. // Note: To be able to return two values from some calls the code in runtime.cc
  4020. // uses the ObjectPair which is essentially two 32-bit values stuffed into a
  4021. // 64-bit value. With the code below we assume that all runtime calls return
  4022. // 64 bits of result. If they don&#39;t, the r1 result register contains a bogus
  4023. // value, which is fine because it is caller-saved.
  4024. <a id='5552' tid='5551', class="m">typedef</a> <a id='5554' tid='5553', class="m">int64_t</a> (<a id='5556' tid='5555', class="m">*</a><a id='5558' tid='5557', class="m">SimulatorRuntimeCall</a>)(<a id='5560' tid='5559', class="m">int32_t</a> <a id='5562' tid='5561', class="m">arg0</a>,
  4025. <a id='5564' tid='5563', class="m">int32_t</a> <a id='5566' tid='5565', class="m">arg1</a>,
  4026. <a id='5568' tid='5567', class="m">int32_t</a> <a id='5570' tid='5569', class="m">arg2</a>,
  4027. <a id='5572' tid='5571', class="m">int32_t</a> <a id='5574' tid='5573', class="m">arg3</a>,
  4028. <a id='5576' tid='5575', class="m">int32_t</a> <a id='5578' tid='5577', class="m">arg4</a>,
  4029. <a id='5580' tid='5579', class="m">int32_t</a> <a id='5582' tid='5581', class="m">arg5</a>);
  4030. <a id='5528' tid='5527', class="m">typedef</a> <a id='5530' tid='5529', class="m">double</a> (<a id='5532' tid='5531', class="m">*</a><a id='5534' tid='5533', class="m">SimulatorRuntimeFPCall</a>)(<a id='5536' tid='5535', class="m">int32_t</a> <a id='5538' tid='5537', class="m">arg0</a>,
  4031. <a id='5540' tid='5539', class="m">int32_t</a> <a id='5542' tid='5541', class="m">arg1</a>,
  4032. <a id='5544' tid='5543', class="m">int32_t</a> <a id='5546' tid='5545', class="m">arg2</a>,
  4033. <a id='5548' tid='5547', class="m">int32_t</a> <a id='5550' tid='5549', class="m">arg3</a>);
  4034. // This signature supports direct call in to API function native callback
  4035. // (refer to InvocationCallback in v8.h).
  4036. <a id='5506' tid='5505', class="m">typedef</a> <a id='5508' tid='5507', class="m">v8</a><a id='5510' tid='5509', class="m">::</a><a id='5512' tid='5511', class="m">Handle</a>&lt;<a id='5514' tid='5513', class="m">v8</a><a id='5516' tid='5515', class="m">::</a><a id='5518' tid='5517', class="m">Value</a>&gt; (<a id='5520' tid='5519', class="m">*</a><a id='5522' tid='5521', class="m">SimulatorRuntimeDirectApiCall</a>)(<a id='5524' tid='5523', class="m">int32_t</a> <a id='5526' tid='5525', class="m">arg0</a>);
  4037. // This signature supports direct call to accessor getter callback.
  4038. <a id='5480' tid='5479', class="m">typedef</a> <a id='5482' tid='5481', class="m">v8</a><a id='5484' tid='5483', class="m">::</a><a id='5486' tid='5485', class="m">Handle</a>&lt;<a id='5488' tid='5487', class="m">v8</a><a id='5490' tid='5489', class="m">::</a><a id='5492' tid='5491', class="m">Value</a>&gt; (<a id='5494' tid='5493', class="m">*</a><a id='5496' tid='5495', class="m">SimulatorRuntimeDirectGetterCall</a>)(<a id='5498' tid='5497', class="m">int32_t</a> <a id='5500' tid='5499', class="m">arg0</a>,
  4039. <a id='5502' tid='5501', class="m">int32_t</a> <a id='5504' tid='5503', class="m">arg1</a>);
  4040. // Software interrupt instructions are used by the simulator to call into the
  4041. // C-based V8 runtime.
  4042. <a id='5452' tid='5451', class="m">void</a> <a id='5454' tid='5453', class="m">Simulator</a><a id='5456' tid='5455', class="m">::</a><a id='5458' tid='5457', class="m">SoftwareInterrupt</a>(<a id='5460' tid='5459', class="m">Instruction</a><a id='5462' tid='5461', class="m">*</a> <a id='5464' tid='5463', class="m">instr</a>) {
  4043. <span class="i">int svc = instr-&gt;SvcValue();</span>
  4044. <span class="i">switch</span> (<span class="i">svc</span>) {
  4045. <span class="i">case</span> <span class="i">kCallRtRedirected</span>: {
  4046. // Check if stack is aligned. Error if not aligned is reported below to
  4047. // include information on the function called.
  4048. <span class="i">bool stack_aligned =
  4049. (get_register(sp)
  4050. & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0;</span>
  4051. <a id='5466' tid='5465', class="m">Redirection</a><a id='5468' tid='5467', class="m">*</a> <a id='5470' tid='5469', class="m">redirection</a> = <a id='5472' tid='5471', class="m">Redirection</a><a id='5474' tid='5473', class="m">::</a><a id='5476' tid='5475', class="m">FromSwiInstruction</a>(<a id='5478' tid='5477', class="m">instr</a>);
  4052. <span class="i">int32_t arg0 = get_register(r0);</span>
  4053. <span class="i">int32_t arg1 = get_register(r1);</span>
  4054. <span class="i">int32_t arg2 = get_register(r2);</span>
  4055. <span class="i">int32_t arg3 = get_register(r3);</span>
  4056. <a id='5436' tid='5435', class="m">int32_t</a><a id='5438' tid='5437', class="m">*</a> <a id='5440' tid='5439', class="m">stack_pointer</a> = <a id='5442' tid='5441', class="m">reinterpret_cast</a>&lt;<a id='5444' tid='5443', class="m">int32_t</a><a id='5446' tid='5445', class="m">*</a>&gt;(<a id='5448' tid='5447', class="m">get_register</a>(<a id='5450' tid='5449', class="m">sp</a>));
  4057. <span class="i">int32_t arg4 = stack_pointer[0];</span>
  4058. <span class="i">int32_t arg5 = stack_pointer[1];</span>
  4059. <a id='5364' tid='5363', class="m">bool</a> <a id='5366' tid='5365', class="m">fp_call</a> =
  4060. (<a id='5368' tid='5367', class="m">redirection</a>-&gt;<a id='5370' tid='5369', class="m">type</a>() <a id='5372' tid='5371', class="m">==</a> <a id='5374' tid='5373', class="m">ExternalReference</a><a id='5376' tid='5375', class="m">::</a><a id='5378' tid='5377', class="m">BUILTIN_FP_FP_CALL</a>) <a id='5380' tid='5379', class="m">||</a>
  4061. (<a id='5382' tid='5381', class="m">redirection</a>-&gt;<a id='5384' tid='5383', class="m">type</a>() <a id='5386' tid='5385', class="m">==</a> <a id='5388' tid='5387', class="m">ExternalReference</a><a id='5390' tid='5389', class="m">::</a><a id='5392' tid='5391', class="m">BUILTIN_COMPARE_CALL</a>) <a id='5394' tid='5393', class="m">||</a>
  4062. (<a id='5396' tid='5395', class="m">redirection</a>-&gt;<a id='5398' tid='5397', class="m">type</a>() <a id='5400' tid='5399', class="m">==</a> <a id='5402' tid='5401', class="m">ExternalReference</a><a id='5404' tid='5403', class="m">::</a><a id='5406' tid='5405', class="m">BUILTIN_FP_CALL</a>) <a id='5408' tid='5407', class="m">||</a>
  4063. (<a id='5410' tid='5409', class="m">redirection</a>-&gt;<a id='5412' tid='5411', class="m">type</a>() <a id='5414' tid='5413', class="m">==</a> <a id='5416' tid='5415', class="m">ExternalReference</a><a id='5418' tid='5417', class="m">::</a><a id='5420' tid='5419', class="m">BUILTIN_FP_INT_CALL</a>);
  4064. <span class="i">if (use_eabi_hardfloat()) {
  4065. // With the hard floating point calling convention, double
  4066. // arguments are passed in VFP registers. Fetch the arguments
  4067. // from there and call the builtin using soft floating point
  4068. // convention.
  4069. switch (redirection-&gt;type()) {
  4070. case ExternalReference::BUILTIN_FP_FP_CALL:
  4071. case ExternalReference::BUILTIN_COMPARE_CALL:
  4072. arg0 = vfp_register[0];
  4073. arg1 = vfp_register[1];
  4074. arg2 = vfp_register[2];
  4075. arg3 = vfp_register[3];
  4076. break;
  4077. case ExternalReference::BUILTIN_FP_CALL:
  4078. arg0 = vfp_register[0];
  4079. arg1 = vfp_register[1];
  4080. break;
  4081. case ExternalReference::BUILTIN_FP_INT_CALL:
  4082. arg0 = vfp_register[0];
  4083. arg1 = vfp_register[1];
  4084. arg2 = get_register(0);
  4085. break;
  4086. default:
  4087. break;
  4088. }
  4089. }</span>
  4090. // This is dodgy but it works because the C entry stubs are never moved.
  4091. // See comment in codegen-arm.cc and bug 1242173.
  4092. <span class="i">int32_t saved_lr = get_register(lr);</span>
  4093. <a id='5328' tid='5327', class="m">intptr_t</a> <a id='5330' tid='5329', class="m">external</a> =
  4094. <a id='5332' tid='5331', class="m">reinterpret_cast</a>&lt;<a id='5334' tid='5333', class="m">intptr_t</a>&gt;(<a id='5336' tid='5335', class="m">redirection</a>-&gt;<a id='5338' tid='5337', class="m">external_function</a>());
  4095. <a id='5228' tid='5227', class="m">if</a> (<a id='5230' tid='5229', class="m">fp_call</a>) {
  4096. <span class="i">if</span> (<a id='5004' tid='5003', class="m">::</a><a id='5006' tid='5005', class="m">v8</a><a id='5008' tid='5007', class="m">::</a><a id='5010' tid='5009', class="m">internal</a><a id='5012' tid='5011', class="m">::</a><a id='5014' tid='5013', class="m">FLAG_trace_sim</a> <span class="i">||</span> <span class="i">!stack_aligned</span>) {
  4097. <a id='5232' tid='5231', class="m">SimulatorRuntimeFPCall</a> <a id='5234' tid='5233', class="m">target</a> =
  4098. <a id='5236' tid='5235', class="m">reinterpret_cast</a>&lt;<a id='5238' tid='5237', class="m">SimulatorRuntimeFPCall</a>&gt;(<a id='5240' tid='5239', class="m">external</a>);
  4099. <span class="i">double dval0, dval1;</span>
  4100. <span class="i">int32_t ival;</span>
  4101. <a id='5016' tid='5015', class="m">switch</a> (<a id='5018' tid='5017', class="m">redirection</a>-&gt;<a id='5020' tid='5019', class="m">type</a>()) {
  4102. <a id='5022' tid='5021', class="m">case</a> <a id='5024' tid='5023', class="m">ExternalReference</a><a id='5026' tid='5025', class="m">::</a><a id='5028' tid='5027', class="m">BUILTIN_FP_FP_CALL</a>:
  4103. <a id='5030' tid='5029', class="m">case</a> <a id='5032' tid='5031', class="m">ExternalReference</a><a id='5034' tid='5033', class="m">::</a><a id='5036' tid='5035', class="m">BUILTIN_COMPARE_CALL</a>:
  4104. <a id='5038' tid='5037', class="m">GetFpArgs</a>(<a id='5040' tid='5039', class="m">&</a><a id='5042' tid='5041', class="m">dval0</a>, <a id='5044' tid='5043', class="m">&</a><a id='5046' tid='5045', class="m">dval1</a>);
  4105. <a id='5048' tid='5047', class="m">PrintF</a>(<a id='5050' tid='5049', class="m">&quot;Call to host function at %p with args %f, %f&quot;</a>,
  4106. <a id='5052' tid='5051', class="m">FUNCTION_ADDR</a>(<a id='5054' tid='5053', class="m">target</a>), <a id='5056' tid='5055', class="m">dval0</a>, <a id='5058' tid='5057', class="m">dval1</a>);
  4107. <a id='5060' tid='5059', class="m">break</a>;
  4108. <a id='5062' tid='5061', class="m">case</a> <a id='5064' tid='5063', class="m">ExternalReference</a><a id='5066' tid='5065', class="m">::</a><a id='5068' tid='5067', class="m">BUILTIN_FP_CALL</a>:
  4109. <a id='5070' tid='5069', class="m">GetFpArgs</a>(<a id='5072' tid='5071', class="m">&</a><a id='5074' tid='5073', class="m">dval0</a>);
  4110. <a id='5076' tid='5075', class="m">PrintF</a>(<a id='5078' tid='5077', class="m">&quot;Call to host function at %p with arg %f&quot;</a>,
  4111. <a id='5080' tid='5079', class="m">FUNCTION_ADDR</a>(<a id='5082' tid='5081', class="m">target</a>), <a id='5084' tid='5083', class="m">dval0</a>);
  4112. <a id='5086' tid='5085', class="m">break</a>;
  4113. <a id='5088' tid='5087', class="m">case</a> <a id='5090' tid='5089', class="m">ExternalReference</a><a id='5092' tid='5091', class="m">::</a><a id='5094' tid='5093', class="m">BUILTIN_FP_INT_CALL</a>:
  4114. <a id='5096' tid='5095', class="m">GetFpArgs</a>(<a id='5098' tid='5097', class="m">&</a><a id='5100' tid='5099', class="m">dval0</a>, <a id='5102' tid='5101', class="m">&</a><a id='5104' tid='5103', class="m">ival</a>);
  4115. <a id='5106' tid='5105', class="m">PrintF</a>(<a id='5108' tid='5107', class="m">&quot;Call to host function at %p with args %f, %d&quot;</a>,
  4116. <a id='5110' tid='5109', class="m">FUNCTION_ADDR</a>(<a id='5112' tid='5111', class="m">target</a>), <a id='5114' tid='5113', class="m">dval0</a>, <a id='5116' tid='5115', class="m">ival</a>);
  4117. <a id='5118' tid='5117', class="m">break</a>;
  4118. <a id='5120' tid='5119', class="m">default</a>:
  4119. <a id='5122' tid='5121', class="m">UNREACHABLE</a>();
  4120. <a id='5124' tid='5123', class="m">break</a>;
  4121. }
  4122. <span class="i">if (!stack_aligned) {
  4123. PrintF(&quot; with unaligned stack %08x\n&quot;, get_register(sp));
  4124. }</span>
  4125. <span class="i">PrintF(&quot;\n&quot;);</span>
  4126. }
  4127. <span class="i">CHECK(stack_aligned);</span>
  4128. <span class="i">if</span> (<a id='4874' tid='4873', class="m">redirection</a>-&gt;<a id='4876' tid='4875', class="m">type</a>() <a id='4878' tid='4877', class="m">!=</a> <a id='4880' tid='4879', class="m">ExternalReference</a><a id='4882' tid='4881', class="m">::</a><a id='4884' tid='4883', class="m">BUILTIN_COMPARE_CALL</a>) {
  4129. <span class="i">SimulatorRuntimeFPCall target =
  4130. reinterpret_cast&lt;SimulatorRuntimeFPCall&gt;(external);</span>
  4131. <span class="i">double</span> <a id='4620' tid='4619', class="m">result</a> = <a id='4622' tid='4621', class="m">target</a>(<a id='4624' tid='4623', class="m">arg0</a>, <a id='4626' tid='4625', class="m">arg1</a>, <a id='4628' tid='4627', class="m">arg2</a>, <a id='4630' tid='4629', class="m">arg3</a>);
  4132. <span class="i">SetFpResult(result);</span>
  4133. } <span class="i">else</span> {
  4134. <span class="i">SimulatorRuntimeCall target =
  4135. reinterpret_cast&lt;SimulatorRuntimeCall&gt;(external);</span>
  4136. <span class="i">int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);</span>
  4137. <span class="i">int32_t lo_res = static_cast&lt;int32_t&gt;(result);</span>
  4138. <span class="i">int32_t hi_res = static_cast&lt;int32_t&gt;(result &gt;&gt; 32);</span>
  4139. <span class="i">if</span> (<a id='4460' tid='4459', class="m">::</a><a id='4462' tid='4461', class="m">v8</a><a id='4464' tid='4463', class="m">::</a><a id='4466' tid='4465', class="m">internal</a><a id='4468' tid='4467', class="m">::</a><a id='4470' tid='4469', class="m">FLAG_trace_sim</a>) <span class="i">{
  4140. PrintF(&quot;Returned %08x\n&quot;, lo_res);
  4141. }</span>
  4142. <span class="i">set_register(r0, lo_res);</span>
  4143. <span class="i">set_register(r1, hi_res);</span>
  4144. }
  4145. } <a id='5242' tid='5241', class="m">else</a> <a id='5244' tid='5243', class="m">if</a> (<a id='5246' tid='5245', class="m">redirection</a>-&gt;<a id='5248' tid='5247', class="m">type</a>() <a id='5250' tid='5249', class="m">==</a> <a id='5252' tid='5251', class="m">ExternalReference</a><a id='5254' tid='5253', class="m">::</a><a id='5256' tid='5255', class="m">DIRECT_API_CALL</a>) {
  4146. <a id='5258' tid='5257', class="m">SimulatorRuntimeDirectApiCall</a> <a id='5260' tid='5259', class="m">target</a> =
  4147. <a id='5262' tid='5261', class="m">reinterpret_cast</a>&lt;<a id='5264' tid='5263', class="m">SimulatorRuntimeDirectApiCall</a>&gt;(<a id='5266' tid='5265', class="m">external</a>);
  4148. <span class="i">if</span> (<a id='5126' tid='5125', class="m">::</a><a id='5128' tid='5127', class="m">v8</a><a id='5130' tid='5129', class="m">::</a><a id='5132' tid='5131', class="m">internal</a><a id='5134' tid='5133', class="m">::</a><a id='5136' tid='5135', class="m">FLAG_trace_sim</a> <span class="i">||</span> <span class="i">!stack_aligned</span>) <span class="i">{
  4149. PrintF(&quot;Call to host function at %p args %08x&quot;,
  4150. FUNCTION_ADDR(target), arg0);
  4151. if (!stack_aligned) {
  4152. PrintF(&quot; with unaligned stack %08x\n&quot;, get_register(sp));
  4153. }
  4154. PrintF(&quot;\n&quot;);
  4155. }</span>
  4156. <span class="i">CHECK(stack_aligned);</span>
  4157. <a id='4886' tid='4885', class="m">v8</a><a id='4888' tid='4887', class="m">::</a><a id='4890' tid='4889', class="m">Handle</a>&lt;<a id='4892' tid='4891', class="m">v8</a><a id='4894' tid='4893', class="m">::</a><a id='4896' tid='4895', class="m">Value</a>&gt; <span class="i">result = target(arg0)</span>;
  4158. <span class="i">if</span> (<a id='4632' tid='4631', class="m">::</a><a id='4634' tid='4633', class="m">v8</a><a id='4636' tid='4635', class="m">::</a><a id='4638' tid='4637', class="m">internal</a><a id='4640' tid='4639', class="m">::</a><a id='4642' tid='4641', class="m">FLAG_trace_sim</a>) <span class="i">{
  4159. PrintF(&quot;Returned %p\n&quot;, reinterpret_cast&lt;void *&gt;(*result));
  4160. }</span>
  4161. <span class="i">set_register(r0, (int32_t) *result);</span>
  4162. } <a id='5268' tid='5267', class="m">else</a> <a id='5270' tid='5269', class="m">if</a> (<a id='5272' tid='5271', class="m">redirection</a>-&gt;<a id='5274' tid='5273', class="m">type</a>() <a id='5276' tid='5275', class="m">==</a> <a id='5278' tid='5277', class="m">ExternalReference</a><a id='5280' tid='5279', class="m">::</a><a id='5282' tid='5281', class="m">DIRECT_GETTER_CALL</a>) {
  4163. <a id='5284' tid='5283', class="m">SimulatorRuntimeDirectGetterCall</a> <a id='5286' tid='5285', class="m">target</a> =
  4164. <a id='5288' tid='5287', class="m">reinterpret_cast</a>&lt;<a id='5290' tid='5289', class="m">SimulatorRuntimeDirectGetterCall</a>&gt;(<a id='5292' tid='5291', class="m">external</a>);
  4165. <span class="i">if</span> (<a id='5138' tid='5137', class="m">::</a><a id='5140' tid='5139', class="m">v8</a><a id='5142' tid='5141', class="m">::</a><a id='5144' tid='5143', class="m">internal</a><a id='5146' tid='5145', class="m">::</a><a id='5148' tid='5147', class="m">FLAG_trace_sim</a> <span class="i">||</span> <span class="i">!stack_aligned</span>) <span class="i">{
  4166. PrintF(&quot;Call to host function at %p args %08x %08x&quot;,
  4167. FUNCTION_ADDR(target), arg0, arg1);
  4168. if (!stack_aligned) {
  4169. PrintF(&quot; with unaligned stack %08x\n&quot;, get_register(sp));
  4170. }
  4171. PrintF(&quot;\n&quot;);
  4172. }</span>
  4173. <span class="i">CHECK(stack_aligned);</span>
  4174. <a id='4898' tid='4897', class="m">v8</a><a id='4900' tid='4899', class="m">::</a><a id='4902' tid='4901', class="m">Handle</a>&lt;<a id='4904' tid='4903', class="m">v8</a><a id='4906' tid='4905', class="m">::</a><a id='4908' tid='4907', class="m">Value</a>&gt; <span class="i">result = target(arg0, arg1)</span>;
  4175. <span class="i">if (::v8::internal::FLAG_trace_sim) {
  4176. PrintF(&quot;Returned %p\n&quot;, reinterpret_cast&lt;void *&gt;(*result));
  4177. }</span>
  4178. <span class="i">set_register(r0, (int32_t) *result);</span>
  4179. } <a id='5294' tid='5293', class="m">else</a> {
  4180. // builtin call.
  4181. <span class="i">ASSERT(redirection-&gt;type() == ExternalReference::BUILTIN_CALL);</span>
  4182. <a id='5296' tid='5295', class="m">SimulatorRuntimeCall</a> <a id='5298' tid='5297', class="m">target</a> =
  4183. <a id='5300' tid='5299', class="m">reinterpret_cast</a>&lt;<a id='5302' tid='5301', class="m">SimulatorRuntimeCall</a>&gt;(<a id='5304' tid='5303', class="m">external</a>);
  4184. <span class="i">if</span> (<a id='5150' tid='5149', class="m">::</a><a id='5152' tid='5151', class="m">v8</a><a id='5154' tid='5153', class="m">::</a><a id='5156' tid='5155', class="m">internal</a><a id='5158' tid='5157', class="m">::</a><a id='5160' tid='5159', class="m">FLAG_trace_sim</a> <span class="i">||</span> <span class="i">!stack_aligned</span>) <span class="i">{
  4185. PrintF(
  4186. &quot;Call to host function at %p&quot;
  4187. &quot;args %08x, %08x, %08x, %08x, %08x, %08x&quot;,
  4188. FUNCTION_ADDR(target),
  4189. arg0,
  4190. arg1,
  4191. arg2,
  4192. arg3,
  4193. arg4,
  4194. arg5);
  4195. if (!stack_aligned) {
  4196. PrintF(&quot; with unaligned stack %08x\n&quot;, get_register(sp));
  4197. }
  4198. PrintF(&quot;\n&quot;);
  4199. }</span>
  4200. <span class="i">CHECK(stack_aligned);</span>
  4201. <a id='4910' tid='4909', class="m">int64_t</a> <a id='4912' tid='4911', class="m">result</a> = <a id='4914' tid='4913', class="m">target</a>(<a id='4916' tid='4915', class="m">arg0</a>, <a id='4918' tid='4917', class="m">arg1</a>, <a id='4920' tid='4919', class="m">arg2</a>, <a id='4922' tid='4921', class="m">arg3</a>, <a id='4924' tid='4923', class="m">arg4</a>, <a id='4926' tid='4925', class="m">arg5</a>);
  4202. <span class="i">int32_t lo_res = static_cast&lt;int32_t&gt;(result);</span>
  4203. <span class="i">int32_t</span> <span class="i">hi_res</span> = <a id='4644' tid='4643', class="m">static_cast</a>&lt;<a id='4646' tid='4645', class="m">int32_t</a>&gt;(<a id='4648' tid='4647', class="m">result</a> <a id='4650' tid='4649', class="m">&gt;&gt;</a> <a id='4652' tid='4651', class="m">32</a>);
  4204. <span class="i">if (::v8::internal::FLAG_trace_sim) {
  4205. PrintF(&quot;Returned %08x\n&quot;, lo_res);
  4206. }</span>
  4207. <span class="i">set_register(r0, lo_res);</span>
  4208. <span class="i">set_register(r1, hi_res);</span>
  4209. }
  4210. <span class="i">set_register(lr, saved_lr);</span>
  4211. <span class="i">set_pc(get_register(lr));</span>
  4212. <span class="i">break;</span>
  4213. }
  4214. <span class="i">case</span> <span class="i">kBreakpoint</span>: <span class="i">{
  4215. ArmDebugger dbg(this);
  4216. dbg.Debug();
  4217. break;
  4218. }</span>
  4219. // stop uses all codes greater than 1 &lt;&lt; 23.
  4220. <span class="i">default</span>: {
  4221. <span class="i">if</span> <span class="i">(svc &gt;= (1 &lt;&lt; 23))</span> {
  4222. <span class="i">uint32_t code = svc & kStopCodeMask;</span>
  4223. <span class="i">if (isWatchedStop(code)) {
  4224. IncreaseStopCounter(code);
  4225. }</span>
  4226. // Stop if it is enabled, otherwise go on jumping over the stop
  4227. // and the message address.
  4228. <span class="i">if</span> <span class="i">(isEnabledStop(code))</span> <span class="i">{
  4229. ArmDebugger dbg(this);
  4230. dbg.Stop(instr);
  4231. }</span> <span class="i">else</span> {
  4232. <span class="i">set_pc</span>(<span class="i">get_pc()</span> <span class="i">+</span> <a id='4472' tid='4471', class="m">2</a> <a id='4474' tid='4473', class="m">*</a> <a id='4476' tid='4475', class="m">Instruction</a><a id='4478' tid='4477', class="m">::</a><a id='4480' tid='4479', class="m">kInstrSize</a>);
  4233. }
  4234. } <span class="i">else {
  4235. // This is not a valid svc code.
  4236. UNREACHABLE();
  4237. break;
  4238. }</span>
  4239. }
  4240. }
  4241. }
  4242. // Stop helper functions.
  4243. <span class="i">bool Simulator::isStopInstruction(Instruction* instr) {
  4244. return (instr-&gt;Bits(27, 24) == 0xF) && (instr-&gt;SvcValue() &gt;= kStopCode);
  4245. }</span>
  4246. <span class="i">bool Simulator::isWatchedStop(uint32_t code) {
  4247. ASSERT(code &lt;= kMaxStopCode);
  4248. return code &lt; kNumOfWatchedStops;
  4249. }</span>
  4250. <span class="i">bool</span> <span class="i">Simulator::isEnabledStop</span><span class="i">(uint32_t code)</span> {
  4251. <span class="i">ASSERT(code &lt;= kMaxStopCode);</span>
  4252. // Unwatched stops are always enabled.
  4253. <a id='5422' tid='5421', class="m">return</a> <span class="i">!isWatchedStop(code)</span> <span class="i">||</span>
  4254. <a id='5424' tid='5423', class="m">!</a>(<a id='5426' tid='5425', class="m">watched_stops</a>[<a id='5428' tid='5427', class="m">code</a>].<a id='5430' tid='5429', class="m">count</a> <a id='5432' tid='5431', class="m">&</a> <a id='5434' tid='5433', class="m">kStopDisabledBit</a>);
  4255. }
  4256. <a id='5340' tid='5339', class="m">void</a> <a id='5342' tid='5341', class="m">Simulator</a><a id='5344' tid='5343', class="m">::</a><a id='5346' tid='5345', class="m">EnableStop</a>(<a id='5348' tid='5347', class="m">uint32_t</a> <a id='5350' tid='5349', class="m">code</a>) {
  4257. <span class="i">ASSERT(isWatchedStop(code));</span>
  4258. <span class="i">if</span> <span class="i">(!isEnabledStop(code))</span> {
  4259. <a id='5352' tid='5351', class="m">watched_stops</a>[<a id='5354' tid='5353', class="m">code</a>].<a id='5356' tid='5355', class="m">count</a> <a id='5358' tid='5357', class="m">&=</a> <a id='5360' tid='5359', class="m">~</a><a id='5362' tid='5361', class="m">kStopDisabledBit</a>;
  4260. }
  4261. }
  4262. <a id='5306' tid='5305', class="m">void</a> <a id='5308' tid='5307', class="m">Simulator</a><a id='5310' tid='5309', class="m">::</a><a id='5312' tid='5311', class="m">DisableStop</a>(<a id='5314' tid='5313', class="m">uint32_t</a> <a id='5316' tid='5315', class="m">code</a>) {
  4263. <span class="i">ASSERT(isWatchedStop(code));</span>
  4264. <span class="i">if</span> <span class="i">(isEnabledStop(code))</span> {
  4265. <a id='5318' tid='5317', class="m">watched_stops</a>[<a id='5320' tid='5319', class="m">code</a>].<a id='5322' tid='5321', class="m">count</a> <a id='5324' tid='5323', class="m">|=</a> <a id='5326' tid='5325', class="m">kStopDisabledBit</a>;
  4266. }
  4267. }
  4268. <a id='5162' tid='5161', class="m">void</a> <a id='5164' tid='5163', class="m">Simulator</a><a id='5166' tid='5165', class="m">::</a><a id='5168' tid='5167', class="m">IncreaseStopCounter</a>(<a id='5170' tid='5169', class="m">uint32_t</a> <a id='5172' tid='5171', class="m">code</a>) {
  4269. <span class="i">ASSERT(code &lt;= kMaxStopCode);</span>
  4270. <span class="i">ASSERT(isWatchedStop(code));</span>
  4271. <a id='5174' tid='5173', class="m">if</a> ((<a id='5176' tid='5175', class="m">watched_stops</a>[<a id='5178' tid='5177', class="m">code</a>].<a id='5180' tid='5179', class="m">count</a> <a id='5182' tid='5181', class="m">&</a> <a id='5184' tid='5183', class="m">~</a>(<a id='5186' tid='5185', class="m">1</a> <a id='5188' tid='5187', class="m">&lt;&lt;</a> <a id='5190' tid='5189', class="m">31</a>)) <a id='5192' tid='5191', class="m">==</a> <a id='5194' tid='5193', class="m">0x7fffffff</a>) {
  4272. <a id='5196' tid='5195', class="m">PrintF</a>(<a id='5198' tid='5197', class="m">&quot;Stop counter for code %i has overflowed.\n&quot;</a>
  4273. <a id='5200' tid='5199', class="m">&quot;Enabling this code and reseting the counter to 0.\n&quot;</a>, <a id='5202' tid='5201', class="m">code</a>);
  4274. <a id='5204' tid='5203', class="m">watched_stops</a>[<a id='5206' tid='5205', class="m">code</a>].<a id='5208' tid='5207', class="m">count</a> <a id='5210' tid='5209', class="m">=</a> <a id='5212' tid='5211', class="m">0</a>;
  4275. <a id='5214' tid='5213', class="m">EnableStop</a>(<a id='5216' tid='5215', class="m">code</a>);
  4276. } <a id='5218' tid='5217', class="m">else</a> {
  4277. <a id='5220' tid='5219', class="m">watched_stops</a>[<a id='5222' tid='5221', class="m">code</a>].<a id='5224' tid='5223', class="m">count</a><a id='5226' tid='5225', class="m">++</a>;
  4278. }
  4279. }
  4280. // Print a stop status.
  4281. <a id='4976' tid='4975', class="m">void</a> <a id='4978' tid='4977', class="m">Simulator</a><a id='4980' tid='4979', class="m">::</a><a id='4982' tid='4981', class="m">PrintStopInfo</a>(<a id='4984' tid='4983', class="m">uint32_t</a> <a id='4986' tid='4985', class="m">code</a>) {
  4282. <span class="i">ASSERT(code &lt;= kMaxStopCode);</span>
  4283. <span class="i">if</span> <span class="i">(!isWatchedStop(code))</span> <span class="i">{
  4284. PrintF(&quot;Stop not watched.&quot;);
  4285. }</span> <span class="i">else</span> {
  4286. <span class="i">const char* state = isEnabledStop(code) ? &quot;Enabled&quot; : &quot;Disabled&quot;;</span>
  4287. <a id='4988' tid='4987', class="m">int32_t</a> <a id='4990' tid='4989', class="m">count</a> = <a id='4992' tid='4991', class="m">watched_stops</a>[<a id='4994' tid='4993', class="m">code</a>].<a id='4996' tid='4995', class="m">count</a> <a id='4998' tid='4997', class="m">&</a> <a id='5000' tid='4999', class="m">~</a><a id='5002' tid='5001', class="m">kStopDisabledBit</a>;
  4288. // Don&#39;t print the state of unused breakpoints.
  4289. <a id='4928' tid='4927', class="m">if</a> (<a id='4930' tid='4929', class="m">count</a> <a id='4932' tid='4931', class="m">!=</a> <a id='4934' tid='4933', class="m">0</a>) {
  4290. <a id='4936' tid='4935', class="m">if</a> (<a id='4938' tid='4937', class="m">watched_stops</a>[<a id='4940' tid='4939', class="m">code</a>].<a id='4942' tid='4941', class="m">desc</a>) {
  4291. <a id='4944' tid='4943', class="m">PrintF</a>(<a id='4946' tid='4945', class="m">&quot;stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n&quot;</a>,
  4292. <a id='4948' tid='4947', class="m">code</a>, <a id='4950' tid='4949', class="m">code</a>, <a id='4952' tid='4951', class="m">state</a>, <a id='4954' tid='4953', class="m">count</a>, <a id='4956' tid='4955', class="m">watched_stops</a>[<a id='4958' tid='4957', class="m">code</a>].<a id='4960' tid='4959', class="m">desc</a>);
  4293. } <a id='4962' tid='4961', class="m">else</a> {
  4294. <a id='4964' tid='4963', class="m">PrintF</a>(<a id='4966' tid='4965', class="m">&quot;stop %i - 0x%x: \t%s, \tcounter = %i\n&quot;</a>,
  4295. <a id='4968' tid='4967', class="m">code</a>, <a id='4970' tid='4969', class="m">code</a>, <a id='4972' tid='4971', class="m">state</a>, <a id='4974' tid='4973', class="m">count</a>);
  4296. }
  4297. }
  4298. }
  4299. }
  4300. // Handle execution based on instruction types.
  4301. // Instruction types 0 and 1 are both rolled into one function because they
  4302. // only differ in the handling of the shifter_operand.
  4303. <span class="i">void Simulator::DecodeType01(Instruction* instr) {
  4304. int type = instr-&gt;TypeValue();
  4305. if ((type == 0) && instr-&gt;IsSpecialType0()) {
  4306. // multiply instruction or extra loads and stores
  4307. if (instr-&gt;Bits(7, 4) == 9) {
  4308. if (instr-&gt;Bit(24) == 0) {
  4309. // Raw field decoding here. Multiply instructions have their Rd in
  4310. // funny places.
  4311. int rn = instr-&gt;RnValue();
  4312. int rm = instr-&gt;RmValue();
  4313. int rs = instr-&gt;RsValue();
  4314. int32_t rs_val = get_register(rs);
  4315. int32_t rm_val = get_register(rm);
  4316. if (instr-&gt;Bit(23) == 0) {
  4317. if (instr-&gt;Bit(21) == 0) {
  4318. // The MUL instruction description (A 4.1.33) refers to Rd as being
  4319. // the destination for the operation, but it confusingly uses the
  4320. // Rn field to encode it.
  4321. // Format(instr, &quot;mul&#39;cond&#39;s &#39;rn, &#39;rm, &#39;rs&quot;);
  4322. int rd = rn; // Remap the rn field to the Rd register.
  4323. int32_t alu_out = rm_val * rs_val;
  4324. set_register(rd, alu_out);
  4325. if (instr-&gt;HasS()) {
  4326. SetNZFlags(alu_out);
  4327. }
  4328. } else {
  4329. // The MLA instruction description (A 4.1.28) refers to the order
  4330. // of registers as &quot;Rd, Rm, Rs, Rn&quot;. But confusingly it uses the
  4331. // Rn field to encode the Rd register and the Rd field to encode
  4332. // the Rn register.
  4333. Format(instr, &quot;mla&#39;cond&#39;s &#39;rn, &#39;rm, &#39;rs, &#39;rd&quot;);
  4334. }
  4335. } else {
  4336. // The signed/long multiply instructions use the terms RdHi and RdLo
  4337. // when referring to the target registers. They are mapped to the Rn
  4338. // and Rd fields as follows:
  4339. // RdLo == Rd
  4340. // RdHi == Rn (This is confusingly stored in variable rd here
  4341. // because the mul instruction from above uses the
  4342. // Rn field to encode the Rd register. Good luck figuring
  4343. // this out without reading the ARM instruction manual
  4344. // at a very detailed level.)
  4345. // Format(instr, &quot;&#39;um&#39;al&#39;cond&#39;s &#39;rd, &#39;rn, &#39;rs, &#39;rm&quot;);
  4346. int rd_hi = rn; // Remap the rn field to the RdHi register.
  4347. int rd_lo = instr-&gt;RdValue();
  4348. int32_t hi_res = 0;
  4349. int32_t lo_res = 0;
  4350. if (instr-&gt;Bit(22) == 1) {
  4351. int64_t left_op = static_cast&lt;int32_t&gt;(rm_val);
  4352. int64_t right_op = static_cast&lt;int32_t&gt;(rs_val);
  4353. uint64_t result = left_op * right_op;
  4354. hi_res = static_cast&lt;int32_t&gt;(result &gt;&gt; 32);
  4355. lo_res = static_cast&lt;int32_t&gt;(result & 0xffffffff);
  4356. } else {
  4357. // unsigned multiply
  4358. uint64_t left_op = static_cast&lt;uint32_t&gt;(rm_val);
  4359. uint64_t right_op = static_cast&lt;uint32_t&gt;(rs_val);
  4360. uint64_t result = left_op * right_op;
  4361. hi_res = static_cast&lt;int32_t&gt;(result &gt;&gt; 32);
  4362. lo_res = static_cast&lt;int32_t&gt;(result & 0xffffffff);
  4363. }
  4364. set_register(rd_lo, lo_res);
  4365. set_register(rd_hi, hi_res);
  4366. if (instr-&gt;HasS()) {
  4367. UNIMPLEMENTED();
  4368. }
  4369. }
  4370. } else {
  4371. UNIMPLEMENTED(); // Not used by V8.
  4372. }
  4373. } else {
  4374. // extra load/store instructions
  4375. int rd = instr-&gt;RdValue();
  4376. int rn = instr-&gt;RnValue();
  4377. int32_t rn_val = get_register(rn);
  4378. int32_t addr = 0;
  4379. if (instr-&gt;Bit(22) == 0) {
  4380. int rm = instr-&gt;RmValue();
  4381. int32_t rm_val = get_register(rm);
  4382. switch (instr-&gt;PUField()) {
  4383. case da_x: {
  4384. // Format(instr, &quot;&#39;memop&#39;cond&#39;sign&#39;h &#39;rd, [&#39;rn], -&#39;rm&quot;);
  4385. ASSERT(!instr-&gt;HasW());
  4386. addr = rn_val;
  4387. rn_val -= rm_val;
  4388. set_register(rn, rn_val);
  4389. break;
  4390. }
  4391. case ia_x: {
  4392. // Format(instr, &quot;&#39;memop&#39;cond&#39;sign&#39;h &#39;rd, [&#39;rn], +&#39;rm&quot;);
  4393. ASSERT(!instr-&gt;HasW());
  4394. addr = rn_val;
  4395. rn_val += rm_val;
  4396. set_register(rn, rn_val);
  4397. break;
  4398. }
  4399. case db_x: {
  4400. // Format(instr, &quot;&#39;memop&#39;cond&#39;sign&#39;h &#39;rd, [&#39;rn, -&#39;rm]&#39;w&quot;);
  4401. rn_val -= rm_val;
  4402. addr = rn_val;
  4403. if (instr-&gt;HasW()) {
  4404. set_register(rn, rn_val);
  4405. }
  4406. break;
  4407. }
  4408. case ib_x: {
  4409. // Format(instr, &quot;&#39;memop&#39;cond&#39;sign&#39;h &#39;rd, [&#39;rn, +&#39;rm]&#39;w&quot;);
  4410. rn_val += rm_val;
  4411. addr = rn_val;
  4412. if (instr-&gt;HasW()) {
  4413. set_register(rn, rn_val);
  4414. }
  4415. break;
  4416. }
  4417. default: {
  4418. // The PU field is a 2-bit field.
  4419. UNREACHABLE();
  4420. break;
  4421. }
  4422. }
  4423. } else {
  4424. int32_t imm_val = (instr-&gt;ImmedHValue() &lt;&lt; 4) | instr-&gt;ImmedLValue();
  4425. switch (instr-&gt;PUField()) {
  4426. case da_x: {
  4427. // Format(instr, &quot;&#39;memop&#39;cond&#39;sign&#39;h &#39;rd, [&#39;rn], #-&#39;off8&quot;);
  4428. ASSERT(!instr-&gt;HasW());
  4429. addr = rn_val;
  4430. rn_val -= imm_val;
  4431. set_register(rn, rn_val);
  4432. break;
  4433. }
  4434. case ia_x: {
  4435. // Format(instr, &quot;&#39;memop&#39;cond&#39;sign&#39;h &#39;rd, [&#39;rn], #+&#39;off8&quot;);
  4436. ASSERT(!instr-&gt;HasW());
  4437. addr = rn_val;
  4438. rn_val += imm_val;
  4439. set_register(rn, rn_val);
  4440. break;
  4441. }
  4442. case db_x: {
  4443. // Format(instr, &quot;&#39;memop&#39;cond&#39;sign&#39;h &#39;rd, [&#39;rn, #-&#39;off8]&#39;w&quot;);
  4444. rn_val -= imm_val;
  4445. addr = rn_val;
  4446. if (instr-&gt;HasW()) {
  4447. set_register(rn, rn_val);
  4448. }
  4449. break;
  4450. }
  4451. case ib_x: {
  4452. // Format(instr, &quot;&#39;memop&#39;cond&#39;sign&#39;h &#39;rd, [&#39;rn, #+&#39;off8]&#39;w&quot;);
  4453. rn_val += imm_val;
  4454. addr = rn_val;
  4455. if (instr-&gt;HasW()) {
  4456. set_register(rn, rn_val);
  4457. }
  4458. break;
  4459. }
  4460. default: {
  4461. // The PU field is a 2-bit field.
  4462. UNREACHABLE();
  4463. break;
  4464. }
  4465. }
  4466. }
  4467. if (((instr-&gt;Bits(7, 4) & 0xd) == 0xd) && (instr-&gt;Bit(20) == 0)) {
  4468. ASSERT((rd % 2) == 0);
  4469. if (instr-&gt;HasH()) {
  4470. // The strd instruction.
  4471. int32_t value1 = get_register(rd);
  4472. int32_t value2 = get_register(rd+1);
  4473. WriteDW(addr, value1, value2);
  4474. } else {
  4475. // The ldrd instruction.
  4476. int* rn_data = ReadDW(addr);
  4477. set_dw_register(rd, rn_data);
  4478. }
  4479. } else if (instr-&gt;HasH()) {
  4480. if (instr-&gt;HasSign()) {
  4481. if (instr-&gt;HasL()) {
  4482. int16_t val = ReadH(addr, instr);
  4483. set_register(rd, val);
  4484. } else {
  4485. int16_t val = get_register(rd);
  4486. WriteH(addr, val, instr);
  4487. }
  4488. } else {
  4489. if (instr-&gt;HasL()) {
  4490. uint16_t val = ReadHU(addr, instr);
  4491. set_register(rd, val);
  4492. } else {
  4493. uint16_t val = get_register(rd);
  4494. WriteH(addr, val, instr);
  4495. }
  4496. }
  4497. } else {
  4498. // signed byte loads
  4499. ASSERT(instr-&gt;HasSign());
  4500. ASSERT(instr-&gt;HasL());
  4501. int8_t val = ReadB(addr);
  4502. set_register(rd, val);
  4503. }
  4504. return;
  4505. }
  4506. } else if ((type == 0) && instr-&gt;IsMiscType0()) {
  4507. if (instr-&gt;Bits(22, 21) == 1) {
  4508. int rm = instr-&gt;RmValue();
  4509. switch (instr-&gt;BitField(7, 4)) {
  4510. case BX:
  4511. set_pc(get_register(rm));
  4512. break;
  4513. case BLX: {
  4514. uint32_t old_pc = get_pc();
  4515. set_pc(get_register(rm));
  4516. set_register(lr, old_pc + Instruction::kInstrSize);
  4517. break;
  4518. }
  4519. case BKPT: {
  4520. ArmDebugger dbg(this);
  4521. PrintF(&quot;Simulator hit BKPT.\n&quot;);
  4522. dbg.Debug();
  4523. break;
  4524. }
  4525. default:
  4526. UNIMPLEMENTED();
  4527. }
  4528. } else if (instr-&gt;Bits(22, 21) == 3) {
  4529. int rm = instr-&gt;RmValue();
  4530. int rd = instr-&gt;RdValue();
  4531. switch (instr-&gt;BitField(7, 4)) {
  4532. case CLZ: {
  4533. uint32_t bits = get_register(rm);
  4534. int leading_zeros = 0;
  4535. if (bits == 0) {
  4536. leading_zeros = 32;
  4537. } else {
  4538. while ((bits & 0x80000000u) == 0) {
  4539. bits &lt;&lt;= 1;
  4540. leading_zeros++;
  4541. }
  4542. }
  4543. set_register(rd, leading_zeros);
  4544. break;
  4545. }
  4546. default:
  4547. UNIMPLEMENTED();
  4548. }
  4549. } else {
  4550. PrintF(&quot;%08x\n&quot;, instr-&gt;InstructionBits());
  4551. UNIMPLEMENTED();
  4552. }
  4553. } else {
  4554. int rd = instr-&gt;RdValue();
  4555. int rn = instr-&gt;RnValue();
  4556. int32_t rn_val = get_register(rn);
  4557. int32_t shifter_operand = 0;
  4558. bool shifter_carry_out = 0;
  4559. if (type == 0) {
  4560. shifter_operand = GetShiftRm(instr, &shifter_carry_out);
  4561. } else {
  4562. ASSERT(instr-&gt;TypeValue() == 1);
  4563. shifter_operand = GetImm(instr, &shifter_carry_out);
  4564. }
  4565. int32_t alu_out;
  4566. switch (instr-&gt;OpcodeField()) {
  4567. case AND: {
  4568. // Format(instr, &quot;and&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4569. // Format(instr, &quot;and&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4570. alu_out = rn_val & shifter_operand;
  4571. set_register(rd, alu_out);
  4572. if (instr-&gt;HasS()) {
  4573. SetNZFlags(alu_out);
  4574. SetCFlag(shifter_carry_out);
  4575. }
  4576. break;
  4577. }
  4578. case EOR: {
  4579. // Format(instr, &quot;eor&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4580. // Format(instr, &quot;eor&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4581. alu_out = rn_val ^ shifter_operand;
  4582. set_register(rd, alu_out);
  4583. if (instr-&gt;HasS()) {
  4584. SetNZFlags(alu_out);
  4585. SetCFlag(shifter_carry_out);
  4586. }
  4587. break;
  4588. }
  4589. case SUB: {
  4590. // Format(instr, &quot;sub&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4591. // Format(instr, &quot;sub&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4592. alu_out = rn_val - shifter_operand;
  4593. set_register(rd, alu_out);
  4594. if (instr-&gt;HasS()) {
  4595. SetNZFlags(alu_out);
  4596. SetCFlag(!BorrowFrom(rn_val, shifter_operand));
  4597. SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
  4598. }
  4599. break;
  4600. }
  4601. case RSB: {
  4602. // Format(instr, &quot;rsb&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4603. // Format(instr, &quot;rsb&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4604. alu_out = shifter_operand - rn_val;
  4605. set_register(rd, alu_out);
  4606. if (instr-&gt;HasS()) {
  4607. SetNZFlags(alu_out);
  4608. SetCFlag(!BorrowFrom(shifter_operand, rn_val));
  4609. SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));
  4610. }
  4611. break;
  4612. }
  4613. case ADD: {
  4614. // Format(instr, &quot;add&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4615. // Format(instr, &quot;add&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4616. alu_out = rn_val + shifter_operand;
  4617. set_register(rd, alu_out);
  4618. if (instr-&gt;HasS()) {
  4619. SetNZFlags(alu_out);
  4620. SetCFlag(CarryFrom(rn_val, shifter_operand));
  4621. SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
  4622. }
  4623. break;
  4624. }
  4625. case ADC: {
  4626. // Format(instr, &quot;adc&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4627. // Format(instr, &quot;adc&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4628. alu_out = rn_val + shifter_operand + GetCarry();
  4629. set_register(rd, alu_out);
  4630. if (instr-&gt;HasS()) {
  4631. SetNZFlags(alu_out);
  4632. SetCFlag(CarryFrom(rn_val, shifter_operand, GetCarry()));
  4633. SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
  4634. }
  4635. break;
  4636. }
  4637. case SBC: {
  4638. Format(instr, &quot;sbc&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4639. Format(instr, &quot;sbc&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4640. break;
  4641. }
  4642. case RSC: {
  4643. Format(instr, &quot;rsc&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4644. Format(instr, &quot;rsc&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4645. break;
  4646. }
  4647. case TST: {
  4648. if (instr-&gt;HasS()) {
  4649. // Format(instr, &quot;tst&#39;cond &#39;rn, &#39;shift_rm&quot;);
  4650. // Format(instr, &quot;tst&#39;cond &#39;rn, &#39;imm&quot;);
  4651. alu_out = rn_val & shifter_operand;
  4652. SetNZFlags(alu_out);
  4653. SetCFlag(shifter_carry_out);
  4654. } else {
  4655. // Format(instr, &quot;movw&#39;cond &#39;rd, &#39;imm&quot;).
  4656. alu_out = instr-&gt;ImmedMovwMovtValue();
  4657. set_register(rd, alu_out);
  4658. }
  4659. break;
  4660. }
  4661. case TEQ: {
  4662. if (instr-&gt;HasS()) {
  4663. // Format(instr, &quot;teq&#39;cond &#39;rn, &#39;shift_rm&quot;);
  4664. // Format(instr, &quot;teq&#39;cond &#39;rn, &#39;imm&quot;);
  4665. alu_out = rn_val ^ shifter_operand;
  4666. SetNZFlags(alu_out);
  4667. SetCFlag(shifter_carry_out);
  4668. } else {
  4669. // Other instructions matching this pattern are handled in the
  4670. // miscellaneous instructions part above.
  4671. UNREACHABLE();
  4672. }
  4673. break;
  4674. }
  4675. case CMP: {
  4676. if (instr-&gt;HasS()) {
  4677. // Format(instr, &quot;cmp&#39;cond &#39;rn, &#39;shift_rm&quot;);
  4678. // Format(instr, &quot;cmp&#39;cond &#39;rn, &#39;imm&quot;);
  4679. alu_out = rn_val - shifter_operand;
  4680. SetNZFlags(alu_out);
  4681. SetCFlag(!BorrowFrom(rn_val, shifter_operand));
  4682. SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
  4683. } else {
  4684. // Format(instr, &quot;movt&#39;cond &#39;rd, &#39;imm&quot;).
  4685. alu_out = (get_register(rd) & 0xffff) |
  4686. (instr-&gt;ImmedMovwMovtValue() &lt;&lt; 16);
  4687. set_register(rd, alu_out);
  4688. }
  4689. break;
  4690. }
  4691. case CMN: {
  4692. if (instr-&gt;HasS()) {
  4693. // Format(instr, &quot;cmn&#39;cond &#39;rn, &#39;shift_rm&quot;);
  4694. // Format(instr, &quot;cmn&#39;cond &#39;rn, &#39;imm&quot;);
  4695. alu_out = rn_val + shifter_operand;
  4696. SetNZFlags(alu_out);
  4697. SetCFlag(!CarryFrom(rn_val, shifter_operand));
  4698. SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
  4699. } else {
  4700. // Other instructions matching this pattern are handled in the
  4701. // miscellaneous instructions part above.
  4702. UNREACHABLE();
  4703. }
  4704. break;
  4705. }
  4706. case ORR: {
  4707. // Format(instr, &quot;orr&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4708. // Format(instr, &quot;orr&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4709. alu_out = rn_val | shifter_operand;
  4710. set_register(rd, alu_out);
  4711. if (instr-&gt;HasS()) {
  4712. SetNZFlags(alu_out);
  4713. SetCFlag(shifter_carry_out);
  4714. }
  4715. break;
  4716. }
  4717. case MOV: {
  4718. // Format(instr, &quot;mov&#39;cond&#39;s &#39;rd, &#39;shift_rm&quot;);
  4719. // Format(instr, &quot;mov&#39;cond&#39;s &#39;rd, &#39;imm&quot;);
  4720. alu_out = shifter_operand;
  4721. set_register(rd, alu_out);
  4722. if (instr-&gt;HasS()) {
  4723. SetNZFlags(alu_out);
  4724. SetCFlag(shifter_carry_out);
  4725. }
  4726. break;
  4727. }
  4728. case BIC: {
  4729. // Format(instr, &quot;bic&#39;cond&#39;s &#39;rd, &#39;rn, &#39;shift_rm&quot;);
  4730. // Format(instr, &quot;bic&#39;cond&#39;s &#39;rd, &#39;rn, &#39;imm&quot;);
  4731. alu_out = rn_val & ~shifter_operand;
  4732. set_register(rd, alu_out);
  4733. if (instr-&gt;HasS()) {
  4734. SetNZFlags(alu_out);
  4735. SetCFlag(shifter_carry_out);
  4736. }
  4737. break;
  4738. }
  4739. case MVN: {
  4740. // Format(instr, &quot;mvn&#39;cond&#39;s &#39;rd, &#39;shift_rm&quot;);
  4741. // Format(instr, &quot;mvn&#39;cond&#39;s &#39;rd, &#39;imm&quot;);
  4742. alu_out = ~shifter_operand;
  4743. set_register(rd, alu_out);
  4744. if (instr-&gt;HasS()) {
  4745. SetNZFlags(alu_out);
  4746. SetCFlag(shifter_carry_out);
  4747. }
  4748. break;
  4749. }
  4750. default: {
  4751. UNREACHABLE();
  4752. break;
  4753. }
  4754. }
  4755. }
  4756. }</span>
  4757. <span class="i">void Simulator::DecodeType2(Instruction* instr) {
  4758. int rd = instr-&gt;RdValue();
  4759. int rn = instr-&gt;RnValue();
  4760. int32_t rn_val = get_register(rn);
  4761. int32_t im_val = instr-&gt;Offset12Value();
  4762. int32_t addr = 0;
  4763. switch (instr-&gt;PUField()) {
  4764. case da_x: {
  4765. // Format(instr, &quot;&#39;memop&#39;cond&#39;b &#39;rd, [&#39;rn], #-&#39;off12&quot;);
  4766. ASSERT(!instr-&gt;HasW());
  4767. addr = rn_val;
  4768. rn_val -= im_val;
  4769. set_register(rn, rn_val);
  4770. break;
  4771. }
  4772. case ia_x: {
  4773. // Format(instr, &quot;&#39;memop&#39;cond&#39;b &#39;rd, [&#39;rn], #+&#39;off12&quot;);
  4774. ASSERT(!instr-&gt;HasW());
  4775. addr = rn_val;
  4776. rn_val += im_val;
  4777. set_register(rn, rn_val);
  4778. break;
  4779. }
  4780. case db_x: {
  4781. // Format(instr, &quot;&#39;memop&#39;cond&#39;b &#39;rd, [&#39;rn, #-&#39;off12]&#39;w&quot;);
  4782. rn_val -= im_val;
  4783. addr = rn_val;
  4784. if (instr-&gt;HasW()) {
  4785. set_register(rn, rn_val);
  4786. }
  4787. break;
  4788. }
  4789. case ib_x: {
  4790. // Format(instr, &quot;&#39;memop&#39;cond&#39;b &#39;rd, [&#39;rn, #+&#39;off12]&#39;w&quot;);
  4791. rn_val += im_val;
  4792. addr = rn_val;
  4793. if (instr-&gt;HasW()) {
  4794. set_register(rn, rn_val);
  4795. }
  4796. break;
  4797. }
  4798. default: {
  4799. UNREACHABLE();
  4800. break;
  4801. }
  4802. }
  4803. if (instr-&gt;HasB()) {
  4804. if (instr-&gt;HasL()) {
  4805. byte val = ReadBU(addr);
  4806. set_register(rd, val);
  4807. } else {
  4808. byte val = get_register(rd);
  4809. WriteB(addr, val);
  4810. }
  4811. } else {
  4812. if (instr-&gt;HasL()) {
  4813. set_register(rd, ReadW(addr, instr));
  4814. } else {
  4815. WriteW(addr, get_register(rd), instr);
  4816. }
  4817. }
  4818. }</span>
  4819. <span class="i">void Simulator::DecodeType3(Instruction* instr) {
  4820. int rd = instr-&gt;RdValue();
  4821. int rn = instr-&gt;RnValue();
  4822. int32_t rn_val = get_register(rn);
  4823. bool shifter_carry_out = 0;
  4824. int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
  4825. int32_t addr = 0;
  4826. switch (instr-&gt;PUField()) {
  4827. case da_x: {
  4828. ASSERT(!instr-&gt;HasW());
  4829. Format(instr, &quot;&#39;memop&#39;cond&#39;b &#39;rd, [&#39;rn], -&#39;shift_rm&quot;);
  4830. UNIMPLEMENTED();
  4831. break;
  4832. }
  4833. case ia_x: {
  4834. if (instr-&gt;HasW()) {
  4835. ASSERT(instr-&gt;Bits(5, 4) == 0x1);
  4836. if (instr-&gt;Bit(22) == 0x1) { // USAT.
  4837. int32_t sat_pos = instr-&gt;Bits(20, 16);
  4838. int32_t sat_val = (1 &lt;&lt; sat_pos) - 1;
  4839. int32_t shift = instr-&gt;Bits(11, 7);
  4840. int32_t shift_type = instr-&gt;Bit(6);
  4841. int32_t rm_val = get_register(instr-&gt;RmValue());
  4842. if (shift_type == 0) { // LSL
  4843. rm_val &lt;&lt;= shift;
  4844. } else { // ASR
  4845. rm_val &gt;&gt;= shift;
  4846. }
  4847. // If saturation occurs, the Q flag should be set in the CPSR.
  4848. // There is no Q flag yet, and no instruction (MRS) to read the
  4849. // CPSR directly.
  4850. if (rm_val &gt; sat_val) {
  4851. rm_val = sat_val;
  4852. } else if (rm_val &lt; 0) {
  4853. rm_val = 0;
  4854. }
  4855. set_register(rd, rm_val);
  4856. } else { // SSAT.
  4857. UNIMPLEMENTED();
  4858. }
  4859. return;
  4860. } else {
  4861. Format(instr, &quot;&#39;memop&#39;cond&#39;b &#39;rd, [&#39;rn], +&#39;shift_rm&quot;);
  4862. UNIMPLEMENTED();
  4863. }
  4864. break;
  4865. }
  4866. case db_x: {
  4867. // Format(instr, &quot;&#39;memop&#39;cond&#39;b &#39;rd, [&#39;rn, -&#39;shift_rm]&#39;w&quot;);
  4868. addr = rn_val - shifter_operand;
  4869. if (instr-&gt;HasW()) {
  4870. set_register(rn, addr);
  4871. }
  4872. break;
  4873. }
  4874. case ib_x: {
  4875. if (instr-&gt;HasW() && (instr-&gt;Bits(6, 4) == 0x5)) {
  4876. uint32_t widthminus1 = static_cast&lt;uint32_t&gt;(instr-&gt;Bits(20, 16));
  4877. uint32_t lsbit = static_cast&lt;uint32_t&gt;(instr-&gt;Bits(11, 7));
  4878. uint32_t msbit = widthminus1 + lsbit;
  4879. if (msbit &lt;= 31) {
  4880. if (instr-&gt;Bit(22)) {
  4881. // ubfx - unsigned bitfield extract.
  4882. uint32_t rm_val =
  4883. static_cast&lt;uint32_t&gt;(get_register(instr-&gt;RmValue()));
  4884. uint32_t extr_val = rm_val &lt;&lt; (31 - msbit);
  4885. extr_val = extr_val &gt;&gt; (31 - widthminus1);
  4886. set_register(instr-&gt;RdValue(), extr_val);
  4887. } else {
  4888. // sbfx - signed bitfield extract.
  4889. int32_t rm_val = get_register(instr-&gt;RmValue());
  4890. int32_t extr_val = rm_val &lt;&lt; (31 - msbit);
  4891. extr_val = extr_val &gt;&gt; (31 - widthminus1);
  4892. set_register(instr-&gt;RdValue(), extr_val);
  4893. }
  4894. } else {
  4895. UNREACHABLE();
  4896. }
  4897. return;
  4898. } else if (!instr-&gt;HasW() && (instr-&gt;Bits(6, 4) == 0x1)) {
  4899. uint32_t lsbit = static_cast&lt;uint32_t&gt;(instr-&gt;Bits(11, 7));
  4900. uint32_t msbit = static_cast&lt;uint32_t&gt;(instr-&gt;Bits(20, 16));
  4901. if (msbit &gt;= lsbit) {
  4902. // bfc or bfi - bitfield clear/insert.
  4903. uint32_t rd_val =
  4904. static_cast&lt;uint32_t&gt;(get_register(instr-&gt;RdValue()));
  4905. uint32_t bitcount = msbit - lsbit + 1;
  4906. uint32_t mask = (1 &lt;&lt; bitcount) - 1;
  4907. rd_val &= ~(mask &lt;&lt; lsbit);
  4908. if (instr-&gt;RmValue() != 15) {
  4909. // bfi - bitfield insert.
  4910. uint32_t rm_val =
  4911. static_cast&lt;uint32_t&gt;(get_register(instr-&gt;RmValue()));
  4912. rm_val &= mask;
  4913. rd_val |= rm_val &lt;&lt; lsbit;
  4914. }
  4915. set_register(instr-&gt;RdValue(), rd_val);
  4916. } else {
  4917. UNREACHABLE();
  4918. }
  4919. return;
  4920. } else {
  4921. // Format(instr, &quot;&#39;memop&#39;cond&#39;b &#39;rd, [&#39;rn, +&#39;shift_rm]&#39;w&quot;);
  4922. addr = rn_val + shifter_operand;
  4923. if (instr-&gt;HasW()) {
  4924. set_register(rn, addr);
  4925. }
  4926. }
  4927. break;
  4928. }
  4929. default: {
  4930. UNREACHABLE();
  4931. break;
  4932. }
  4933. }
  4934. if (instr-&gt;HasB()) {
  4935. if (instr-&gt;HasL()) {
  4936. uint8_t byte = ReadB(addr);
  4937. set_register(rd, byte);
  4938. } else {
  4939. uint8_t byte = get_register(rd);
  4940. WriteB(addr, byte);
  4941. }
  4942. } else {
  4943. if (instr-&gt;HasL()) {
  4944. set_register(rd, ReadW(addr, instr));
  4945. } else {
  4946. WriteW(addr, get_register(rd), instr);
  4947. }
  4948. }
  4949. }</span>
  4950. <span class="i">void Simulator::DecodeType4(Instruction* instr) {
  4951. ASSERT(instr-&gt;Bit(22) == 0); // only allowed to be set in privileged mode
  4952. if (instr-&gt;HasL()) {
  4953. // Format(instr, &quot;ldm&#39;cond&#39;pu &#39;rn&#39;w, &#39;rlist&quot;);
  4954. HandleRList(instr, true);
  4955. } else {
  4956. // Format(instr, &quot;stm&#39;cond&#39;pu &#39;rn&#39;w, &#39;rlist&quot;);
  4957. HandleRList(instr, false);
  4958. }
  4959. }</span>
  4960. <span class="i">void Simulator::DecodeType5(Instruction* instr) {
  4961. // Format(instr, &quot;b&#39;l&#39;cond &#39;target&quot;);
  4962. int off = (instr-&gt;SImmed24Value() &lt;&lt; 2);
  4963. intptr_t pc_address = get_pc();
  4964. if (instr-&gt;HasLink()) {
  4965. set_register(lr, pc_address + Instruction::kInstrSize);
  4966. }
  4967. int pc_reg = get_register(pc);
  4968. set_pc(pc_reg + off);
  4969. }</span>
  4970. <span class="i">void Simulator::DecodeType6(Instruction* instr) {
  4971. DecodeType6CoprocessorIns(instr);
  4972. }</span>
  4973. <span class="i">void Simulator::DecodeType7(Instruction* instr) {
  4974. if (instr-&gt;Bit(24) == 1) {
  4975. SoftwareInterrupt(instr);
  4976. } else {
  4977. DecodeTypeVFP(instr);
  4978. }
  4979. }</span>
  4980. // void Simulator::DecodeTypeVFP(Instruction* instr)
  4981. // The Following ARMv7 VFPv instructions are currently supported.
  4982. // vmov :Sn = Rt
  4983. // vmov :Rt = Sn
  4984. // vcvt: Dd = Sm
  4985. // vcvt: Sd = Dm
  4986. // Dd = vabs(Dm)
  4987. // Dd = vneg(Dm)
  4988. // Dd = vadd(Dn, Dm)
  4989. // Dd = vsub(Dn, Dm)
  4990. // Dd = vmul(Dn, Dm)
  4991. // Dd = vdiv(Dn, Dm)
  4992. // vcmp(Dd, Dm)
  4993. // vmrs
  4994. // Dd = vsqrt(Dm)
  4995. <span class="i">void Simulator::DecodeTypeVFP(Instruction* instr) {
  4996. ASSERT((instr-&gt;TypeValue() == 7) && (instr-&gt;Bit(24) == 0x0) );
  4997. ASSERT(instr-&gt;Bits(11, 9) == 0x5);
  4998. // Obtain double precision register codes.
  4999. int vm = instr-&gt;VFPMRegValue(kDoublePrecision);
  5000. int vd = instr-&gt;VFPDRegValue(kDoublePrecision);
  5001. int vn = instr-&gt;VFPNRegValue(kDoublePrecision);
  5002. if (instr-&gt;Bit(4) == 0) {
  5003. if (instr-&gt;Opc1Value() == 0x7) {
  5004. // Other data processing instructions
  5005. if ((instr-&gt;Opc2Value() == 0x0) && (instr-&gt;Opc3Value() == 0x1)) {
  5006. // vmov register to register.
  5007. if (instr-&gt;SzValue() == 0x1) {
  5008. int m = instr-&gt;VFPMRegValue(kDoublePrecision);
  5009. int d = instr-&gt;VFPDRegValue(kDoublePrecision);
  5010. set_d_register_from_double(d, get_double_from_d_register(m));
  5011. } else {
  5012. int m = instr-&gt;VFPMRegValue(kSinglePrecision);
  5013. int d = instr-&gt;VFPDRegValue(kSinglePrecision);
  5014. set_s_register_from_float(d, get_float_from_s_register(m));
  5015. }
  5016. } else if ((instr-&gt;Opc2Value() == 0x0) && (instr-&gt;Opc3Value() == 0x3)) {
  5017. // vabs
  5018. double dm_value = get_double_from_d_register(vm);
  5019. double dd_value = fabs(dm_value);
  5020. set_d_register_from_double(vd, dd_value);
  5021. } else if ((instr-&gt;Opc2Value() == 0x1) && (instr-&gt;Opc3Value() == 0x1)) {
  5022. // vneg
  5023. double dm_value = get_double_from_d_register(vm);
  5024. double dd_value = -dm_value;
  5025. set_d_register_from_double(vd, dd_value);
  5026. } else if ((instr-&gt;Opc2Value() == 0x7) && (instr-&gt;Opc3Value() == 0x3)) {
  5027. DecodeVCVTBetweenDoubleAndSingle(instr);
  5028. } else if ((instr-&gt;Opc2Value() == 0x8) && (instr-&gt;Opc3Value() & 0x1)) {
  5029. DecodeVCVTBetweenFloatingPointAndInteger(instr);
  5030. } else if (((instr-&gt;Opc2Value() &gt;&gt; 1) == 0x6) &&
  5031. (instr-&gt;Opc3Value() & 0x1)) {
  5032. DecodeVCVTBetweenFloatingPointAndInteger(instr);
  5033. } else if (((instr-&gt;Opc2Value() == 0x4) || (instr-&gt;Opc2Value() == 0x5)) &&
  5034. (instr-&gt;Opc3Value() & 0x1)) {
  5035. DecodeVCMP(instr);
  5036. } else if (((instr-&gt;Opc2Value() == 0x1)) && (instr-&gt;Opc3Value() == 0x3)) {
  5037. // vsqrt
  5038. double dm_value = get_double_from_d_register(vm);
  5039. double dd_value = sqrt(dm_value);
  5040. set_d_register_from_double(vd, dd_value);
  5041. } else if (instr-&gt;Opc3Value() == 0x0) {
  5042. // vmov immediate.
  5043. if (instr-&gt;SzValue() == 0x1) {
  5044. set_d_register_from_double(vd, instr-&gt;DoubleImmedVmov());
  5045. } else {
  5046. UNREACHABLE(); // Not used by v8.
  5047. }
  5048. } else {
  5049. UNREACHABLE(); // Not used by V8.
  5050. }
  5051. } else if (instr-&gt;Opc1Value() == 0x3) {
  5052. if (instr-&gt;SzValue() != 0x1) {
  5053. UNREACHABLE(); // Not used by V8.
  5054. }
  5055. if (instr-&gt;Opc3Value() & 0x1) {
  5056. // vsub
  5057. double dn_value = get_double_from_d_register(vn);
  5058. double dm_value = get_double_from_d_register(vm);
  5059. double dd_value = dn_value - dm_value;
  5060. set_d_register_from_double(vd, dd_value);
  5061. } else {
  5062. // vadd
  5063. double dn_value = get_double_from_d_register(vn);
  5064. double dm_value = get_double_from_d_register(vm);
  5065. double dd_value = dn_value + dm_value;
  5066. set_d_register_from_double(vd, dd_value);
  5067. }
  5068. } else if ((instr-&gt;Opc1Value() == 0x2) && !(instr-&gt;Opc3Value() & 0x1)) {
  5069. // vmul
  5070. if (instr-&gt;SzValue() != 0x1) {
  5071. UNREACHABLE(); // Not used by V8.
  5072. }
  5073. double dn_value = get_double_from_d_register(vn);
  5074. double dm_value = get_double_from_d_register(vm);
  5075. double dd_value = dn_value * dm_value;
  5076. set_d_register_from_double(vd, dd_value);
  5077. } else if ((instr-&gt;Opc1Value() == 0x4) && !(instr-&gt;Opc3Value() & 0x1)) {
  5078. // vdiv
  5079. if (instr-&gt;SzValue() != 0x1) {
  5080. UNREACHABLE(); // Not used by V8.
  5081. }
  5082. double dn_value = get_double_from_d_register(vn);
  5083. double dm_value = get_double_from_d_register(vm);
  5084. double dd_value = dn_value / dm_value;
  5085. div_zero_vfp_flag_ = (dm_value == 0);
  5086. set_d_register_from_double(vd, dd_value);
  5087. } else {
  5088. UNIMPLEMENTED(); // Not used by V8.
  5089. }
  5090. } else {
  5091. if ((instr-&gt;VCValue() == 0x0) &&
  5092. (instr-&gt;VAValue() == 0x0)) {
  5093. DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
  5094. } else if ((instr-&gt;VLValue() == 0x1) &&
  5095. (instr-&gt;VCValue() == 0x0) &&
  5096. (instr-&gt;VAValue() == 0x7) &&
  5097. (instr-&gt;Bits(19, 16) == 0x1)) {
  5098. // vmrs
  5099. uint32_t rt = instr-&gt;RtValue();
  5100. if (rt == 0xF) {
  5101. Copy_FPSCR_to_APSR();
  5102. } else {
  5103. // Emulate FPSCR from the Simulator flags.
  5104. uint32_t fpscr = (n_flag_FPSCR_ &lt;&lt; 31) |
  5105. (z_flag_FPSCR_ &lt;&lt; 30) |
  5106. (c_flag_FPSCR_ &lt;&lt; 29) |
  5107. (v_flag_FPSCR_ &lt;&lt; 28) |
  5108. (inexact_vfp_flag_ &lt;&lt; 4) |
  5109. (underflow_vfp_flag_ &lt;&lt; 3) |
  5110. (overflow_vfp_flag_ &lt;&lt; 2) |
  5111. (div_zero_vfp_flag_ &lt;&lt; 1) |
  5112. (inv_op_vfp_flag_ &lt;&lt; 0) |
  5113. (FPSCR_rounding_mode_);
  5114. set_register(rt, fpscr);
  5115. }
  5116. } else if ((instr-&gt;VLValue() == 0x0) &&
  5117. (instr-&gt;VCValue() == 0x0) &&
  5118. (instr-&gt;VAValue() == 0x7) &&
  5119. (instr-&gt;Bits(19, 16) == 0x1)) {
  5120. // vmsr
  5121. uint32_t rt = instr-&gt;RtValue();
  5122. if (rt == pc) {
  5123. UNREACHABLE();
  5124. } else {
  5125. uint32_t rt_value = get_register(rt);
  5126. n_flag_FPSCR_ = (rt_value &gt;&gt; 31) & 1;
  5127. z_flag_FPSCR_ = (rt_value &gt;&gt; 30) & 1;
  5128. c_flag_FPSCR_ = (rt_value &gt;&gt; 29) & 1;
  5129. v_flag_FPSCR_ = (rt_value &gt;&gt; 28) & 1;
  5130. inexact_vfp_flag_ = (rt_value &gt;&gt; 4) & 1;
  5131. underflow_vfp_flag_ = (rt_value &gt;&gt; 3) & 1;
  5132. overflow_vfp_flag_ = (rt_value &gt;&gt; 2) & 1;
  5133. div_zero_vfp_flag_ = (rt_value &gt;&gt; 1) & 1;
  5134. inv_op_vfp_flag_ = (rt_value &gt;&gt; 0) & 1;
  5135. FPSCR_rounding_mode_ =
  5136. static_cast&lt;VFPRoundingMode&gt;((rt_value) & kVFPRoundingModeMask);
  5137. }
  5138. } else {
  5139. UNIMPLEMENTED(); // Not used by V8.
  5140. }
  5141. }
  5142. }</span>
  5143. <span class="i">void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
  5144. Instruction* instr) {
  5145. ASSERT((instr-&gt;Bit(4) == 1) && (instr-&gt;VCValue() == 0x0) &&
  5146. (instr-&gt;VAValue() == 0x0));
  5147. int t = instr-&gt;RtValue();
  5148. int n = instr-&gt;VFPNRegValue(kSinglePrecision);
  5149. bool to_arm_register = (instr-&gt;VLValue() == 0x1);
  5150. if (to_arm_register) {
  5151. int32_t int_value = get_sinteger_from_s_register(n);
  5152. set_register(t, int_value);
  5153. } else {
  5154. int32_t rs_val = get_register(t);
  5155. set_s_register_from_sinteger(n, rs_val);
  5156. }
  5157. }</span>
  5158. <span class="i">void Simulator::DecodeVCMP(Instruction* instr) {
  5159. ASSERT((instr-&gt;Bit(4) == 0) && (instr-&gt;Opc1Value() == 0x7));
  5160. ASSERT(((instr-&gt;Opc2Value() == 0x4) || (instr-&gt;Opc2Value() == 0x5)) &&
  5161. (instr-&gt;Opc3Value() & 0x1));
  5162. // Comparison.
  5163. VFPRegPrecision precision = kSinglePrecision;
  5164. if (instr-&gt;SzValue() == 1) {
  5165. precision = kDoublePrecision;
  5166. }
  5167. int d = instr-&gt;VFPDRegValue(precision);
  5168. int m = 0;
  5169. if (instr-&gt;Opc2Value() == 0x4) {
  5170. m = instr-&gt;VFPMRegValue(precision);
  5171. }
  5172. if (precision == kDoublePrecision) {
  5173. double dd_value = get_double_from_d_register(d);
  5174. double dm_value = 0.0;
  5175. if (instr-&gt;Opc2Value() == 0x4) {
  5176. dm_value = get_double_from_d_register(m);
  5177. }
  5178. // Raise exceptions for quiet NaNs if necessary.
  5179. if (instr-&gt;Bit(7) == 1) {
  5180. if (isnan(dd_value)) {
  5181. inv_op_vfp_flag_ = true;
  5182. }
  5183. }
  5184. Compute_FPSCR_Flags(dd_value, dm_value);
  5185. } else {
  5186. UNIMPLEMENTED(); // Not used by V8.
  5187. }
  5188. }</span>
  5189. <span class="i">void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
  5190. ASSERT((instr-&gt;Bit(4) == 0) && (instr-&gt;Opc1Value() == 0x7));
  5191. ASSERT((instr-&gt;Opc2Value() == 0x7) && (instr-&gt;Opc3Value() == 0x3));
  5192. VFPRegPrecision dst_precision = kDoublePrecision;
  5193. VFPRegPrecision src_precision = kSinglePrecision;
  5194. if (instr-&gt;SzValue() == 1) {
  5195. dst_precision = kSinglePrecision;
  5196. src_precision = kDoublePrecision;
  5197. }
  5198. int dst = instr-&gt;VFPDRegValue(dst_precision);
  5199. int src = instr-&gt;VFPMRegValue(src_precision);
  5200. if (dst_precision == kSinglePrecision) {
  5201. double val = get_double_from_d_register(src);
  5202. set_s_register_from_float(dst, static_cast&lt;float&gt;(val));
  5203. } else {
  5204. float val = get_float_from_s_register(src);
  5205. set_d_register_from_double(dst, static_cast&lt;double&gt;(val));
  5206. }
  5207. }</span>
  5208. <span class="i">bool get_inv_op_vfp_flag(VFPRoundingMode mode,
  5209. double val,
  5210. bool unsigned_) {
  5211. ASSERT((mode == RN) || (mode == RM) || (mode == RZ));
  5212. double max_uint = static_cast&lt;double&gt;(0xffffffffu);
  5213. double max_int = static_cast&lt;double&gt;(kMaxInt);
  5214. double min_int = static_cast&lt;double&gt;(kMinInt);
  5215. // Check for NaN.
  5216. if (val != val) {
  5217. return true;
  5218. }
  5219. // Check for overflow. This code works because 32bit integers can be
  5220. // exactly represented by ieee-754 64bit floating-point values.
  5221. switch (mode) {
  5222. case RN:
  5223. return unsigned_ ? (val &gt;= (max_uint + 0.5)) ||
  5224. (val &lt; -0.5)
  5225. : (val &gt;= (max_int + 0.5)) ||
  5226. (val &lt; (min_int - 0.5));
  5227. case RM:
  5228. return unsigned_ ? (val &gt;= (max_uint + 1.0)) ||
  5229. (val &lt; 0)
  5230. : (val &gt;= (max_int + 1.0)) ||
  5231. (val &lt; min_int);
  5232. case RZ:
  5233. return unsigned_ ? (val &gt;= (max_uint + 1.0)) ||
  5234. (val &lt;= -1)
  5235. : (val &gt;= (max_int + 1.0)) ||
  5236. (val &lt;= (min_int - 1.0));
  5237. default:
  5238. UNREACHABLE();
  5239. return true;
  5240. }
  5241. }</span>
  5242. // We call this function only if we had a vfp invalid exception.
  5243. // It returns the correct saturated value.
  5244. <span class="i">int VFPConversionSaturate(double val, bool unsigned_res) {
  5245. if (val != val) {
  5246. return 0;
  5247. } else {
  5248. if (unsigned_res) {
  5249. return (val &lt; 0) ? 0 : 0xffffffffu;
  5250. } else {
  5251. return (val &lt; 0) ? kMinInt : kMaxInt;
  5252. }
  5253. }
  5254. }</span>
  5255. <span class="i">void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
  5256. ASSERT((instr-&gt;Bit(4) == 0) && (instr-&gt;Opc1Value() == 0x7) &&
  5257. (instr-&gt;Bits(27, 23) == 0x1D));
  5258. ASSERT(((instr-&gt;Opc2Value() == 0x8) && (instr-&gt;Opc3Value() & 0x1)) ||
  5259. (((instr-&gt;Opc2Value() &gt;&gt; 1) == 0x6) && (instr-&gt;Opc3Value() & 0x1)));
  5260. // Conversion between floating-point and integer.
  5261. bool to_integer = (instr-&gt;Bit(18) == 1);
  5262. VFPRegPrecision src_precision = (instr-&gt;SzValue() == 1) ? kDoublePrecision
  5263. : kSinglePrecision;
  5264. if (to_integer) {
  5265. // We are playing with code close to the C++ standard&#39;s limits below,
  5266. // hence the very simple code and heavy checks.
  5267. //
  5268. // Note:
  5269. // C++ defines default type casting from floating point to integer as
  5270. // (close to) rounding toward zero (&quot;fractional part discarded&quot;).
  5271. int dst = instr-&gt;VFPDRegValue(kSinglePrecision);
  5272. int src = instr-&gt;VFPMRegValue(src_precision);
  5273. // Bit 7 in vcvt instructions indicates if we should use the FPSCR rounding
  5274. // mode or the default Round to Zero mode.
  5275. VFPRoundingMode mode = (instr-&gt;Bit(7) != 1) ? FPSCR_rounding_mode_
  5276. : RZ;
  5277. ASSERT((mode == RM) || (mode == RZ) || (mode == RN));
  5278. bool unsigned_integer = (instr-&gt;Bit(16) == 0);
  5279. bool double_precision = (src_precision == kDoublePrecision);
  5280. double val = double_precision ? get_double_from_d_register(src)
  5281. : get_float_from_s_register(src);
  5282. int temp = unsigned_integer ? static_cast&lt;uint32_t&gt;(val)
  5283. : static_cast&lt;int32_t&gt;(val);
  5284. inv_op_vfp_flag_ = get_inv_op_vfp_flag(mode, val, unsigned_integer);
  5285. double abs_diff =
  5286. unsigned_integer ? fabs(val - static_cast&lt;uint32_t&gt;(temp))
  5287. : fabs(val - temp);
  5288. inexact_vfp_flag_ = (abs_diff != 0);
  5289. if (inv_op_vfp_flag_) {
  5290. temp = VFPConversionSaturate(val, unsigned_integer);
  5291. } else {
  5292. switch (mode) {
  5293. case RN: {
  5294. int val_sign = (val &gt; 0) ? 1 : -1;
  5295. if (abs_diff &gt; 0.5) {
  5296. temp += val_sign;
  5297. } else if (abs_diff == 0.5) {
  5298. // Round to even if exactly halfway.
  5299. temp = ((temp % 2) == 0) ? temp : temp + val_sign;
  5300. }
  5301. break;
  5302. }
  5303. case RM:
  5304. temp = temp &gt; val ? temp - 1 : temp;
  5305. break;
  5306. case RZ:
  5307. // Nothing to do.
  5308. break;
  5309. default:
  5310. UNREACHABLE();
  5311. }
  5312. }
  5313. // Update the destination register.
  5314. set_s_register_from_sinteger(dst, temp);
  5315. } else {
  5316. bool unsigned_integer = (instr-&gt;Bit(7) == 0);
  5317. int dst = instr-&gt;VFPDRegValue(src_precision);
  5318. int src = instr-&gt;VFPMRegValue(kSinglePrecision);
  5319. int val = get_sinteger_from_s_register(src);
  5320. if (src_precision == kDoublePrecision) {
  5321. if (unsigned_integer) {
  5322. set_d_register_from_double(dst,
  5323. static_cast&lt;double&gt;((uint32_t)val));
  5324. } else {
  5325. set_d_register_from_double(dst, static_cast&lt;double&gt;(val));
  5326. }
  5327. } else {
  5328. if (unsigned_integer) {
  5329. set_s_register_from_float(dst,
  5330. static_cast&lt;float&gt;((uint32_t)val));
  5331. } else {
  5332. set_s_register_from_float(dst, static_cast&lt;float&gt;(val));
  5333. }
  5334. }
  5335. }
  5336. }</span>
  5337. // void Simulator::DecodeType6CoprocessorIns(Instruction* instr)
  5338. // Decode Type 6 coprocessor instructions.
  5339. // Dm = vmov(Rt, Rt2)
  5340. // &lt;Rt, Rt2&gt; = vmov(Dm)
  5341. // Ddst = MEM(Rbase + 4*offset).
  5342. // MEM(Rbase + 4*offset) = Dsrc.
  5343. <span class="i">void Simulator::DecodeType6CoprocessorIns(Instruction* instr) {
  5344. ASSERT((instr-&gt;TypeValue() == 6));
  5345. if (instr-&gt;CoprocessorValue() == 0xA) {
  5346. switch (instr-&gt;OpcodeValue()) {
  5347. case 0x8:
  5348. case 0xA:
  5349. case 0xC:
  5350. case 0xE: { // Load and store single precision float to memory.
  5351. int rn = instr-&gt;RnValue();
  5352. int vd = instr-&gt;VFPDRegValue(kSinglePrecision);
  5353. int offset = instr-&gt;Immed8Value();
  5354. if (!instr-&gt;HasU()) {
  5355. offset = -offset;
  5356. }
  5357. int32_t address = get_register(rn) + 4 * offset;
  5358. if (instr-&gt;HasL()) {
  5359. // Load double from memory: vldr.
  5360. set_s_register_from_sinteger(vd, ReadW(address, instr));
  5361. } else {
  5362. // Store double to memory: vstr.
  5363. WriteW(address, get_sinteger_from_s_register(vd), instr);
  5364. }
  5365. break;
  5366. }
  5367. case 0x4:
  5368. case 0x5:
  5369. case 0x6:
  5370. case 0x7:
  5371. case 0x9:
  5372. case 0xB:
  5373. // Load/store multiple single from memory: vldm/vstm.
  5374. HandleVList(instr);
  5375. break;
  5376. default:
  5377. UNIMPLEMENTED(); // Not used by V8.
  5378. }
  5379. } else if (instr-&gt;CoprocessorValue() == 0xB) {
  5380. switch (instr-&gt;OpcodeValue()) {
  5381. case 0x2:
  5382. // Load and store double to two GP registers
  5383. if (instr-&gt;Bits(7, 4) != 0x1) {
  5384. UNIMPLEMENTED(); // Not used by V8.
  5385. } else {
  5386. int rt = instr-&gt;RtValue();
  5387. int rn = instr-&gt;RnValue();
  5388. int vm = instr-&gt;VmValue();
  5389. if (instr-&gt;HasL()) {
  5390. int32_t rt_int_value = get_sinteger_from_s_register(2*vm);
  5391. int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1);
  5392. set_register(rt, rt_int_value);
  5393. set_register(rn, rn_int_value);
  5394. } else {
  5395. int32_t rs_val = get_register(rt);
  5396. int32_t rn_val = get_register(rn);
  5397. set_s_register_from_sinteger(2*vm, rs_val);
  5398. set_s_register_from_sinteger((2*vm+1), rn_val);
  5399. }
  5400. }
  5401. break;
  5402. case 0x8:
  5403. case 0xC: { // Load and store double to memory.
  5404. int rn = instr-&gt;RnValue();
  5405. int vd = instr-&gt;VdValue();
  5406. int offset = instr-&gt;Immed8Value();
  5407. if (!instr-&gt;HasU()) {
  5408. offset = -offset;
  5409. }
  5410. int32_t address = get_register(rn) + 4 * offset;
  5411. if (instr-&gt;HasL()) {
  5412. // Load double from memory: vldr.
  5413. set_s_register_from_sinteger(2*vd, ReadW(address, instr));
  5414. set_s_register_from_sinteger(2*vd + 1, ReadW(address + 4, instr));
  5415. } else {
  5416. // Store double to memory: vstr.
  5417. WriteW(address, get_sinteger_from_s_register(2*vd), instr);
  5418. WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr);
  5419. }
  5420. break;
  5421. }
  5422. case 0x4:
  5423. case 0x5:
  5424. case 0x9:
  5425. // Load/store multiple double from memory: vldm/vstm.
  5426. HandleVList(instr);
  5427. break;
  5428. default:
  5429. UNIMPLEMENTED(); // Not used by V8.
  5430. }
  5431. } else {
  5432. UNIMPLEMENTED(); // Not used by V8.
  5433. }
  5434. }</span>
  5435. // Executes the current instruction.
  5436. <a id='4402' tid='4401', class="m">void</a> <a id='4404' tid='4403', class="m">Simulator</a><a id='4406' tid='4405', class="m">::</a><a id='4408' tid='4407', class="m">InstructionDecode</a>(<a id='4410' tid='4409', class="m">Instruction</a><a id='4412' tid='4411', class="m">*</a> <a id='4414' tid='4413', class="m">instr</a>) {
  5437. <a id='4426' tid='4425', class="m">if</a> (<a id='4428' tid='4427', class="m">v8</a><a id='4430' tid='4429', class="m">::</a><a id='4432' tid='4431', class="m">internal</a><a id='4434' tid='4433', class="m">::</a><a id='4436' tid='4435', class="m">FLAG_check_icache</a>) {
  5438. <a id='4438' tid='4437', class="m">CheckICache</a>(<a id='4440' tid='4439', class="m">isolate_</a>-&gt;<a id='4442' tid='4441', class="m">simulator_i_cache</a>(), <a id='4444' tid='4443', class="m">instr</a>);
  5439. }
  5440. <span class="i">pc_modified_ = false;</span>
  5441. <span class="i">if</span> <span class="i">(::v8::internal::FLAG_trace_sim)</span> {
  5442. <span class="i">disasm::NameConverter converter;</span>
  5443. <a id='4846' tid='4845', class="m">disasm</a><a id='4848' tid='4847', class="m">::</a><a id='4850' tid='4849', class="m">Disassembler</a> <a id='4852' tid='4851', class="m">dasm</a>(<a id='4854' tid='4853', class="m">converter</a>);
  5444. // use a reasonably large buffer
  5445. <a id='4712' tid='4711', class="m">v8</a><a id='4714' tid='4713', class="m">::</a><a id='4716' tid='4715', class="m">internal</a><a id='4718' tid='4717', class="m">::</a><a id='4720' tid='4719', class="m">EmbeddedVector</a>&lt;<a id='4722' tid='4721', class="m">char</a>, <a id='4724' tid='4723', class="m">256</a>&gt; <a id='4726' tid='4725', class="m">buffer</a>;
  5446. <a id='4446' tid='4445', class="m">dasm</a>.<a id='4448' tid='4447', class="m">InstructionDecode</a>(<a id='4450' tid='4449', class="m">buffer</a>,
  5447. <a id='4452' tid='4451', class="m">reinterpret_cast</a>&lt;<a id='4454' tid='4453', class="m">byte</a><a id='4456' tid='4455', class="m">*</a>&gt;(<a id='4458' tid='4457', class="m">instr</a>));
  5448. <a id='4388' tid='4387', class="m">PrintF</a>(<a id='4390' tid='4389', class="m">&quot; 0x%08x %s\n&quot;</a>, <a id='4392' tid='4391', class="m">reinterpret_cast</a>&lt;<a id='4394' tid='4393', class="m">intptr_t</a>&gt;(<a id='4396' tid='4395', class="m">instr</a>), <a id='4398' tid='4397', class="m">buffer</a>.<a id='4400' tid='4399', class="m">start</a>());
  5449. }
  5450. <span class="i">if</span> <span class="i">(instr-&gt;ConditionField() == kSpecialCondition)</span> <span class="i">{
  5451. UNIMPLEMENTED();
  5452. }</span> <span class="i">else</span> <span class="i">if</span> <span class="i">(ConditionallyExecute(instr))</span> <span class="i">{
  5453. switch (instr-&gt;TypeValue()) {
  5454. case 0:
  5455. case 1: {
  5456. DecodeType01(instr);
  5457. break;
  5458. }
  5459. case 2: {
  5460. DecodeType2(instr);
  5461. break;
  5462. }
  5463. case 3: {
  5464. DecodeType3(instr);
  5465. break;
  5466. }
  5467. case 4: {
  5468. DecodeType4(instr);
  5469. break;
  5470. }
  5471. case 5: {
  5472. DecodeType5(instr);
  5473. break;
  5474. }
  5475. case 6: {
  5476. DecodeType6(instr);
  5477. break;
  5478. }
  5479. case 7: {
  5480. DecodeType7(instr);
  5481. break;
  5482. }
  5483. default: {
  5484. UNIMPLEMENTED();
  5485. break;
  5486. }
  5487. }
  5488. // If the instruction is a non taken conditional stop, we need to skip the
  5489. // inlined message address.
  5490. }</span> <a id='4856' tid='4855', class="m">else</a> <span class="i">if</span> <span class="i">(instr-&gt;IsStop())</span> {
  5491. <a id='4858' tid='4857', class="m">set_pc</a>(<a id='4860' tid='4859', class="m">get_pc</a>() <a id='4862' tid='4861', class="m">+</a> <a id='4864' tid='4863', class="m">2</a> <a id='4866' tid='4865', class="m">*</a> <a id='4868' tid='4867', class="m">Instruction</a><a id='4870' tid='4869', class="m">::</a><a id='4872' tid='4871', class="m">kInstrSize</a>);
  5492. }
  5493. <a id='4364' tid='4363', class="m">if</a> (<a id='4366' tid='4365', class="m">!</a><a id='4368' tid='4367', class="m">pc_modified_</a>) {
  5494. <a id='4370' tid='4369', class="m">set_register</a>(<a id='4372' tid='4371', class="m">pc</a>, <a id='4374' tid='4373', class="m">reinterpret_cast</a>&lt;<a id='4376' tid='4375', class="m">int32_t</a>&gt;(<a id='4378' tid='4377', class="m">instr</a>)
  5495. <a id='4380' tid='4379', class="m">+</a> <a id='4382' tid='4381', class="m">Instruction</a><a id='4384' tid='4383', class="m">::</a><a id='4386' tid='4385', class="m">kInstrSize</a>);
  5496. }
  5497. }
  5498. <a id='4728' tid='4727', class="m">void</a> <a id='4730' tid='4729', class="m">Simulator</a><a id='4732' tid='4731', class="m">::</a><a id='4734' tid='4733', class="m">Execute</a>() {
  5499. // Get the PC to simulate. Cannot use the accessor here as we need the
  5500. // raw PC value and not the one used as input to arithmetic instructions.
  5501. <a id='4736' tid='4735', class="m">int</a> <a id='4738' tid='4737', class="m">program_counter</a> = <a id='4740' tid='4739', class="m">get_pc</a>();
  5502. <a id='4742' tid='4741', class="m">if</a> (<a id='4744' tid='4743', class="m">::</a><a id='4746' tid='4745', class="m">v8</a><a id='4748' tid='4747', class="m">::</a><a id='4750' tid='4749', class="m">internal</a><a id='4752' tid='4751', class="m">::</a><a id='4754' tid='4753', class="m">FLAG_stop_sim_at</a> <a id='4756' tid='4755', class="m">==</a> <a id='4758' tid='4757', class="m">0</a>) {
  5503. // Fast version of the dispatch loop without checking whether the simulator
  5504. // should be stopping at a particular executed instruction.
  5505. <a id='4760' tid='4759', class="m">while</a> (<a id='4762' tid='4761', class="m">program_counter</a> <a id='4764' tid='4763', class="m">!=</a> <a id='4766' tid='4765', class="m">end_sim_pc</a>) {
  5506. <a id='4768' tid='4767', class="m">Instruction</a><a id='4770' tid='4769', class="m">*</a> <a id='4772' tid='4771', class="m">instr</a> = <a id='4774' tid='4773', class="m">reinterpret_cast</a>&lt;<a id='4776' tid='4775', class="m">Instruction</a><a id='4778' tid='4777', class="m">*</a>&gt;(<a id='4780' tid='4779', class="m">program_counter</a>);
  5507. <a id='4782' tid='4781', class="m">icount_</a><a id='4784' tid='4783', class="m">++</a>;
  5508. <a id='4786' tid='4785', class="m">InstructionDecode</a>(<a id='4788' tid='4787', class="m">instr</a>);
  5509. <a id='4790' tid='4789', class="m">program_counter</a> <a id='4792' tid='4791', class="m">=</a> <a id='4794' tid='4793', class="m">get_pc</a>();
  5510. }
  5511. } <a id='4796' tid='4795', class="m">else</a> {
  5512. // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
  5513. // we reach the particular instuction count.
  5514. <a id='4798' tid='4797', class="m">while</a> (<a id='4800' tid='4799', class="m">program_counter</a> <a id='4802' tid='4801', class="m">!=</a> <a id='4804' tid='4803', class="m">end_sim_pc</a>) {
  5515. <a id='4806' tid='4805', class="m">Instruction</a><a id='4808' tid='4807', class="m">*</a> <a id='4810' tid='4809', class="m">instr</a> = <a id='4812' tid='4811', class="m">reinterpret_cast</a>&lt;<a id='4814' tid='4813', class="m">Instruction</a><a id='4816' tid='4815', class="m">*</a>&gt;(<a id='4818' tid='4817', class="m">program_counter</a>);
  5516. <a id='4820' tid='4819', class="m">icount_</a><a id='4822' tid='4821', class="m">++</a>;
  5517. <span class="i">if</span> (<a id='4824' tid='4823', class="m">icount_</a> <a id='4826' tid='4825', class="m">==</a> <a id='4828' tid='4827', class="m">::</a><a id='4830' tid='4829', class="m">v8</a><a id='4832' tid='4831', class="m">::</a><a id='4834' tid='4833', class="m">internal</a><a id='4836' tid='4835', class="m">::</a><a id='4838' tid='4837', class="m">FLAG_stop_sim_at</a>) <span class="i">{
  5518. ArmDebugger dbg(this);
  5519. dbg.Debug();
  5520. }</span> <span class="i">else {
  5521. InstructionDecode(instr);
  5522. }</span>
  5523. <a id='4840' tid='4839', class="m">program_counter</a> <a id='4842' tid='4841', class="m">=</a> <a id='4844' tid='4843', class="m">get_pc</a>();
  5524. }
  5525. }
  5526. }
  5527. <a id='4668' tid='4667', class="m">int32_t</a> <a id='4670' tid='4669', class="m">Simulator</a><a id='4672' tid='4671', class="m">::</a><a id='4674' tid='4673', class="m">Call</a>(<a id='4676' tid='4675', class="m">byte</a><a id='4678' tid='4677', class="m">*</a> <a id='4680' tid='4679', class="m">entry</a>, <a id='4682' tid='4681', class="m">int</a> <a id='4684' tid='4683', class="m">argument_count</a>, <a id='4686' tid='4685', class="m">...</a>) {
  5528. <span class="i">va_list parameters;</span>
  5529. <span class="i">va_start(parameters, argument_count);</span>
  5530. // Setup arguments
  5531. // First four arguments passed in registers.
  5532. <span class="i">ASSERT(argument_count &gt;= 4);</span>
  5533. <span class="i">set_register(r0, va_arg(parameters, int32_t));</span>
  5534. <span class="i">set_register(r1, va_arg(parameters, int32_t));</span>
  5535. <span class="i">set_register(r2, va_arg(parameters, int32_t));</span>
  5536. <span class="i">set_register(r3, va_arg(parameters, int32_t));</span>
  5537. // Remaining arguments passed on stack.
  5538. <span class="i">int original_stack = get_register(sp);</span>
  5539. // Compute position of stack on entry to generated code.
  5540. <span class="i">int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t));</span>
  5541. <a id='4688' tid='4687', class="m">if</a> (<a id='4690' tid='4689', class="m">OS</a><a id='4692' tid='4691', class="m">::</a><a id='4694' tid='4693', class="m">ActivationFrameAlignment</a>() <a id='4696' tid='4695', class="m">!=</a> <a id='4698' tid='4697', class="m">0</a>) {
  5542. <a id='4700' tid='4699', class="m">entry_stack</a> <a id='4702' tid='4701', class="m">&=</a> <a id='4704' tid='4703', class="m">-</a><a id='4706' tid='4705', class="m">OS</a><a id='4708' tid='4707', class="m">::</a><a id='4710' tid='4709', class="m">ActivationFrameAlignment</a>();
  5543. }
  5544. // Store remaining arguments on stack, from low to high memory.
  5545. <a id='4654' tid='4653', class="m">intptr_t</a><a id='4656' tid='4655', class="m">*</a> <a id='4658' tid='4657', class="m">stack_argument</a> = <a id='4660' tid='4659', class="m">reinterpret_cast</a>&lt;<a id='4662' tid='4661', class="m">intptr_t</a><a id='4664' tid='4663', class="m">*</a>&gt;(<a id='4666' tid='4665', class="m">entry_stack</a>);
  5546. <span class="i">for</span> (<a id='4546' tid='4545', class="m">int</a> <a id='4548' tid='4547', class="m">i</a> = <a id='4550' tid='4549', class="m">4</a>; <a id='4552' tid='4551', class="m">i</a> <a id='4554' tid='4553', class="m">&lt;</a> <a id='4556' tid='4555', class="m">argument_count</a>; <a id='4558' tid='4557', class="m">i</a><a id='4560' tid='4559', class="m">++</a>) <span class="i">{
  5547. stack_argument[i - 4] = va_arg(parameters, int32_t);
  5548. }</span>
  5549. <span class="i">va_end(parameters);</span>
  5550. <span class="i">set_register(sp, entry_stack);</span>
  5551. // Prepare to execute the code at entry
  5552. <a id='4482' tid='4481', class="m">set_register</a>(<a id='4484' tid='4483', class="m">pc</a>, <a id='4486' tid='4485', class="m">reinterpret_cast</a>&lt;<a id='4488' tid='4487', class="m">int32_t</a>&gt;(<a id='4490' tid='4489', class="m">entry</a>));
  5553. // Put down marker for end of simulation. The simulator will stop simulation
  5554. // when the PC reaches this value. By saving the &quot;end simulation&quot; value into
  5555. // the LR the simulation stops when returning to this call point.
  5556. <span class="i">set_register(lr, end_sim_pc);</span>
  5557. // Remember the values of callee-saved registers.
  5558. // The code below assumes that r9 is not used as sb (static base) in
  5559. // simulator code and therefore is regarded as a callee-saved register.
  5560. <span class="i">int32_t r4_val = get_register(r4);</span>
  5561. <span class="i">int32_t r5_val = get_register(r5);</span>
  5562. <span class="i">int32_t r6_val = get_register(r6);</span>
  5563. <span class="i">int32_t r7_val = get_register(r7);</span>
  5564. <span class="i">int32_t r8_val = get_register(r8);</span>
  5565. <span class="i">int32_t r9_val = get_register(r9);</span>
  5566. <span class="i">int32_t r10_val = get_register(r10);</span>
  5567. <span class="i">int32_t r11_val = get_register(r11);</span>
  5568. // Setup the callee-saved registers with a known value. To be able to check
  5569. // that they are preserved properly across JS execution.
  5570. <span class="i">int32_t callee_saved_value = icount_;</span>
  5571. <span class="i">set_register(r4, callee_saved_value);</span>
  5572. <span class="i">set_register(r5, callee_saved_value);</span>
  5573. <span class="i">set_register(r6, callee_saved_value);</span>
  5574. <span class="i">set_register(r7, callee_saved_value);</span>
  5575. <span class="i">set_register(r8, callee_saved_value);</span>
  5576. <span class="i">set_register(r9, callee_saved_value);</span>
  5577. <span class="i">set_register(r10, callee_saved_value);</span>
  5578. <span class="i">set_register(r11, callee_saved_value);</span>
  5579. // Start the simulation
  5580. <span class="i">Execute();</span>
  5581. // Check that the callee-saved registers have been preserved.
  5582. <span class="i">CHECK_EQ(callee_saved_value, get_register(r4));</span>
  5583. <span class="i">CHECK_EQ(callee_saved_value, get_register(r5));</span>
  5584. <span class="i">CHECK_EQ(callee_saved_value, get_register(r6));</span>
  5585. <span class="i">CHECK_EQ(callee_saved_value, get_register(r7));</span>
  5586. <span class="i">CHECK_EQ(callee_saved_value, get_register(r8));</span>
  5587. <span class="i">CHECK_EQ(callee_saved_value, get_register(r9));</span>
  5588. <span class="i">CHECK_EQ(callee_saved_value, get_register(r10));</span>
  5589. <span class="i">CHECK_EQ(callee_saved_value, get_register(r11));</span>
  5590. // Restore callee-saved registers with the original value.
  5591. <span class="i">set_register(r4, r4_val);</span>
  5592. <span class="i">set_register(r5, r5_val);</span>
  5593. <span class="i">set_register(r6, r6_val);</span>
  5594. <span class="i">set_register(r7, r7_val);</span>
  5595. <span class="i">set_register(r8, r8_val);</span>
  5596. <span class="i">set_register(r9, r9_val);</span>
  5597. <span class="i">set_register(r10, r10_val);</span>
  5598. <span class="i">set_register(r11, r11_val);</span>
  5599. // Pop stack passed arguments.
  5600. <span class="i">CHECK_EQ(entry_stack, get_register(sp));</span>
  5601. <span class="i">set_register(sp, original_stack);</span>
  5602. <span class="i">int32_t result = get_register(r0);</span>
  5603. <span class="i">return result;</span>
  5604. }
  5605. <a id='4562' tid='4561', class="m">uintptr_t</a> <a id='4564' tid='4563', class="m">Simulator</a><a id='4566' tid='4565', class="m">::</a><a id='4568' tid='4567', class="m">PushAddress</a>(<a id='4570' tid='4569', class="m">uintptr_t</a> <a id='4572' tid='4571', class="m">address</a>) {
  5606. <a id='4574' tid='4573', class="m">int</a> <a id='4576' tid='4575', class="m">new_sp</a> = <a id='4578' tid='4577', class="m">get_register</a>(<a id='4580' tid='4579', class="m">sp</a>) <a id='4582' tid='4581', class="m">-</a> <a id='4584' tid='4583', class="m">sizeof</a>(<a id='4586' tid='4585', class="m">uintptr_t</a>);
  5607. <a id='4588' tid='4587', class="m">uintptr_t</a><a id='4590' tid='4589', class="m">*</a> <a id='4592' tid='4591', class="m">stack_slot</a> = <a id='4594' tid='4593', class="m">reinterpret_cast</a>&lt;<a id='4596' tid='4595', class="m">uintptr_t</a><a id='4598' tid='4597', class="m">*</a>&gt;(<a id='4600' tid='4599', class="m">new_sp</a>);
  5608. <a id='4602' tid='4601', class="m">*</a><a id='4604' tid='4603', class="m">stack_slot</a> <a id='4606' tid='4605', class="m">=</a> <a id='4608' tid='4607', class="m">address</a>;
  5609. <a id='4610' tid='4609', class="m">set_register</a>(<a id='4612' tid='4611', class="m">sp</a>, <a id='4614' tid='4613', class="m">new_sp</a>);
  5610. <a id='4616' tid='4615', class="m">return</a> <a id='4618' tid='4617', class="m">new_sp</a>;
  5611. }
  5612. <a id='4492' tid='4491', class="m">uintptr_t</a> <a id='4494' tid='4493', class="m">Simulator</a><a id='4496' tid='4495', class="m">::</a><a id='4498' tid='4497', class="m">PopAddress</a>() {
  5613. <a id='4500' tid='4499', class="m">int</a> <a id='4502' tid='4501', class="m">current_sp</a> = <a id='4504' tid='4503', class="m">get_register</a>(<a id='4506' tid='4505', class="m">sp</a>);
  5614. <a id='4508' tid='4507', class="m">uintptr_t</a><a id='4510' tid='4509', class="m">*</a> <a id='4512' tid='4511', class="m">stack_slot</a> = <a id='4514' tid='4513', class="m">reinterpret_cast</a>&lt;<a id='4516' tid='4515', class="m">uintptr_t</a><a id='4518' tid='4517', class="m">*</a>&gt;(<a id='4520' tid='4519', class="m">current_sp</a>);
  5615. <a id='4522' tid='4521', class="m">uintptr_t</a> <a id='4524' tid='4523', class="m">address</a> = <a id='4526' tid='4525', class="m">*</a><a id='4528' tid='4527', class="m">stack_slot</a>;
  5616. <a id='4530' tid='4529', class="m">set_register</a>(<a id='4532' tid='4531', class="m">sp</a>, <a id='4534' tid='4533', class="m">current_sp</a> <a id='4536' tid='4535', class="m">+</a> <a id='4538' tid='4537', class="m">sizeof</a>(<a id='4540' tid='4539', class="m">uintptr_t</a>));
  5617. <a id='4542' tid='4541', class="m">return</a> <a id='4544' tid='4543', class="m">address</a>;
  5618. }
  5619. } } // namespace v8::internal
  5620. <span class="i">#endif</span> // USE_SIMULATOR
  5621. <span class="i">#endif</span> // V8_TARGET_ARCH_ARM
  5622. </pre>
  5623. </div>
  5624. </body>
  5625. </html>