/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
- <html>
- <head>
- <META http-equiv="Content-Type" content="text/html; charset=utf-8">
- <LINK href="diff-s.css" rel="stylesheet" type="text/css">
- <script type="text/javascript" src="nav-div.js"></script>
- </head>
- <body>
- <div id="left" class="src">
- <pre>
- <a id='leftstart' tid='rightstart'></a>
- // Copyright 2011 the V8 project authors. All rights reserved.
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following
- // disclaimer in the documentation and/or other materials provided
- // with the distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived
- // from this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #<a id='9613' tid='9614', class="m">include</a> <a id='9615' tid='9616', class="m"><</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">></a>
- #<a id='9601' tid='9602', class="m">include</a> <a id='9603' tid='9604', class="m"><</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">></a>
- <span class="d">#include <limits.h></span>
- <span class="d">#include <cstdarg></span>
- <span class="d">#include "v8.h"</span>
- <span class="d">#if defined(V8_TARGET_ARCH_MIPS)</span>
- <span class="d">#include "disasm.h"</span>
- <span class="d">#include "assembler.h"</span>
- <span class="d">#include "globals.h"</span> // Need the BitCast.
- <span class="d">#include "mips/constants-mips.h"</span>
- <span class="d">#include "mips/simulator-mips.h"</span>
- // Only build the simulator if not compiling for real MIPS hardware.
- #<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>
- namespace <span class="d">v8</span> {
- namespace <span class="d">internal</span> {
- // Utils functions.
- <span class="d">bool HaveSameSign(int32_t a, int32_t b) {
- return ((a ^ b) >= 0);
- }</span>
- <span class="d">uint32_t get_fcsr_condition_bit(uint32_t cc) {
- if (cc == 0) {
- return 23;
- } else {
- return 24 + cc;
- }
- }</span>
- // This macro provides a platform independent use of sscanf. The reason for
- // SScanF not being implemented in a platform independent was through
- // ::v8::internal::OS in the same way as SNPrintF is that the Windows C Run-Time
- // Library does not provide vsscanf.
- <span class="d">#define SScanF sscanf</span> // NOLINT
- // The MipsDebugger class is used by the simulator while debugging simulated
- // code.
- <span class="d">class</span> <span class="d">MipsDebugger</span> {
- <span class="d">public:</span>
- <span class="d">explicit MipsDebugger(Simulator* sim)</span>;
- <span class="d">~MipsDebugger();</span>
- <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>);
- <span class="d">void Debug()</span>;
- // Print all registers with a nice formatting.
- <span class="d">void PrintAllRegs()</span>;
- <span class="d">void PrintAllRegsIncludingFPU()</span>;
- <span class="d">private:</span>
- // We set the breakpoint code to 0xfffff to easily recognize it.
- <span class="d">static const Instr kBreakpointInstr = SPECIAL | BREAK | 0xfffff << 6;</span>
- <span class="d">static const Instr kNopInstr = 0x0;</span>
- <span class="d">Simulator* sim_;</span>
- <span class="d">int32_t GetRegisterValue(int regnum)</span>;
- <span class="d">int32_t GetFPURegisterValueInt(int regnum)</span>;
- <span class="d">int64_t GetFPURegisterValueLong(int regnum)</span>;
- <span class="d">float GetFPURegisterValueFloat(int regnum)</span>;
- <span class="d">double GetFPURegisterValueDouble(int regnum)</span>;
- <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>);
- // Set or delete a breakpoint. Returns true if successful.
- <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>);
- <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>);
- // Undo and redo all breakpoints. This is needed to bracket disassembly and
- // execution to skip past breakpoints when run from the debugger.
- <span class="d">void UndoBreakpoints()</span>;
- <span class="d">void RedoBreakpoints()</span>;
- };
- <span class="d">MipsDebugger::MipsDebugger(Simulator* sim) {
- sim_ = sim;
- }</span>
- <span class="d">MipsDebugger::~MipsDebugger() {
- }</span>
- <span class="d">#ifdef GENERATED_CODE_COVERAGE</span>
- <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>;
- <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>() {
- <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">"V8_GENERATED_CODE_COVERAGE_LOG"</a>);
- <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>) {
- <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">"aw+"</a>);
- }
- }
- <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>) {
- // Get the stop code.
- <span class="d">uint32_t code = instr->Bits(25, 6);</span>
- // Retrieve the encoded address, which comes just after this stop.
- <span class="d">char** msg_address =
- reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);</span>
- <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>;
- <span class="d">ASSERT(msg != NULL);</span>
- // Update this stop description.
- <span class="d">if</span> <span class="d">(!watched_stops[code].desc)</span> {
- <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>;
- }
- <span class="d">if (strlen(msg) > 0) {
- if (coverage_log != NULL) {
- fprintf(coverage_log, "%s\n", str);
- fflush(coverage_log);
- }
- // Overwrite the instruction and address with nops.
- instr->SetInstructionBits(kNopInstr);
- reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr);
- }</span>
- <span class="d">sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstructionSize);</span>
- }
- <span class="d">#else</span> // GENERATED_CODE_COVERAGE
- <span class="d">#define UNSUPPORTED() printf("Unsupported instruction.\n");</span>
- <span class="d">static void InitializeCoverage() {}</span>
- <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>) {
- // Get the stop code.
- <span class="d">uint32_t code = instr->Bits(25, 6);</span>
- // Retrieve the encoded address, which comes just after this stop.
- <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><<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>>(<a id='9467' tid='9468', class="m">sim_</a>-><a id='9469' tid='9470', class="m">get_pc</a>() <a id='9471' tid='9472', class="m">+</a>
- <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>);
- // Update this stop description.
- <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>-><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>) {
- <a id='9393' tid='9394', class="m">sim_</a>-><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>;
- }
- <span class="d">PrintF("Simulator hit %s (%u)\n", msg, code);</span>
- <a id='9423' tid='9424', class="m">sim_</a>-><a id='9425' tid='9426', class="m">set_pc</a>(<a id='9427' tid='9428', class="m">sim_</a>-><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>);
- <span class="d">Debug();</span>
- }
- <span class="d">#endif</span> // GENERATED_CODE_COVERAGE
- <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>) {
- <span class="d">if</span> <span class="d">(regnum == kNumSimuRegisters)</span> <span class="d">{
- return sim_->get_pc();
- }</span> <a id='9413' tid='9414', class="m">else</a> {
- <a id='9415' tid='9416', class="m">return</a> <a id='9417' tid='9418', class="m">sim_</a>-><a id='9419' tid='9420', class="m">get_register</a>(<a id='9421' tid='9422', class="m">regnum</a>);
- }
- }
- <span class="d">int32_t MipsDebugger::GetFPURegisterValueInt(int regnum) {
- if (regnum == kNumFPURegisters) {
- return sim_->get_pc();
- } else {
- return sim_->get_fpu_register(regnum);
- }
- }</span>
- <span class="d">int64_t MipsDebugger::GetFPURegisterValueLong(int regnum) {
- if (regnum == kNumFPURegisters) {
- return sim_->get_pc();
- } else {
- return sim_->get_fpu_register_long(regnum);
- }
- }</span>
- <span class="d">float MipsDebugger::GetFPURegisterValueFloat(int regnum) {
- if (regnum == kNumFPURegisters) {
- return sim_->get_pc();
- } else {
- return sim_->get_fpu_register_float(regnum);
- }
- }</span>
- <span class="d">double MipsDebugger::GetFPURegisterValueDouble(int regnum) {
- if (regnum == kNumFPURegisters) {
- return sim_->get_pc();
- } else {
- return sim_->get_fpu_register_double(regnum);
- }
- }</span>
- <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>) {
- <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>);
- <span class="d">int fpuregnum = FPURegisters::Number(desc);</span>
- <span class="d">if</span> <span class="d">(regnum != kInvalidRegister)</span> {
- <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>);
- <a id='9309' tid='9310', class="m">return</a> <a id='9311' tid='9312', class="m">true</a>;
- } <span class="d">else</span> <span class="d">if</span> <span class="d">(fpuregnum != kInvalidFPURegister)</span> <span class="d">{
- *value = GetFPURegisterValueInt(fpuregnum);
- return true;
- }</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">"0x"</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">{
- return SScanF(desc, "%x", reinterpret_cast<uint32_t*>(value)) == 1;
- }</span> <span class="d">else {
- return SScanF(desc, "%i", value) == 1;
- }</span>
- <span class="d">return false;</span>
- }
- <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>) {
- // Check if a breakpoint can be set. If not return without any side-effects.
- <a id='9325' tid='9326', class="m">if</a> (<a id='9327' tid='9328', class="m">sim_</a>-><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>) {
- <a id='9335' tid='9336', class="m">return</a> <a id='9337' tid='9338', class="m">false</a>;
- }
- // Set the breakpoint.
- <a id='9339' tid='9340', class="m">sim_</a>-><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>;
- <a id='9347' tid='9348', class="m">sim_</a>-><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>-><a id='9355' tid='9356', class="m">InstructionBits</a>();
- // Not setting the breakpoint instruction in the code itself. It will be set
- // when the debugger shell continues.
- <a id='9357' tid='9358', class="m">return</a> <a id='9359' tid='9360', class="m">true</a>;
- }
- <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>) {
- <a id='9259' tid='9260', class="m">if</a> (<a id='9261' tid='9262', class="m">sim_</a>-><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>) {
- <a id='9269' tid='9270', class="m">sim_</a>-><a id='9271' tid='9272', class="m">break_pc_</a>-><a id='9273' tid='9274', class="m">SetInstructionBits</a>(<a id='9275' tid='9276', class="m">sim_</a>-><a id='9277' tid='9278', class="m">break_instr_</a>);
- }
- <a id='9279' tid='9280', class="m">sim_</a>-><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>;
- <a id='9287' tid='9288', class="m">sim_</a>-><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>;
- <a id='9295' tid='9296', class="m">return</a> <a id='9297' tid='9298', class="m">true</a>;
- }
- <span class="d">void</span> <span class="d">MipsDebugger::UndoBreakpoints</span><span class="d">()</span> {
- <a id='9217' tid='9218', class="m">if</a> (<a id='9219' tid='9220', class="m">sim_</a>-><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>) {
- <a id='9227' tid='9228', class="m">sim_</a>-><a id='9229' tid='9230', class="m">break_pc_</a>-><a id='9231' tid='9232', class="m">SetInstructionBits</a>(<a id='9233' tid='9234', class="m">sim_</a>-><a id='9235' tid='9236', class="m">break_instr_</a>);
- }
- }
- <span class="d">void</span> <span class="d">MipsDebugger::RedoBreakpoints</span><span class="d">()</span> {
- <a id='9191' tid='9192', class="m">if</a> (<a id='9193' tid='9194', class="m">sim_</a>-><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>) {
- <a id='9201' tid='9202', class="m">sim_</a>-><a id='9203' tid='9204', class="m">break_pc_</a>-><a id='9205' tid='9206', class="m">SetInstructionBits</a>(<a id='9207' tid='9208', class="m">kBreakpointInstr</a>);
- }
- }
- <span class="d">void MipsDebugger::PrintAllRegs() {
- #define REG_INFO(n) Registers::Name(n), GetRegisterValue(n), GetRegisterValue(n)
- PrintF("\n");
- // at, v0, a0.
- PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
- REG_INFO(1), REG_INFO(2), REG_INFO(4));
- // v1, a1.
- PrintF("%26s\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
- "", REG_INFO(3), REG_INFO(5));
- // a2.
- PrintF("%26s\t%26s\t%3s: 0x%08x %10d\n", "", "", REG_INFO(6));
- // a3.
- PrintF("%26s\t%26s\t%3s: 0x%08x %10d\n", "", "", REG_INFO(7));
- PrintF("\n");
- // t0-t7, s0-s7
- for (int i = 0; i < 8; i++) {
- PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
- REG_INFO(8+i), REG_INFO(16+i));
- }
- PrintF("\n");
- // t8, k0, LO.
- PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
- REG_INFO(24), REG_INFO(26), REG_INFO(32));
- // t9, k1, HI.
- PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
- REG_INFO(25), REG_INFO(27), REG_INFO(33));
- // sp, fp, gp.
- PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
- REG_INFO(29), REG_INFO(30), REG_INFO(28));
- // pc.
- PrintF("%3s: 0x%08x %10d\t%3s: 0x%08x %10d\n",
- REG_INFO(31), REG_INFO(34));
- #undef REG_INFO
- #undef FPU_REG_INFO
- }</span>
- <span class="d">void MipsDebugger::PrintAllRegsIncludingFPU() {
- #define FPU_REG_INFO(n) FPURegisters::Name(n), FPURegisters::Name(n+1), \
- GetFPURegisterValueInt(n+1), \
- GetFPURegisterValueInt(n), \
- GetFPURegisterValueDouble(n)
- PrintAllRegs();
- PrintF("\n\n");
- // f0, f1, f2, ... f31.
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(0) );
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(2) );
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(4) );
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(6) );
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(8) );
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(10));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(12));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(14));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(16));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(18));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(20));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(22));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(24));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(26));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(28));
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n", FPU_REG_INFO(30));
- #undef REG_INFO
- #undef FPU_REG_INFO
- }</span>
- <span class="d">void</span> <span class="d">MipsDebugger::Debug</span><span class="d">()</span> {
- <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>;
- <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>;
- #<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>
- #<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>
- #<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>
- #<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>
- <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>];
- <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>];
- <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>];
- <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> };
- // Make sure to have a proper terminating character if reaching the limit.
- <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>;
- <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>;
- <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>;
- // Undo all set breakpoints while running in the debugger shell. This will
- // make them invisible to all commands.
- <a id='9077' tid='9078', class="m">UndoBreakpoints</a>();
- <span class="d">while</span> <span class="d">(!done && (sim_->get_pc() != Simulator::end_sim_pc))</span> {
- <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>-><a id='9087' tid='9088', class="m">get_pc</a>()) {
- <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>;
- <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>);
- // Use a reasonably large buffer.
- <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><<a id='9117' tid='9118', class="m">char</a>, <a id='9119' tid='9120', class="m">256</a>> <a id='9121' tid='9122', class="m">buffer</a>;
- <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>,
- <a id='9129' tid='9130', class="m">reinterpret_cast</a><<a id='9131' tid='9132', class="m">byte</a><a id='9133' tid='9134', class="m">*</a>>(<a id='9135' tid='9136', class="m">sim_</a>-><a id='9137' tid='9138', class="m">get_pc</a>()));
- <a id='9139' tid='9140', class="m">PrintF</a>(<a id='9141' tid='9142', class="m">" 0x%08x %s\n"</a>, <a id='9143' tid='9144', class="m">sim_</a>-><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>());
- <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>-><a id='9157' tid='9158', class="m">get_pc</a>();
- }
- <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">"sim> "</a>);
- <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>) {
- <a id='8133' tid='8134', class="m">break</a>;
- } <a id='8135' tid='8136', class="m">else</a> {
- // Use sscanf to parse the individual parts of the command line. At the
- // moment no command expects more than two parameters.
- <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>,
- <a id='8145' tid='8146', class="m">"%"</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">"s "</a>
- <a id='8153' tid='8154', class="m">"%"</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">"s "</a>
- <a id='8161' tid='8162', class="m">"%"</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">"s"</a>,
- <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>);
- <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">"si"</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">"stepi"</a>) <a id='8195' tid='8196', class="m">==</a> <a id='8197' tid='8198', class="m">0</a>)) {
- <span class="d">Instruction* instr = reinterpret_cast<Instruction*>(sim_->get_pc());</span>
- <span class="d">if</span> <span class="d">(!(instr->IsTrap()) ||
- instr->InstructionBits() == rtCallRedirInstr)</span> {
- <a id='8199' tid='8200', class="m">sim_</a>-><a id='8201' tid='8202', class="m">InstructionDecode</a>(
- <a id='8203' tid='8204', class="m">reinterpret_cast</a><<a id='8205' tid='8206', class="m">Instruction</a><a id='8207' tid='8208', class="m">*</a>>(<a id='8209' tid='8210', class="m">sim_</a>-><a id='8211' tid='8212', class="m">get_pc</a>()));
- } <span class="d">else</span> {
- // Allow si to jump over generated breakpoints.
- <span class="d">PrintF("/!\\ Jumping over generated breakpoint.\n");</span>
- <span class="d">sim_->set_pc</span>(<a id='8037' tid='8038', class="m">sim_</a>-><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>);
- }
- } <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">"c"</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">"cont"</a>) <a id='8235' tid='8236', class="m">==</a> <a id='8237' tid='8238', class="m">0</a>)) {
- // Execute the one instruction we broke at with breakpoints disabled.
- <a id='8239' tid='8240', class="m">sim_</a>-><a id='8241' tid='8242', class="m">InstructionDecode</a>(<a id='8243' tid='8244', class="m">reinterpret_cast</a><<a id='8245' tid='8246', class="m">Instruction</a><a id='8247' tid='8248', class="m">*</a>>(<a id='8249' tid='8250', class="m">sim_</a>-><a id='8251' tid='8252', class="m">get_pc</a>()));
- // Leave the debugger shell.
- <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>;
- } <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">"p"</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">"print"</a>) <a id='8281' tid='8282', class="m">==</a> <a id='8283' tid='8284', class="m">0</a>)) {
- <span class="d">if</span> <span class="d">(argc == 2)</span> {
- <span class="d">int32_t value;</span>
- <span class="d">float fvalue;</span>
- <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">"all"</a>) <a id='8291' tid='8292', class="m">==</a> <a id='8293' tid='8294', class="m">0</a>) <span class="d">{
- PrintAllRegs();
- }</span> <a id='8049' tid='8050', class="m">else</a> <span class="d">if</span> <span class="d">(strcmp(arg1, "allf") == 0)</span> <span class="d">{
- PrintAllRegsIncludingFPU();
- }</span> <span class="d">else</span> {
- <span class="d">int regnum = Registers::Number(arg1);</span>
- <span class="d">int fpuregnum = FPURegisters::Number(arg1);</span>
- <span class="d">if</span> <span class="d">(regnum != kInvalidRegister)</span> {
- <span class="d">value = GetRegisterValue(regnum);</span>
- <a id='8051' tid='8052', class="m">PrintF</a>(<a id='8053' tid='8054', class="m">"%s: 0x%08x %d \n"</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>);
- } <span class="d">else if (fpuregnum != kInvalidFPURegister) {
- if (fpuregnum % 2 == 1) {
- value = GetFPURegisterValueInt(fpuregnum);
- fvalue = GetFPURegisterValueFloat(fpuregnum);
- PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue);
- } else {
- double dfvalue;
- int32_t lvalue1 = GetFPURegisterValueInt(fpuregnum);
- int32_t lvalue2 = GetFPURegisterValueInt(fpuregnum + 1);
- dfvalue = GetFPURegisterValueDouble(fpuregnum);
- PrintF("%3s,%3s: 0x%08x%08x %16.4e\n",
- FPURegisters::Name(fpuregnum+1),
- FPURegisters::Name(fpuregnum),
- lvalue1,
- lvalue2,
- dfvalue);
- }
- } else {
- PrintF("%s unrecognized\n", arg1);
- }</span>
- }
- } <span class="d">else {
- if (argc == 3) {
- if (strcmp(arg2, "single") == 0) {
- int32_t value;
- float fvalue;
- int fpuregnum = FPURegisters::Number(arg1);
- if (fpuregnum != kInvalidFPURegister) {
- value = GetFPURegisterValueInt(fpuregnum);
- fvalue = GetFPURegisterValueFloat(fpuregnum);
- PrintF("%s: 0x%08x %11.4e\n", arg1, value, fvalue);
- } else {
- PrintF("%s unrecognized\n", arg1);
- }
- } else {
- PrintF("print <fpu register> single\n");
- }
- } else {
- PrintF("print <register> or print <fpu register> single\n");
- }
- }</span>
- } <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">"po"</a>) <a id='8305' tid='8306', class="m">==</a> <a id='8307' tid='8308', class="m">0</a>)
- <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">"printobject"</a>) <a id='8317' tid='8318', class="m">==</a> <a id='8319' tid='8320', class="m">0</a>)) {
- <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>) {
- <a id='8329' tid='8330', class="m">int32_t</a> <a id='8331' tid='8332', class="m">value</a>;
- <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>)) {
- <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><<a id='8351' tid='8352', class="m">Object</a><a id='8353' tid='8354', class="m">*</a>>(<a id='8355' tid='8356', class="m">value</a>);
- <a id='8357' tid='8358', class="m">PrintF</a>(<a id='8359' tid='8360', class="m">"%s: \n"</a>, <a id='8361' tid='8362', class="m">arg1</a>);
- #<a id='8363' tid='8364', class="m">ifdef</a> <a id='8365' tid='8366', class="m">DEBUG</a>
- <a id='8367' tid='8368', class="m">obj</a>-><a id='8369' tid='8370', class="m">PrintLn</a>();
- #<a id='8371' tid='8372', class="m">else</a>
- <a id='8373' tid='8374', class="m">obj</a>-><a id='8375' tid='8376', class="m">ShortPrint</a>();
- <a id='8377' tid='8378', class="m">PrintF</a>(<a id='8379' tid='8380', class="m">"\n"</a>);
- #<a id='8381' tid='8382', class="m">endif</a>
- } <a id='8383' tid='8384', class="m">else</a> {
- <a id='8385' tid='8386', class="m">PrintF</a>(<a id='8387' tid='8388', class="m">"%s unrecognized\n"</a>, <a id='8389' tid='8390', class="m">arg1</a>);
- }
- } <a id='8391' tid='8392', class="m">else</a> {
- <a id='8393' tid='8394', class="m">PrintF</a>(<a id='8395' tid='8396', class="m">"printobject <value>\n"</a>);
- }
- } <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">"stack"</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">"mem"</a>) <a id='8419' tid='8420', class="m">==</a> <a id='8421' tid='8422', class="m">0</a>) {
- <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>;
- <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>;
- <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>;
- <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">"stack"</a>) <a id='8453' tid='8454', class="m">==</a> <a id='8455' tid='8456', class="m">0</a>) {
- <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><<a id='8463' tid='8464', class="m">int32_t</a><a id='8465' tid='8466', class="m">*</a>>(<a id='8467' tid='8468', class="m">sim_</a>-><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>));
- } <a id='8477' tid='8478', class="m">else</a> { // Command "mem".
- <a id='8479' tid='8480', class="m">int32_t</a> <a id='8481' tid='8482', class="m">value</a>;
- <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>)) {
- <a id='8495' tid='8496', class="m">PrintF</a>(<a id='8497' tid='8498', class="m">"%s unrecognized\n"</a>, <a id='8499' tid='8500', class="m">arg1</a>);
- <a id='8501' tid='8502', class="m">continue</a>;
- }
- <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><<a id='8509' tid='8510', class="m">int32_t</a><a id='8511' tid='8512', class="m">*</a>>(<a id='8513' tid='8514', class="m">value</a>);
- <a id='8515' tid='8516', class="m">next_arg</a><a id='8517' tid='8518', class="m">++</a>;
- }
- <a id='8519' tid='8520', class="m">int32_t</a> <a id='8521' tid='8522', class="m">words</a>;
- <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>) {
- <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>;
- } <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>) {
- <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>)) {
- <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>;
- }
- }
- <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>;
- <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"><</a> <a id='8587' tid='8588', class="m">end</a>) {
- <a id='8589' tid='8590', class="m">PrintF</a>(<a id='8591' tid='8592', class="m">" 0x%08x: 0x%08x %10d"</a>,
- <a id='8593' tid='8594', class="m">reinterpret_cast</a><<a id='8595' tid='8596', class="m">intptr_t</a>>(<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>);
- <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><<a id='8615' tid='8616', class="m">HeapObject</a><a id='8617' tid='8618', class="m">*</a>>(<a id='8619' tid='8620', class="m">*</a><a id='8621' tid='8622', class="m">cur</a>);
- <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>;
- <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>()-><a id='8651' tid='8652', class="m">heap</a>();
- <a id='8653' tid='8654', class="m">if</a> (<a id='8655' tid='8656', class="m">current_heap</a>-><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>)) {
- <a id='8673' tid='8674', class="m">PrintF</a>(<a id='8675' tid='8676', class="m">" ("</a>);
- <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>) {
- <a id='8689' tid='8690', class="m">PrintF</a>(<a id='8691' tid='8692', class="m">"smi %d"</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>);
- } <a id='8699' tid='8700', class="m">else</a> {
- <a id='8701' tid='8702', class="m">obj</a>-><a id='8703' tid='8704', class="m">ShortPrint</a>();
- }
- <a id='8705' tid='8706', class="m">PrintF</a>(<a id='8707' tid='8708', class="m">")"</a>);
- }
- <a id='8709' tid='8710', class="m">PrintF</a>(<a id='8711' tid='8712', class="m">"\n"</a>);
- <a id='8713' tid='8714', class="m">cur</a><a id='8715' tid='8716', class="m">++</a>;
- }
- } <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">"disasm"</a>) <a id='8727' tid='8728', class="m">==</a> <a id='8729' tid='8730', class="m">0</a>) <span class="d">||</span>
- (<span class="d">strcmp(cmd, "dpc") == 0</span>) <a id='8731' tid='8732', class="m">||</a>
- (<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">"di"</a>) <a id='8739' tid='8740', class="m">==</a> <a id='8741' tid='8742', class="m">0</a>)) {
- <span class="d">disasm::NameConverter converter;</span>
- <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>);
- // Use a reasonably large buffer.
- <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><<a id='8071' tid='8072', class="m">char</a>, <a id='8073' tid='8074', class="m">256</a>> <a id='8075' tid='8076', class="m">buffer</a>;
- <span class="d">byte* cur = NULL;</span>
- <span class="d">byte* end = NULL;</span>
- <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>) {
- <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><<a id='7559' tid='7560', class="m">byte</a><a id='7561' tid='7562', class="m">*</a>>(<a id='7563' tid='7564', class="m">sim_</a>-><a id='7565' tid='7566', class="m">get_pc</a>());
- <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>);
- } <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>) {
- <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>);
- <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">"0x"</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>) {
- // The argument is an address or a register name.
- <a id='7621' tid='7622', class="m">int32_t</a> <a id='7623' tid='7624', class="m">value</a>;
- <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>)) {
- <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><<a id='7641' tid='7642', class="m">byte</a><a id='7643' tid='7644', class="m">*</a>>(<a id='7645' tid='7646', class="m">value</a>);
- // Disassemble 10 instructions at <arg1>.
- <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>);
- }
- } <a id='7665' tid='7666', class="m">else</a> {
- // The argument is the number of instructions.
- <a id='7667' tid='7668', class="m">int32_t</a> <a id='7669' tid='7670', class="m">value</a>;
- <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>)) {
- <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><<a id='7687' tid='7688', class="m">byte</a><a id='7689' tid='7690', class="m">*</a>>(<a id='7691' tid='7692', class="m">sim_</a>-><a id='7693' tid='7694', class="m">get_pc</a>());
- // Disassemble <arg1> instructions.
- <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>);
- }
- }
- } <a id='7713' tid='7714', class="m">else</a> {
- <a id='7715' tid='7716', class="m">int32_t</a> <a id='7717' tid='7718', class="m">value1</a>;
- <a id='7719' tid='7720', class="m">int32_t</a> <a id='7721' tid='7722', class="m">value2</a>;
- <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>)) {
- <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><<a id='7749' tid='7750', class="m">byte</a><a id='7751' tid='7752', class="m">*</a>>(<a id='7753' tid='7754', class="m">value1</a>);
- <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>);
- }
- }
- <span class="d">while (cur < end) {
- dasm.InstructionDecode(buffer, cur);
- PrintF(" 0x%08x %s\n",
- reinterpret_cast<intptr_t>(cur), buffer.start());
- cur += Instruction::kInstrSize;
- }</span>
- } <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">"gdb"</a>) <a id='8763' tid='8764', class="m">==</a> <a id='8765' tid='8766', class="m">0</a>) {
- <a id='8767' tid='8768', class="m">PrintF</a>(<a id='8769' tid='8770', class="m">"relinquishing control to gdb\n"</a>);
- <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>();
- <a id='8785' tid='8786', class="m">PrintF</a>(<a id='8787' tid='8788', class="m">"regaining control from gdb\n"</a>);
- } <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">"break"</a>) <a id='8799' tid='8800', class="m">==</a> <a id='8801' tid='8802', class="m">0</a>) {
- <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>) {
- <a id='8811' tid='8812', class="m">int32_t</a> <a id='8813' tid='8814', class="m">value</a>;
- <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>)) {
- <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><<a id='8833' tid='8834', class="m">Instruction</a><a id='8835' tid='8836', class="m">*</a>>(<a id='8837' tid='8838', class="m">value</a>))) {
- <a id='8839' tid='8840', class="m">PrintF</a>(<a id='8841' tid='8842', class="m">"setting breakpoint failed\n"</a>);
- }
- } <a id='8843' tid='8844', class="m">else</a> {
- <a id='8845' tid='8846', class="m">PrintF</a>(<a id='8847' tid='8848', class="m">"%s unrecognized\n"</a>, <a id='8849' tid='8850', class="m">arg1</a>);
- }
- } <a id='8851' tid='8852', class="m">else</a> {
- <a id='8853' tid='8854', class="m">PrintF</a>(<a id='8855' tid='8856', class="m">"break <address>\n"</a>);
- }
- } <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">"del"</a>) <a id='8867' tid='8868', class="m">==</a> <a id='8869' tid='8870', class="m">0</a>) {
- <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>)) {
- <a id='8879' tid='8880', class="m">PrintF</a>(<a id='8881' tid='8882', class="m">"deleting breakpoint failed\n"</a>);
- }
- } <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">"flags"</a>) <a id='8891' tid='8892', class="m">==</a> <a id='8893' tid='8894', class="m">0</a>) <span class="d">{
- PrintF("No flags on MIPS !\n");
- }</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">"stop"</a>) <a id='8083' tid='8084', class="m">==</a> <a id='8085' tid='8086', class="m">0</a>) {
- <a id='7775' tid='7776', class="m">int32_t</a> <a id='7777' tid='7778', class="m">value</a>;
- <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>-><a id='7785' tid='7786', class="m">get_pc</a>() <a id='7787' tid='7788', class="m">-</a>
- <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>;
- <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><<a id='7807' tid='7808', class="m">Instruction</a><a id='7809' tid='7810', class="m">*</a>>(<a id='7811' tid='7812', class="m">stop_pc</a>);
- <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> =
- <a id='7819' tid='7820', class="m">reinterpret_cast</a><<a id='7821' tid='7822', class="m">Instruction</a><a id='7823' tid='7824', class="m">*</a>>(<a id='7825' tid='7826', class="m">stop_pc</a> <a id='7827' tid='7828', class="m">+</a>
- <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>);
- <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">"unstop"</a>) <a id='7851' tid='7852', class="m">==</a> <a id='7853' tid='7854', class="m">0</a>)) {
- // Remove the current stop.
- <span class="d">if</span> <span class="d">(sim_->IsStopInstruction(stop_instr))</span> {
- <a id='7855' tid='7856', class="m">stop_instr</a>-><a id='7857' tid='7858', class="m">SetInstructionBits</a>(<a id='7859' tid='7860', class="m">kNopInstr</a>);
- <a id='7861' tid='7862', class="m">msg_address</a>-><a id='7863' tid='7864', class="m">SetInstructionBits</a>(<a id='7865' tid='7866', class="m">kNopInstr</a>);
- } <span class="d">else {
- PrintF("Not at debugger stop.\n");
- }</span>
- } <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>) {
- // Print information about all/the specified breakpoint(s).
- <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">"info"</a>) <a id='7885' tid='7886', class="m">==</a> <a id='7887' tid='7888', class="m">0</a>) {
- <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">"all"</a>) <a id='7895' tid='7896', class="m">==</a> <a id='7897' tid='7898', class="m">0</a>) <span class="d">{
- PrintF("Stop information:\n");
- for (uint32_t i = kMaxWatchpointCode + 1;
- i <= kMaxStopCode;
- i++) {
- sim_->PrintStopInfo(i);
- }
- }</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>)) {
- <a id='7297' tid='7298', class="m">sim_</a>-><a id='7299' tid='7300', class="m">PrintStopInfo</a>(<a id='7301' tid='7302', class="m">value</a>);
- } <a id='7303' tid='7304', class="m">else</a> {
- <a id='7305' tid='7306', class="m">PrintF</a>(<a id='7307' tid='7308', class="m">"Unrecognized argument.\n"</a>);
- }
- } <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">"enable"</a>) <a id='7909' tid='7910', class="m">==</a> <a id='7911' tid='7912', class="m">0</a>) {
- // Enable all/the specified breakpoint(s).
- <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">"all"</a>) <a id='7919' tid='7920', class="m">==</a> <a id='7921' tid='7922', class="m">0</a>) <span class="d">{
- for (uint32_t i = kMaxWatchpointCode + 1;
- i <= kMaxStopCode;
- i++) {
- sim_->EnableStop(i);
- }
- }</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>)) {
- <a id='7321' tid='7322', class="m">sim_</a>-><a id='7323' tid='7324', class="m">EnableStop</a>(<a id='7325' tid='7326', class="m">value</a>);
- } <a id='7327' tid='7328', class="m">else</a> {
- <a id='7329' tid='7330', class="m">PrintF</a>(<a id='7331' tid='7332', class="m">"Unrecognized argument.\n"</a>);
- }
- } <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">"disable"</a>) <a id='7933' tid='7934', class="m">==</a> <a id='7935' tid='7936', class="m">0</a>) {
- // Disable all/the specified breakpoint(s).
- <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">"all"</a>) <a id='7943' tid='7944', class="m">==</a> <a id='7945' tid='7946', class="m">0</a>) <span class="d">{
- for (uint32_t i = kMaxWatchpointCode + 1;
- i <= kMaxStopCode;
- i++) {
- sim_->DisableStop(i);
- }
- }</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>)) {
- <a id='7345' tid='7346', class="m">sim_</a>-><a id='7347' tid='7348', class="m">DisableStop</a>(<a id='7349' tid='7350', class="m">value</a>);
- } <a id='7351' tid='7352', class="m">else</a> {
- <a id='7353' tid='7354', class="m">PrintF</a>(<a id='7355' tid='7356', class="m">"Unrecognized argument.\n"</a>);
- }
- }
- } <a id='7947' tid='7948', class="m">else</a> {
- <a id='7949' tid='7950', class="m">PrintF</a>(<a id='7951' tid='7952', class="m">"Wrong usage. Use help command for more information.\n"</a>);
- }
- } <a id='7953' tid='7954', class="m">else</a> <span class="d">if</span> <span class="d">((strcmp(cmd, "stat") == 0) || (strcmp(cmd, "st") == 0))</span> {
- // Print registers and disassemble.
- <span class="d">PrintAllRegs();</span>
- <span class="d">PrintF("\n");</span>
- <span class="d">disasm::NameConverter converter;</span>
- <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>);
- // Use a reasonably large buffer.
- <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><<a id='4721' tid='4722', class="m">char</a>, <a id='4723' tid='4724', class="m">256</a>> <a id='4725' tid='4726', class="m">buffer</a>;
- <span class="d">byte* cur = NULL;</span>
- <span class="d">byte* end = NULL;</span>
- <span class="d">if (argc == 1) {
- cur = reinterpret_cast<byte*>(sim_->get_pc());
- end = cur + (10 * Instruction::kInstrSize);
- } else if (argc == 2) {
- int32_t value;
- if (GetValue(arg1, &value)) {
- cur = reinterpret_cast<byte*>(value);
- // no length parameter passed, assume 10 instructions
- end = cur + (10 * Instruction::kInstrSize);
- }
- } else {
- int32_t value1;
- int32_t value2;
- if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
- cur = reinterpret_cast<byte*>(value1);
- end = cur + (value2 * Instruction::kInstrSize);
- }
- }</span>
- <span class="d">while (cur < end) {
- dasm.InstructionDecode(buffer, cur);
- PrintF(" 0x%08x %s\n",
- reinterpret_cast<intptr_t>(cur), buffer.start());
- cur += Instruction::kInstrSize;
- }</span>
- } <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">"h"</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">"help"</a>) <a id='7975' tid='7976', class="m">==</a> <a id='7977' tid='7978', class="m">0</a>)) <span class="d">{
- PrintF("cont\n");
- PrintF(" continue execution (alias 'c')\n");
- PrintF("stepi\n");
- PrintF(" step one instruction (alias 'si')\n");
- PrintF("print <register>\n");
- PrintF(" print register content (alias 'p')\n");
- PrintF(" use register name 'all' to print all registers\n");
- PrintF("printobject <register>\n");
- PrintF(" print an object from a register (alias 'po')\n");
- PrintF("stack [<words>]\n");
- PrintF(" dump stack content, default dump 10 words)\n");
- PrintF("mem <address> [<words>]\n");
- PrintF(" dump memory content, default dump 10 words)\n");
- PrintF("flags\n");
- PrintF(" print flags\n");
- PrintF("disasm [<instructions>]\n");
- PrintF("disasm [<address/register>]\n");
- PrintF("disasm [[<address/register>] <instructions>]\n");
- PrintF(" disassemble code, default is 10 instructions\n");
- PrintF(" from pc (alias 'di')\n");
- PrintF("gdb\n");
- PrintF(" enter gdb\n");
- PrintF("break <address>\n");
- PrintF(" set a break point on the address\n");
- PrintF("del\n");
- PrintF(" delete the breakpoint\n");
- PrintF("stop feature:\n");
- PrintF(" Description:\n");
- PrintF(" Stops are debug instructions inserted by\n");
- PrintF(" the Assembler::stop() function.\n");
- PrintF(" When hitting a stop, the Simulator will\n");
- PrintF(" stop and and give control to the Debugger.\n");
- PrintF(" All stop codes are watched:\n");
- PrintF(" - They can be enabled / disabled: the Simulator\n");
- PrintF(" will / won't stop when hitting them.\n");
- PrintF(" - The Simulator keeps track of how many times they \n");
- PrintF(" are met. (See the info command.) Going over a\n");
- PrintF(" disabled stop still increases its counter. \n");
- PrintF(" Commands:\n");
- PrintF(" stop info all/<code> : print infos about number <code>\n");
- PrintF(" or all stop(s).\n");
- PrintF(" stop enable/disable all/<code> : enables / disables\n");
- PrintF(" all or number <code> stop(s)\n");
- PrintF(" stop unstop\n");
- PrintF(" ignore the stop instruction at the current location\n");
- PrintF(" from now on\n");
- }</span> <span class="d">else {
- PrintF("Unknown command: %s\n", cmd);
- }</span>
- }
- <a id='8895' tid='8896', class="m">DeleteArray</a>(<a id='8897' tid='8898', class="m">line</a>);
- }
- // Add all the breakpoints back to stop execution and enter the debugger
- // shell when hit.
- <a id='9159' tid='9160', class="m">RedoBreakpoints</a>();
- #<a id='9161' tid='9162', class="m">undef</a> <a id='9163' tid='9164', class="m">COMMAND_SIZE</a>
- #<a id='9165' tid='9166', class="m">undef</a> <a id='9167' tid='9168', class="m">ARG_SIZE</a>
- #<a id='9169' tid='9170', class="m">undef</a> <a id='9171' tid='9172', class="m">STR</a>
- #<a id='9173' tid='9174', class="m">undef</a> <a id='9175' tid='9176', class="m">XSTR</a>
- }
- <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>) {
- <a id='8917' tid='8918', class="m">ASSERT</a>((<a id='8919' tid='8920', class="m">reinterpret_cast</a><<a id='8921' tid='8922', class="m">intptr_t</a>>(<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>);
- <a id='8937' tid='8938', class="m">ASSERT</a>((<a id='8939' tid='8940', class="m">reinterpret_cast</a><<a id='8941' tid='8942', class="m">intptr_t</a>>(<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>);
- <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>;
- }
- <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>) {
- <a id='8099' tid='8100', class="m">return</a> <a id='8101' tid='8102', class="m">static_cast</a><<a id='8103' tid='8104', class="m">uint32_t</a>>(<a id='8105' tid='8106', class="m">reinterpret_cast</a><<a id='8107' tid='8108', class="m">uintptr_t</a>>(<a id='8109' tid='8110', class="m">key</a>)) <a id='8111' tid='8112', class="m">>></a> <a id='8113' tid='8114', class="m">2</a>;
- }
- <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>) {
- <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>);
- <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>);
- <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>;
- }
- <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>,
- <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>,
- <a id='7385' tid='7386', class="m">size_t</a> <a id='7387' tid='7388', class="m">size</a>) {
- <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><<a id='7395' tid='7396', class="m">intptr_t</a>>(<a id='7397' tid='7398', class="m">start_addr</a>);
- <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>);
- <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>;
- <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>;
- <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>;
- <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>);
- <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>)) {
- <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>;
- <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>);
- <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>;
- <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>;
- <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>);
- <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>;
- }
- <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>) {
- <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>);
- }
- }
- <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>) {
- <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>-><a id='7235' tid='7236', class="m">Lookup</a>(<a id='7237' tid='7238', class="m">page</a>,
- <a id='7239' tid='7240', class="m">ICacheHash</a>(<a id='7241' tid='7242', class="m">page</a>),
- <a id='7243' tid='7244', class="m">true</a>);
- <a id='7245' tid='7246', class="m">if</a> (<a id='7247' tid='7248', class="m">entry</a>-><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>) {
- <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>();
- <a id='7265' tid='7266', class="m">entry</a>-><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>;
- }
- <a id='7273' tid='7274', class="m">return</a> <a id='7275' tid='7276', class="m">reinterpret_cast</a><<a id='7277' tid='7278', class="m">CachePage</a><a id='7279' tid='7280', class="m">*</a>>(<a id='7281' tid='7282', class="m">entry</a>-><a id='7283' tid='7284', class="m">value</a>);
- }
- // Flush from start up to and not including start + size.
- <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>,
- <a id='7039' tid='7040', class="m">intptr_t</a> <a id='7041' tid='7042', class="m">start</a>,
- <a id='7043' tid='7044', class="m">int</a> <a id='7045' tid='7046', class="m">size</a>) {
- <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"><=</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>);
- <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>));
- <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>);
- <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>);
- <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><<a id='7111' tid='7112', class="m">void</a><a id='7113' tid='7114', class="m">*</a>>(<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>));
- <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>);
- <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>);
- <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>-><a id='7161' tid='7162', class="m">ValidityByte</a>(<a id='7163' tid='7164', class="m">offset</a>);
- <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">>></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>);
- }
- <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>,
- <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>) {
- <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><<a id='6831' tid='6832', class="m">intptr_t</a>>(<a id='6833' tid='6834', class="m">instr</a>);
- <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><<a id='6843' tid='6844', class="m">void</a><a id='6845' tid='6846', class="m">*</a>>(<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>));
- <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><<a id='6867' tid='6868', class="m">void</a><a id='6869' tid='6870', class="m">*</a>>(<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>));
- <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>);
- <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>);
- <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>-><a id='6917' tid='6918', class="m">ValidityByte</a>(<a id='6919' tid='6920', class="m">offset</a>);
- <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>);
- <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>-><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>);
- <a id='6959' tid='6960', class="m">if</a> (<a id='6961' tid='6962', class="m">cache_hit</a>) {
- // Check that the data in memory matches the contents of the I-cache.
- <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><<a id='6969' tid='6970', class="m">void</a><a id='6971' tid='6972', class="m">*</a>>(<a id='6973' tid='6974', class="m">instr</a>),
- <a id='6975' tid='6976', class="m">cache_page</a>-><a id='6977' tid='6978', class="m">CachedData</a>(<a id='6979' tid='6980', class="m">offset</a>),
- <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>);
- } <a id='6991' tid='6992', class="m">else</a> {
- // Cache miss. Load memory into the cache.
- <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>);
- <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>;
- }
- }
- <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>) {
- <a id='6761' tid='6762', class="m">if</a> (<a id='6763' tid='6764', class="m">isolate</a>-><a id='6765' tid='6766', class="m">simulator_initialized</a>()) <a id='6767' tid='6768', class="m">return</a>;
- <a id='6769' tid='6770', class="m">isolate</a>-><a id='6771' tid='6772', class="m">set_simulator_initialized</a>(<a id='6773' tid='6774', class="m">true</a>);
- <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>,
- <a id='6793' tid='6794', class="m">&</a><a id='6795' tid='6796', class="m">RedirectExternalReference</a>);
- }
- <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>) {
- <span class="d">i_cache_ = isolate_->simulator_i_cache();</span>
- <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>) {
- <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>);
- <a id='6741' tid='6742', class="m">isolate_</a>-><a id='6743' tid='6744', class="m">set_simulator_i_cache</a>(<a id='6745' tid='6746', class="m">i_cache_</a>);
- }
- <span class="d">Initialize(isolate);</span>
- // Setup simulator support first. Some of this information is needed to
- // setup the architecture state.
- <span class="d">stack_ = reinterpret_cast<char*>(malloc(stack_size_));</span>
- <span class="d">pc_modified_ = false;</span>
- <span class="d">icount_ = 0;</span>
- <span class="d">break_count_ = 0;</span>
- <span class="d">break_pc_ = NULL;</span>
- <span class="d">break_instr_ = 0;</span>
- // Setup architecture state.
- // All registers are initialized to zero to start with.
- <span class="d">for (int i = 0; i < kNumSimuRegisters; i++) {
- registers_[i] = 0;
- }</span>
- <span class="d">for (int i = 0; i < kNumFPURegisters; i++) {
- FPUregisters_[i] = 0;
- }</span>
- <span class="d">FCSR_ = 0;</span>
- // The sp is initialized to point to the bottom (high address) of the
- // allocated stack area. To be safe in potential stack underflows we leave
- // some buffer below.
- <span class="d">registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size_ - 64;</span>
- // The ra and pc are initialized to a known bad value that will cause an
- // access violation if the simulator ever tries to execute it.
- <span class="d">registers_[pc] = bad_ra;</span>
- <span class="d">registers_[ra] = bad_ra;</span>
- <span class="d">InitializeCoverage();</span>
- <span class="d">for (int i = 0; i < kNumExceptions; i++) {
- exceptions[i] = 0;
- }</span>
- }
- // When the generated code calls an external reference we need to catch that in
- // the simulator. The external reference will be a function compiled for the
- // host architecture. We need to call that function instead of trying to
- // execute it with the simulator. We do that by redirecting the external
- // reference to a swi (software-interrupt) instruction that is handled by
- // the simulator. We write the original destination of the jump just at a known
- // offset from the swi instruction so the simulator knows what to call.
- <a id='6473' tid='6474', class="m">class</a> <a id='6475' tid='6476', class="m">Redirection</a> {
- <a id='6669' tid='6670', class="m">public</a>:
- <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>)
- : <span class="d">external_function_(external_function),
- swi_instruction_(rtCallRedirInstr),
- type_(type),
- next_(NULL)</span> {
- <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>();
- <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>-><a id='6389' tid='6390', class="m">simulator_redirection</a>();
- <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>)->
- <a id='6399' tid='6400', class="m">FlushICache</a>(<a id='6401' tid='6402', class="m">isolate</a>-><a id='6403' tid='6404', class="m">simulator_i_cache</a>(),
- <a id='6405' tid='6406', class="m">reinterpret_cast</a><<a id='6407' tid='6408', class="m">void</a><a id='6409' tid='6410', class="m">*</a>>(<a id='6411' tid='6412', class="m">&</a><a id='6413' tid='6414', class="m">swi_instruction_</a>),
- <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>);
- <a id='6421' tid='6422', class="m">isolate</a>-><a id='6423' tid='6424', class="m">set_simulator_redirection</a>(<a id='6425' tid='6426', class="m">this</a>);
- }
- <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>() {
- <a id='6635' tid='6636', class="m">return</a> <a id='6637' tid='6638', class="m">reinterpret_cast</a><<a id='6639' tid='6640', class="m">void</a><a id='6641' tid='6642', class="m">*</a>>(<a id='6643' tid='6644', class="m">&</a><a id='6645' tid='6646', class="m">swi_instruction_</a>);
- }
- <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>; }
- <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>; }
- <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>,
- <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>) {
- <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>();
- <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>-><a id='6573' tid='6574', class="m">simulator_redirection</a>();
- <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>-><a id='6589' tid='6590', class="m">next_</a>) {
- <a id='6591' tid='6592', class="m">if</a> (<a id='6593' tid='6594', class="m">current</a>-><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>;
- }
- <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>);
- }
- <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>) {
- <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><<a id='6499' tid='6500', class="m">char</a><a id='6501' tid='6502', class="m">*</a>>(<a id='6503' tid='6504', class="m">swi_instruction</a>);
- <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> =
- <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>);
- <a id='6521' tid='6522', class="m">return</a> <a id='6523' tid='6524', class="m">reinterpret_cast</a><<a id='6525' tid='6526', class="m">Redirection</a><a id='6527' tid='6528', class="m">*</a>>(<a id='6529' tid='6530', class="m">addr_of_redirection</a>);
- }
- <a id='6671' tid='6672', class="m">private</a>:
- <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>;
- <a id='6679' tid='6680', class="m">uint32_t</a> <a id='6681' tid='6682', class="m">swi_instruction_</a>;
- <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>;
- <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>;
- };
- <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>,
- <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>) {
- <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>);
- <a id='6467' tid='6468', class="m">return</a> <a id='6469' tid='6470', class="m">redirection</a>-><a id='6471' tid='6472', class="m">address_of_swi_instruction</a>();
- }
- // Get the active Simulator for the current thread.
- <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>) {
- <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> =
- <a id='6367' tid='6368', class="m">isolate</a>-><a id='6369' tid='6370', class="m">FindOrAllocatePerThreadDataForThisThread</a>();
- <span class="d">ASSERT(isolate_data != NULL);</span>
- <span class="d">ASSERT(isolate_data != NULL);</span>
- <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>-><a id='6329' tid='6330', class="m">simulator</a>();
- <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>) {
- // TODO(146): delete the simulator object when a thread/isolate goes away.
- <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>);
- <a id='6285' tid='6286', class="m">isolate_data</a>-><a id='6287' tid='6288', class="m">set_simulator</a>(<a id='6289' tid='6290', class="m">sim</a>);
- }
- <span class="d">return sim;</span>
- }
- // Sets the register in the architecture state. It will also deal with updating
- // Simulator internal state for special registers such as PC.
- <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>) {
- <span class="d">ASSERT((reg >= 0) && (reg < kNumSimuRegisters));</span>
- <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>) {
- <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>;
- }
- // Zero register always holds 0.
- <span class="d">registers_[reg] = (reg == 0) ? 0 : value;</span>
- }
- <span class="d">void Simulator::set_fpu_register(int fpureg, int32_t value) {
- ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
- FPUregisters_[fpureg] = value;
- }</span>
- <span class="d">void Simulator::set_fpu_register_float(int fpureg, float value) {
- ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
- *BitCast<float*>(&FPUregisters_[fpureg]) = value;
- }</span>
- <span class="d">void Simulator::set_fpu_register_double(int fpureg, double value) {
- ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
- *BitCast<double*>(&FPUregisters_[fpureg]) = value;
- }</span>
- // Get the register from the architecture state. This function does handle
- // the special case of accessing the PC register.
- <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> {
- <span class="d">ASSERT((reg >= 0) && (reg < kNumSimuRegisters));</span>
- <span class="d">if</span> <span class="d">(reg == 0)</span>
- <span class="d">return 0;</span>
- <span class="d">else</span>
- <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>);
- }
- <span class="d">int32_t Simulator::get_fpu_register(int fpureg) const</span> <span class="d">{
- ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
- return FPUregisters_[fpureg];
- }</span>
- <span class="d">int64_t Simulator::get_fpu_register_long(int fpureg) const</span> <span class="d">{
- ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
- return *BitCast<int64_t*>(
- const_cast<int32_t*>(&FPUregisters_[fpureg]));
- }</span>
- <span class="d">float Simulator::get_fpu_register_float(int fpureg) const</span> <span class="d">{
- ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters));
- return *BitCast<float*>(
- const_cast<int32_t*>(&FPUregisters_[fpureg]));
- }</span>
- <span class="d">double Simulator::get_fpu_register_double(int fpureg) const</span> <span class="d">{
- ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0));
- return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg]));
- }</span>
- // For use in calls that take two double values, constructed either
- // from a0-a3 or f12 and f14.
- <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>) {
- <span class="d">if</span> <span class="d">(!IsMipsSoftFloatABI)</span> <span class="d">{
- *x = get_fpu_register_double(12);
- *y = get_fpu_register_double(14);
- }</span> <a id='6173' tid='6174', class="m">else</a> {
- // We use a char buffer to get around the strict-aliasing rules which
- // otherwise allow the compiler to optimize away the copy.
- <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>)];
- <span class="d">int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);</span>
- // Registers a0 and a1 -> x.
- <span class="d">reg_buffer[0] = get_register(a0);</span>
- <span class="d">reg_buffer[1] = get_register(a1);</span>
- <span class="d">memcpy(x, buffer, sizeof(buffer));</span>
- // Registers a2 and a3 -> y.
- <span class="d">reg_buffer[0] = get_register(a2);</span>
- <span class="d">reg_buffer[1] = get_register(a3);</span>
- <span class="d">memcpy(y, buffer, sizeof(buffer));</span>
- }
- }
- // For use in calls that take one double value, constructed either
- // from a0 and a1 or f12.
- <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>) {
- <span class="d">if</span> <span class="d">(!IsMipsSoftFloatABI)</span> <span class="d">{
- *x = get_fpu_register_double(12);
- }</span> <span class="d">else</span> {
- // We use a char buffer to get around the strict-aliasing rules which
- // otherwise allow the compiler to optimize away the copy.
- <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>)];
- <span class="d">int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);</span>
- // Registers a0 and a1 -> x.
- <span class="d">reg_buffer[0] = get_register(a0);</span>
- <span class="d">reg_buffer[1] = get_register(a1);</span>
- <span class="d">memcpy(x, buffer, sizeof(buffer));</span>
- }
- }
- // For use in calls that take one double value constructed either
- // from a0 and a1 or f12 and one integer value.
- <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>) {
- <span class="d">if</span> <span class="d">(!IsMipsSoftFloatABI)</span> <span class="d">{
- *x = get_fpu_register_double(12);
- *y = get_register(a2);
- }</span> <a id='6117' tid='6118', class="m">else</a> {
- // We use a char buffer to get around the strict-aliasing rules which
- // otherwise allow the compiler to optimize away the copy.
- <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>)];
- <span class="d">int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);</span>
- // Registers 0 and 1 -> x.
- <span class="d">reg_buffer[0] = get_register(a0);</span>
- <span class="d">reg_buffer[1] = get_register(a1);</span>
- <span class="d">memcpy(x, buffer, sizeof(buffer));</span>
- // Register 2 -> y.
- <span class="d">reg_buffer[0] = get_register(a2);</span>
- <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>));
- }
- }
- // The return value is either in v0/v1 or f0.
- <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>) {
- <span class="d">if</span> <span class="d">(!IsMipsSoftFloatABI)</span> <span class="d">{
- set_fpu_register_double(0, result);
- }</span> <span class="d">else</span> {
- <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>])];
- <span class="d">int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);</span>
- <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>));
- // Copy result to v0 and v1.
- <span class="d">set_register(v0, reg_buffer[0]);</span>
- <span class="d">set_register(v1, reg_buffer[1]);</span>
- }
- }
- // Helper functions for setting and testing the FCSR register's bits.
- <span class="d">void Simulator::set_fcsr_bit(uint32_t cc, bool value) {
- if (value) {
- FCSR_ |= (1 << cc);
- } else {
- FCSR_ &= ~(1 << cc);
- }
- }</span>
- <span class="d">bool Simulator::test_fcsr_bit(uint32_t cc) {
- return FCSR_ & (1 << cc);
- }</span>
- // Sets the rounding error codes in FCSR based on the result of the rounding.
- // Returns true if the operation was invalid.
- <span class="d">bool Simulator::set_fcsr_round_error(double original, double rounded) {
- bool ret = false;
- if (!isfinite(original) || !isfinite(rounded)) {
- set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
- ret = true;
- }
- if (original != rounded) {
- set_fcsr_bit(kFCSRInexactFlagBit, true);
- }
- if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
- set_fcsr_bit(kFCSRUnderflowFlagBit, true);
- ret = true;
- }
- if (rounded > INT_MAX || rounded < INT_MIN) {
- set_fcsr_bit(kFCSROverflowFlagBit, true);
- // The reference is not really clear but it seems this is required:
- set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
- ret = true;
- }
- return ret;
- }</span>
- // Raw access to the PC register.
- <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>) {
- <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>;
- <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>;
- }
- <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">{
- return ((registers_[pc] == bad_ra) || (registers_[pc] == end_sim_pc));
- }</span>
- // Raw access to the PC register without the special adjustment when reading.
- <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">{
- return registers_[pc];
- }</span>
- // The MIPS cannot do unaligned reads and writes. On some MIPS platforms an
- // interrupt is caused. On others it does a funky rotation thing. For now we
- // simply disallow unaligned reads, but at some point we may want to move to
- // emulating the rotate behaviour. Note that simulator runs have the runtime
- // system running directly on the host system and only generated code is
- // executed in the simulator. Since the host is typically IA32 we will not
- // get the correct MIPS-like behaviour on unaligned accesses.
- <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>) {
- <span class="d">if (addr >=0 && addr < 0x400) {
- // This has to be a NULL-dereference, drop into debugger.
- MipsDebugger dbg(this);
- dbg.Debug();
- }</span>
- <span class="d">if</span> <span class="d">((addr & kPointerAlignmentMask) == 0)</span> {
- <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><<a id='6037' tid='6038', class="m">intptr_t</a><a id='6039' tid='6040', class="m">*</a>>(<a id='6041' tid='6042', class="m">addr</a>);
- <span class="d">return *ptr;</span>
- }
- <a id='5995' tid='5996', class="m">PrintF</a>(<a id='5997' tid='5998', class="m">"Unaligned read at 0x%08x, pc=0x%08"</a> <a id='5999' tid='6000', class="m">V8PRIxPTR</a> <a id='6001' tid='6002', class="m">"\n"</a>,
- <a id='6003' tid='6004', class="m">addr</a>,
- <a id='6005' tid='6006', class="m">reinterpret_cast</a><<a id='6007' tid='6008', class="m">intptr_t</a>>(<a id='6009' tid='6010', class="m">instr</a>));
- <span class="d">MipsDebugger dbg(this)</span>;
- <span class="d">dbg.Debug();</span>
- <span class="d">return 0;</span>
- }
- <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>) {
- <span class="d">if (addr >= 0 && addr < 0x400) {
- // This has to be a NULL-dereference, drop into debugger.
- MipsDebugger dbg(this);
- dbg.Debug();
- }</span>
- <span class="d">if</span> <span class="d">((addr & kPointerAlignmentMask) == 0)</span> {
- <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><<a id='5989' tid='5990', class="m">intptr_t</a><a id='5991' tid='5992', class="m">*</a>>(<a id='5993' tid='5994', class="m">addr</a>);
- <span class="d">*ptr = value;</span>
- <span class="d">return;</span>
- }
- <a id='5943' tid='5944', class="m">PrintF</a>(<a id='5945' tid='5946', class="m">"Unaligned write at 0x%08x, pc=0x%08"</a> <a id='5947' tid='5948', class="m">V8PRIxPTR</a> <a id='5949' tid='5950', class="m">"\n"</a>,
- <a id='5951' tid='5952', class="m">addr</a>,
- <a id='5953' tid='5954', class="m">reinterpret_cast</a><<a id='5955' tid='5956', class="m">intptr_t</a>>(<a id='5957' tid='5958', class="m">instr</a>));
- <span class="d">MipsDebugger dbg(this)</span>;
- <span class="d">dbg.Debug();</span>
- }
- <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">{
- if ((addr & kDoubleAlignmentMask) == 0) {
- double* ptr = reinterpret_cast<double*>(addr);
- return *ptr;
- }
- PrintF("Unaligned (double) read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
- addr,
- reinterpret_cast<intptr_t>(instr));
- OS::Abort();
- return 0;
- }</span>
- <span class="d">void Simulator::WriteD(int32_t addr, double value, Instruction* instr) {
- if ((addr & kDoubleAlignmentMask) == 0) {
- double* ptr = reinterpret_cast<double*>(addr);
- *ptr = value;
- return;
- }
- PrintF("Unaligned (double) write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
- addr,
- reinterpret_cast<intptr_t>(instr));
- OS::Abort();
- }</span>
- <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>) {
- <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>) {
- <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><<a id='5907' tid='5908', class="m">uint16_t</a><a id='5909' tid='5910', class="m">*</a>>(<a id='5911' tid='5912', class="m">addr</a>);
- <span class="d">return *ptr;</span>
- }
- <a id='5875' tid='5876', class="m">PrintF</a>(<a id='5877' tid='5878', class="m">"Unaligned unsigned halfword read at 0x%08x, pc=0x%08"</a> <a id='5879' tid='5880', class="m">V8PRIxPTR</a> <a id='5881' tid='5882', class="m">"\n"</a>,
- <a id='5883' tid='5884', class="m">addr</a>,
- <a id='5885' tid='5886', class="m">reinterpret_cast</a><<a id='5887' tid='5888', class="m">intptr_t</a>>(<a id='5889' tid='5890', class="m">instr</a>));
- <span class="d">OS::Abort();</span>
- <span class="d">return 0;</span>
- }
- <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> {
- <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>) {
- <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><<a id='5809' tid='5810', class="m">int16_t</a><a id='5811' tid='5812', class="m">*</a>>(<a id='5813' tid='5814', class="m">addr</a>);
- <span class="d">return *ptr;</span>
- }
- <span class="d">PrintF("Unaligned signed halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
- addr,
- reinterpret_cast<intptr_t>(instr));</span>
- <span class="d">OS::Abort();</span>
- <span class="d">return 0;</span>
- }
- <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>) {
- <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>) {
- <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><<a id='5841' tid='5842', class="m">uint16_t</a><a id='5843' tid='5844', class="m">*</a>>(<a id='5845' tid='5846', class="m">addr</a>);
- <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>;
- <a id='5855' tid='5856', class="m">return</a>;
- }
- <a id='5815' tid='5816', class="m">PrintF</a>(<a id='5817' tid='5818', class="m">"Unaligned unsigned halfword write at 0x%08x, pc=0x%08"</a> <a id='5819' tid='5820', class="m">V8PRIxPTR</a> <a id='5821' tid='5822', class="m">"\n"</a>,
- <a id='5823' tid='5824', class="m">addr</a>,
- <a id='5825' tid='5826', class="m">reinterpret_cast</a><<a id='5827' tid='5828', class="m">intptr_t</a>>(<a id='5829' tid='5830', class="m">instr</a>));
- <span class="d">OS::Abort();</span>
- }
- <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>) {
- <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>) {
- <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><<a id='4357' tid='4358', class="m">int16_t</a><a id='4359' tid='4360', class="m">*</a>>(<a id='4361' tid='4362', class="m">addr</a>);
- <span class="d">*ptr = value;</span>
- <span class="d">return;</span>
- }
- <a id='4321' tid='4322', class="m">PrintF</a>(<a id='4323' tid='4324', class="m">"Unaligned halfword write at 0x%08x, pc=0x%08"</a> <a id='4325' tid='4326', class="m">V8PRIxPTR</a> <a id='4327' tid='4328', class="m">"\n"</a>,
- <a id='4329' tid='4330', class="m">addr</a>,
- <a id='4331' tid='4332', class="m">reinterpret_cast</a><<a id='4333' tid='4334', class="m">intptr_t</a>>(<a id='4335' tid='4336', class="m">instr</a>));
- <span class="d">OS::Abort();</span>
- }
- <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>) {
- <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><<a id='5785' tid='5786', class="m">uint8_t</a><a id='5787' tid='5788', class="m">*</a>>(<a id='5789' tid='5790', class="m">addr</a>);
- <span class="d">return *ptr & 0xff;</span>
- }
- <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>) {
- <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><<a id='5743' tid='5744', class="m">int8_t</a><a id='5745' tid='5746', class="m">*</a>>(<a id='5747' tid='5748', class="m">addr</a>);
- <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>;
- }
- <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>) {
- <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><<a id='5711' tid='5712', class="m">uint8_t</a><a id='5713' tid='5714', class="m">*</a>>(<a id='5715' tid='5716', class="m">addr</a>);
- <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>;
- }
- <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>) {
- <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><<a id='5663' tid='5664', class="m">int8_t</a><a id='5665' tid='5666', class="m">*</a>>(<a id='5667' tid='5668', class="m">addr</a>);
- <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>;
- }
- // Returns the limit of the stack area to enable checking for stack overflows.
- <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> {
- // Leave a safety margin of 256 bytes to prevent overrunning the stack when
- // pushing values.
- <a id='5617' tid='5618', class="m">return</a> <a id='5619' tid='5620', class="m">reinterpret_cast</a><<a id='5621' tid='5622', class="m">uintptr_t</a>>(<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>;
- }
- // Unsupported instructions use Format to print an error and stop execution.
- <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>) {
- <a id='5605' tid='5606', class="m">PrintF</a>(<a id='5607' tid='5608', class="m">"Simulator found unsupported instruction:\n 0x%08x: %s\n"</a>,
- <a id='5609' tid='5610', class="m">reinterpret_cast</a><<a id='5611' tid='5612', class="m">intptr_t</a>>(<a id='5613' tid='5614', class="m">instr</a>), <a id='5615' tid='5616', class="m">format</a>);
- <span class="d">UNIMPLEMENTED_MIPS();</span>
- }
- // Calls into the V8 runtime are based on this very simple interface.
- // Note: To be able to return two values from some calls the code in runtime.cc
- // uses the ObjectPair which is essentially two 32-bit values stuffed into a
- // 64-bit value. With the code below we assume that all runtime calls return
- // 64 bits of result. If they don't, the v1 result register contains a bogus
- // value, which is fine because it is caller-saved.
- <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>,
- <a id='5563' tid='5564', class="m">int32_t</a> <a id='5565' tid='5566', class="m">arg1</a>,
- <a id='5567' tid='5568', class="m">int32_t</a> <a id='5569' tid='5570', class="m">arg2</a>,
- <a id='5571' tid='5572', class="m">int32_t</a> <a id='5573' tid='5574', class="m">arg3</a>,
- <a id='5575' tid='5576', class="m">int32_t</a> <a id='5577' tid='5578', class="m">arg4</a>,
- <a id='5579' tid='5580', class="m">int32_t</a> <a id='5581' tid='5582', class="m">arg5</a>);
- <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>,
- <a id='5539' tid='5540', class="m">int32_t</a> <a id='5541' tid='5542', class="m">arg1</a>,
- <a id='5543' tid='5544', class="m">int32_t</a> <a id='5545' tid='5546', class="m">arg2</a>,
- <a id='5547' tid='5548', class="m">int32_t</a> <a id='5549' tid='5550', class="m">arg3</a>);
- // This signature supports direct call in to API function native callback
- // (refer to InvocationCallback in v8.h).
- <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><<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>> (<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>);
- // This signature supports direct call to accessor getter callback.
- <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><<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>> (<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>,
- <a id='5501' tid='5502', class="m">int32_t</a> <a id='5503' tid='5504', class="m">arg1</a>);
- // Software interrupt instructions are used by the simulator to call into the
- // C-based V8 runtime. They are also used for debugging with simulator.
- <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>) {
- // There are several instructions that could get us here,
- // the break_ instruction, or several variants of traps. All
- // Are "SPECIAL" class opcode, and are distinuished by function.
- <span class="d">int32_t func = instr->FunctionFieldRaw();</span>
- <span class="d">uint32_t code = (func == BREAK) ? instr->Bits(25, 6) : -1;</span>
- // We first check if we met a call_rt_redirected.
- <span class="d">if</span> <span class="d">(instr->InstructionBits() == rtCallRedirInstr)</span> {
- <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>);
- <span class="d">int32_t arg0 = get_register(a0);</span>
- <span class="d">int32_t arg1 = get_register(a1);</span>
- <span class="d">int32_t arg2 = get_register(a2);</span>
- <span class="d">int32_t arg3 = get_register(a3);</span>
- <span class="d">int32_t arg4 = 0;</span>
- <span class="d">int32_t arg5 = 0;</span>
- // Need to check if sp is valid before assigning arg4, arg5.
- // This is a fix for cctest test-api/CatchStackOverflow which causes
- // the stack to overflow. For some reason arm doesn't need this
- // stack check here.
- <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><<a id='5443' tid='5444', class="m">int32_t</a><a id='5445' tid='5446', class="m">*</a>>(<a id='5447' tid='5448', class="m">get_register</a>(<a id='5449' tid='5450', class="m">sp</a>));
- <span class="d">int32_t* stack = reinterpret_cast<int32_t*>(stack_);</span>
- <span class="d">if (stack_pointer >= stack && stack_pointer < stack + stack_size_ - 5) {
- // Args 4 and 5 are on the stack after the reserved space for args 0..3.
- arg4 = stack_pointer[4];
- arg5 = stack_pointer[5];
- }</span>
- <a id='5363' tid='5364', class="m">bool</a> <a id='5365' tid='5366', class="m">fp_call</a> =
- (<a id='5367' tid='5368', class="m">redirection</a>-><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>
- (<a id='5381' tid='5382', class="m">redirection</a>-><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>
- (<a id='5395' tid='5396', class="m">redirection</a>-><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>
- (<a id='5409' tid='5410', class="m">redirection</a>-><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>);
- <span class="d">if (!IsMipsSoftFloatABI) {
- // With the hard floating point calling convention, double
- // arguments are passed in FPU registers. Fetch the arguments
- // from there and call the builtin using soft floating point
- // convention.
- switch (redirection->type()) {
- case ExternalReference::BUILTIN_FP_FP_CALL:
- case ExternalReference::BUILTIN_COMPARE_CALL:
- arg0 = get_fpu_register(f12);
- arg1 = get_fpu_register(f13);
- arg2 = get_fpu_register(f14);
- arg3 = get_fpu_register(f15);
- break;
- case ExternalReference::BUILTIN_FP_CALL:
- arg0 = get_fpu_register(f12);
- arg1 = get_fpu_register(f13);
- break;
- case ExternalReference::BUILTIN_FP_INT_CALL:
- arg0 = get_fpu_register(f12);
- arg1 = get_fpu_register(f13);
- arg2 = get_register(a2);
- break;
- default:
- break;
- }
- }</span>
- // This is dodgy but it works because the C entry stubs are never moved.
- // See comment in codegen-arm.cc and bug 1242173.
- <span class="d">int32_t saved_ra = get_register(ra);</span>
- <a id='5327' tid='5328', class="m">intptr_t</a> <a id='5329' tid='5330', class="m">external</a> =
- <a id='5331' tid='5332', class="m">reinterpret_cast</a><<a id='5333' tid='5334', class="m">intptr_t</a>>(<a id='5335' tid='5336', class="m">redirection</a>-><a id='5337' tid='5338', class="m">external_function</a>());
- // Based on CpuFeatures::IsSupported(FPU), Mips will use either hardware
- // FPU, or gcc soft-float routines. Hardware FPU is simulated in this
- // simulator. Soft-float has additional abstraction of ExternalReference,
- // to support serialization.
- <a id='5227' tid='5228', class="m">if</a> (<a id='5229' tid='5230', class="m">fp_call</a>) {
- <a id='5231' tid='5232', class="m">SimulatorRuntimeFPCall</a> <a id='5233' tid='5234', class="m">target</a> =
- <a id='5235' tid='5236', class="m">reinterpret_cast</a><<a id='5237' tid='5238', class="m">SimulatorRuntimeFPCall</a>>(<a id='5239' tid='5240', class="m">external</a>);
- <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>) {
- <span class="d">double dval0, dval1;</span>
- <span class="d">int32_t ival;</span>
- <a id='5015' tid='5016', class="m">switch</a> (<a id='5017' tid='5018', class="m">redirection</a>-><a id='5019' tid='5020', class="m">type</a>()) {
- <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>:
- <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>:
- <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>);
- <a id='5047' tid='5048', class="m">PrintF</a>(<a id='5049' tid='5050', class="m">"Call to host function at %p with args %f, %f"</a>,
- <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>);
- <a id='5059' tid='5060', class="m">break</a>;
- <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>:
- <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>);
- <a id='5075' tid='5076', class="m">PrintF</a>(<a id='5077' tid='5078', class="m">"Call to host function at %p with arg %f"</a>,
- <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>);
- <a id='5085' tid='5086', class="m">break</a>;
- <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>:
- <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>);
- <a id='5105' tid='5106', class="m">PrintF</a>(<a id='5107' tid='5108', class="m">"Call to host function at %p with args %f, %d"</a>,
- <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>);
- <a id='5117' tid='5118', class="m">break</a>;
- <a id='5119' tid='5120', class="m">default</a>:
- <a id='5121' tid='5122', class="m">UNREACHABLE</a>();
- <a id='5123' tid='5124', class="m">break</a>;
- }
- }
- <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>);
- <span class="d">if</span> (<a id='4873' tid='4874', class="m">redirection</a>-><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">{
- SetFpResult(result);
- }</span> <span class="d">else {
- int32_t gpreg_pair[2];
- memcpy(&gpreg_pair[0], &result, 2 * sizeof(int32_t));
- set_register(v0, gpreg_pair[0]);
- set_register(v1, gpreg_pair[1]);
- }</span>
- } <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>-><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>) {
- // See DirectCEntryStub::GenerateCall for explanation of register usage.
- <a id='5257' tid='5258', class="m">SimulatorRuntimeDirectApiCall</a> <a id='5259' tid='5260', class="m">target</a> =
- <a id='5261' tid='5262', class="m">reinterpret_cast</a><<a id='5263' tid='5264', class="m">SimulatorRuntimeDirectApiCall</a>>(<a id='5265' tid='5266', class="m">external</a>);
- <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">{
- PrintF("Call to host function at %p args %08x\n",
- FUNCTION_ADDR(target), arg1);
- }</span>
- <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><<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>> <span class="d">result = target(arg1)</span>;
- <span class="d">*(reinterpret_cast<int*>(arg0)) = (int32_t) *result;</span>
- <span class="d">set_register(v0, arg0);</span>
- } <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>-><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>) {
- // See DirectCEntryStub::GenerateCall for explanation of register usage.
- <a id='5283' tid='5284', class="m">SimulatorRuntimeDirectGetterCall</a> <a id='5285' tid='5286', class="m">target</a> =
- <a id='5287' tid='5288', class="m">reinterpret_cast</a><<a id='5289' tid='5290', class="m">SimulatorRuntimeDirectGetterCall</a>>(<a id='5291' tid='5292', class="m">external</a>);
- <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">{
- PrintF("Call to host function at %p args %08x %08x\n",
- FUNCTION_ADDR(target), arg1, arg2);
- }</span>
- <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><<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>> <span class="d">result = target(arg1, arg2)</span>;
- <span class="d">*(reinterpret_cast<int*>(arg0)) = (int32_t) *result;</span>
- <span class="d">set_register(v0, arg0);</span>
- } <a id='5293' tid='5294', class="m">else</a> {
- <a id='5295' tid='5296', class="m">SimulatorRuntimeCall</a> <a id='5297' tid='5298', class="m">target</a> =
- <a id='5299' tid='5300', class="m">reinterpret_cast</a><<a id='5301' tid='5302', class="m">SimulatorRuntimeCall</a>>(<a id='5303' tid='5304', class="m">external</a>);
- <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">{
- PrintF(
- "Call to host function at %p "
- "args %08x, %08x, %08x, %08x, %08x, %08x\n",
- FUNCTION_ADDR(target),
- arg0,
- arg1,
- arg2,
- arg3,
- arg4,
- arg5);
- }</span>
- <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>);
- <span class="d">set_register(v0, static_cast<int32_t>(result));</span>
- <span class="d">set_register</span>(<span class="d">v1</span>, <a id='4643' tid='4644', class="m">static_cast</a><<a id='4645' tid='4646', class="m">int32_t</a>>(<a id='4647' tid='4648', class="m">result</a> <a id='4649' tid='4650', class="m">>></a> <a id='4651' tid='4652', class="m">32</a>));
- }
- <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">{
- PrintF("Returned %08x : %08x\n", get_register(v1), get_register(v0));
- }</span>
- <span class="d">set_register(ra, saved_ra);</span>
- <span class="d">set_pc(get_register(ra));</span>
- } <span class="d">else if (func == BREAK && code <= kMaxStopCode) {
- if (IsWatchpoint(code)) {
- PrintWatchpoint(code);
- } else {
- IncreaseStopCounter(code);
- HandleStop(code, instr);
- }
- } else {
- // All remaining break_ codes, and all traps are handled here.
- MipsDebugger dbg(this);
- dbg.Debug();
- }</span>
- }
- // Stop helper functions.
- <span class="d">bool Simulator::IsWatchpoint(uint32_t code) {
- return (code <= kMaxWatchpointCode);
- }</span>
- <span class="d">void Simulator::PrintWatchpoint(uint32_t code) {
- MipsDebugger dbg(this);
- ++break_count_;
- PrintF("\n---- break %d marker: %3d (instr count: %8d) ----------"
- "----------------------------------",
- code, break_count_, icount_);
- dbg.PrintAllRegs(); // Print registers and continue running.
- }</span>
- <span class="d">void</span> <span class="d">Simulator::HandleStop</span><span class="d">(uint32_t code, Instruction* instr)</span> {
- // Stop if it is enabled, otherwise go on jumping over the stop
- // and the message address.
- <span class="d">if</span> <span class="d">(IsEnabledStop(code))</span> <span class="d">{
- MipsDebugger dbg(this);
- dbg.Stop(instr);
- }</span> <a id='4855' tid='4856', class="m">else</a> {
- <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>);
- }
- }
- <span class="d">bool Simulator::IsStopInstruction(Instruction* instr) {
- int32_t func = instr->FunctionFieldRaw();
- uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6));
- return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode;
- }</span>
- <span class="d">bool</span> <span class="d">Simulator::IsEnabledStop</span><span class="d">(uint32_t code)</span> {
- <span class="d">ASSERT(code <= kMaxStopCode);</span>
- <span class="d">ASSERT(code > kMaxWatchpointCode);</span>
- <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>);
- }
- <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>) {
- <span class="d">if</span> <span class="d">(!IsEnabledStop(code))</span> {
- <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>;
- }
- }
- <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>) {
- <span class="d">if</span> <span class="d">(IsEnabledStop(code))</span> {
- <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>;
- }
- }
- <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>) {
- <span class="d">ASSERT(code <= kMaxStopCode);</span>
- <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"><<</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>) {
- <a id='5195' tid='5196', class="m">PrintF</a>(<a id='5197' tid='5198', class="m">"Stop counter for code %i has overflowed.\n"</a>
- <a id='5199' tid='5200', class="m">"Enabling this code and reseting the counter to 0.\n"</a>, <a id='5201' tid='5202', class="m">code</a>);
- <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>;
- <a id='5213' tid='5214', class="m">EnableStop</a>(<a id='5215' tid='5216', class="m">code</a>);
- } <a id='5217' tid='5218', class="m">else</a> {
- <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>;
- }
- }
- // Print a stop status.
- <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>) {
- <span class="d">if (code <= kMaxWatchpointCode) {
- PrintF("That is a watchpoint, not a stop.\n");
- return;
- } else if (code > kMaxStopCode) {
- PrintF("Code too large, only %u stops can be used\n", kMaxStopCode + 1);
- return;
- }</span>
- <span class="d">const char* state = IsEnabledStop(code) ? "Enabled" : "Disabled";</span>
- <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>;
- // Don't print the state of unused breakpoints.
- <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>) {
- <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>) {
- <a id='4943' tid='4944', class="m">PrintF</a>(<a id='4945' tid='4946', class="m">"stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n"</a>,
- <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>);
- } <a id='4961' tid='4962', class="m">else</a> {
- <a id='4963' tid='4964', class="m">PrintF</a>(<a id='4965' tid='4966', class="m">"stop %i - 0x%x: \t%s, \tcounter = %i\n"</a>,
- <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>);
- }
- }
- }
- <span class="d">void Simulator::SignalExceptions() {
- for (int i = 1; i < kNumExceptions; i++) {
- if (exceptions[i] != 0) {
- V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i);
- }
- }
- }</span>
- // Handle execution based on instruction types.
- <span class="d">void Simulator::ConfigureTypeRegister(Instruction* instr,
- int32_t& alu_out,
- int64_t& i64hilo,
- uint64_t& u64hilo,
- int32_t& next_pc,
- bool& do_interrupt) {
- // Every local variable declared here needs to be const.
- // This is to make sure that changed values are sent back to
- // DecodeTypeRegister correctly.
- // Instruction fields.
- const Opcode op = instr->OpcodeFieldRaw();
- const int32_t rs_reg = instr->RsValue();
- const int32_t rs = get_register(rs_reg);
- const uint32_t rs_u = static_cast<uint32_t>(rs);
- const int32_t rt_reg = instr->RtValue();
- const int32_t rt = get_register(rt_reg);
- const uint32_t rt_u = static_cast<uint32_t>(rt);
- const int32_t rd_reg = instr->RdValue();
- const uint32_t sa = instr->SaValue();
- const int32_t fs_reg = instr->FsValue();
- // ---------- Configuration.
- switch (op) {
- case COP1: // Coprocessor instructions.
- switch (instr->RsFieldRaw()) {
- case BC1: // Handled in DecodeTypeImmed, should never come here.
- UNREACHABLE();
- break;
- case CFC1:
- // At the moment only FCSR is supported.
- ASSERT(fs_reg == kFCSRRegister);
- alu_out = FCSR_;
- break;
- case MFC1:
- alu_out = get_fpu_register(fs_reg);
- break;
- case MFHC1:
- UNIMPLEMENTED_MIPS();
- break;
- case CTC1:
- case MTC1:
- case MTHC1:
- // Do the store in the execution step.
- break;
- case S:
- case D:
- case W:
- case L:
- case PS:
- // Do everything in the execution step.
- break;
- default:
- UNIMPLEMENTED_MIPS();
- };
- break;
- case SPECIAL:
- switch (instr->FunctionFieldRaw()) {
- case JR:
- case JALR:
- next_pc = get_register(instr->RsValue());
- break;
- case SLL:
- alu_out = rt << sa;
- break;
- case SRL:
- if (rs_reg == 0) {
- // Regular logical right shift of a word by a fixed number of
- // bits instruction. RS field is always equal to 0.
- alu_out = rt_u >> sa;
- } else {
- // Logical right-rotate of a word by a fixed number of bits. This
- // is special case of SRL instruction, added in MIPS32 Release 2.
- // RS field is equal to 00001.
- alu_out = (rt_u >> sa) | (rt_u << (32 - sa));
- }
- break;
- case SRA:
- alu_out = rt >> sa;
- break;
- case SLLV:
- alu_out = rt << rs;
- break;
- case SRLV:
- if (sa == 0) {
- // Regular logical right-shift of a word by a variable number of
- // bits instruction. SA field is always equal to 0.
- alu_out = rt_u >> rs;
- } else {
- // Logical right-rotate of a word by a variable number of bits.
- // This is special case od SRLV instruction, added in MIPS32
- // Release 2. SA field is equal to 00001.
- alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u));
- }
- break;
- case SRAV:
- alu_out = rt >> rs;
- break;
- case MFHI:
- alu_out = get_register(HI);
- break;
- case MFLO:
- alu_out = get_register(LO);
- break;
- case MULT:
- i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt);
- break;
- case MULTU:
- u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u);
- break;
- case ADD:
- if (HaveSameSign(rs, rt)) {
- if (rs > 0) {
- exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt);
- } else if (rs < 0) {
- exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt);
- }
- }
- alu_out = rs + rt;
- break;
- case ADDU:
- alu_out = rs + rt;
- break;
- case SUB:
- if (!HaveSameSign(rs, rt)) {
- if (rs > 0) {
- exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt);
- } else if (rs < 0) {
- exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt);
- }
- }
- alu_out = rs - rt;
- break;
- case SUBU:
- alu_out = rs - rt;
- break;
- case AND:
- alu_out = rs & rt;
- break;
- case OR:
- alu_out = rs | rt;
- break;
- case XOR:
- alu_out = rs ^ rt;
- break;
- case NOR:
- alu_out = ~(rs | rt);
- break;
- case SLT:
- alu_out = rs < rt ? 1 : 0;
- break;
- case SLTU:
- alu_out = rs_u < rt_u ? 1 : 0;
- break;
- // Break and trap instructions.
- case BREAK:
- do_interrupt = true;
- break;
- case TGE:
- do_interrupt = rs >= rt;
- break;
- case TGEU:
- do_interrupt = rs_u >= rt_u;
- break;
- case TLT:
- do_interrupt = rs < rt;
- break;
- case TLTU:
- do_interrupt = rs_u < rt_u;
- break;
- case TEQ:
- do_interrupt = rs == rt;
- break;
- case TNE:
- do_interrupt = rs != rt;
- break;
- case MOVN:
- case MOVZ:
- case MOVCI:
- // No action taken on decode.
- break;
- case DIV:
- case DIVU:
- // div and divu never raise exceptions.
- break;
- default:
- UNREACHABLE();
- };
- break;
- case SPECIAL2:
- switch (instr->FunctionFieldRaw()) {
- case MUL:
- alu_out = rs_u * rt_u; // Only the lower 32 bits are kept.
- break;
- case CLZ:
- alu_out = __builtin_clz(rs_u);
- break;
- default:
- UNREACHABLE();
- };
- break;
- case SPECIAL3:
- switch (instr->FunctionFieldRaw()) {
- case INS: { // Mips32r2 instruction.
- // Interpret rd field as 5-bit msb of insert.
- uint16_t msb = rd_reg;
- // Interpret sa field as 5-bit lsb of insert.
- uint16_t lsb = sa;
- uint16_t size = msb - lsb + 1;
- uint32_t mask = (1 << size) - 1;
- alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb);
- break;
- }
- case EXT: { // Mips32r2 instruction.
- // Interpret rd field as 5-bit msb of extract.
- uint16_t msb = rd_reg;
- // Interpret sa field as 5-bit lsb of extract.
- uint16_t lsb = sa;
- uint16_t size = msb + 1;
- uint32_t mask = (1 << size) - 1;
- alu_out = (rs_u & (mask << lsb)) >> lsb;
- break;
- }
- default:
- UNREACHABLE();
- };
- break;
- default:
- UNREACHABLE();
- };
- }</span>
- <span class="d">void</span> <span class="d">Simulator::DecodeTypeRegister</span><span class="d">(Instruction* instr)</span> {
- // Instruction fields.
- <span class="d">const Opcode op = instr->OpcodeFieldRaw();</span>
- <span class="d">const int32_t rs_reg = instr->RsValue();</span>
- <span class="d">const int32_t rs = get_register(rs_reg);</span>
- <span class="d">const uint32_t rs_u = static_cast<uint32_t>(rs);</span>
- <span class="d">const int32_t rt_reg = instr->RtValue();</span>
- <span class="d">const int32_t rt = get_register(rt_reg);</span>
- <span class="d">const uint32_t rt_u = static_cast<uint32_t>(rt);</span>
- <span class="d">const int32_t rd_reg = instr->RdValue();</span>
- <span class="d">const int32_t fs_reg = instr->FsValue();</span>
- <span class="d">const int32_t ft_reg = instr->FtValue();</span>
- <span class="d">const int32_t fd_reg = instr->FdValue();</span>
- <span class="d">int64_t i64hilo = 0;</span>
- <span class="d">uint64_t u64hilo = 0;</span>
- // ALU output.
- // It should not be used as is. Instructions using it should always
- // initialize it first.
- <span class="d">int32_t alu_out = 0x12345678;</span>
- // For break and trap instructions.
- <span class="d">bool do_interrupt = false;</span>
- // For jr and jalr.
- // Get current pc.
- <span class="d">int32_t current_pc = get_pc();</span>
- // Next pc
- <span class="d">int32_t next_pc = 0;</span>
- // Setup the variables if needed before executing the instruction.
- <span class="d">ConfigureTypeRegister(instr,
- alu_out,
- i64hilo,
- u64hilo,
- next_pc,
- do_interrupt);</span>
- // ---------- Raise exceptions triggered.
- <span class="d">SignalExceptions();</span>
- // ---------- Execution.
- <span class="d">switch</span> (<span class="d">op</span>) {
- <span class="d">case COP1:
- switch (instr->RsFieldRaw()) {
- case BC1: // Branch on coprocessor condition.
- UNREACHABLE();
- break;
- case CFC1:
- set_register(rt_reg, alu_out);
- case MFC1:
- set_register(rt_reg, alu_out);
- break;
- case MFHC1:
- UNIMPLEMENTED_MIPS();
- break;
- case CTC1:
- // At the moment only FCSR is supported.
- ASSERT(fs_reg == kFCSRRegister);
- FCSR_ = registers_[rt_reg];
- break;
- case MTC1:
- FPUregisters_[fs_reg] = registers_[rt_reg];
- break;
- case MTHC1:
- UNIMPLEMENTED_MIPS();
- break;
- case S:
- float f;
- switch (instr->FunctionFieldRaw()) {
- case CVT_D_S:
- f = get_fpu_register_float(fs_reg);
- set_fpu_register_double(fd_reg, static_cast<double>(f));
- break;
- case CVT_W_S:
- case CVT_L_S:
- case TRUNC_W_S:
- case TRUNC_L_S:
- case ROUND_W_S:
- case ROUND_L_S:
- case FLOOR_W_S:
- case FLOOR_L_S:
- case CEIL_W_S:
- case CEIL_L_S:
- case CVT_PS_S:
- UNIMPLEMENTED_MIPS();
- break;
- default:
- UNREACHABLE();
- }
- break;
- case D:
- double ft, fs;
- uint32_t cc, fcsr_cc;
- int64_t i64;
- fs = get_fpu_register_double(fs_reg);
- ft = get_fpu_register_double(ft_reg);
- cc = instr->FCccValue();
- fcsr_cc = get_fcsr_condition_bit(cc);
- switch (instr->FunctionFieldRaw()) {
- case ADD_D:
- set_fpu_register_double(fd_reg, fs + ft);
- break;
- case SUB_D:
- set_fpu_register_double(fd_reg, fs - ft);
- break;
- case MUL_D:
- set_fpu_register_double(fd_reg, fs * ft);
- break;
- case DIV_D:
- set_fpu_register_double(fd_reg, fs / ft);
- break;
- case ABS_D:
- set_fpu_register_double(fd_reg, fs < 0 ? -fs : fs);
- break;
- case MOV_D:
- set_fpu_register_double(fd_reg, fs);
- break;
- case NEG_D:
- set_fpu_register_double(fd_reg, -fs);
- break;
- case SQRT_D:
- set_fpu_register_double(fd_reg, sqrt(fs));
- break;
- case C_UN_D:
- set_fcsr_bit(fcsr_cc, isnan(fs) || isnan(ft));
- break;
- case C_EQ_D:
- set_fcsr_bit(fcsr_cc, (fs == ft));
- break;
- case C_UEQ_D:
- set_fcsr_bit(fcsr_cc, (fs == ft) || (isnan(fs) || isnan(ft)));
- break;
- case C_OLT_D:
- set_fcsr_bit(fcsr_cc, (fs < ft));
- break;
- case C_ULT_D:
- set_fcsr_bit(fcsr_cc, (fs < ft) || (isnan(fs) || isnan(ft)));
- break;
- case C_OLE_D:
- set_fcsr_bit(fcsr_cc, (fs <= ft));
- break;
- case C_ULE_D:
- set_fcsr_bit(fcsr_cc, (fs <= ft) || (isnan(fs) || isnan(ft)));
- break;
- case CVT_W_D: // Convert double to word.
- // Rounding modes are not yet supported.
- ASSERT((FCSR_ & 3) == 0);
- // In rounding mode 0 it should behave like ROUND.
- case ROUND_W_D: // Round double to word.
- {
- double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
- int32_t result = static_cast<int32_t>(rounded);
- set_fpu_register(fd_reg, result);
- if (set_fcsr_round_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPUInvalidResult);
- }
- }
- break;
- case TRUNC_W_D: // Truncate double to word (round towards 0).
- {
- double rounded = trunc(fs);
- int32_t result = static_cast<int32_t>(rounded);
- set_fpu_register(fd_reg, result);
- if (set_fcsr_round_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPUInvalidResult);
- }
- }
- break;
- case FLOOR_W_D: // Round double to word towards negative infinity.
- {
- double rounded = floor(fs);
- int32_t result = static_cast<int32_t>(rounded);
- set_fpu_register(fd_reg, result);
- if (set_fcsr_round_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPUInvalidResult);
- }
- }
- break;
- case CEIL_W_D: // Round double to word towards positive infinity.
- {
- double rounded = ceil(fs);
- int32_t result = static_cast<int32_t>(rounded);
- set_fpu_register(fd_reg, result);
- if (set_fcsr_round_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPUInvalidResult);
- }
- }
- break;
- case CVT_S_D: // Convert double to float (single).
- set_fpu_register_float(fd_reg, static_cast<float>(fs));
- break;
- case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word.
- double rounded = trunc(fs);
- i64 = static_cast<int64_t>(rounded);
- set_fpu_register(fd_reg, i64 & 0xffffffff);
- set_fpu_register(fd_reg + 1, i64 >> 32);
- break;
- }
- case TRUNC_L_D: { // Mips32r2 instruction.
- double rounded = trunc(fs);
- i64 = static_cast<int64_t>(rounded);
- set_fpu_register(fd_reg, i64 & 0xffffffff);
- set_fpu_register(fd_reg + 1, i64 >> 32);
- break;
- }
- case ROUND_L_D: { // Mips32r2 instruction.
- double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
- i64 = static_cast<int64_t>(rounded);
- set_fpu_register(fd_reg, i64 & 0xffffffff);
- set_fpu_register(fd_reg + 1, i64 >> 32);
- break;
- }
- case FLOOR_L_D: // Mips32r2 instruction.
- i64 = static_cast<int64_t>(floor(fs));
- set_fpu_register(fd_reg, i64 & 0xffffffff);
- set_fpu_register(fd_reg + 1, i64 >> 32);
- break;
- case CEIL_L_D: // Mips32r2 instruction.
- i64 = static_cast<int64_t>(ceil(fs));
- set_fpu_register(fd_reg, i64 & 0xffffffff);
- set_fpu_register(fd_reg + 1, i64 >> 32);
- break;
- case C_F_D:
- UNIMPLEMENTED_MIPS();
- break;
- default:
- UNREACHABLE();
- }
- break;
- case W:
- switch (instr->FunctionFieldRaw()) {
- case CVT_S_W: // Convert word to float (single).
- alu_out = get_fpu_register(fs_reg);
- set_fpu_register_float(fd_reg, static_cast<float>(alu_out));
- break;
- case CVT_D_W: // Convert word to double.
- alu_out = get_fpu_register(fs_reg);
- set_fpu_register_double(fd_reg, static_cast<double>(alu_out));
- break;
- default:
- UNREACHABLE();
- };
- break;
- case L:
- switch (instr->FunctionFieldRaw()) {
- case CVT_D_L: // Mips32r2 instruction.
- // Watch the signs here, we want 2 32-bit vals
- // to make a sign-64.
- i64 = (uint32_t) get_fpu_register(fs_reg);
- i64 |= ((int64_t) get_fpu_register(fs_reg + 1) << 32);
- set_fpu_register_double(fd_reg, static_cast<double>(i64));
- break;
- case CVT_S_L:
- UNIMPLEMENTED_MIPS();
- break;
- default:
- UNREACHABLE();
- }
- break;
- case PS:
- break;
- default:
- UNREACHABLE();
- };
- break;</span>
- <span class="d">case</span> <span class="d">SPECIAL</span>:
- <span class="d">switch</span> (<span class="d">instr->FunctionFieldRaw()</span>) {
- <span class="d">case JR: {
- Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
- current_pc+Instruction::kInstrSize);
- BranchDelayInstructionDecode(branch_delay_instr);
- set_pc(next_pc);
- pc_modified_ = true;
- break;
- }</span>
- <span class="d">case</span> <span class="d">JALR</span>: {
- <span class="d">Instruction* branch_delay_instr = reinterpret_cast<Instruction*>(
- current_pc+Instruction::kInstrSize);</span>
- <span class="d">BranchDelayInstructionDecode(branch_delay_instr);</span>
- <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>);
- <span class="d">set_pc(next_pc);</span>
- <span class="d">pc_modified_ = true;</span>
- <span class="d">break;</span>
- }
- // Instructions using HI and LO registers.
- <span class="d">case MULT:
- set_register(LO, static_cast<int32_t>(i64hilo & 0xffffffff));</span>
- <span class="d">set_register(HI, static_cast<int32_t>(i64hilo >> 32));</span>
- <span class="d">break;</span>
- <span class="d">case MULTU:
- set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff));</span>
- <span class="d">set_register(HI, static_cast<int32_t>(u64hilo >> 32));</span>
- <span class="d">break;</span>
- <span class="d">case DIV:
- // Divide by zero was not checked in the configuration step - div and
- // divu do not raise exceptions. On division by 0, the result will
- // be UNPREDICTABLE.
- if (rt != 0) {
- set_register(LO, rs / rt);
- set_register(HI, rs % rt);
- }
- break;</span>
- <span class="d">case DIVU:
- if (rt_u != 0) {
- set_register(LO, rs_u / rt_u);
- set_register(HI, rs_u % rt_u);
- }
- break;</span>
- // Break and trap instructions.
- <span class="d">case BREAK</span>:
- <span class="d">case TGE</span>:
- <span class="d">case TGEU</span>:
- <span class="d">case TLT</span>:
- <span class="d">case TLTU</span>:
- <span class="d">case TEQ</span>:
- <span class="d">case TNE:
- if (do_interrupt) {
- SoftwareInterrupt(instr);
- }
- break;</span>
- // Conditional moves.
- <span class="d">case MOVN:
- if (rt) set_register(rd_reg, rs);
- break;</span>
- <span class="d">case MOVCI: {
- uint32_t cc = instr->FBccValue();
- uint32_t fcsr_cc = get_fcsr_condition_bit(cc);
- if (instr->Bit(16)) { // Read Tf bit.
- if (test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
- } else {
- if (!test_fcsr_bit(fcsr_cc)) set_register(rd_reg, rs);
- }
- break;
- }</span>
- <span class="d">case MOVZ:
- if (!rt) set_register(rd_reg, rs);
- break;
- default: // For other special opcodes we do the default operation.
- set_register(rd_reg, alu_out);</span>
- };
- <span class="d">break;</span>
- <span class="d">case SPECIAL2:
- switch (instr->FunctionFieldRaw()) {
- case MUL:
- set_register(rd_reg, alu_out);
- // HI and LO are UNPREDICTABLE after the operation.
- set_register(LO, Unpredictable);
- set_register(HI, Unpredictable);
- break;
- default: // For other special2 opcodes we do the default operation.
- set_register(rd_reg, alu_out);
- }
- break;</span>
- <span class="d">case SPECIAL3:
- switch (instr->FunctionFieldRaw()) {
- case INS:
- // Ins instr leaves result in Rt, rather than Rd.
- set_register(rt_reg, alu_out);
- break;
- case EXT:
- // Ext instr leaves result in Rt, rather than Rd.
- set_register(rt_reg, alu_out);
- break;
- default:
- UNREACHABLE();
- };
- break;
- // Unimplemented opcodes raised an error in the configuration step before,
- // so we can use the default here to set the destination register in common
- // cases.
- default:
- set_register(rd_reg, alu_out);</span>
- };
- }
- // Type 2: instructions using a 16 bytes immediate. (eg: addi, beq).
- <span class="d">void</span> <span class="d">Simulator::DecodeTypeImmediate</span><span class="d">(Instruction* instr)</span> {
- // Instruction fields.
- <span class="d">Opcode op = instr->OpcodeFieldRaw();</span>
- <span class="d">int32_t rs = get_register(instr->RsValue());</span>
- <span class="d">uint32_t rs_u = static_cast<uint32_t>(rs);</span>
- <span class="d">int32_t rt_reg = instr->RtValue();</span> // Destination register.
- <span class="d">int32_t rt = get_register(rt_reg);</span>
- <span class="d">int16_t imm16 = instr->Imm16Value();</span>
- <span class="d">int32_t ft_reg = instr->FtValue();</span> // Destination register.
- // Zero extended immediate.
- <span class="d">uint32_t oe_imm16 = 0xffff & imm16;</span>
- // Sign extended immediate.
- <span class="d">int32_t se_imm16 = imm16;</span>
- // Get current pc.
- <span class="d">int32_t current_pc = get_pc();</span>
- // Next pc.
- <span class="d">int32_t next_pc = bad_ra;</span>
- // Used for conditional branch instructions.
- <span class="d">bool do_branch = false;</span>
- <span class="d">bool execute_branch_delay_instruction = false;</span>
- // Used for arithmetic instructions.
- <span class="d">int32_t alu_out = 0;</span>
- // Floating point.
- <span class="d">double fp_out = 0.0;</span>
- <span class="d">uint32_t cc, cc_value, fcsr_cc;</span>
- // Used for memory instructions.
- <span class="d">int32_t addr = 0x0;</span>
- // Value to be written in memory.
- <span class="d">uint32_t mem_value = 0x0;</span>
- // ---------- Configuration (and execution for REGIMM).
- <span class="d">switch (op) {
- // ------------- COP1. Coprocessor instructions.
- case COP1:
- switch (instr->RsFieldRaw()) {
- case BC1: // Branch on coprocessor condition.
- cc = instr->FBccValue();
- fcsr_cc = get_fcsr_condition_bit(cc);
- cc_value = test_fcsr_bit(fcsr_cc);
- do_branch = (instr->FBtrueValue()) ? cc_value : !cc_value;
- execute_branch_delay_instruction = true;
- // Set next_pc.
- if (do_branch) {
- next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
- } else {
- next_pc = current_pc + kBranchReturnOffset;
- }
- break;
- default:
- UNREACHABLE();
- };
- break;
- // ------------- REGIMM class.
- case REGIMM:
- switch (instr->RtFieldRaw()) {
- case BLTZ:
- do_branch = (rs < 0);
- break;
- case BLTZAL:
- do_branch = rs < 0;
- break;
- case BGEZ:
- do_branch = rs >= 0;
- break;
- case BGEZAL:
- do_branch = rs >= 0;
- break;
- default:
- UNREACHABLE();
- };
- switch (instr->RtFieldRaw()) {
- case BLTZ:
- case BLTZAL:
- case BGEZ:
- case BGEZAL:
- // Branch instructions common part.
- execute_branch_delay_instruction = true;
- // Set next_pc.
- if (do_branch) {
- next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;
- if (instr->IsLinkingInstruction()) {
- set_register(31, current_pc + kBranchReturnOffset);
- }
- } else {
- next_pc = current_pc + kBranchReturnOffset;
- }
- default:
- break;
- };
- break; // case REGIMM.
- // ------------- Branch instructions.
- // When comparing to zero, the encoding of rt field is always 0, so we don't
- // need to replace rt with zero.
- case BEQ:
- do_branch = (rs == rt);
- break;
- case BNE:
- do_branch = rs != rt;
- break;
- case BLEZ:
- do_branch = rs <= 0;
- break;
- case BGTZ:
- do_branch = rs > 0;
- break;
- // ------------- Arithmetic instructions.
- case ADDI:
- if (HaveSameSign(rs, se_imm16)) {
- if (rs > 0) {
- exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - se_imm16);
- } else if (rs < 0) {
- exceptions[kIntegerUnderflow] =
- rs < (Registers::kMinValue - se_imm16);
- }
- }
- alu_out = rs + se_imm16;
- break;
- case ADDIU:
- alu_out = rs + se_imm16;
- break;
- case SLTI:
- alu_out = (rs < se_imm16) ? 1 : 0;
- break;
- case SLTIU:
- alu_out = (rs_u < static_cast<uint32_t>(se_imm16)) ? 1 : 0;
- break;
- case ANDI:
- alu_out = rs & oe_imm16;
- break;
- case ORI:
- alu_out = rs | oe_imm16;
- break;
- case XORI:
- alu_out = rs ^ oe_imm16;
- break;
- case LUI:
- alu_out = (oe_imm16 << 16);
- break;
- // ------------- Memory instructions.
- case LB:
- addr = rs + se_imm16;
- alu_out = ReadB(addr);
- break;
- case LH:
- addr = rs + se_imm16;
- alu_out = ReadH(addr, instr);
- break;
- case LWL: {
- // al_offset is offset of the effective address within an aligned word.
- uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
- uint8_t byte_shift = kPointerAlignmentMask - al_offset;
- uint32_t mask = (1 << byte_shift * 8) - 1;
- addr = rs + se_imm16 - al_offset;
- alu_out = ReadW(addr, instr);
- alu_out <<= byte_shift * 8;
- alu_out |= rt & mask;
- break;
- }
- case LW:
- addr = rs + se_imm16;
- alu_out = ReadW(addr, instr);
- break;
- case LBU:
- addr = rs + se_imm16;
- alu_out = ReadBU(addr);
- break;
- case LHU:
- addr = rs + se_imm16;
- alu_out = ReadHU(addr, instr);
- break;
- case LWR: {
- // al_offset is offset of the effective address within an aligned word.
- uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
- uint8_t byte_shift = kPointerAlignmentMask - al_offset;
- uint32_t mask = al_offset ? (~0 << (byte_shift + 1) * 8) : 0;
- addr = rs + se_imm16 - al_offset;
- alu_out = ReadW(addr, instr);
- alu_out = static_cast<uint32_t> (alu_out) >> al_offset * 8;
- alu_out |= rt & mask;
- break;
- }
- case SB:
- addr = rs + se_imm16;
- break;
- case SH:
- addr = rs + se_imm16;
- break;
- case SWL: {
- uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
- uint8_t byte_shift = kPointerAlignmentMask - al_offset;
- uint32_t mask = byte_shift ? (~0 << (al_offset + 1) * 8) : 0;
- addr = rs + se_imm16 - al_offset;
- mem_value = ReadW(addr, instr) & mask;
- mem_value |= static_cast<uint32_t>(rt) >> byte_shift * 8;
- break;
- }
- case SW:
- addr = rs + se_imm16;
- break;
- case SWR: {
- uint8_t al_offset = (rs + se_imm16) & kPointerAlignmentMask;
- uint32_t mask = (1 << al_offset * 8) - 1;
- addr = rs + se_imm16 - al_offset;
- mem_value = ReadW(addr, instr);
- mem_value = (rt << al_offset * 8) | (mem_value & mask);
- break;
- }
- case LWC1:
- addr = rs + se_imm16;
- alu_out = ReadW(addr, instr);
- break;
- case LDC1:
- addr = rs + se_imm16;
- fp_out = ReadD(addr, instr);
- break;
- case SWC1:
- case SDC1:
- addr = rs + se_imm16;
- break;
- default:
- UNREACHABLE();
- }</span>;
- // ---------- Raise exceptions triggered.
- <span class="d">SignalExceptions();</span>
- // ---------- Execution.
- <span class="d">switch</span> (<span class="d">op</span>) {
- // ------------- Branch instructions.
- <span class="d">case BEQ</span>:
- <span class="d">case BNE</span>:
- <span class="d">case</span> <span class="d">BLEZ</span>:
- <span class="d">case BGTZ:
- // Branch instructions common part.
- execute_branch_delay_instruction = true;</span>
- // Set next_pc.
- <span class="d">if</span> <span class="d">(do_branch)</span> {
- <span class="d">next_pc = current_pc + (imm16 << 2) + Instruction::kInstrSize;</span>
- <span class="d">if</span> <span class="d">(instr->IsLinkingInstruction())</span> {
- <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>);
- }
- } <span class="d">else {
- next_pc = current_pc + 2 * Instruction::kInstrSize;
- }</span>
- <span class="d">break;</span>
- // ------------- Arithmetic instructions.
- <span class="d">case ADDI</span>:
- <span class="d">case ADDIU</span>:
- <span class="d">case SLTI</span>:
- <span class="d">case SLTIU</span>:
- <span class="d">case ANDI</span>:
- <span class="d">case ORI</span>:
- <span class="d">case XORI:
- case LUI:
- set_register(rt_reg, alu_out);
- break;</span>
- // ------------- Memory instructions.
- <span class="d">case LB</span>:
- <span class="d">case LH</span>:
- <span class="d">case LWL</span>:
- <span class="d">case LW</span>:
- <span class="d">case LBU</span>:
- <span class="d">case LHU:
- case LWR:
- set_register(rt_reg, alu_out);
- break;
- case SB:
- WriteB(addr, static_cast<int8_t>(rt));
- break;
- case SH:
- WriteH(addr, static_cast<uint16_t>(rt), instr);
- break;
- case SWL:
- WriteW(addr, mem_value, instr);
- break;
- case SW:
- WriteW(addr, rt, instr);
- break;
- case SWR:
- WriteW(addr, mem_value, instr);
- break;
- case LWC1:
- set_fpu_register(ft_reg, alu_out);
- break;
- case LDC1:
- set_fpu_register_double(ft_reg, fp_out);
- break;
- case SWC1:
- addr = rs + se_imm16;
- WriteW(addr, get_fpu_register(ft_reg), instr);
- break;
- case SDC1:
- addr = rs + se_imm16;
- WriteD(addr, get_fpu_register_double(ft_reg), instr);
- break;
- default:
- break;</span>
- };
- <span class="d">if (execute_branch_delay_instruction) {
- // Execute branch delay slot
- // We don't check for end_sim_pc. First it should not be met as the current
- // pc is valid. Secondly a jump should always execute its branch delay slot.
- Instruction* branch_delay_instr =
- reinterpret_cast<Instruction*>(current_pc+Instruction::kInstrSize);
- BranchDelayInstructionDecode(branch_delay_instr);
- }</span>
- // If needed update pc after the branch delay execution.
- <span class="d">if (next_pc != bad_ra) {
- set_pc(next_pc);
- }</span>
- }
- // Type 3: instructions using a 26 bytes immediate. (eg: j, jal).
- <span class="d">void Simulator::DecodeTypeJump(Instruction* instr) {
- // Get current pc.
- int32_t current_pc = get_pc();
- // Get unchanged bits of pc.
- int32_t pc_high_bits = current_pc & 0xf0000000;
- // Next pc.
- int32_t next_pc = pc_high_bits | (instr->Imm26Value() << 2);
- // Execute branch delay slot.
- // We don't check for end_sim_pc. First it should not be met as the current pc
- // is valid. Secondly a jump should always execute its branch delay slot.
- Instruction* branch_delay_instr =
- reinterpret_cast<Instruction*>(current_pc + Instruction::kInstrSize);
- BranchDelayInstructionDecode(branch_delay_instr);
- // Update pc and ra if necessary.
- // Do this after the branch delay execution.
- if (instr->IsLinkingInstruction()) {
- set_register(31, current_pc + 2 * Instruction::kInstrSize);
- }
- set_pc(next_pc);
- pc_modified_ = true;
- }</span>
- // Executes the current instruction.
- <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>) {
- <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>) {
- <a id='4437' tid='4438', class="m">CheckICache</a>(<a id='4439' tid='4440', class="m">isolate_</a>-><a id='4441' tid='4442', class="m">simulator_i_cache</a>(), <a id='4443' tid='4444', class="m">instr</a>);
- }
- <span class="d">pc_modified_ = false;</span>
- <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>) {
- <span class="d">disasm::NameConverter converter;</span>
- <span class="d">disasm::Disassembler dasm(converter)</span>;
- // Use a reasonably large buffer.
- <span class="d">v8::internal::EmbeddedVector<char, 256> buffer;</span>
- <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><<a id='4453' tid='4454', class="m">byte</a><a id='4455' tid='4456', class="m">*</a>>(<a id='4457' tid='4458', class="m">instr</a>));
- <a id='4387' tid='4388', class="m">PrintF</a>(<a id='4389' tid='4390', class="m">" 0x%08x %s\n"</a>, <a id='4391' tid='4392', class="m">reinterpret_cast</a><<a id='4393' tid='4394', class="m">intptr_t</a>>(<a id='4395' tid='4396', class="m">instr</a>),
- <a id='4397' tid='4398', class="m">buffer</a>.<a id='4399' tid='4400', class="m">start</a>());
- }
- <span class="d">switch (instr->InstructionType()) {
- case Instruction::kRegisterType:
- DecodeTypeRegister(instr);
- break;
- case Instruction::kImmediateType:
- DecodeTypeImmediate(instr);
- break;
- case Instruction::kJumpType:
- DecodeTypeJump(instr);
- break;
- default:
- UNSUPPORTED();
- }</span>
- <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>) {
- <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><<a id='4375' tid='4376', class="m">int32_t</a>>(<a id='4377' tid='4378', class="m">instr</a>) <a id='4379' tid='4380', class="m">+</a>
- <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>);
- }
- }
- <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>() {
- // Get the PC to simulate. Cannot use the accessor here as we need the
- // raw PC value and not the one used as input to arithmetic instructions.
- <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>();
- <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>) {
- // Fast version of the dispatch loop without checking whether the simulator
- // should be stopping at a particular executed instruction.
- <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>) {
- <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><<a id='4775' tid='4776', class="m">Instruction</a><a id='4777' tid='4778', class="m">*</a>>(<a id='4779' tid='4780', class="m">program_counter</a>);
- <a id='4781' tid='4782', class="m">icount_</a><a id='4783' tid='4784', class="m">++</a>;
- <a id='4785' tid='4786', class="m">InstructionDecode</a>(<a id='4787' tid='4788', class="m">instr</a>);
- <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>();
- }
- } <a id='4795' tid='4796', class="m">else</a> {
- // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
- // we reach the particular instuction count.
- <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>) {
- <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><<a id='4813' tid='4814', class="m">Instruction</a><a id='4815' tid='4816', class="m">*</a>>(<a id='4817' tid='4818', class="m">program_counter</a>);
- <a id='4819' tid='4820', class="m">icount_</a><a id='4821' tid='4822', class="m">++</a>;
- <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">{
- MipsDebugger dbg(this);
- dbg.Debug();
- }</span> <span class="d">else {
- InstructionDecode(instr);
- }</span>
- <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>();
- }
- }
- }
- <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>) {
- <span class="d">va_list parameters;</span>
- <span class="d">va_start(parameters, argument_count);</span>
- // Setup arguments.
- // First four arguments passed in registers.
- <span class="d">ASSERT(argument_count >= 4);</span>
- <span class="d">set_register(a0, va_arg(parameters, int32_t));</span>
- <span class="d">set_register(a1, va_arg(parameters, int32_t));</span>
- <span class="d">set_register(a2, va_arg(parameters, int32_t));</span>
- <span class="d">set_register(a3, va_arg(parameters, int32_t));</span>
- // Remaining arguments passed on stack.
- <span class="d">int original_stack = get_register(sp);</span>
- // Compute position of stack on entry to generated code.
- <span class="d">int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t)
- - kCArgsSlotsSize);</span>
- <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>) {
- <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>();
- }
- // Store remaining arguments on stack, from low to high memory.
- <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><<a id='4661' tid='4662', class="m">intptr_t</a><a id='4663' tid='4664', class="m">*</a>>(<a id='4665' tid='4666', class="m">entry_stack</a>);
- <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"><</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">{
- stack_argument[i - 4 + kArgsSlotsNum] = va_arg(parameters, int32_t);
- }</span>
- <span class="d">va_end(parameters);</span>
- <span class="d">set_register(sp, entry_stack);</span>
- // Prepare to execute the code at entry.
- <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><<a id='4487' tid='4488', class="m">int32_t</a>>(<a id='4489' tid='4490', class="m">entry</a>));
- // Put down marker for end of simulation. The simulator will stop simulation
- // when the PC reaches this value. By saving the "end simulation" value into
- // the LR the simulation stops when returning to this call point.
- <span class="d">set_register(ra, end_sim_pc);</span>
- // Remember the values of callee-saved registers.
- // The code below assumes that r9 is not used as sb (static base) in
- // simulator code and therefore is regarded as a callee-saved register.
- <span class="d">int32_t s0_val = get_register(s0);</span>
- <span class="d">int32_t s1_val = get_register(s1);</span>
- <span class="d">int32_t s2_val = get_register(s2);</span>
- <span class="d">int32_t s3_val = get_register(s3);</span>
- <span class="d">int32_t s4_val = get_register(s4);</span>
- <span class="d">int32_t s5_val = get_register(s5);</span>
- <span class="d">int32_t s6_val = get_register(s6);</span>
- <span class="d">int32_t s7_val = get_register(s7);</span>
- <span class="d">int32_t gp_val = get_register(gp);</span>
- <span class="d">int32_t sp_val = get_register(sp);</span>
- <span class="d">int32_t fp_val = get_register(fp);</span>
- // Setup the callee-saved registers with a known value. To be able to check
- // that they are preserved properly across JS execution.
- <span class="d">int32_t callee_saved_value = icount_;</span>
- <span class="d">set_register(s0, callee_saved_value);</span>
- <span class="d">set_register(s1, callee_saved_value);</span>
- <span class="d">set_register(s2, callee_saved_value);</span>
- <span class="d">set_register(s3, callee_saved_value);</span>
- <span class="d">set_register(s4, callee_saved_value);</span>
- <span class="d">set_register(s5, callee_saved_value);</span>
- <span class="d">set_register(s6, callee_saved_value);</span>
- <span class="d">set_register(s7, callee_saved_value);</span>
- <span class="d">set_register(gp, callee_saved_value);</span>
- <span class="d">set_register(fp, callee_saved_value);</span>
- // Start the simulation.
- <span class="d">Execute();</span>
- // Check that the callee-saved registers have been preserved.
- <span class="d">CHECK_EQ(callee_saved_value, get_register(s0));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(s1));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(s2));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(s3));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(s4));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(s5));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(s6));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(s7));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(gp));</span>
- <span class="d">CHECK_EQ(callee_saved_value, get_register(fp));</span>
- // Restore callee-saved registers with the original value.
- <span class="d">set_register(s0, s0_val);</span>
- <span class="d">set_register(s1, s1_val);</span>
- <span class="d">set_register(s2, s2_val);</span>
- <span class="d">set_register(s3, s3_val);</span>
- <span class="d">set_register(s4, s4_val);</span>
- <span class="d">set_register(s5, s5_val);</span>
- <span class="d">set_register(s6, s6_val);</span>
- <span class="d">set_register(s7, s7_val);</span>
- <span class="d">set_register(gp, gp_val);</span>
- <span class="d">set_register(sp, sp_val);</span>
- <span class="d">set_register(fp, fp_val);</span>
- // Pop stack passed arguments.
- <span class="d">CHECK_EQ(entry_stack, get_register(sp));</span>
- <span class="d">set_register(sp, original_stack);</span>
- <span class="d">int32_t result = get_register(v0);</span>
- <span class="d">return result;</span>
- }
- <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>) {
- <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>);
- <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><<a id='4595' tid='4596', class="m">uintptr_t</a><a id='4597' tid='4598', class="m">*</a>>(<a id='4599' tid='4600', class="m">new_sp</a>);
- <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>;
- <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>);
- <a id='4615' tid='4616', class="m">return</a> <a id='4617' tid='4618', class="m">new_sp</a>;
- }
- <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>() {
- <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>);
- <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><<a id='4515' tid='4516', class="m">uintptr_t</a><a id='4517' tid='4518', class="m">*</a>>(<a id='4519' tid='4520', class="m">current_sp</a>);
- <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>;
- <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>));
- <a id='4541' tid='4542', class="m">return</a> <a id='4543' tid='4544', class="m">address</a>;
- }
- <span class="d">#undef UNSUPPORTED</span>
- } } // namespace v8::internal
- <span class="d">#endif</span> // USE_SIMULATOR
- <span class="d">#endif</span> // V8_TARGET_ARCH_MIPS
- </pre>
- </div>
- <div id="right" class="src">
- <pre>
- <a id='rightstart' tid='leftstart'></a>
- // Copyright 2011 the V8 project authors. All rights reserved.
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following
- // disclaimer in the documentation and/or other materials provided
- // with the distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived
- // from this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #<a id='9614' tid='9613', class="m">include</a> <a id='9616' tid='9615', class="m"><</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">></a>
- #<a id='9602' tid='9601', class="m">include</a> <a id='9604' tid='9603', class="m"><</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">></a>
- <span class="i">#include <cstdarg></span>
- <span class="i">#include "v8.h"</span>
- <span class="i">#if defined(V8_TARGET_ARCH_ARM)</span>
- <span class="i">#include "disasm.h"</span>
- <span class="i">#include "assembler.h"</span>
- <span class="i">#include "arm/constants-arm.h"</span>
- <span class="i">#include "arm/simulator-arm.h"</span>
- #<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>
- // Only build the simulator if not compiling for real ARM hardware.
- namespace <span class="i">v8</span> {
- namespace <span class="i">internal</span> {
- // This macro provides a platform independent use of sscanf. The reason for
- // SScanF not being implemented in a platform independent way through
- // ::v8::internal::OS in the same way as SNPrintF is that the
- // Windows C Run-Time Library does not provide vsscanf.
- <span class="i">#define SScanF sscanf</span> // NOLINT
- // The ArmDebugger class is used by the simulator while debugging simulated ARM
- // code.
- <span class="i">class</span> <span class="i">ArmDebugger</span> {
- <span class="i">public:</span>
- <span class="i">explicit ArmDebugger(Simulator* sim)</span>;
- <span class="i">~ArmDebugger();</span>
- <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>);
- <span class="i">void Debug()</span>;
- <span class="i">private:</span>
- <span class="i">static const Instr kBreakpointInstr =
- (al | (7*B25) | (1*B24) | kBreakpoint);</span>
- <span class="i">static const Instr kNopInstr = (al | (13*B21));</span>
- <span class="i">Simulator* sim_;</span>
- <span class="i">int32_t GetRegisterValue(int regnum)</span>;
- <span class="i">double GetRegisterPairDoubleValue(int regnum)</span>;
- <span class="i">double GetVFPDoubleRegisterValue(int regnum)</span>;
- <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>);
- <span class="i">bool GetVFPSingleValue(const char* desc, float* value)</span>;
- <span class="i">bool GetVFPDoubleValue(const char* desc, double* value)</span>;
- // Set or delete a breakpoint. Returns true if successful.
- <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>);
- <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>);
- // Undo and redo all breakpoints. This is needed to bracket disassembly and
- // execution to skip past breakpoints when run from the debugger.
- <span class="i">void UndoBreakpoints()</span>;
- <span class="i">void RedoBreakpoints()</span>;
- };
- <span class="i">ArmDebugger::ArmDebugger(Simulator* sim) {
- sim_ = sim;
- }</span>
- <span class="i">ArmDebugger::~ArmDebugger() {
- }</span>
- <span class="i">#ifdef GENERATED_CODE_COVERAGE</span>
- <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>;
- <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>() {
- <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">"V8_GENERATED_CODE_COVERAGE_LOG"</a>);
- <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>) {
- <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">"aw+"</a>);
- }
- }
- <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>) {
- // Get the stop code.
- <span class="i">uint32_t code = instr->SvcValue() & kStopCodeMask;</span>
- // Retrieve the encoded address, which comes just after this stop.
- <span class="i">char**</span> <span class="i">msg_address</span> =
- <span class="i">reinterpret_cast<char**></span>(<a id='8038' tid='8037', class="m">sim_</a>-><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>);
- <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>;
- <span class="i">ASSERT(msg != NULL);</span>
- // Update this stop description.
- <span class="i">if</span> <span class="i">(isWatchedStop(code) && !watched_stops[code].desc)</span> {
- <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>;
- }
- <span class="i">if (strlen(msg) > 0) {
- if (coverage_log != NULL) {
- fprintf(coverage_log, "%s\n", msg);
- fflush(coverage_log);
- }
- // Overwrite the instruction and address with nops.
- instr->SetInstructionBits(kNopInstr);
- reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr);
- }</span>
- <a id='9424' tid='9423', class="m">sim_</a>-><a id='9426' tid='9425', class="m">set_pc</a>(<a id='9428' tid='9427', class="m">sim_</a>-><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>);
- }
- <span class="i">#else</span> // ndef GENERATED_CODE_COVERAGE
- <span class="i">static void InitializeCoverage() {
- }</span>
- <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>) {
- // Get the stop code.
- <span class="i">uint32_t code = instr->SvcValue() & kStopCodeMask;</span>
- // Retrieve the encoded address, which comes just after this stop.
- <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><<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>>(<a id='9468' tid='9467', class="m">sim_</a>-><a id='9470' tid='9469', class="m">get_pc</a>()
- <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>);
- // Update this stop description.
- <a id='9382' tid='9381', class="m">if</a> (<span class="i">sim_->isWatchedStop(code)</span> <span class="i">&&</span> <a id='9384' tid='9383', class="m">!</a><a id='9386' tid='9385', class="m">sim_</a>-><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>) {
- <a id='9394' tid='9393', class="m">sim_</a>-><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>;
- }
- // Print the stop message and code if it is not the default code.
- <span class="i">if (code != kMaxStopCode) {
- PrintF("Simulator hit stop %u: %s\n", code, msg);
- } else {
- PrintF("Simulator hit %s\n", msg);
- }</span>
- <span class="i">sim_->set_pc</span>(<span class="i">sim_->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>);
- <span class="i">Debug();</span>
- }
- <span class="i">#endif</span>
- <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>) {
- <span class="i">if</span> <span class="i">(regnum == kPCRegister)</span> <span class="i">{
- return sim_->get_pc();
- }</span> <a id='9414' tid='9413', class="m">else</a> {
- <a id='9416' tid='9415', class="m">return</a> <a id='9418' tid='9417', class="m">sim_</a>-><a id='9420' tid='9419', class="m">get_register</a>(<a id='9422' tid='9421', class="m">regnum</a>);
- }
- }
- <span class="i">double ArmDebugger::GetRegisterPairDoubleValue(int regnum) {
- return sim_->get_double_from_register_pair(regnum);
- }</span>
- <span class="i">double ArmDebugger::GetVFPDoubleRegisterValue(int regnum) {
- return sim_->get_double_from_d_register(regnum);
- }</span>
- <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>) {
- <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>);
- <span class="i">if</span> <span class="i">(regnum != kNoRegister)</span> {
- <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>);
- <a id='9310' tid='9309', class="m">return</a> <a id='9312' tid='9311', class="m">true</a>;
- } <a id='9238' tid='9237', class="m">else</a> {
- <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">"0x"</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">{
- return SScanF(desc + 2, "%x", reinterpret_cast<uint32_t*>(value)) == 1;
- }</span> <span class="i">else {
- return SScanF(desc, "%u", reinterpret_cast<uint32_t*>(value)) == 1;
- }</span>
- }
- <span class="i">return false;</span>
- }
- <span class="i">bool ArmDebugger::GetVFPSingleValue(const char* desc, float* value) {
- bool is_double;
- int regnum = VFPRegisters::Number(desc, &is_double);
- if (regnum != kNoRegister && !is_double) {
- *value = sim_->get_float_from_s_register(regnum);
- return true;
- }
- return false;
- }</span>
- <span class="i">bool ArmDebugger::GetVFPDoubleValue(const char* desc, double* value) {
- bool is_double;
- int regnum = VFPRegisters::Number(desc, &is_double);
- if (regnum != kNoRegister && is_double) {
- *value = sim_->get_double_from_d_register(regnum);
- return true;
- }
- return false;
- }</span>
- <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>) {
- // Check if a breakpoint can be set. If not return without any side-effects.
- <a id='9326' tid='9325', class="m">if</a> (<a id='9328' tid='9327', class="m">sim_</a>-><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>) {
- <a id='9336' tid='9335', class="m">return</a> <a id='9338' tid='9337', class="m">false</a>;
- }
- // Set the breakpoint.
- <a id='9340' tid='9339', class="m">sim_</a>-><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>;
- <a id='9348' tid='9347', class="m">sim_</a>-><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>-><a id='9356' tid='9355', class="m">InstructionBits</a>();
- // Not setting the breakpoint instruction in the code itself. It will be set
- // when the debugger shell continues.
- <a id='9358' tid='9357', class="m">return</a> <a id='9360' tid='9359', class="m">true</a>;
- }
- <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>) {
- <a id='9260' tid='9259', class="m">if</a> (<a id='9262' tid='9261', class="m">sim_</a>-><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>) {
- <a id='9270' tid='9269', class="m">sim_</a>-><a id='9272' tid='9271', class="m">break_pc_</a>-><a id='9274' tid='9273', class="m">SetInstructionBits</a>(<a id='9276' tid='9275', class="m">sim_</a>-><a id='9278' tid='9277', class="m">break_instr_</a>);
- }
- <a id='9280' tid='9279', class="m">sim_</a>-><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>;
- <a id='9288' tid='9287', class="m">sim_</a>-><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>;
- <a id='9296' tid='9295', class="m">return</a> <a id='9298' tid='9297', class="m">true</a>;
- }
- <span class="i">void</span> <span class="i">ArmDebugger::UndoBreakpoints</span><span class="i">()</span> {
- <a id='9218' tid='9217', class="m">if</a> (<a id='9220' tid='9219', class="m">sim_</a>-><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>) {
- <a id='9228' tid='9227', class="m">sim_</a>-><a id='9230' tid='9229', class="m">break_pc_</a>-><a id='9232' tid='9231', class="m">SetInstructionBits</a>(<a id='9234' tid='9233', class="m">sim_</a>-><a id='9236' tid='9235', class="m">break_instr_</a>);
- }
- }
- <span class="i">void</span> <span class="i">ArmDebugger::RedoBreakpoints</span><span class="i">()</span> {
- <a id='9192' tid='9191', class="m">if</a> (<a id='9194' tid='9193', class="m">sim_</a>-><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>) {
- <a id='9202' tid='9201', class="m">sim_</a>-><a id='9204' tid='9203', class="m">break_pc_</a>-><a id='9206' tid='9205', class="m">SetInstructionBits</a>(<a id='9208' tid='9207', class="m">kBreakpointInstr</a>);
- }
- }
- <span class="i">void</span> <span class="i">ArmDebugger::Debug</span><span class="i">()</span> {
- <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>;
- <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>;
- #<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>
- #<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>
- #<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>
- #<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>
- <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>];
- <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>];
- <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>];
- <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> };
- // make sure to have a proper terminating character if reaching the limit
- <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>;
- <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>;
- <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>;
- // Undo all set breakpoints while running in the debugger shell. This will
- // make them invisible to all commands.
- <a id='9078' tid='9077', class="m">UndoBreakpoints</a>();
- <span class="i">while</span> <span class="i">(!done)</span> {
- <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>-><a id='9088' tid='9087', class="m">get_pc</a>()) {
- <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>;
- <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>);
- // use a reasonably large buffer
- <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><<a id='9118' tid='9117', class="m">char</a>, <a id='9120' tid='9119', class="m">256</a>> <a id='9122' tid='9121', class="m">buffer</a>;
- <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>,
- <a id='9130' tid='9129', class="m">reinterpret_cast</a><<a id='9132' tid='9131', class="m">byte</a><a id='9134' tid='9133', class="m">*</a>>(<a id='9136' tid='9135', class="m">sim_</a>-><a id='9138' tid='9137', class="m">get_pc</a>()));
- <a id='9140' tid='9139', class="m">PrintF</a>(<a id='9142' tid='9141', class="m">" 0x%08x %s\n"</a>, <a id='9144' tid='9143', class="m">sim_</a>-><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>());
- <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>-><a id='9158' tid='9157', class="m">get_pc</a>();
- }
- <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">"sim> "</a>);
- <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>) {
- <a id='8134' tid='8133', class="m">break</a>;
- } <a id='8136' tid='8135', class="m">else</a> {
- // Use sscanf to parse the individual parts of the command line. At the
- // moment no command expects more than two parameters.
- <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>,
- <a id='8146' tid='8145', class="m">"%"</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">"s "</a>
- <a id='8154' tid='8153', class="m">"%"</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">"s "</a>
- <a id='8162' tid='8161', class="m">"%"</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">"s"</a>,
- <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>);
- <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">"si"</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">"stepi"</a>) <a id='8196' tid='8195', class="m">==</a> <a id='8198' tid='8197', class="m">0</a>)) {
- <a id='8200' tid='8199', class="m">sim_</a>-><a id='8202' tid='8201', class="m">InstructionDecode</a>(<a id='8204' tid='8203', class="m">reinterpret_cast</a><<a id='8206' tid='8205', class="m">Instruction</a><a id='8208' tid='8207', class="m">*</a>>(<a id='8210' tid='8209', class="m">sim_</a>-><a id='8212' tid='8211', class="m">get_pc</a>()));
- } <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">"c"</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">"cont"</a>) <a id='8236' tid='8235', class="m">==</a> <a id='8238' tid='8237', class="m">0</a>)) {
- // Execute the one instruction we broke at with breakpoints disabled.
- <a id='8240' tid='8239', class="m">sim_</a>-><a id='8242' tid='8241', class="m">InstructionDecode</a>(<a id='8244' tid='8243', class="m">reinterpret_cast</a><<a id='8246' tid='8245', class="m">Instruction</a><a id='8248' tid='8247', class="m">*</a>>(<a id='8250' tid='8249', class="m">sim_</a>-><a id='8252' tid='8251', class="m">get_pc</a>()));
- // Leave the debugger shell.
- <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>;
- } <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">"p"</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">"print"</a>) <a id='8282' tid='8281', class="m">==</a> <a id='8284' tid='8283', class="m">0</a>)) {
- <span class="i">if</span> <span class="i">(argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0))</span> {
- <span class="i">int32_t value;</span>
- <span class="i">float svalue;</span>
- <span class="i">double dvalue;</span>
- <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">"all"</a>) <a id='8292' tid='8291', class="m">==</a> <a id='8294' tid='8293', class="m">0</a>) <span class="i">{
- for (int i = 0; i < kNumRegisters; i++) {
- value = GetRegisterValue(i);
- PrintF("%3s: 0x%08x %10d", Registers::Name(i), value, value);
- if ((argc == 3 && strcmp(arg2, "fp") == 0) &&
- i < 8 &&
- (i % 2) == 0) {
- dvalue = GetRegisterPairDoubleValue(i);
- PrintF(" (%f)\n", dvalue);
- } else {
- PrintF("\n");
- }
- }
- for (int i = 0; i < kNumVFPDoubleRegisters; i++) {
- dvalue = GetVFPDoubleRegisterValue(i);
- uint64_t as_words = BitCast<uint64_t>(dvalue);
- PrintF("%3s: %f 0x%08x %08x\n",
- VFPRegisters::Name(i, true),
- dvalue,
- static_cast<uint32_t>(as_words >> 32),
- static_cast<uint32_t>(as_words & 0xffffffff));
- }
- }</span> <a id='8050' tid='8049', class="m">else</a> {
- <span class="i">if</span> <span class="i">(GetValue(arg1, &value))</span> {
- <a id='8052' tid='8051', class="m">PrintF</a>(<a id='8054' tid='8053', class="m">"%s: 0x%08x %d \n"</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>);
- } <span class="i">else if (GetVFPSingleValue(arg1, &svalue)) {
- uint32_t as_word = BitCast<uint32_t>(svalue);
- PrintF("%s: %f 0x%08x\n", arg1, svalue, as_word);
- } else if (GetVFPDoubleValue(arg1, &dvalue)) {
- uint64_t as_words = BitCast<uint64_t>(dvalue);
- PrintF("%s: %f 0x%08x %08x\n",
- arg1,
- dvalue,
- static_cast<uint32_t>(as_words >> 32),
- static_cast<uint32_t>(as_words & 0xffffffff));
- } else {
- PrintF("%s unrecognized\n", arg1);
- }</span>
- }
- } <span class="i">else {
- PrintF("print <register>\n");
- }</span>
- } <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">"po"</a>) <a id='8306' tid='8305', class="m">==</a> <a id='8308' tid='8307', class="m">0</a>)
- <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">"printobject"</a>) <a id='8318' tid='8317', class="m">==</a> <a id='8320' tid='8319', class="m">0</a>)) {
- <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>) {
- <a id='8330' tid='8329', class="m">int32_t</a> <a id='8332' tid='8331', class="m">value</a>;
- <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>)) {
- <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><<a id='8352' tid='8351', class="m">Object</a><a id='8354' tid='8353', class="m">*</a>>(<a id='8356' tid='8355', class="m">value</a>);
- <a id='8358' tid='8357', class="m">PrintF</a>(<a id='8360' tid='8359', class="m">"%s: \n"</a>, <a id='8362' tid='8361', class="m">arg1</a>);
- #<a id='8364' tid='8363', class="m">ifdef</a> <a id='8366' tid='8365', class="m">DEBUG</a>
- <a id='8368' tid='8367', class="m">obj</a>-><a id='8370' tid='8369', class="m">PrintLn</a>();
- #<a id='8372' tid='8371', class="m">else</a>
- <a id='8374' tid='8373', class="m">obj</a>-><a id='8376' tid='8375', class="m">ShortPrint</a>();
- <a id='8378' tid='8377', class="m">PrintF</a>(<a id='8380' tid='8379', class="m">"\n"</a>);
- #<a id='8382' tid='8381', class="m">endif</a>
- } <a id='8384' tid='8383', class="m">else</a> {
- <a id='8386' tid='8385', class="m">PrintF</a>(<a id='8388' tid='8387', class="m">"%s unrecognized\n"</a>, <a id='8390' tid='8389', class="m">arg1</a>);
- }
- } <a id='8392' tid='8391', class="m">else</a> {
- <a id='8394' tid='8393', class="m">PrintF</a>(<a id='8396' tid='8395', class="m">"printobject <value>\n"</a>);
- }
- } <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">"stack"</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">"mem"</a>) <a id='8420' tid='8419', class="m">==</a> <a id='8422' tid='8421', class="m">0</a>) {
- <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>;
- <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>;
- <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>;
- <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">"stack"</a>) <a id='8454' tid='8453', class="m">==</a> <a id='8456' tid='8455', class="m">0</a>) {
- <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><<a id='8464' tid='8463', class="m">int32_t</a><a id='8466' tid='8465', class="m">*</a>>(<a id='8468' tid='8467', class="m">sim_</a>-><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>));
- } <a id='8478' tid='8477', class="m">else</a> { // "mem"
- <a id='8480' tid='8479', class="m">int32_t</a> <a id='8482' tid='8481', class="m">value</a>;
- <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>)) {
- <a id='8496' tid='8495', class="m">PrintF</a>(<a id='8498' tid='8497', class="m">"%s unrecognized\n"</a>, <a id='8500' tid='8499', class="m">arg1</a>);
- <a id='8502' tid='8501', class="m">continue</a>;
- }
- <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><<a id='8510' tid='8509', class="m">int32_t</a><a id='8512' tid='8511', class="m">*</a>>(<a id='8514' tid='8513', class="m">value</a>);
- <a id='8516' tid='8515', class="m">next_arg</a><a id='8518' tid='8517', class="m">++</a>;
- }
- <a id='8520' tid='8519', class="m">int32_t</a> <a id='8522' tid='8521', class="m">words</a>;
- <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>) {
- <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>;
- } <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>) {
- <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>)) {
- <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>;
- }
- }
- <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>;
- <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"><</a> <a id='8588' tid='8587', class="m">end</a>) {
- <a id='8590' tid='8589', class="m">PrintF</a>(<a id='8592' tid='8591', class="m">" 0x%08x: 0x%08x %10d"</a>,
- <a id='8594' tid='8593', class="m">reinterpret_cast</a><<a id='8596' tid='8595', class="m">intptr_t</a>>(<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>);
- <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><<a id='8616' tid='8615', class="m">HeapObject</a><a id='8618' tid='8617', class="m">*</a>>(<a id='8620' tid='8619', class="m">*</a><a id='8622' tid='8621', class="m">cur</a>);
- <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>;
- <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>()-><a id='8652' tid='8651', class="m">heap</a>();
- <a id='8654' tid='8653', class="m">if</a> (<a id='8656' tid='8655', class="m">current_heap</a>-><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>)) {
- <a id='8674' tid='8673', class="m">PrintF</a>(<a id='8676' tid='8675', class="m">" ("</a>);
- <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>) {
- <a id='8690' tid='8689', class="m">PrintF</a>(<a id='8692' tid='8691', class="m">"smi %d"</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>);
- } <a id='8700' tid='8699', class="m">else</a> {
- <a id='8702' tid='8701', class="m">obj</a>-><a id='8704' tid='8703', class="m">ShortPrint</a>();
- }
- <a id='8706' tid='8705', class="m">PrintF</a>(<a id='8708' tid='8707', class="m">")"</a>);
- }
- <a id='8710' tid='8709', class="m">PrintF</a>(<a id='8712' tid='8711', class="m">"\n"</a>);
- <a id='8714' tid='8713', class="m">cur</a><a id='8716' tid='8715', class="m">++</a>;
- }
- } <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">"disasm"</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">"di"</a>) <a id='8740' tid='8739', class="m">==</a> <a id='8742' tid='8741', class="m">0</a>) {
- <span class="i">disasm::NameConverter converter;</span>
- <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>);
- // use a reasonably large buffer
- <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><<a id='8072' tid='8071', class="m">char</a>, <a id='8074' tid='8073', class="m">256</a>> <a id='8076' tid='8075', class="m">buffer</a>;
- <span class="i">byte* prev = NULL;</span>
- <span class="i">byte* cur = NULL;</span>
- <span class="i">byte* end = NULL;</span>
- <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>) {
- <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><<a id='7560' tid='7559', class="m">byte</a><a id='7562' tid='7561', class="m">*</a>>(<a id='7564' tid='7563', class="m">sim_</a>-><a id='7566' tid='7565', class="m">get_pc</a>());
- <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>);
- } <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>) {
- <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>);
- <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">"0x"</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>) {
- // The argument is an address or a register name.
- <a id='7622' tid='7621', class="m">int32_t</a> <a id='7624' tid='7623', class="m">value</a>;
- <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>)) {
- <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><<a id='7642' tid='7641', class="m">byte</a><a id='7644' tid='7643', class="m">*</a>>(<a id='7646' tid='7645', class="m">value</a>);
- // Disassemble 10 instructions at <arg1>.
- <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>);
- }
- } <a id='7666' tid='7665', class="m">else</a> {
- // The argument is the number of instructions.
- <a id='7668' tid='7667', class="m">int32_t</a> <a id='7670' tid='7669', class="m">value</a>;
- <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>)) {
- <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><<a id='7688' tid='7687', class="m">byte</a><a id='7690' tid='7689', class="m">*</a>>(<a id='7692' tid='7691', class="m">sim_</a>-><a id='7694' tid='7693', class="m">get_pc</a>());
- // Disassemble <arg1> instructions.
- <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>);
- }
- }
- } <a id='7714' tid='7713', class="m">else</a> {
- <a id='7716' tid='7715', class="m">int32_t</a> <a id='7718' tid='7717', class="m">value1</a>;
- <a id='7720' tid='7719', class="m">int32_t</a> <a id='7722' tid='7721', class="m">value2</a>;
- <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>)) {
- <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><<a id='7750' tid='7749', class="m">byte</a><a id='7752' tid='7751', class="m">*</a>>(<a id='7754' tid='7753', class="m">value1</a>);
- <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>);
- }
- }
- <span class="i">while (cur < end) {
- prev = cur;
- cur += dasm.InstructionDecode(buffer, cur);
- PrintF(" 0x%08x %s\n",
- reinterpret_cast<intptr_t>(prev), buffer.start());
- }</span>
- } <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">"gdb"</a>) <a id='8764' tid='8763', class="m">==</a> <a id='8766' tid='8765', class="m">0</a>) {
- <a id='8768' tid='8767', class="m">PrintF</a>(<a id='8770' tid='8769', class="m">"relinquishing control to gdb\n"</a>);
- <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>();
- <a id='8786' tid='8785', class="m">PrintF</a>(<a id='8788' tid='8787', class="m">"regaining control from gdb\n"</a>);
- } <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">"break"</a>) <a id='8800' tid='8799', class="m">==</a> <a id='8802' tid='8801', class="m">0</a>) {
- <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>) {
- <a id='8812' tid='8811', class="m">int32_t</a> <a id='8814' tid='8813', class="m">value</a>;
- <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>)) {
- <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><<a id='8834' tid='8833', class="m">Instruction</a><a id='8836' tid='8835', class="m">*</a>>(<a id='8838' tid='8837', class="m">value</a>))) {
- <a id='8840' tid='8839', class="m">PrintF</a>(<a id='8842' tid='8841', class="m">"setting breakpoint failed\n"</a>);
- }
- } <a id='8844' tid='8843', class="m">else</a> {
- <a id='8846' tid='8845', class="m">PrintF</a>(<a id='8848' tid='8847', class="m">"%s unrecognized\n"</a>, <a id='8850' tid='8849', class="m">arg1</a>);
- }
- } <a id='8852' tid='8851', class="m">else</a> {
- <a id='8854' tid='8853', class="m">PrintF</a>(<a id='8856' tid='8855', class="m">"break <address>\n"</a>);
- }
- } <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">"del"</a>) <a id='8868' tid='8867', class="m">==</a> <a id='8870' tid='8869', class="m">0</a>) {
- <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>)) {
- <a id='8880' tid='8879', class="m">PrintF</a>(<a id='8882' tid='8881', class="m">"deleting breakpoint failed\n"</a>);
- }
- } <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">"flags"</a>) <a id='8892' tid='8891', class="m">==</a> <a id='8894' tid='8893', class="m">0</a>) <span class="i">{
- PrintF("N flag: %d; ", sim_->n_flag_);
- PrintF("Z flag: %d; ", sim_->z_flag_);
- PrintF("C flag: %d; ", sim_->c_flag_);
- PrintF("V flag: %d\n", sim_->v_flag_);
- PrintF("INVALID OP flag: %d; ", sim_->inv_op_vfp_flag_);
- PrintF("DIV BY ZERO flag: %d; ", sim_->div_zero_vfp_flag_);
- PrintF("OVERFLOW flag: %d; ", sim_->overflow_vfp_flag_);
- PrintF("UNDERFLOW flag: %d; ", sim_->underflow_vfp_flag_);
- PrintF("INEXACT flag: %d;\n", sim_->inexact_vfp_flag_);
- }</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">"stop"</a>) <a id='8084' tid='8083', class="m">==</a> <a id='8086' tid='8085', class="m">0</a>) {
- <a id='7776' tid='7775', class="m">int32_t</a> <a id='7778' tid='7777', class="m">value</a>;
- <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>-><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>;
- <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><<a id='7808' tid='7807', class="m">Instruction</a><a id='7810' tid='7809', class="m">*</a>>(<a id='7812' tid='7811', class="m">stop_pc</a>);
- <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> =
- <a id='7820' tid='7819', class="m">reinterpret_cast</a><<a id='7822' tid='7821', class="m">Instruction</a><a id='7824' tid='7823', class="m">*</a>>(<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>);
- <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">"unstop"</a>) <a id='7852' tid='7851', class="m">==</a> <a id='7854' tid='7853', class="m">0</a>)) {
- // Remove the current stop.
- <span class="i">if</span> <span class="i">(sim_->isStopInstruction(stop_instr))</span> {
- <a id='7856' tid='7855', class="m">stop_instr</a>-><a id='7858' tid='7857', class="m">SetInstructionBits</a>(<a id='7860' tid='7859', class="m">kNopInstr</a>);
- <a id='7862' tid='7861', class="m">msg_address</a>-><a id='7864' tid='7863', class="m">SetInstructionBits</a>(<a id='7866' tid='7865', class="m">kNopInstr</a>);
- } <span class="i">else {
- PrintF("Not at debugger stop.\n");
- }</span>
- } <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>) {
- // Print information about all/the specified breakpoint(s).
- <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">"info"</a>) <a id='7886' tid='7885', class="m">==</a> <a id='7888' tid='7887', class="m">0</a>) {
- <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">"all"</a>) <a id='7896' tid='7895', class="m">==</a> <a id='7898' tid='7897', class="m">0</a>) <span class="i">{
- PrintF("Stop information:\n");
- for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
- sim_->PrintStopInfo(i);
- }
- }</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>)) {
- <a id='7298' tid='7297', class="m">sim_</a>-><a id='7300' tid='7299', class="m">PrintStopInfo</a>(<a id='7302' tid='7301', class="m">value</a>);
- } <a id='7304' tid='7303', class="m">else</a> {
- <a id='7306' tid='7305', class="m">PrintF</a>(<a id='7308' tid='7307', class="m">"Unrecognized argument.\n"</a>);
- }
- } <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">"enable"</a>) <a id='7910' tid='7909', class="m">==</a> <a id='7912' tid='7911', class="m">0</a>) {
- // Enable all/the specified breakpoint(s).
- <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">"all"</a>) <a id='7920' tid='7919', class="m">==</a> <a id='7922' tid='7921', class="m">0</a>) <span class="i">{
- for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
- sim_->EnableStop(i);
- }
- }</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>)) {
- <a id='7322' tid='7321', class="m">sim_</a>-><a id='7324' tid='7323', class="m">EnableStop</a>(<a id='7326' tid='7325', class="m">value</a>);
- } <a id='7328' tid='7327', class="m">else</a> {
- <a id='7330' tid='7329', class="m">PrintF</a>(<a id='7332' tid='7331', class="m">"Unrecognized argument.\n"</a>);
- }
- } <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">"disable"</a>) <a id='7934' tid='7933', class="m">==</a> <a id='7936' tid='7935', class="m">0</a>) {
- // Disable all/the specified breakpoint(s).
- <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">"all"</a>) <a id='7944' tid='7943', class="m">==</a> <a id='7946' tid='7945', class="m">0</a>) <span class="i">{
- for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
- sim_->DisableStop(i);
- }
- }</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>)) {
- <a id='7346' tid='7345', class="m">sim_</a>-><a id='7348' tid='7347', class="m">DisableStop</a>(<a id='7350' tid='7349', class="m">value</a>);
- } <a id='7352' tid='7351', class="m">else</a> {
- <a id='7354' tid='7353', class="m">PrintF</a>(<a id='7356' tid='7355', class="m">"Unrecognized argument.\n"</a>);
- }
- }
- } <a id='7948' tid='7947', class="m">else</a> {
- <a id='7950' tid='7949', class="m">PrintF</a>(<a id='7952' tid='7951', class="m">"Wrong usage. Use help command for more information.\n"</a>);
- }
- } <a id='7954' tid='7953', class="m">else</a> <span class="i">if</span> <span class="i">((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0)</span> <span class="i">{
- ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
- PrintF("Trace of executed instructions is %s\n",
- ::v8::internal::FLAG_trace_sim ? "on" : "off");
- }</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">"h"</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">"help"</a>) <a id='7976' tid='7975', class="m">==</a> <a id='7978' tid='7977', class="m">0</a>)) <span class="i">{
- PrintF("cont\n");
- PrintF(" continue execution (alias 'c')\n");
- PrintF("stepi\n");
- PrintF(" step one instruction (alias 'si')\n");
- PrintF("print <register>\n");
- PrintF(" print register content (alias 'p')\n");
- PrintF(" use register name 'all' to print all registers\n");
- PrintF(" add argument 'fp' to print register pair double values\n");
- PrintF("printobject <register>\n");
- PrintF(" print an object from a register (alias 'po')\n");
- PrintF("flags\n");
- PrintF(" print flags\n");
- PrintF("stack [<words>]\n");
- PrintF(" dump stack content, default dump 10 words)\n");
- PrintF("mem <address> [<words>]\n");
- PrintF(" dump memory content, default dump 10 words)\n");
- PrintF("disasm [<instructions>]\n");
- PrintF("disasm [<address/register>]\n");
- PrintF("disasm [[<address/register>] <instructions>]\n");
- PrintF(" disassemble code, default is 10 instructions\n");
- PrintF(" from pc (alias 'di')\n");
- PrintF("gdb\n");
- PrintF(" enter gdb\n");
- PrintF("break <address>\n");
- PrintF(" set a break point on the address\n");
- PrintF("del\n");
- PrintF(" delete the breakpoint\n");
- PrintF("trace (alias 't')\n");
- PrintF(" toogle the tracing of all executed statements\n");
- PrintF("stop feature:\n");
- PrintF(" Description:\n");
- PrintF(" Stops are debug instructions inserted by\n");
- PrintF(" the Assembler::stop() function.\n");
- PrintF(" When hitting a stop, the Simulator will\n");
- PrintF(" stop and and give control to the ArmDebugger.\n");
- PrintF(" The first %d stop codes are watched:\n",
- Simulator::kNumOfWatchedStops);
- PrintF(" - They can be enabled / disabled: the Simulator\n");
- PrintF(" will / won't stop when hitting them.\n");
- PrintF(" - The Simulator keeps track of how many times they \n");
- PrintF(" are met. (See the info command.) Going over a\n");
- PrintF(" disabled stop still increases its counter. \n");
- PrintF(" Commands:\n");
- PrintF(" stop info all/<code> : print infos about number <code>\n");
- PrintF(" or all stop(s).\n");
- PrintF(" stop enable/disable all/<code> : enables / disables\n");
- PrintF(" all or number <code> stop(s)\n");
- PrintF(" stop unstop\n");
- PrintF(" ignore the stop instruction at the current location\n");
- PrintF(" from now on\n");
- }</span> <span class="i">else {
- PrintF("Unknown command: %s\n", cmd);
- }</span>
- }
- <a id='8896' tid='8895', class="m">DeleteArray</a>(<a id='8898' tid='8897', class="m">line</a>);
- }
- // Add all the breakpoints back to stop execution and enter the debugger
- // shell when hit.
- <a id='9160' tid='9159', class="m">RedoBreakpoints</a>();
- #<a id='9162' tid='9161', class="m">undef</a> <a id='9164' tid='9163', class="m">COMMAND_SIZE</a>
- #<a id='9166' tid='9165', class="m">undef</a> <a id='9168' tid='9167', class="m">ARG_SIZE</a>
- #<a id='9170' tid='9169', class="m">undef</a> <a id='9172' tid='9171', class="m">STR</a>
- #<a id='9174' tid='9173', class="m">undef</a> <a id='9176' tid='9175', class="m">XSTR</a>
- }
- <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>) {
- <a id='8918' tid='8917', class="m">ASSERT</a>((<a id='8920' tid='8919', class="m">reinterpret_cast</a><<a id='8922' tid='8921', class="m">intptr_t</a>>(<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>);
- <a id='8938' tid='8937', class="m">ASSERT</a>((<a id='8940' tid='8939', class="m">reinterpret_cast</a><<a id='8942' tid='8941', class="m">intptr_t</a>>(<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>);
- <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>;
- }
- <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>) {
- <a id='8100' tid='8099', class="m">return</a> <a id='8102' tid='8101', class="m">static_cast</a><<a id='8104' tid='8103', class="m">uint32_t</a>>(<a id='8106' tid='8105', class="m">reinterpret_cast</a><<a id='8108' tid='8107', class="m">uintptr_t</a>>(<a id='8110' tid='8109', class="m">key</a>)) <a id='8112' tid='8111', class="m">>></a> <a id='8114' tid='8113', class="m">2</a>;
- }
- <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>) {
- <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>);
- <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>);
- <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>;
- }
- <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>,
- <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>,
- <a id='7386' tid='7385', class="m">size_t</a> <a id='7388' tid='7387', class="m">size</a>) {
- <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><<a id='7396' tid='7395', class="m">intptr_t</a>>(<a id='7398' tid='7397', class="m">start_addr</a>);
- <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>);
- <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>;
- <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>;
- <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>;
- <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>);
- <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>)) {
- <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>;
- <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>);
- <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>;
- <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>;
- <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>);
- <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>;
- }
- <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>) {
- <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>);
- }
- }
- <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>) {
- <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>-><a id='7236' tid='7235', class="m">Lookup</a>(<a id='7238' tid='7237', class="m">page</a>,
- <a id='7240' tid='7239', class="m">ICacheHash</a>(<a id='7242' tid='7241', class="m">page</a>),
- <a id='7244' tid='7243', class="m">true</a>);
- <a id='7246' tid='7245', class="m">if</a> (<a id='7248' tid='7247', class="m">entry</a>-><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>) {
- <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>();
- <a id='7266' tid='7265', class="m">entry</a>-><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>;
- }
- <a id='7274' tid='7273', class="m">return</a> <a id='7276' tid='7275', class="m">reinterpret_cast</a><<a id='7278' tid='7277', class="m">CachePage</a><a id='7280' tid='7279', class="m">*</a>>(<a id='7282' tid='7281', class="m">entry</a>-><a id='7284' tid='7283', class="m">value</a>);
- }
- // Flush from start up to and not including start + size.
- <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>,
- <a id='7040' tid='7039', class="m">intptr_t</a> <a id='7042' tid='7041', class="m">start</a>,
- <a id='7044' tid='7043', class="m">int</a> <a id='7046' tid='7045', class="m">size</a>) {
- <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"><=</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>);
- <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>));
- <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>);
- <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>);
- <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><<a id='7112' tid='7111', class="m">void</a><a id='7114' tid='7113', class="m">*</a>>(<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>));
- <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>);
- <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>);
- <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>-><a id='7162' tid='7161', class="m">ValidityByte</a>(<a id='7164' tid='7163', class="m">offset</a>);
- <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">>></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>);
- }
- <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>,
- <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>) {
- <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><<a id='6832' tid='6831', class="m">intptr_t</a>>(<a id='6834' tid='6833', class="m">instr</a>);
- <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><<a id='6844' tid='6843', class="m">void</a><a id='6846' tid='6845', class="m">*</a>>(<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>));
- <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><<a id='6868' tid='6867', class="m">void</a><a id='6870' tid='6869', class="m">*</a>>(<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>));
- <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>);
- <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>);
- <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>-><a id='6918' tid='6917', class="m">ValidityByte</a>(<a id='6920' tid='6919', class="m">offset</a>);
- <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>);
- <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>-><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>);
- <a id='6960' tid='6959', class="m">if</a> (<a id='6962' tid='6961', class="m">cache_hit</a>) {
- // Check that the data in memory matches the contents of the I-cache.
- <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><<a id='6970' tid='6969', class="m">void</a><a id='6972' tid='6971', class="m">*</a>>(<a id='6974' tid='6973', class="m">instr</a>),
- <a id='6976' tid='6975', class="m">cache_page</a>-><a id='6978' tid='6977', class="m">CachedData</a>(<a id='6980' tid='6979', class="m">offset</a>),
- <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>);
- } <a id='6992' tid='6991', class="m">else</a> {
- // Cache miss. Load memory into the cache.
- <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>);
- <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>;
- }
- }
- <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>) {
- <a id='6762' tid='6761', class="m">if</a> (<a id='6764' tid='6763', class="m">isolate</a>-><a id='6766' tid='6765', class="m">simulator_initialized</a>()) <a id='6768' tid='6767', class="m">return</a>;
- <a id='6770' tid='6769', class="m">isolate</a>-><a id='6772' tid='6771', class="m">set_simulator_initialized</a>(<a id='6774' tid='6773', class="m">true</a>);
- <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>,
- <a id='6794' tid='6793', class="m">&</a><a id='6796' tid='6795', class="m">RedirectExternalReference</a>);
- }
- <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>) {
- <span class="i">i_cache_ = isolate_->simulator_i_cache();</span>
- <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>) {
- <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>);
- <a id='6742' tid='6741', class="m">isolate_</a>-><a id='6744' tid='6743', class="m">set_simulator_i_cache</a>(<a id='6746' tid='6745', class="m">i_cache_</a>);
- }
- <span class="i">Initialize(isolate);</span>
- // Setup simulator support first. Some of this information is needed to
- // setup the architecture state.
- <span class="i">size_t stack_size = 1 * 1024*1024;</span> // allocate 1MB for stack
- <span class="i">stack_ = reinterpret_cast<char*>(malloc(stack_size));</span>
- <span class="i">pc_modified_ = false;</span>
- <span class="i">icount_ = 0;</span>
- <span class="i">break_pc_ = NULL;</span>
- <span class="i">break_instr_ = 0;</span>
- // Setup architecture state.
- // All registers are initialized to zero to start with.
- <span class="i">for (int i = 0; i < num_registers; i++) {
- registers_[i] = 0;
- }</span>
- <span class="i">n_flag_ = false;</span>
- <span class="i">z_flag_ = false;</span>
- <span class="i">c_flag_ = false;</span>
- <span class="i">v_flag_ = false;</span>
- // Initializing VFP registers.
- // All registers are initialized to zero to start with
- // even though s_registers_ & d_registers_ share the same
- // physical registers in the target.
- <span class="i">for (int i = 0; i < num_s_registers; i++) {
- vfp_register[i] = 0;
- }</span>
- <span class="i">n_flag_FPSCR_ = false;</span>
- <span class="i">z_flag_FPSCR_ = false;</span>
- <span class="i">c_flag_FPSCR_ = false;</span>
- <span class="i">v_flag_FPSCR_ = false;</span>
- <span class="i">FPSCR_rounding_mode_ = RZ;</span>
- <span class="i">inv_op_vfp_flag_ = false;</span>
- <span class="i">div_zero_vfp_flag_ = false;</span>
- <span class="i">overflow_vfp_flag_ = false;</span>
- <span class="i">underflow_vfp_flag_ = false;</span>
- <span class="i">inexact_vfp_flag_ = false;</span>
- // The sp is initialized to point to the bottom (high address) of the
- // allocated stack area. To be safe in potential stack underflows we leave
- // some buffer below.
- <span class="i">registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64;</span>
- // The lr and pc are initialized to a known bad value that will cause an
- // access violation if the simulator ever tries to execute it.
- <span class="i">registers_[pc] = bad_lr;</span>
- <span class="i">registers_[lr] = bad_lr;</span>
- <span class="i">InitializeCoverage();</span>
- }
- // When the generated code calls an external reference we need to catch that in
- // the simulator. The external reference will be a function compiled for the
- // host architecture. We need to call that function instead of trying to
- // execute it with the simulator. We do that by redirecting the external
- // reference to a svc (Supervisor Call) instruction that is handled by
- // the simulator. We write the original destination of the jump just at a known
- // offset from the svc instruction so the simulator knows what to call.
- <a id='6474' tid='6473', class="m">class</a> <a id='6476' tid='6475', class="m">Redirection</a> {
- <a id='6670' tid='6669', class="m">public</a>:
- <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>)
- : <span class="i">external_function_(external_function),
- swi_instruction_(al | (0xf*B24) | kCallRtRedirected),
- type_(type),
- next_(NULL)</span> {
- <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>();
- <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>-><a id='6390' tid='6389', class="m">simulator_redirection</a>();
- <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>)->
- <a id='6400' tid='6399', class="m">FlushICache</a>(<a id='6402' tid='6401', class="m">isolate</a>-><a id='6404' tid='6403', class="m">simulator_i_cache</a>(),
- <a id='6406' tid='6405', class="m">reinterpret_cast</a><<a id='6408' tid='6407', class="m">void</a><a id='6410' tid='6409', class="m">*</a>>(<a id='6412' tid='6411', class="m">&</a><a id='6414' tid='6413', class="m">swi_instruction_</a>),
- <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>);
- <a id='6422' tid='6421', class="m">isolate</a>-><a id='6424' tid='6423', class="m">set_simulator_redirection</a>(<a id='6426' tid='6425', class="m">this</a>);
- }
- <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>() {
- <a id='6636' tid='6635', class="m">return</a> <a id='6638' tid='6637', class="m">reinterpret_cast</a><<a id='6640' tid='6639', class="m">void</a><a id='6642' tid='6641', class="m">*</a>>(<a id='6644' tid='6643', class="m">&</a><a id='6646' tid='6645', class="m">swi_instruction_</a>);
- }
- <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>; }
- <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>; }
- <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>,
- <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>) {
- <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>();
- <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>-><a id='6574' tid='6573', class="m">simulator_redirection</a>();
- <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>-><a id='6590' tid='6589', class="m">next_</a>) {
- <a id='6592' tid='6591', class="m">if</a> (<a id='6594' tid='6593', class="m">current</a>-><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>;
- }
- <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>);
- }
- <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>) {
- <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><<a id='6500' tid='6499', class="m">char</a><a id='6502' tid='6501', class="m">*</a>>(<a id='6504' tid='6503', class="m">swi_instruction</a>);
- <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> =
- <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>);
- <a id='6522' tid='6521', class="m">return</a> <a id='6524' tid='6523', class="m">reinterpret_cast</a><<a id='6526' tid='6525', class="m">Redirection</a><a id='6528' tid='6527', class="m">*</a>>(<a id='6530' tid='6529', class="m">addr_of_redirection</a>);
- }
- <a id='6672' tid='6671', class="m">private</a>:
- <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>;
- <a id='6680' tid='6679', class="m">uint32_t</a> <a id='6682' tid='6681', class="m">swi_instruction_</a>;
- <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>;
- <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>;
- };
- <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>,
- <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>) {
- <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>);
- <a id='6468' tid='6467', class="m">return</a> <a id='6470' tid='6469', class="m">redirection</a>-><a id='6472' tid='6471', class="m">address_of_swi_instruction</a>();
- }
- // Get the active Simulator for the current thread.
- <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>) {
- <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> =
- <a id='6368' tid='6367', class="m">isolate</a>-><a id='6370' tid='6369', class="m">FindOrAllocatePerThreadDataForThisThread</a>();
- <span class="i">ASSERT(isolate_data != NULL);</span>
- <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>-><a id='6330' tid='6329', class="m">simulator</a>();
- <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>) {
- // TODO(146): delete the simulator object when a thread/isolate goes away.
- <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>);
- <a id='6286' tid='6285', class="m">isolate_data</a>-><a id='6288' tid='6287', class="m">set_simulator</a>(<a id='6290' tid='6289', class="m">sim</a>);
- }
- <span class="i">return sim;</span>
- }
- // Sets the register in the architecture state. It will also deal with updating
- // Simulator internal state for special registers such as PC.
- <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>) {
- <span class="i">ASSERT((reg >= 0) && (reg < num_registers));</span>
- <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>) {
- <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>;
- }
- <span class="i">registers_[reg] = value;</span>
- }
- // Get the register from the architecture state. This function does handle
- // the special case of accessing the PC register.
- <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> {
- <span class="i">ASSERT((reg >= 0) && (reg < num_registers));</span>
- // Stupid code added to avoid bug in GCC.
- // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
- <span class="i">if (reg >= num_registers) return 0;</span>
- // End stupid code.
- <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>);
- }
- <span class="i">double Simulator::get_double_from_register_pair(int reg) {
- ASSERT((reg >= 0) && (reg < num_registers) && ((reg % 2) == 0));
- double dm_val = 0.0;
- // Read the bits from the unsigned integer register_[] array
- // into the double precision floating point value and return it.
- char buffer[2 * sizeof(vfp_register[0])];
- memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0]));
- memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
- return(dm_val);
- }</span>
- <span class="i">void Simulator::set_dw_register(int dreg, const int* dbl) {
- ASSERT((dreg >= 0) && (dreg < num_d_registers));
- registers_[dreg] = dbl[0];
- registers_[dreg + 1] = dbl[1];
- }</span>
- // Raw access to the PC register.
- <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>) {
- <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>;
- <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>;
- }
- <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">{
- return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc));
- }</span>
- // Raw access to the PC register without the special adjustment when reading.
- <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">{
- return registers_[pc];
- }</span>
- // Getting from and setting into VFP registers.
- <span class="i">void Simulator::set_s_register(int sreg, unsigned int value) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
- vfp_register[sreg] = value;
- }</span>
- <span class="i">unsigned int Simulator::get_s_register(int sreg) const</span> <span class="i">{
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
- return vfp_register[sreg];
- }</span>
- <span class="i">void Simulator::set_s_register_from_float(int sreg, const float flt) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
- // Read the bits from the single precision floating point value
- // into the unsigned integer element of vfp_register[] given by index=sreg.
- char buffer[sizeof(vfp_register[0])];
- memcpy(buffer, &flt, sizeof(vfp_register[0]));
- memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
- }</span>
- <span class="i">void Simulator::set_s_register_from_sinteger(int sreg, const int sint) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
- // Read the bits from the integer value into the unsigned integer element of
- // vfp_register[] given by index=sreg.
- char buffer[sizeof(vfp_register[0])];
- memcpy(buffer, &sint, sizeof(vfp_register[0]));
- memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
- }</span>
- <span class="i">void Simulator::set_d_register_from_double(int dreg, const double& dbl) {
- ASSERT((dreg >= 0) && (dreg < num_d_registers));
- // Read the bits from the double precision floating point value into the two
- // consecutive unsigned integer elements of vfp_register[] given by index
- // 2*sreg and 2*sreg+1.
- char buffer[2 * sizeof(vfp_register[0])];
- memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0]));
- memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0]));
- }</span>
- <span class="i">float Simulator::get_float_from_s_register(int sreg) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
- float sm_val = 0.0;
- // Read the bits from the unsigned integer vfp_register[] array
- // into the single precision floating point value and return it.
- char buffer[sizeof(vfp_register[0])];
- memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
- memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
- return(sm_val);
- }</span>
- <span class="i">int Simulator::get_sinteger_from_s_register(int sreg) {
- ASSERT((sreg >= 0) && (sreg < num_s_registers));
- int sm_val = 0;
- // Read the bits from the unsigned integer vfp_register[] array
- // into the single precision floating point value and return it.
- char buffer[sizeof(vfp_register[0])];
- memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
- memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
- return(sm_val);
- }</span>
- <span class="i">double Simulator::get_double_from_d_register(int dreg) {
- ASSERT((dreg >= 0) && (dreg < num_d_registers));
- double dm_val = 0.0;
- // Read the bits from the unsigned integer vfp_register[] array
- // into the double precision floating point value and return it.
- char buffer[2 * sizeof(vfp_register[0])];
- memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0]));
- memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0]));
- return(dm_val);
- }</span>
- // For use in calls that take two double values, constructed either
- // from r0-r3 or d0 and d1.
- <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>) {
- <span class="i">if</span> <span class="i">(use_eabi_hardfloat())</span> <span class="i">{
- *x = vfp_register[0];
- *y = vfp_register[1];
- }</span> <a id='6174' tid='6173', class="m">else</a> {
- // We use a char buffer to get around the strict-aliasing rules which
- // otherwise allow the compiler to optimize away the copy.
- <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>)];
- // Registers 0 and 1 -> x.
- <span class="i">memcpy(buffer, registers_, sizeof(*x));</span>
- <span class="i">memcpy(x, buffer, sizeof(*x));</span>
- // Registers 2 and 3 -> y.
- <span class="i">memcpy(buffer, registers_ + 2, sizeof(*y));</span>
- <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>));
- }
- }
- // For use in calls that take one double value, constructed either
- // from r0 and r1 or d0.
- <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>) {
- <span class="i">if</span> <span class="i">(use_eabi_hardfloat())</span> <span class="i">{
- *x = vfp_register[0];
- }</span> <span class="i">else</span> {
- // We use a char buffer to get around the strict-aliasing rules which
- // otherwise allow the compiler to optimize away the copy.
- <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>)];
- // Registers 0 and 1 -> x.
- <span class="i">memcpy(buffer, registers_, sizeof(*x));</span>
- <span class="i">memcpy(x, buffer, sizeof(*x));</span>
- }
- }
- // For use in calls that take one double value constructed either
- // from r0 and r1 or d0 and one integer value.
- <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>) {
- <span class="i">if</span> <span class="i">(use_eabi_hardfloat())</span> <span class="i">{
- *x = vfp_register[0];
- *y = registers_[1];
- }</span> <a id='6118' tid='6117', class="m">else</a> {
- // We use a char buffer to get around the strict-aliasing rules which
- // otherwise allow the compiler to optimize away the copy.
- <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>)];
- // Registers 0 and 1 -> x.
- <span class="i">memcpy(buffer, registers_, sizeof(*x));</span>
- <span class="i">memcpy(x, buffer, sizeof(*x));</span>
- // Register 2 -> y.
- <span class="i">memcpy(buffer, registers_ + 2, sizeof(*y));</span>
- <span class="i">memcpy(y, buffer, sizeof(*y));</span>
- }
- }
- // The return value is either in r0/r1 or d0.
- <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>) {
- <span class="i">if</span> <span class="i">(use_eabi_hardfloat())</span> {
- <span class="i">char buffer[2 * sizeof(vfp_register[0])];</span>
- <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>));
- // Copy result to d0.
- <span class="i">memcpy(vfp_register, buffer, sizeof(buffer));</span>
- } <span class="i">else</span> {
- <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>])];
- <span class="i">memcpy(buffer, &result, sizeof(buffer));</span>
- // Copy result to r0 and r1.
- <span class="i">memcpy(registers_, buffer, sizeof(buffer));</span>
- }
- }
- <span class="i">void Simulator::TrashCallerSaveRegisters() {
- // We don't trash the registers with the return value.
- registers_[2] = 0x50Bad4U;
- registers_[3] = 0x50Bad4U;
- registers_[12] = 0x50Bad4U;
- }</span>
- // Some Operating Systems allow unaligned access on ARMv7 targets. We
- // assume that unaligned accesses are not allowed unless the v8 build system
- // defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero.
- // The following statements below describes the behavior of the ARM CPUs
- // that don't support unaligned access.
- // Some ARM platforms raise an interrupt on detecting unaligned access.
- // On others it does a funky rotation thing. For now we
- // simply disallow unaligned reads. Note that simulator runs have the runtime
- // system running directly on the host system and only generated code is
- // executed in the simulator. Since the host is typically IA32 we will not
- // get the correct ARM-like behaviour on unaligned accesses for those ARM
- // targets that don't support unaligned loads and stores.
- <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>) {
- <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
- <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><<a id='6038' tid='6037', class="m">intptr_t</a><a id='6040' tid='6039', class="m">*</a>>(<a id='6042' tid='6041', class="m">addr</a>);
- <span class="i">return *ptr;</span>
- <span class="i">#else</span>
- <span class="i">if ((addr & 3) == 0) {
- intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
- return *ptr;
- }</span>
- <a id='5996' tid='5995', class="m">PrintF</a>(<a id='5998' tid='5997', class="m">"Unaligned read at 0x%08x, pc=0x%08"</a> <a id='6000' tid='5999', class="m">V8PRIxPTR</a> <a id='6002' tid='6001', class="m">"\n"</a>,
- <a id='6004' tid='6003', class="m">addr</a>,
- <a id='6006' tid='6005', class="m">reinterpret_cast</a><<a id='6008' tid='6007', class="m">intptr_t</a>>(<a id='6010' tid='6009', class="m">instr</a>));
- <span class="i">UNIMPLEMENTED();</span>
- <span class="i">return 0;</span>
- <span class="i">#endif</span>
- }
- <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>) {
- <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
- <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><<a id='5990' tid='5989', class="m">intptr_t</a><a id='5992' tid='5991', class="m">*</a>>(<a id='5994' tid='5993', class="m">addr</a>);
- <span class="i">*ptr = value;</span>
- <span class="i">return;</span>
- <span class="i">#else</span>
- <span class="i">if ((addr & 3) == 0) {
- intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
- *ptr = value;
- return;
- }</span>
- <a id='5944' tid='5943', class="m">PrintF</a>(<a id='5946' tid='5945', class="m">"Unaligned write at 0x%08x, pc=0x%08"</a> <a id='5948' tid='5947', class="m">V8PRIxPTR</a> <a id='5950' tid='5949', class="m">"\n"</a>,
- <a id='5952' tid='5951', class="m">addr</a>,
- <a id='5954' tid='5953', class="m">reinterpret_cast</a><<a id='5956' tid='5955', class="m">intptr_t</a>>(<a id='5958' tid='5957', class="m">instr</a>));
- <span class="i">UNIMPLEMENTED();</span>
- <span class="i">#endif</span>
- }
- <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>) {
- <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
- <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><<a id='5908' tid='5907', class="m">uint16_t</a><a id='5910' tid='5909', class="m">*</a>>(<a id='5912' tid='5911', class="m">addr</a>);
- <span class="i">return *ptr;</span>
- <span class="i">#else</span>
- <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">{
- uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
- return *ptr;
- }</span>
- <a id='5876' tid='5875', class="m">PrintF</a>(<a id='5878' tid='5877', class="m">"Unaligned unsigned halfword read at 0x%08x, pc=0x%08"</a> <a id='5880' tid='5879', class="m">V8PRIxPTR</a> <a id='5882' tid='5881', class="m">"\n"</a>,
- <a id='5884' tid='5883', class="m">addr</a>,
- <a id='5886' tid='5885', class="m">reinterpret_cast</a><<a id='5888' tid='5887', class="m">intptr_t</a>>(<a id='5890' tid='5889', class="m">instr</a>));
- <span class="i">UNIMPLEMENTED();</span>
- <span class="i">return 0;</span>
- <span class="i">#endif</span>
- }
- <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>) {
- <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
- <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><<a id='5810' tid='5809', class="m">int16_t</a><a id='5812' tid='5811', class="m">*</a>>(<a id='5814' tid='5813', class="m">addr</a>);
- <span class="i">return *ptr;</span>
- <span class="i">#else</span>
- <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>) {
- <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><<a id='4358' tid='4357', class="m">int16_t</a><a id='4360' tid='4359', class="m">*</a>>(<a id='4362' tid='4361', class="m">addr</a>);
- <span class="i">return *ptr;</span>
- }
- <span class="i">PrintF("Unaligned signed halfword read at 0x%08x\n", addr);</span>
- <span class="i">UNIMPLEMENTED();</span>
- <span class="i">return 0;</span>
- <span class="i">#endif</span>
- }
- <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>) {
- <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
- <span class="i">uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);</span>
- <span class="i">*ptr = value;</span>
- <span class="i">return;</span>
- <span class="i">#else</span>
- <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>) {
- <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><<a id='5842' tid='5841', class="m">uint16_t</a><a id='5844' tid='5843', class="m">*</a>>(<a id='5846' tid='5845', class="m">addr</a>);
- <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>;
- <a id='5856' tid='5855', class="m">return</a>;
- }
- <a id='5816' tid='5815', class="m">PrintF</a>(<a id='5818' tid='5817', class="m">"Unaligned unsigned halfword write at 0x%08x, pc=0x%08"</a> <a id='5820' tid='5819', class="m">V8PRIxPTR</a> <a id='5822' tid='5821', class="m">"\n"</a>,
- <a id='5824' tid='5823', class="m">addr</a>,
- <a id='5826' tid='5825', class="m">reinterpret_cast</a><<a id='5828' tid='5827', class="m">intptr_t</a>>(<a id='5830' tid='5829', class="m">instr</a>));
- <span class="i">UNIMPLEMENTED();</span>
- <span class="i">#endif</span>
- }
- <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>) {
- <span class="i">#if V8_TARGET_CAN_READ_UNALIGNED</span>
- <span class="i">int16_t* ptr = reinterpret_cast<int16_t*>(addr);</span>
- <span class="i">*ptr = value;</span>
- <span class="i">return;</span>
- <span class="i">#else</span>
- <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">{
- int16_t* ptr = reinterpret_cast<int16_t*>(addr);
- *ptr = value;
- return;
- }</span>
- <a id='4322' tid='4321', class="m">PrintF</a>(<a id='4324' tid='4323', class="m">"Unaligned halfword write at 0x%08x, pc=0x%08"</a> <a id='4326' tid='4325', class="m">V8PRIxPTR</a> <a id='4328' tid='4327', class="m">"\n"</a>,
- <a id='4330' tid='4329', class="m">addr</a>,
- <a id='4332' tid='4331', class="m">reinterpret_cast</a><<a id='4334' tid='4333', class="m">intptr_t</a>>(<a id='4336' tid='4335', class="m">instr</a>));
- <span class="i">UNIMPLEMENTED();</span>
- <span class="i">#endif</span>
- }
- <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>) {
- <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><<a id='5786' tid='5785', class="m">uint8_t</a><a id='5788' tid='5787', class="m">*</a>>(<a id='5790' tid='5789', class="m">addr</a>);
- <span class="i">return *ptr;</span>
- }
- <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>) {
- <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><<a id='5744' tid='5743', class="m">int8_t</a><a id='5746' tid='5745', class="m">*</a>>(<a id='5748' tid='5747', class="m">addr</a>);
- <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>;
- }
- <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>) {
- <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><<a id='5712' tid='5711', class="m">uint8_t</a><a id='5714' tid='5713', class="m">*</a>>(<a id='5716' tid='5715', class="m">addr</a>);
- <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>;
- }
- <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>) {
- <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><<a id='5664' tid='5663', class="m">int8_t</a><a id='5666' tid='5665', class="m">*</a>>(<a id='5668' tid='5667', class="m">addr</a>);
- <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>;
- }
- <span class="i">int32_t* Simulator::ReadDW(int32_t addr) {
- #if V8_TARGET_CAN_READ_UNALIGNED
- int32_t* ptr = reinterpret_cast<int32_t*>(addr);
- return ptr;
- #else
- if ((addr & 3) == 0) {
- int32_t* ptr = reinterpret_cast<int32_t*>(addr);
- return ptr;
- }
- PrintF("Unaligned read at 0x%08x\n", addr);
- UNIMPLEMENTED();
- return 0;
- #endif
- }</span>
- <span class="i">void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) {
- #if V8_TARGET_CAN_READ_UNALIGNED
- int32_t* ptr = reinterpret_cast<int32_t*>(addr);
- *ptr++ = value1;
- *ptr = value2;
- return;
- #else
- if ((addr & 3) == 0) {
- int32_t* ptr = reinterpret_cast<int32_t*>(addr);
- *ptr++ = value1;
- *ptr = value2;
- return;
- }
- PrintF("Unaligned write at 0x%08x\n", addr);
- UNIMPLEMENTED();
- #endif
- }</span>
- // Returns the limit of the stack area to enable checking for stack overflows.
- <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> {
- // Leave a safety margin of 256 bytes to prevent overrunning the stack when
- // pushing values.
- <a id='5618' tid='5617', class="m">return</a> <a id='5620' tid='5619', class="m">reinterpret_cast</a><<a id='5622' tid='5621', class="m">uintptr_t</a>>(<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>;
- }
- // Unsupported instructions use Format to print an error and stop execution.
- <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>) {
- <a id='5606' tid='5605', class="m">PrintF</a>(<a id='5608' tid='5607', class="m">"Simulator found unsupported instruction:\n 0x%08x: %s\n"</a>,
- <a id='5610' tid='5609', class="m">reinterpret_cast</a><<a id='5612' tid='5611', class="m">intptr_t</a>>(<a id='5614' tid='5613', class="m">instr</a>), <a id='5616' tid='5615', class="m">format</a>);
- <span class="i">UNIMPLEMENTED();</span>
- }
- // Checks if the current instruction should be executed based on its
- // condition bits.
- <span class="i">bool Simulator::ConditionallyExecute(Instruction* instr) {
- switch (instr->ConditionField()) {
- case eq: return z_flag_;
- case ne: return !z_flag_;
- case cs: return c_flag_;
- case cc: return !c_flag_;
- case mi: return n_flag_;
- case pl: return !n_flag_;
- case vs: return v_flag_;
- case vc: return !v_flag_;
- case hi: return c_flag_ && !z_flag_;
- case ls: return !c_flag_ || z_flag_;
- case ge: return n_flag_ == v_flag_;
- case lt: return n_flag_ != v_flag_;
- case gt: return !z_flag_ && (n_flag_ == v_flag_);
- case le: return z_flag_ || (n_flag_ != v_flag_);
- case al: return true;
- default: UNREACHABLE();
- }
- return false;
- }</span>
- // Calculate and set the Negative and Zero flags.
- <span class="i">void Simulator::SetNZFlags(int32_t val) {
- n_flag_ = (val < 0);
- z_flag_ = (val == 0);
- }</span>
- // Set the Carry flag.
- <span class="i">void Simulator::SetCFlag(bool val) {
- c_flag_ = val;
- }</span>
- // Set the oVerflow flag.
- <span class="i">void Simulator::SetVFlag(bool val) {
- v_flag_ = val;
- }</span>
- // Calculate C flag value for additions.
- <span class="i">bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
- uint32_t uleft = static_cast<uint32_t>(left);
- uint32_t uright = static_cast<uint32_t>(right);
- uint32_t urest = 0xffffffffU - uleft;
- return (uright > urest) ||
- (carry && (((uright + 1) > urest) || (uright > (urest - 1))));
- }</span>
- // Calculate C flag value for subtractions.
- <span class="i">bool Simulator::BorrowFrom(int32_t left, int32_t right) {
- uint32_t uleft = static_cast<uint32_t>(left);
- uint32_t uright = static_cast<uint32_t>(right);
- return (uright > uleft);
- }</span>
- // Calculate V flag value for additions and subtractions.
- <span class="i">bool Simulator::OverflowFrom(int32_t alu_out,
- int32_t left, int32_t right, bool addition) {
- bool overflow;
- if (addition) {
- // operands have the same sign
- overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
- // and operands and result have different sign
- && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
- } else {
- // operands have different signs
- overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
- // and first operand and result have different signs
- && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
- }
- return overflow;
- }</span>
- // Support for VFP comparisons.
- <span class="i">void Simulator::Compute_FPSCR_Flags(double val1, double val2) {
- if (isnan(val1) || isnan(val2)) {
- n_flag_FPSCR_ = false;
- z_flag_FPSCR_ = false;
- c_flag_FPSCR_ = true;
- v_flag_FPSCR_ = true;
- // All non-NaN cases.
- } else if (val1 == val2) {
- n_flag_FPSCR_ = false;
- z_flag_FPSCR_ = true;
- c_flag_FPSCR_ = true;
- v_flag_FPSCR_ = false;
- } else if (val1 < val2) {
- n_flag_FPSCR_ = true;
- z_flag_FPSCR_ = false;
- c_flag_FPSCR_ = false;
- v_flag_FPSCR_ = false;
- } else {
- // Case when (val1 > val2).
- n_flag_FPSCR_ = false;
- z_flag_FPSCR_ = false;
- c_flag_FPSCR_ = true;
- v_flag_FPSCR_ = false;
- }
- }</span>
- <span class="i">void Simulator::Copy_FPSCR_to_APSR() {
- n_flag_ = n_flag_FPSCR_;
- z_flag_ = z_flag_FPSCR_;
- c_flag_ = c_flag_FPSCR_;
- v_flag_ = v_flag_FPSCR_;
- }</span>
- // Addressing Mode 1 - Data-processing operands:
- // Get the value based on the shifter_operand with register.
- <span class="i">int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) {
- ShiftOp shift = instr->ShiftField();
- int shift_amount = instr->ShiftAmountValue();
- int32_t result = get_register(instr->RmValue());
- if (instr->Bit(4) == 0) {
- // by immediate
- if ((shift == ROR) && (shift_amount == 0)) {
- UNIMPLEMENTED();
- return result;
- } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
- shift_amount = 32;
- }
- switch (shift) {
- case ASR: {
- if (shift_amount == 0) {
- if (result < 0) {
- result = 0xffffffff;
- *carry_out = true;
- } else {
- result = 0;
- *carry_out = false;
- }
- } else {
- result >>= (shift_amount - 1);
- *carry_out = (result & 1) == 1;
- result >>= 1;
- }
- break;
- }
- case LSL: {
- if (shift_amount == 0) {
- *carry_out = c_flag_;
- } else {
- result <<= (shift_amount - 1);
- *carry_out = (result < 0);
- result <<= 1;
- }
- break;
- }
- case LSR: {
- if (shift_amount == 0) {
- result = 0;
- *carry_out = c_flag_;
- } else {
- uint32_t uresult = static_cast<uint32_t>(result);
- uresult >>= (shift_amount - 1);
- *carry_out = (uresult & 1) == 1;
- uresult >>= 1;
- result = static_cast<int32_t>(uresult);
- }
- break;
- }
- case ROR: {
- UNIMPLEMENTED();
- break;
- }
- default: {
- UNREACHABLE();
- break;
- }
- }
- } else {
- // by register
- int rs = instr->RsValue();
- shift_amount = get_register(rs) &0xff;
- switch (shift) {
- case ASR: {
- if (shift_amount == 0) {
- *carry_out = c_flag_;
- } else if (shift_amount < 32) {
- result >>= (shift_amount - 1);
- *carry_out = (result & 1) == 1;
- result >>= 1;
- } else {
- ASSERT(shift_amount >= 32);
- if (result < 0) {
- *carry_out = true;
- result = 0xffffffff;
- } else {
- *carry_out = false;
- result = 0;
- }
- }
- break;
- }
- case LSL: {
- if (shift_amount == 0) {
- *carry_out = c_flag_;
- } else if (shift_amount < 32) {
- result <<= (shift_amount - 1);
- *carry_out = (result < 0);
- result <<= 1;
- } else if (shift_amount == 32) {
- *carry_out = (result & 1) == 1;
- result = 0;
- } else {
- ASSERT(shift_amount > 32);
- *carry_out = false;
- result = 0;
- }
- break;
- }
- case LSR: {
- if (shift_amount == 0) {
- *carry_out = c_flag_;
- } else if (shift_amount < 32) {
- uint32_t uresult = static_cast<uint32_t>(result);
- uresult >>= (shift_amount - 1);
- *carry_out = (uresult & 1) == 1;
- uresult >>= 1;
- result = static_cast<int32_t>(uresult);
- } else if (shift_amount == 32) {
- *carry_out = (result < 0);
- result = 0;
- } else {
- *carry_out = false;
- result = 0;
- }
- break;
- }
- case ROR: {
- UNIMPLEMENTED();
- break;
- }
- default: {
- UNREACHABLE();
- break;
- }
- }
- }
- return result;
- }</span>
- // Addressing Mode 1 - Data-processing operands:
- // Get the value based on the shifter_operand with immediate.
- <span class="i">int32_t Simulator::GetImm(Instruction* instr, bool* carry_out) {
- int rotate = instr->RotateValue() * 2;
- int immed8 = instr->Immed8Value();
- int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
- *carry_out = (rotate == 0) ? c_flag_ : (imm < 0);
- return imm;
- }</span>
- <span class="i">static int count_bits(int bit_vector) {
- int count = 0;
- while (bit_vector != 0) {
- if ((bit_vector & 1) != 0) {
- count++;
- }
- bit_vector >>= 1;
- }
- return count;
- }</span>
- <span class="i">void Simulator::ProcessPUW(Instruction* instr,
- int num_regs,
- int reg_size,
- intptr_t* start_address,
- intptr_t* end_address) {
- int rn = instr->RnValue();
- int32_t rn_val = get_register(rn);
- switch (instr->PUField()) {
- case da_x: {
- UNIMPLEMENTED();
- break;
- }
- case ia_x: {
- *start_address = rn_val;
- *end_address = rn_val + (num_regs * reg_size) - reg_size;
- rn_val = rn_val + (num_regs * reg_size);
- break;
- }
- case db_x: {
- *start_address = rn_val - (num_regs * reg_size);
- *end_address = rn_val - reg_size;
- rn_val = *start_address;
- break;
- }
- case ib_x: {
- *start_address = rn_val + reg_size;
- *end_address = rn_val + (num_regs * reg_size);
- rn_val = *end_address;
- break;
- }
- default: {
- UNREACHABLE();
- break;
- }
- }
- if (instr->HasW()) {
- set_register(rn, rn_val);
- }
- }</span>
- // Addressing Mode 4 - Load and Store Multiple
- <span class="i">void Simulator::HandleRList(Instruction* instr, bool load) {
- int rlist = instr->RlistValue();
- int num_regs = count_bits(rlist);
- intptr_t start_address = 0;
- intptr_t end_address = 0;
- ProcessPUW(instr, num_regs, kPointerSize, &start_address, &end_address);
- intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
- int reg = 0;
- while (rlist != 0) {
- if ((rlist & 1) != 0) {
- if (load) {
- set_register(reg, *address);
- } else {
- *address = get_register(reg);
- }
- address += 1;
- }
- reg++;
- rlist >>= 1;
- }
- ASSERT(end_address == ((intptr_t)address) - 4);
- }</span>
- // Addressing Mode 6 - Load and Store Multiple Coprocessor registers.
- <span class="i">void Simulator::HandleVList(Instruction* instr) {
- VFPRegPrecision precision =
- (instr->SzValue() == 0) ? kSinglePrecision : kDoublePrecision;
- int operand_size = (precision == kSinglePrecision) ? 4 : 8;
- bool load = (instr->VLValue() == 0x1);
- int vd;
- int num_regs;
- vd = instr->VFPDRegValue(precision);
- if (precision == kSinglePrecision) {
- num_regs = instr->Immed8Value();
- } else {
- num_regs = instr->Immed8Value() / 2;
- }
- intptr_t start_address = 0;
- intptr_t end_address = 0;
- ProcessPUW(instr, num_regs, operand_size, &start_address, &end_address);
- intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
- for (int reg = vd; reg < vd + num_regs; reg++) {
- if (precision == kSinglePrecision) {
- if (load) {
- set_s_register_from_sinteger(
- reg, ReadW(reinterpret_cast<int32_t>(address), instr));
- } else {
- WriteW(reinterpret_cast<int32_t>(address),
- get_sinteger_from_s_register(reg), instr);
- }
- address += 1;
- } else {
- if (load) {
- set_s_register_from_sinteger(
- 2 * reg, ReadW(reinterpret_cast<int32_t>(address), instr));
- set_s_register_from_sinteger(
- 2 * reg + 1, ReadW(reinterpret_cast<int32_t>(address + 1), instr));
- } else {
- WriteW(reinterpret_cast<int32_t>(address),
- get_sinteger_from_s_register(2 * reg), instr);
- WriteW(reinterpret_cast<int32_t>(address + 1),
- get_sinteger_from_s_register(2 * reg + 1), instr);
- }
- address += 2;
- }
- }
- ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address);
- }</span>
- // Calls into the V8 runtime are based on this very simple interface.
- // Note: To be able to return two values from some calls the code in runtime.cc
- // uses the ObjectPair which is essentially two 32-bit values stuffed into a
- // 64-bit value. With the code below we assume that all runtime calls return
- // 64 bits of result. If they don't, the r1 result register contains a bogus
- // value, which is fine because it is caller-saved.
- <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>,
- <a id='5564' tid='5563', class="m">int32_t</a> <a id='5566' tid='5565', class="m">arg1</a>,
- <a id='5568' tid='5567', class="m">int32_t</a> <a id='5570' tid='5569', class="m">arg2</a>,
- <a id='5572' tid='5571', class="m">int32_t</a> <a id='5574' tid='5573', class="m">arg3</a>,
- <a id='5576' tid='5575', class="m">int32_t</a> <a id='5578' tid='5577', class="m">arg4</a>,
- <a id='5580' tid='5579', class="m">int32_t</a> <a id='5582' tid='5581', class="m">arg5</a>);
- <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>,
- <a id='5540' tid='5539', class="m">int32_t</a> <a id='5542' tid='5541', class="m">arg1</a>,
- <a id='5544' tid='5543', class="m">int32_t</a> <a id='5546' tid='5545', class="m">arg2</a>,
- <a id='5548' tid='5547', class="m">int32_t</a> <a id='5550' tid='5549', class="m">arg3</a>);
- // This signature supports direct call in to API function native callback
- // (refer to InvocationCallback in v8.h).
- <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><<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>> (<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>);
- // This signature supports direct call to accessor getter callback.
- <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><<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>> (<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>,
- <a id='5502' tid='5501', class="m">int32_t</a> <a id='5504' tid='5503', class="m">arg1</a>);
- // Software interrupt instructions are used by the simulator to call into the
- // C-based V8 runtime.
- <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>) {
- <span class="i">int svc = instr->SvcValue();</span>
- <span class="i">switch</span> (<span class="i">svc</span>) {
- <span class="i">case</span> <span class="i">kCallRtRedirected</span>: {
- // Check if stack is aligned. Error if not aligned is reported below to
- // include information on the function called.
- <span class="i">bool stack_aligned =
- (get_register(sp)
- & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0;</span>
- <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>);
- <span class="i">int32_t arg0 = get_register(r0);</span>
- <span class="i">int32_t arg1 = get_register(r1);</span>
- <span class="i">int32_t arg2 = get_register(r2);</span>
- <span class="i">int32_t arg3 = get_register(r3);</span>
- <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><<a id='5444' tid='5443', class="m">int32_t</a><a id='5446' tid='5445', class="m">*</a>>(<a id='5448' tid='5447', class="m">get_register</a>(<a id='5450' tid='5449', class="m">sp</a>));
- <span class="i">int32_t arg4 = stack_pointer[0];</span>
- <span class="i">int32_t arg5 = stack_pointer[1];</span>
- <a id='5364' tid='5363', class="m">bool</a> <a id='5366' tid='5365', class="m">fp_call</a> =
- (<a id='5368' tid='5367', class="m">redirection</a>-><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>
- (<a id='5382' tid='5381', class="m">redirection</a>-><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>
- (<a id='5396' tid='5395', class="m">redirection</a>-><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>
- (<a id='5410' tid='5409', class="m">redirection</a>-><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>);
- <span class="i">if (use_eabi_hardfloat()) {
- // With the hard floating point calling convention, double
- // arguments are passed in VFP registers. Fetch the arguments
- // from there and call the builtin using soft floating point
- // convention.
- switch (redirection->type()) {
- case ExternalReference::BUILTIN_FP_FP_CALL:
- case ExternalReference::BUILTIN_COMPARE_CALL:
- arg0 = vfp_register[0];
- arg1 = vfp_register[1];
- arg2 = vfp_register[2];
- arg3 = vfp_register[3];
- break;
- case ExternalReference::BUILTIN_FP_CALL:
- arg0 = vfp_register[0];
- arg1 = vfp_register[1];
- break;
- case ExternalReference::BUILTIN_FP_INT_CALL:
- arg0 = vfp_register[0];
- arg1 = vfp_register[1];
- arg2 = get_register(0);
- break;
- default:
- break;
- }
- }</span>
- // This is dodgy but it works because the C entry stubs are never moved.
- // See comment in codegen-arm.cc and bug 1242173.
- <span class="i">int32_t saved_lr = get_register(lr);</span>
- <a id='5328' tid='5327', class="m">intptr_t</a> <a id='5330' tid='5329', class="m">external</a> =
- <a id='5332' tid='5331', class="m">reinterpret_cast</a><<a id='5334' tid='5333', class="m">intptr_t</a>>(<a id='5336' tid='5335', class="m">redirection</a>-><a id='5338' tid='5337', class="m">external_function</a>());
- <a id='5228' tid='5227', class="m">if</a> (<a id='5230' tid='5229', class="m">fp_call</a>) {
- <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>) {
- <a id='5232' tid='5231', class="m">SimulatorRuntimeFPCall</a> <a id='5234' tid='5233', class="m">target</a> =
- <a id='5236' tid='5235', class="m">reinterpret_cast</a><<a id='5238' tid='5237', class="m">SimulatorRuntimeFPCall</a>>(<a id='5240' tid='5239', class="m">external</a>);
- <span class="i">double dval0, dval1;</span>
- <span class="i">int32_t ival;</span>
- <a id='5016' tid='5015', class="m">switch</a> (<a id='5018' tid='5017', class="m">redirection</a>-><a id='5020' tid='5019', class="m">type</a>()) {
- <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>:
- <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>:
- <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>);
- <a id='5048' tid='5047', class="m">PrintF</a>(<a id='5050' tid='5049', class="m">"Call to host function at %p with args %f, %f"</a>,
- <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>);
- <a id='5060' tid='5059', class="m">break</a>;
- <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>:
- <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>);
- <a id='5076' tid='5075', class="m">PrintF</a>(<a id='5078' tid='5077', class="m">"Call to host function at %p with arg %f"</a>,
- <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>);
- <a id='5086' tid='5085', class="m">break</a>;
- <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>:
- <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>);
- <a id='5106' tid='5105', class="m">PrintF</a>(<a id='5108' tid='5107', class="m">"Call to host function at %p with args %f, %d"</a>,
- <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>);
- <a id='5118' tid='5117', class="m">break</a>;
- <a id='5120' tid='5119', class="m">default</a>:
- <a id='5122' tid='5121', class="m">UNREACHABLE</a>();
- <a id='5124' tid='5123', class="m">break</a>;
- }
- <span class="i">if (!stack_aligned) {
- PrintF(" with unaligned stack %08x\n", get_register(sp));
- }</span>
- <span class="i">PrintF("\n");</span>
- }
- <span class="i">CHECK(stack_aligned);</span>
- <span class="i">if</span> (<a id='4874' tid='4873', class="m">redirection</a>-><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>) {
- <span class="i">SimulatorRuntimeFPCall target =
- reinterpret_cast<SimulatorRuntimeFPCall>(external);</span>
- <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>);
- <span class="i">SetFpResult(result);</span>
- } <span class="i">else</span> {
- <span class="i">SimulatorRuntimeCall target =
- reinterpret_cast<SimulatorRuntimeCall>(external);</span>
- <span class="i">int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);</span>
- <span class="i">int32_t lo_res = static_cast<int32_t>(result);</span>
- <span class="i">int32_t hi_res = static_cast<int32_t>(result >> 32);</span>
- <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">{
- PrintF("Returned %08x\n", lo_res);
- }</span>
- <span class="i">set_register(r0, lo_res);</span>
- <span class="i">set_register(r1, hi_res);</span>
- }
- } <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>-><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>) {
- <a id='5258' tid='5257', class="m">SimulatorRuntimeDirectApiCall</a> <a id='5260' tid='5259', class="m">target</a> =
- <a id='5262' tid='5261', class="m">reinterpret_cast</a><<a id='5264' tid='5263', class="m">SimulatorRuntimeDirectApiCall</a>>(<a id='5266' tid='5265', class="m">external</a>);
- <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">{
- PrintF("Call to host function at %p args %08x",
- FUNCTION_ADDR(target), arg0);
- if (!stack_aligned) {
- PrintF(" with unaligned stack %08x\n", get_register(sp));
- }
- PrintF("\n");
- }</span>
- <span class="i">CHECK(stack_aligned);</span>
- <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><<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>> <span class="i">result = target(arg0)</span>;
- <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">{
- PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
- }</span>
- <span class="i">set_register(r0, (int32_t) *result);</span>
- } <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>-><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>) {
- <a id='5284' tid='5283', class="m">SimulatorRuntimeDirectGetterCall</a> <a id='5286' tid='5285', class="m">target</a> =
- <a id='5288' tid='5287', class="m">reinterpret_cast</a><<a id='5290' tid='5289', class="m">SimulatorRuntimeDirectGetterCall</a>>(<a id='5292' tid='5291', class="m">external</a>);
- <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">{
- PrintF("Call to host function at %p args %08x %08x",
- FUNCTION_ADDR(target), arg0, arg1);
- if (!stack_aligned) {
- PrintF(" with unaligned stack %08x\n", get_register(sp));
- }
- PrintF("\n");
- }</span>
- <span class="i">CHECK(stack_aligned);</span>
- <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><<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>> <span class="i">result = target(arg0, arg1)</span>;
- <span class="i">if (::v8::internal::FLAG_trace_sim) {
- PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
- }</span>
- <span class="i">set_register(r0, (int32_t) *result);</span>
- } <a id='5294' tid='5293', class="m">else</a> {
- // builtin call.
- <span class="i">ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);</span>
- <a id='5296' tid='5295', class="m">SimulatorRuntimeCall</a> <a id='5298' tid='5297', class="m">target</a> =
- <a id='5300' tid='5299', class="m">reinterpret_cast</a><<a id='5302' tid='5301', class="m">SimulatorRuntimeCall</a>>(<a id='5304' tid='5303', class="m">external</a>);
- <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">{
- PrintF(
- "Call to host function at %p"
- "args %08x, %08x, %08x, %08x, %08x, %08x",
- FUNCTION_ADDR(target),
- arg0,
- arg1,
- arg2,
- arg3,
- arg4,
- arg5);
- if (!stack_aligned) {
- PrintF(" with unaligned stack %08x\n", get_register(sp));
- }
- PrintF("\n");
- }</span>
- <span class="i">CHECK(stack_aligned);</span>
- <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>);
- <span class="i">int32_t lo_res = static_cast<int32_t>(result);</span>
- <span class="i">int32_t</span> <span class="i">hi_res</span> = <a id='4644' tid='4643', class="m">static_cast</a><<a id='4646' tid='4645', class="m">int32_t</a>>(<a id='4648' tid='4647', class="m">result</a> <a id='4650' tid='4649', class="m">>></a> <a id='4652' tid='4651', class="m">32</a>);
- <span class="i">if (::v8::internal::FLAG_trace_sim) {
- PrintF("Returned %08x\n", lo_res);
- }</span>
- <span class="i">set_register(r0, lo_res);</span>
- <span class="i">set_register(r1, hi_res);</span>
- }
- <span class="i">set_register(lr, saved_lr);</span>
- <span class="i">set_pc(get_register(lr));</span>
- <span class="i">break;</span>
- }
- <span class="i">case</span> <span class="i">kBreakpoint</span>: <span class="i">{
- ArmDebugger dbg(this);
- dbg.Debug();
- break;
- }</span>
- // stop uses all codes greater than 1 << 23.
- <span class="i">default</span>: {
- <span class="i">if</span> <span class="i">(svc >= (1 << 23))</span> {
- <span class="i">uint32_t code = svc & kStopCodeMask;</span>
- <span class="i">if (isWatchedStop(code)) {
- IncreaseStopCounter(code);
- }</span>
- // Stop if it is enabled, otherwise go on jumping over the stop
- // and the message address.
- <span class="i">if</span> <span class="i">(isEnabledStop(code))</span> <span class="i">{
- ArmDebugger dbg(this);
- dbg.Stop(instr);
- }</span> <span class="i">else</span> {
- <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>);
- }
- } <span class="i">else {
- // This is not a valid svc code.
- UNREACHABLE();
- break;
- }</span>
- }
- }
- }
- // Stop helper functions.
- <span class="i">bool Simulator::isStopInstruction(Instruction* instr) {
- return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
- }</span>
- <span class="i">bool Simulator::isWatchedStop(uint32_t code) {
- ASSERT(code <= kMaxStopCode);
- return code < kNumOfWatchedStops;
- }</span>
- <span class="i">bool</span> <span class="i">Simulator::isEnabledStop</span><span class="i">(uint32_t code)</span> {
- <span class="i">ASSERT(code <= kMaxStopCode);</span>
- // Unwatched stops are always enabled.
- <a id='5422' tid='5421', class="m">return</a> <span class="i">!isWatchedStop(code)</span> <span class="i">||</span>
- <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>);
- }
- <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>) {
- <span class="i">ASSERT(isWatchedStop(code));</span>
- <span class="i">if</span> <span class="i">(!isEnabledStop(code))</span> {
- <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>;
- }
- }
- <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>) {
- <span class="i">ASSERT(isWatchedStop(code));</span>
- <span class="i">if</span> <span class="i">(isEnabledStop(code))</span> {
- <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>;
- }
- }
- <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>) {
- <span class="i">ASSERT(code <= kMaxStopCode);</span>
- <span class="i">ASSERT(isWatchedStop(code));</span>
- <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"><<</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>) {
- <a id='5196' tid='5195', class="m">PrintF</a>(<a id='5198' tid='5197', class="m">"Stop counter for code %i has overflowed.\n"</a>
- <a id='5200' tid='5199', class="m">"Enabling this code and reseting the counter to 0.\n"</a>, <a id='5202' tid='5201', class="m">code</a>);
- <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>;
- <a id='5214' tid='5213', class="m">EnableStop</a>(<a id='5216' tid='5215', class="m">code</a>);
- } <a id='5218' tid='5217', class="m">else</a> {
- <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>;
- }
- }
- // Print a stop status.
- <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>) {
- <span class="i">ASSERT(code <= kMaxStopCode);</span>
- <span class="i">if</span> <span class="i">(!isWatchedStop(code))</span> <span class="i">{
- PrintF("Stop not watched.");
- }</span> <span class="i">else</span> {
- <span class="i">const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";</span>
- <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>;
- // Don't print the state of unused breakpoints.
- <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>) {
- <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>) {
- <a id='4944' tid='4943', class="m">PrintF</a>(<a id='4946' tid='4945', class="m">"stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n"</a>,
- <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>);
- } <a id='4962' tid='4961', class="m">else</a> {
- <a id='4964' tid='4963', class="m">PrintF</a>(<a id='4966' tid='4965', class="m">"stop %i - 0x%x: \t%s, \tcounter = %i\n"</a>,
- <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>);
- }
- }
- }
- }
- // Handle execution based on instruction types.
- // Instruction types 0 and 1 are both rolled into one function because they
- // only differ in the handling of the shifter_operand.
- <span class="i">void Simulator::DecodeType01(Instruction* instr) {
- int type = instr->TypeValue();
- if ((type == 0) && instr->IsSpecialType0()) {
- // multiply instruction or extra loads and stores
- if (instr->Bits(7, 4) == 9) {
- if (instr->Bit(24) == 0) {
- // Raw field decoding here. Multiply instructions have their Rd in
- // funny places.
- int rn = instr->RnValue();
- int rm = instr->RmValue();
- int rs = instr->RsValue();
- int32_t rs_val = get_register(rs);
- int32_t rm_val = get_register(rm);
- if (instr->Bit(23) == 0) {
- if (instr->Bit(21) == 0) {
- // The MUL instruction description (A 4.1.33) refers to Rd as being
- // the destination for the operation, but it confusingly uses the
- // Rn field to encode it.
- // Format(instr, "mul'cond's 'rn, 'rm, 'rs");
- int rd = rn; // Remap the rn field to the Rd register.
- int32_t alu_out = rm_val * rs_val;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- }
- } else {
- // The MLA instruction description (A 4.1.28) refers to the order
- // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
- // Rn field to encode the Rd register and the Rd field to encode
- // the Rn register.
- Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
- }
- } else {
- // The signed/long multiply instructions use the terms RdHi and RdLo
- // when referring to the target registers. They are mapped to the Rn
- // and Rd fields as follows:
- // RdLo == Rd
- // RdHi == Rn (This is confusingly stored in variable rd here
- // because the mul instruction from above uses the
- // Rn field to encode the Rd register. Good luck figuring
- // this out without reading the ARM instruction manual
- // at a very detailed level.)
- // Format(instr, "'um'al'cond's 'rd, 'rn, 'rs, 'rm");
- int rd_hi = rn; // Remap the rn field to the RdHi register.
- int rd_lo = instr->RdValue();
- int32_t hi_res = 0;
- int32_t lo_res = 0;
- if (instr->Bit(22) == 1) {
- int64_t left_op = static_cast<int32_t>(rm_val);
- int64_t right_op = static_cast<int32_t>(rs_val);
- uint64_t result = left_op * right_op;
- hi_res = static_cast<int32_t>(result >> 32);
- lo_res = static_cast<int32_t>(result & 0xffffffff);
- } else {
- // unsigned multiply
- uint64_t left_op = static_cast<uint32_t>(rm_val);
- uint64_t right_op = static_cast<uint32_t>(rs_val);
- uint64_t result = left_op * right_op;
- hi_res = static_cast<int32_t>(result >> 32);
- lo_res = static_cast<int32_t>(result & 0xffffffff);
- }
- set_register(rd_lo, lo_res);
- set_register(rd_hi, hi_res);
- if (instr->HasS()) {
- UNIMPLEMENTED();
- }
- }
- } else {
- UNIMPLEMENTED(); // Not used by V8.
- }
- } else {
- // extra load/store instructions
- int rd = instr->RdValue();
- int rn = instr->RnValue();
- int32_t rn_val = get_register(rn);
- int32_t addr = 0;
- if (instr->Bit(22) == 0) {
- int rm = instr->RmValue();
- int32_t rm_val = get_register(rm);
- switch (instr->PUField()) {
- case da_x: {
- // Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
- ASSERT(!instr->HasW());
- addr = rn_val;
- rn_val -= rm_val;
- set_register(rn, rn_val);
- break;
- }
- case ia_x: {
- // Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
- ASSERT(!instr->HasW());
- addr = rn_val;
- rn_val += rm_val;
- set_register(rn, rn_val);
- break;
- }
- case db_x: {
- // Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
- rn_val -= rm_val;
- addr = rn_val;
- if (instr->HasW()) {
- set_register(rn, rn_val);
- }
- break;
- }
- case ib_x: {
- // Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
- rn_val += rm_val;
- addr = rn_val;
- if (instr->HasW()) {
- set_register(rn, rn_val);
- }
- break;
- }
- default: {
- // The PU field is a 2-bit field.
- UNREACHABLE();
- break;
- }
- }
- } else {
- int32_t imm_val = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
- switch (instr->PUField()) {
- case da_x: {
- // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
- ASSERT(!instr->HasW());
- addr = rn_val;
- rn_val -= imm_val;
- set_register(rn, rn_val);
- break;
- }
- case ia_x: {
- // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
- ASSERT(!instr->HasW());
- addr = rn_val;
- rn_val += imm_val;
- set_register(rn, rn_val);
- break;
- }
- case db_x: {
- // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
- rn_val -= imm_val;
- addr = rn_val;
- if (instr->HasW()) {
- set_register(rn, rn_val);
- }
- break;
- }
- case ib_x: {
- // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
- rn_val += imm_val;
- addr = rn_val;
- if (instr->HasW()) {
- set_register(rn, rn_val);
- }
- break;
- }
- default: {
- // The PU field is a 2-bit field.
- UNREACHABLE();
- break;
- }
- }
- }
- if (((instr->Bits(7, 4) & 0xd) == 0xd) && (instr->Bit(20) == 0)) {
- ASSERT((rd % 2) == 0);
- if (instr->HasH()) {
- // The strd instruction.
- int32_t value1 = get_register(rd);
- int32_t value2 = get_register(rd+1);
- WriteDW(addr, value1, value2);
- } else {
- // The ldrd instruction.
- int* rn_data = ReadDW(addr);
- set_dw_register(rd, rn_data);
- }
- } else if (instr->HasH()) {
- if (instr->HasSign()) {
- if (instr->HasL()) {
- int16_t val = ReadH(addr, instr);
- set_register(rd, val);
- } else {
- int16_t val = get_register(rd);
- WriteH(addr, val, instr);
- }
- } else {
- if (instr->HasL()) {
- uint16_t val = ReadHU(addr, instr);
- set_register(rd, val);
- } else {
- uint16_t val = get_register(rd);
- WriteH(addr, val, instr);
- }
- }
- } else {
- // signed byte loads
- ASSERT(instr->HasSign());
- ASSERT(instr->HasL());
- int8_t val = ReadB(addr);
- set_register(rd, val);
- }
- return;
- }
- } else if ((type == 0) && instr->IsMiscType0()) {
- if (instr->Bits(22, 21) == 1) {
- int rm = instr->RmValue();
- switch (instr->BitField(7, 4)) {
- case BX:
- set_pc(get_register(rm));
- break;
- case BLX: {
- uint32_t old_pc = get_pc();
- set_pc(get_register(rm));
- set_register(lr, old_pc + Instruction::kInstrSize);
- break;
- }
- case BKPT: {
- ArmDebugger dbg(this);
- PrintF("Simulator hit BKPT.\n");
- dbg.Debug();
- break;
- }
- default:
- UNIMPLEMENTED();
- }
- } else if (instr->Bits(22, 21) == 3) {
- int rm = instr->RmValue();
- int rd = instr->RdValue();
- switch (instr->BitField(7, 4)) {
- case CLZ: {
- uint32_t bits = get_register(rm);
- int leading_zeros = 0;
- if (bits == 0) {
- leading_zeros = 32;
- } else {
- while ((bits & 0x80000000u) == 0) {
- bits <<= 1;
- leading_zeros++;
- }
- }
- set_register(rd, leading_zeros);
- break;
- }
- default:
- UNIMPLEMENTED();
- }
- } else {
- PrintF("%08x\n", instr->InstructionBits());
- UNIMPLEMENTED();
- }
- } else {
- int rd = instr->RdValue();
- int rn = instr->RnValue();
- int32_t rn_val = get_register(rn);
- int32_t shifter_operand = 0;
- bool shifter_carry_out = 0;
- if (type == 0) {
- shifter_operand = GetShiftRm(instr, &shifter_carry_out);
- } else {
- ASSERT(instr->TypeValue() == 1);
- shifter_operand = GetImm(instr, &shifter_carry_out);
- }
- int32_t alu_out;
- switch (instr->OpcodeField()) {
- case AND: {
- // Format(instr, "and'cond's 'rd, 'rn, 'shift_rm");
- // Format(instr, "and'cond's 'rd, 'rn, 'imm");
- alu_out = rn_val & shifter_operand;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(shifter_carry_out);
- }
- break;
- }
- case EOR: {
- // Format(instr, "eor'cond's 'rd, 'rn, 'shift_rm");
- // Format(instr, "eor'cond's 'rd, 'rn, 'imm");
- alu_out = rn_val ^ shifter_operand;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(shifter_carry_out);
- }
- break;
- }
- case SUB: {
- // Format(instr, "sub'cond's 'rd, 'rn, 'shift_rm");
- // Format(instr, "sub'cond's 'rd, 'rn, 'imm");
- alu_out = rn_val - shifter_operand;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(!BorrowFrom(rn_val, shifter_operand));
- SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
- }
- break;
- }
- case RSB: {
- // Format(instr, "rsb'cond's 'rd, 'rn, 'shift_rm");
- // Format(instr, "rsb'cond's 'rd, 'rn, 'imm");
- alu_out = shifter_operand - rn_val;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(!BorrowFrom(shifter_operand, rn_val));
- SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));
- }
- break;
- }
- case ADD: {
- // Format(instr, "add'cond's 'rd, 'rn, 'shift_rm");
- // Format(instr, "add'cond's 'rd, 'rn, 'imm");
- alu_out = rn_val + shifter_operand;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(CarryFrom(rn_val, shifter_operand));
- SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
- }
- break;
- }
- case ADC: {
- // Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm");
- // Format(instr, "adc'cond's 'rd, 'rn, 'imm");
- alu_out = rn_val + shifter_operand + GetCarry();
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(CarryFrom(rn_val, shifter_operand, GetCarry()));
- SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
- }
- break;
- }
- case SBC: {
- Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm");
- Format(instr, "sbc'cond's 'rd, 'rn, 'imm");
- break;
- }
- case RSC: {
- Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm");
- Format(instr, "rsc'cond's 'rd, 'rn, 'imm");
- break;
- }
- case TST: {
- if (instr->HasS()) {
- // Format(instr, "tst'cond 'rn, 'shift_rm");
- // Format(instr, "tst'cond 'rn, 'imm");
- alu_out = rn_val & shifter_operand;
- SetNZFlags(alu_out);
- SetCFlag(shifter_carry_out);
- } else {
- // Format(instr, "movw'cond 'rd, 'imm").
- alu_out = instr->ImmedMovwMovtValue();
- set_register(rd, alu_out);
- }
- break;
- }
- case TEQ: {
- if (instr->HasS()) {
- // Format(instr, "teq'cond 'rn, 'shift_rm");
- // Format(instr, "teq'cond 'rn, 'imm");
- alu_out = rn_val ^ shifter_operand;
- SetNZFlags(alu_out);
- SetCFlag(shifter_carry_out);
- } else {
- // Other instructions matching this pattern are handled in the
- // miscellaneous instructions part above.
- UNREACHABLE();
- }
- break;
- }
- case CMP: {
- if (instr->HasS()) {
- // Format(instr, "cmp'cond 'rn, 'shift_rm");
- // Format(instr, "cmp'cond 'rn, 'imm");
- alu_out = rn_val - shifter_operand;
- SetNZFlags(alu_out);
- SetCFlag(!BorrowFrom(rn_val, shifter_operand));
- SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
- } else {
- // Format(instr, "movt'cond 'rd, 'imm").
- alu_out = (get_register(rd) & 0xffff) |
- (instr->ImmedMovwMovtValue() << 16);
- set_register(rd, alu_out);
- }
- break;
- }
- case CMN: {
- if (instr->HasS()) {
- // Format(instr, "cmn'cond 'rn, 'shift_rm");
- // Format(instr, "cmn'cond 'rn, 'imm");
- alu_out = rn_val + shifter_operand;
- SetNZFlags(alu_out);
- SetCFlag(!CarryFrom(rn_val, shifter_operand));
- SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
- } else {
- // Other instructions matching this pattern are handled in the
- // miscellaneous instructions part above.
- UNREACHABLE();
- }
- break;
- }
- case ORR: {
- // Format(instr, "orr'cond's 'rd, 'rn, 'shift_rm");
- // Format(instr, "orr'cond's 'rd, 'rn, 'imm");
- alu_out = rn_val | shifter_operand;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(shifter_carry_out);
- }
- break;
- }
- case MOV: {
- // Format(instr, "mov'cond's 'rd, 'shift_rm");
- // Format(instr, "mov'cond's 'rd, 'imm");
- alu_out = shifter_operand;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(shifter_carry_out);
- }
- break;
- }
- case BIC: {
- // Format(instr, "bic'cond's 'rd, 'rn, 'shift_rm");
- // Format(instr, "bic'cond's 'rd, 'rn, 'imm");
- alu_out = rn_val & ~shifter_operand;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(shifter_carry_out);
- }
- break;
- }
- case MVN: {
- // Format(instr, "mvn'cond's 'rd, 'shift_rm");
- // Format(instr, "mvn'cond's 'rd, 'imm");
- alu_out = ~shifter_operand;
- set_register(rd, alu_out);
- if (instr->HasS()) {
- SetNZFlags(alu_out);
- SetCFlag(shifter_carry_out);
- }
- break;
- }
- default: {
- UNREACHABLE();
- break;
- }
- }
- }
- }</span>
- <span class="i">void Simulator::DecodeType2(Instruction* instr) {
- int rd = instr->RdValue();
- int rn = instr->RnValue();
- int32_t rn_val = get_register(rn);
- int32_t im_val = instr->Offset12Value();
- int32_t addr = 0;
- switch (instr->PUField()) {
- case da_x: {
- // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
- ASSERT(!instr->HasW());
- addr = rn_val;
- rn_val -= im_val;
- set_register(rn, rn_val);
- break;
- }
- case ia_x: {
- // Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
- ASSERT(!instr->HasW());
- addr = rn_val;
- rn_val += im_val;
- set_register(rn, rn_val);
- break;
- }
- case db_x: {
- // Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
- rn_val -= im_val;
- addr = rn_val;
- if (instr->HasW()) {
- set_register(rn, rn_val);
- }
- break;
- }
- case ib_x: {
- // Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
- rn_val += im_val;
- addr = rn_val;
- if (instr->HasW()) {
- set_register(rn, rn_val);
- }
- break;
- }
- default: {
- UNREACHABLE();
- break;
- }
- }
- if (instr->HasB()) {
- if (instr->HasL()) {
- byte val = ReadBU(addr);
- set_register(rd, val);
- } else {
- byte val = get_register(rd);
- WriteB(addr, val);
- }
- } else {
- if (instr->HasL()) {
- set_register(rd, ReadW(addr, instr));
- } else {
- WriteW(addr, get_register(rd), instr);
- }
- }
- }</span>
- <span class="i">void Simulator::DecodeType3(Instruction* instr) {
- int rd = instr->RdValue();
- int rn = instr->RnValue();
- int32_t rn_val = get_register(rn);
- bool shifter_carry_out = 0;
- int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
- int32_t addr = 0;
- switch (instr->PUField()) {
- case da_x: {
- ASSERT(!instr->HasW());
- Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
- UNIMPLEMENTED();
- break;
- }
- case ia_x: {
- if (instr->HasW()) {
- ASSERT(instr->Bits(5, 4) == 0x1);
- if (instr->Bit(22) == 0x1) { // USAT.
- int32_t sat_pos = instr->Bits(20, 16);
- int32_t sat_val = (1 << sat_pos) - 1;
- int32_t shift = instr->Bits(11, 7);
- int32_t shift_type = instr->Bit(6);
- int32_t rm_val = get_register(instr->RmValue());
- if (shift_type == 0) { // LSL
- rm_val <<= shift;
- } else { // ASR
- rm_val >>= shift;
- }
- // If saturation occurs, the Q flag should be set in the CPSR.
- // There is no Q flag yet, and no instruction (MRS) to read the
- // CPSR directly.
- if (rm_val > sat_val) {
- rm_val = sat_val;
- } else if (rm_val < 0) {
- rm_val = 0;
- }
- set_register(rd, rm_val);
- } else { // SSAT.
- UNIMPLEMENTED();
- }
- return;
- } else {
- Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
- UNIMPLEMENTED();
- }
- break;
- }
- case db_x: {
- // Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
- addr = rn_val - shifter_operand;
- if (instr->HasW()) {
- set_register(rn, addr);
- }
- break;
- }
- case ib_x: {
- if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
- uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
- uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
- uint32_t msbit = widthminus1 + lsbit;
- if (msbit <= 31) {
- if (instr->Bit(22)) {
- // ubfx - unsigned bitfield extract.
- uint32_t rm_val =
- static_cast<uint32_t>(get_register(instr->RmValue()));
- uint32_t extr_val = rm_val << (31 - msbit);
- extr_val = extr_val >> (31 - widthminus1);
- set_register(instr->RdValue(), extr_val);
- } else {
- // sbfx - signed bitfield extract.
- int32_t rm_val = get_register(instr->RmValue());
- int32_t extr_val = rm_val << (31 - msbit);
- extr_val = extr_val >> (31 - widthminus1);
- set_register(instr->RdValue(), extr_val);
- }
- } else {
- UNREACHABLE();
- }
- return;
- } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) {
- uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
- uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16));
- if (msbit >= lsbit) {
- // bfc or bfi - bitfield clear/insert.
- uint32_t rd_val =
- static_cast<uint32_t>(get_register(instr->RdValue()));
- uint32_t bitcount = msbit - lsbit + 1;
- uint32_t mask = (1 << bitcount) - 1;
- rd_val &= ~(mask << lsbit);
- if (instr->RmValue() != 15) {
- // bfi - bitfield insert.
- uint32_t rm_val =
- static_cast<uint32_t>(get_register(instr->RmValue()));
- rm_val &= mask;
- rd_val |= rm_val << lsbit;
- }
- set_register(instr->RdValue(), rd_val);
- } else {
- UNREACHABLE();
- }
- return;
- } else {
- // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
- addr = rn_val + shifter_operand;
- if (instr->HasW()) {
- set_register(rn, addr);
- }
- }
- break;
- }
- default: {
- UNREACHABLE();
- break;
- }
- }
- if (instr->HasB()) {
- if (instr->HasL()) {
- uint8_t byte = ReadB(addr);
- set_register(rd, byte);
- } else {
- uint8_t byte = get_register(rd);
- WriteB(addr, byte);
- }
- } else {
- if (instr->HasL()) {
- set_register(rd, ReadW(addr, instr));
- } else {
- WriteW(addr, get_register(rd), instr);
- }
- }
- }</span>
- <span class="i">void Simulator::DecodeType4(Instruction* instr) {
- ASSERT(instr->Bit(22) == 0); // only allowed to be set in privileged mode
- if (instr->HasL()) {
- // Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
- HandleRList(instr, true);
- } else {
- // Format(instr, "stm'cond'pu 'rn'w, 'rlist");
- HandleRList(instr, false);
- }
- }</span>
- <span class="i">void Simulator::DecodeType5(Instruction* instr) {
- // Format(instr, "b'l'cond 'target");
- int off = (instr->SImmed24Value() << 2);
- intptr_t pc_address = get_pc();
- if (instr->HasLink()) {
- set_register(lr, pc_address + Instruction::kInstrSize);
- }
- int pc_reg = get_register(pc);
- set_pc(pc_reg + off);
- }</span>
- <span class="i">void Simulator::DecodeType6(Instruction* instr) {
- DecodeType6CoprocessorIns(instr);
- }</span>
- <span class="i">void Simulator::DecodeType7(Instruction* instr) {
- if (instr->Bit(24) == 1) {
- SoftwareInterrupt(instr);
- } else {
- DecodeTypeVFP(instr);
- }
- }</span>
- // void Simulator::DecodeTypeVFP(Instruction* instr)
- // The Following ARMv7 VFPv instructions are currently supported.
- // vmov :Sn = Rt
- // vmov :Rt = Sn
- // vcvt: Dd = Sm
- // vcvt: Sd = Dm
- // Dd = vabs(Dm)
- // Dd = vneg(Dm)
- // Dd = vadd(Dn, Dm)
- // Dd = vsub(Dn, Dm)
- // Dd = vmul(Dn, Dm)
- // Dd = vdiv(Dn, Dm)
- // vcmp(Dd, Dm)
- // vmrs
- // Dd = vsqrt(Dm)
- <span class="i">void Simulator::DecodeTypeVFP(Instruction* instr) {
- ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
- ASSERT(instr->Bits(11, 9) == 0x5);
- // Obtain double precision register codes.
- int vm = instr->VFPMRegValue(kDoublePrecision);
- int vd = instr->VFPDRegValue(kDoublePrecision);
- int vn = instr->VFPNRegValue(kDoublePrecision);
- if (instr->Bit(4) == 0) {
- if (instr->Opc1Value() == 0x7) {
- // Other data processing instructions
- if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
- // vmov register to register.
- if (instr->SzValue() == 0x1) {
- int m = instr->VFPMRegValue(kDoublePrecision);
- int d = instr->VFPDRegValue(kDoublePrecision);
- set_d_register_from_double(d, get_double_from_d_register(m));
- } else {
- int m = instr->VFPMRegValue(kSinglePrecision);
- int d = instr->VFPDRegValue(kSinglePrecision);
- set_s_register_from_float(d, get_float_from_s_register(m));
- }
- } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
- // vabs
- double dm_value = get_double_from_d_register(vm);
- double dd_value = fabs(dm_value);
- set_d_register_from_double(vd, dd_value);
- } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
- // vneg
- double dm_value = get_double_from_d_register(vm);
- double dd_value = -dm_value;
- set_d_register_from_double(vd, dd_value);
- } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
- DecodeVCVTBetweenDoubleAndSingle(instr);
- } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
- DecodeVCVTBetweenFloatingPointAndInteger(instr);
- } else if (((instr->Opc2Value() >> 1) == 0x6) &&
- (instr->Opc3Value() & 0x1)) {
- DecodeVCVTBetweenFloatingPointAndInteger(instr);
- } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
- (instr->Opc3Value() & 0x1)) {
- DecodeVCMP(instr);
- } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
- // vsqrt
- double dm_value = get_double_from_d_register(vm);
- double dd_value = sqrt(dm_value);
- set_d_register_from_double(vd, dd_value);
- } else if (instr->Opc3Value() == 0x0) {
- // vmov immediate.
- if (instr->SzValue() == 0x1) {
- set_d_register_from_double(vd, instr->DoubleImmedVmov());
- } else {
- UNREACHABLE(); // Not used by v8.
- }
- } else {
- UNREACHABLE(); // Not used by V8.
- }
- } else if (instr->Opc1Value() == 0x3) {
- if (instr->SzValue() != 0x1) {
- UNREACHABLE(); // Not used by V8.
- }
- if (instr->Opc3Value() & 0x1) {
- // vsub
- double dn_value = get_double_from_d_register(vn);
- double dm_value = get_double_from_d_register(vm);
- double dd_value = dn_value - dm_value;
- set_d_register_from_double(vd, dd_value);
- } else {
- // vadd
- double dn_value = get_double_from_d_register(vn);
- double dm_value = get_double_from_d_register(vm);
- double dd_value = dn_value + dm_value;
- set_d_register_from_double(vd, dd_value);
- }
- } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
- // vmul
- if (instr->SzValue() != 0x1) {
- UNREACHABLE(); // Not used by V8.
- }
- double dn_value = get_double_from_d_register(vn);
- double dm_value = get_double_from_d_register(vm);
- double dd_value = dn_value * dm_value;
- set_d_register_from_double(vd, dd_value);
- } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
- // vdiv
- if (instr->SzValue() != 0x1) {
- UNREACHABLE(); // Not used by V8.
- }
- double dn_value = get_double_from_d_register(vn);
- double dm_value = get_double_from_d_register(vm);
- double dd_value = dn_value / dm_value;
- div_zero_vfp_flag_ = (dm_value == 0);
- set_d_register_from_double(vd, dd_value);
- } else {
- UNIMPLEMENTED(); // Not used by V8.
- }
- } else {
- if ((instr->VCValue() == 0x0) &&
- (instr->VAValue() == 0x0)) {
- DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
- } else if ((instr->VLValue() == 0x1) &&
- (instr->VCValue() == 0x0) &&
- (instr->VAValue() == 0x7) &&
- (instr->Bits(19, 16) == 0x1)) {
- // vmrs
- uint32_t rt = instr->RtValue();
- if (rt == 0xF) {
- Copy_FPSCR_to_APSR();
- } else {
- // Emulate FPSCR from the Simulator flags.
- uint32_t fpscr = (n_flag_FPSCR_ << 31) |
- (z_flag_FPSCR_ << 30) |
- (c_flag_FPSCR_ << 29) |
- (v_flag_FPSCR_ << 28) |
- (inexact_vfp_flag_ << 4) |
- (underflow_vfp_flag_ << 3) |
- (overflow_vfp_flag_ << 2) |
- (div_zero_vfp_flag_ << 1) |
- (inv_op_vfp_flag_ << 0) |
- (FPSCR_rounding_mode_);
- set_register(rt, fpscr);
- }
- } else if ((instr->VLValue() == 0x0) &&
- (instr->VCValue() == 0x0) &&
- (instr->VAValue() == 0x7) &&
- (instr->Bits(19, 16) == 0x1)) {
- // vmsr
- uint32_t rt = instr->RtValue();
- if (rt == pc) {
- UNREACHABLE();
- } else {
- uint32_t rt_value = get_register(rt);
- n_flag_FPSCR_ = (rt_value >> 31) & 1;
- z_flag_FPSCR_ = (rt_value >> 30) & 1;
- c_flag_FPSCR_ = (rt_value >> 29) & 1;
- v_flag_FPSCR_ = (rt_value >> 28) & 1;
- inexact_vfp_flag_ = (rt_value >> 4) & 1;
- underflow_vfp_flag_ = (rt_value >> 3) & 1;
- overflow_vfp_flag_ = (rt_value >> 2) & 1;
- div_zero_vfp_flag_ = (rt_value >> 1) & 1;
- inv_op_vfp_flag_ = (rt_value >> 0) & 1;
- FPSCR_rounding_mode_ =
- static_cast<VFPRoundingMode>((rt_value) & kVFPRoundingModeMask);
- }
- } else {
- UNIMPLEMENTED(); // Not used by V8.
- }
- }
- }</span>
- <span class="i">void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
- Instruction* instr) {
- ASSERT((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
- (instr->VAValue() == 0x0));
- int t = instr->RtValue();
- int n = instr->VFPNRegValue(kSinglePrecision);
- bool to_arm_register = (instr->VLValue() == 0x1);
- if (to_arm_register) {
- int32_t int_value = get_sinteger_from_s_register(n);
- set_register(t, int_value);
- } else {
- int32_t rs_val = get_register(t);
- set_s_register_from_sinteger(n, rs_val);
- }
- }</span>
- <span class="i">void Simulator::DecodeVCMP(Instruction* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
- ASSERT(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
- (instr->Opc3Value() & 0x1));
- // Comparison.
- VFPRegPrecision precision = kSinglePrecision;
- if (instr->SzValue() == 1) {
- precision = kDoublePrecision;
- }
- int d = instr->VFPDRegValue(precision);
- int m = 0;
- if (instr->Opc2Value() == 0x4) {
- m = instr->VFPMRegValue(precision);
- }
- if (precision == kDoublePrecision) {
- double dd_value = get_double_from_d_register(d);
- double dm_value = 0.0;
- if (instr->Opc2Value() == 0x4) {
- dm_value = get_double_from_d_register(m);
- }
- // Raise exceptions for quiet NaNs if necessary.
- if (instr->Bit(7) == 1) {
- if (isnan(dd_value)) {
- inv_op_vfp_flag_ = true;
- }
- }
- Compute_FPSCR_Flags(dd_value, dm_value);
- } else {
- UNIMPLEMENTED(); // Not used by V8.
- }
- }</span>
- <span class="i">void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
- ASSERT((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
- VFPRegPrecision dst_precision = kDoublePrecision;
- VFPRegPrecision src_precision = kSinglePrecision;
- if (instr->SzValue() == 1) {
- dst_precision = kSinglePrecision;
- src_precision = kDoublePrecision;
- }
- int dst = instr->VFPDRegValue(dst_precision);
- int src = instr->VFPMRegValue(src_precision);
- if (dst_precision == kSinglePrecision) {
- double val = get_double_from_d_register(src);
- set_s_register_from_float(dst, static_cast<float>(val));
- } else {
- float val = get_float_from_s_register(src);
- set_d_register_from_double(dst, static_cast<double>(val));
- }
- }</span>
- <span class="i">bool get_inv_op_vfp_flag(VFPRoundingMode mode,
- double val,
- bool unsigned_) {
- ASSERT((mode == RN) || (mode == RM) || (mode == RZ));
- double max_uint = static_cast<double>(0xffffffffu);
- double max_int = static_cast<double>(kMaxInt);
- double min_int = static_cast<double>(kMinInt);
- // Check for NaN.
- if (val != val) {
- return true;
- }
- // Check for overflow. This code works because 32bit integers can be
- // exactly represented by ieee-754 64bit floating-point values.
- switch (mode) {
- case RN:
- return unsigned_ ? (val >= (max_uint + 0.5)) ||
- (val < -0.5)
- : (val >= (max_int + 0.5)) ||
- (val < (min_int - 0.5));
- case RM:
- return unsigned_ ? (val >= (max_uint + 1.0)) ||
- (val < 0)
- : (val >= (max_int + 1.0)) ||
- (val < min_int);
- case RZ:
- return unsigned_ ? (val >= (max_uint + 1.0)) ||
- (val <= -1)
- : (val >= (max_int + 1.0)) ||
- (val <= (min_int - 1.0));
- default:
- UNREACHABLE();
- return true;
- }
- }</span>
- // We call this function only if we had a vfp invalid exception.
- // It returns the correct saturated value.
- <span class="i">int VFPConversionSaturate(double val, bool unsigned_res) {
- if (val != val) {
- return 0;
- } else {
- if (unsigned_res) {
- return (val < 0) ? 0 : 0xffffffffu;
- } else {
- return (val < 0) ? kMinInt : kMaxInt;
- }
- }
- }</span>
- <span class="i">void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
- ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7) &&
- (instr->Bits(27, 23) == 0x1D));
- ASSERT(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
- (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
- // Conversion between floating-point and integer.
- bool to_integer = (instr->Bit(18) == 1);
- VFPRegPrecision src_precision = (instr->SzValue() == 1) ? kDoublePrecision
- : kSinglePrecision;
- if (to_integer) {
- // We are playing with code close to the C++ standard's limits below,
- // hence the very simple code and heavy checks.
- //
- // Note:
- // C++ defines default type casting from floating point to integer as
- // (close to) rounding toward zero ("fractional part discarded").
- int dst = instr->VFPDRegValue(kSinglePrecision);
- int src = instr->VFPMRegValue(src_precision);
- // Bit 7 in vcvt instructions indicates if we should use the FPSCR rounding
- // mode or the default Round to Zero mode.
- VFPRoundingMode mode = (instr->Bit(7) != 1) ? FPSCR_rounding_mode_
- : RZ;
- ASSERT((mode == RM) || (mode == RZ) || (mode == RN));
- bool unsigned_integer = (instr->Bit(16) == 0);
- bool double_precision = (src_precision == kDoublePrecision);
- double val = double_precision ? get_double_from_d_register(src)
- : get_float_from_s_register(src);
- int temp = unsigned_integer ? static_cast<uint32_t>(val)
- : static_cast<int32_t>(val);
- inv_op_vfp_flag_ = get_inv_op_vfp_flag(mode, val, unsigned_integer);
- double abs_diff =
- unsigned_integer ? fabs(val - static_cast<uint32_t>(temp))
- : fabs(val - temp);
- inexact_vfp_flag_ = (abs_diff != 0);
- if (inv_op_vfp_flag_) {
- temp = VFPConversionSaturate(val, unsigned_integer);
- } else {
- switch (mode) {
- case RN: {
- int val_sign = (val > 0) ? 1 : -1;
- if (abs_diff > 0.5) {
- temp += val_sign;
- } else if (abs_diff == 0.5) {
- // Round to even if exactly halfway.
- temp = ((temp % 2) == 0) ? temp : temp + val_sign;
- }
- break;
- }
- case RM:
- temp = temp > val ? temp - 1 : temp;
- break;
- case RZ:
- // Nothing to do.
- break;
- default:
- UNREACHABLE();
- }
- }
- // Update the destination register.
- set_s_register_from_sinteger(dst, temp);
- } else {
- bool unsigned_integer = (instr->Bit(7) == 0);
- int dst = instr->VFPDRegValue(src_precision);
- int src = instr->VFPMRegValue(kSinglePrecision);
- int val = get_sinteger_from_s_register(src);
- if (src_precision == kDoublePrecision) {
- if (unsigned_integer) {
- set_d_register_from_double(dst,
- static_cast<double>((uint32_t)val));
- } else {
- set_d_register_from_double(dst, static_cast<double>(val));
- }
- } else {
- if (unsigned_integer) {
- set_s_register_from_float(dst,
- static_cast<float>((uint32_t)val));
- } else {
- set_s_register_from_float(dst, static_cast<float>(val));
- }
- }
- }
- }</span>
- // void Simulator::DecodeType6CoprocessorIns(Instruction* instr)
- // Decode Type 6 coprocessor instructions.
- // Dm = vmov(Rt, Rt2)
- // <Rt, Rt2> = vmov(Dm)
- // Ddst = MEM(Rbase + 4*offset).
- // MEM(Rbase + 4*offset) = Dsrc.
- <span class="i">void Simulator::DecodeType6CoprocessorIns(Instruction* instr) {
- ASSERT((instr->TypeValue() == 6));
- if (instr->CoprocessorValue() == 0xA) {
- switch (instr->OpcodeValue()) {
- case 0x8:
- case 0xA:
- case 0xC:
- case 0xE: { // Load and store single precision float to memory.
- int rn = instr->RnValue();
- int vd = instr->VFPDRegValue(kSinglePrecision);
- int offset = instr->Immed8Value();
- if (!instr->HasU()) {
- offset = -offset;
- }
- int32_t address = get_register(rn) + 4 * offset;
- if (instr->HasL()) {
- // Load double from memory: vldr.
- set_s_register_from_sinteger(vd, ReadW(address, instr));
- } else {
- // Store double to memory: vstr.
- WriteW(address, get_sinteger_from_s_register(vd), instr);
- }
- break;
- }
- case 0x4:
- case 0x5:
- case 0x6:
- case 0x7:
- case 0x9:
- case 0xB:
- // Load/store multiple single from memory: vldm/vstm.
- HandleVList(instr);
- break;
- default:
- UNIMPLEMENTED(); // Not used by V8.
- }
- } else if (instr->CoprocessorValue() == 0xB) {
- switch (instr->OpcodeValue()) {
- case 0x2:
- // Load and store double to two GP registers
- if (instr->Bits(7, 4) != 0x1) {
- UNIMPLEMENTED(); // Not used by V8.
- } else {
- int rt = instr->RtValue();
- int rn = instr->RnValue();
- int vm = instr->VmValue();
- if (instr->HasL()) {
- int32_t rt_int_value = get_sinteger_from_s_register(2*vm);
- int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1);
- set_register(rt, rt_int_value);
- set_register(rn, rn_int_value);
- } else {
- int32_t rs_val = get_register(rt);
- int32_t rn_val = get_register(rn);
- set_s_register_from_sinteger(2*vm, rs_val);
- set_s_register_from_sinteger((2*vm+1), rn_val);
- }
- }
- break;
- case 0x8:
- case 0xC: { // Load and store double to memory.
- int rn = instr->RnValue();
- int vd = instr->VdValue();
- int offset = instr->Immed8Value();
- if (!instr->HasU()) {
- offset = -offset;
- }
- int32_t address = get_register(rn) + 4 * offset;
- if (instr->HasL()) {
- // Load double from memory: vldr.
- set_s_register_from_sinteger(2*vd, ReadW(address, instr));
- set_s_register_from_sinteger(2*vd + 1, ReadW(address + 4, instr));
- } else {
- // Store double to memory: vstr.
- WriteW(address, get_sinteger_from_s_register(2*vd), instr);
- WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr);
- }
- break;
- }
- case 0x4:
- case 0x5:
- case 0x9:
- // Load/store multiple double from memory: vldm/vstm.
- HandleVList(instr);
- break;
- default:
- UNIMPLEMENTED(); // Not used by V8.
- }
- } else {
- UNIMPLEMENTED(); // Not used by V8.
- }
- }</span>
- // Executes the current instruction.
- <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>) {
- <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>) {
- <a id='4438' tid='4437', class="m">CheckICache</a>(<a id='4440' tid='4439', class="m">isolate_</a>-><a id='4442' tid='4441', class="m">simulator_i_cache</a>(), <a id='4444' tid='4443', class="m">instr</a>);
- }
- <span class="i">pc_modified_ = false;</span>
- <span class="i">if</span> <span class="i">(::v8::internal::FLAG_trace_sim)</span> {
- <span class="i">disasm::NameConverter converter;</span>
- <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>);
- // use a reasonably large buffer
- <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><<a id='4722' tid='4721', class="m">char</a>, <a id='4724' tid='4723', class="m">256</a>> <a id='4726' tid='4725', class="m">buffer</a>;
- <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>,
- <a id='4452' tid='4451', class="m">reinterpret_cast</a><<a id='4454' tid='4453', class="m">byte</a><a id='4456' tid='4455', class="m">*</a>>(<a id='4458' tid='4457', class="m">instr</a>));
- <a id='4388' tid='4387', class="m">PrintF</a>(<a id='4390' tid='4389', class="m">" 0x%08x %s\n"</a>, <a id='4392' tid='4391', class="m">reinterpret_cast</a><<a id='4394' tid='4393', class="m">intptr_t</a>>(<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>());
- }
- <span class="i">if</span> <span class="i">(instr->ConditionField() == kSpecialCondition)</span> <span class="i">{
- UNIMPLEMENTED();
- }</span> <span class="i">else</span> <span class="i">if</span> <span class="i">(ConditionallyExecute(instr))</span> <span class="i">{
- switch (instr->TypeValue()) {
- case 0:
- case 1: {
- DecodeType01(instr);
- break;
- }
- case 2: {
- DecodeType2(instr);
- break;
- }
- case 3: {
- DecodeType3(instr);
- break;
- }
- case 4: {
- DecodeType4(instr);
- break;
- }
- case 5: {
- DecodeType5(instr);
- break;
- }
- case 6: {
- DecodeType6(instr);
- break;
- }
- case 7: {
- DecodeType7(instr);
- break;
- }
- default: {
- UNIMPLEMENTED();
- break;
- }
- }
- // If the instruction is a non taken conditional stop, we need to skip the
- // inlined message address.
- }</span> <a id='4856' tid='4855', class="m">else</a> <span class="i">if</span> <span class="i">(instr->IsStop())</span> {
- <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>);
- }
- <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>) {
- <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><<a id='4376' tid='4375', class="m">int32_t</a>>(<a id='4378' tid='4377', class="m">instr</a>)
- <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>);
- }
- }
- <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>() {
- // Get the PC to simulate. Cannot use the accessor here as we need the
- // raw PC value and not the one used as input to arithmetic instructions.
- <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>();
- <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>) {
- // Fast version of the dispatch loop without checking whether the simulator
- // should be stopping at a particular executed instruction.
- <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>) {
- <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><<a id='4776' tid='4775', class="m">Instruction</a><a id='4778' tid='4777', class="m">*</a>>(<a id='4780' tid='4779', class="m">program_counter</a>);
- <a id='4782' tid='4781', class="m">icount_</a><a id='4784' tid='4783', class="m">++</a>;
- <a id='4786' tid='4785', class="m">InstructionDecode</a>(<a id='4788' tid='4787', class="m">instr</a>);
- <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>();
- }
- } <a id='4796' tid='4795', class="m">else</a> {
- // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
- // we reach the particular instuction count.
- <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>) {
- <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><<a id='4814' tid='4813', class="m">Instruction</a><a id='4816' tid='4815', class="m">*</a>>(<a id='4818' tid='4817', class="m">program_counter</a>);
- <a id='4820' tid='4819', class="m">icount_</a><a id='4822' tid='4821', class="m">++</a>;
- <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">{
- ArmDebugger dbg(this);
- dbg.Debug();
- }</span> <span class="i">else {
- InstructionDecode(instr);
- }</span>
- <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>();
- }
- }
- }
- <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>) {
- <span class="i">va_list parameters;</span>
- <span class="i">va_start(parameters, argument_count);</span>
- // Setup arguments
- // First four arguments passed in registers.
- <span class="i">ASSERT(argument_count >= 4);</span>
- <span class="i">set_register(r0, va_arg(parameters, int32_t));</span>
- <span class="i">set_register(r1, va_arg(parameters, int32_t));</span>
- <span class="i">set_register(r2, va_arg(parameters, int32_t));</span>
- <span class="i">set_register(r3, va_arg(parameters, int32_t));</span>
- // Remaining arguments passed on stack.
- <span class="i">int original_stack = get_register(sp);</span>
- // Compute position of stack on entry to generated code.
- <span class="i">int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t));</span>
- <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>) {
- <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>();
- }
- // Store remaining arguments on stack, from low to high memory.
- <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><<a id='4662' tid='4661', class="m">intptr_t</a><a id='4664' tid='4663', class="m">*</a>>(<a id='4666' tid='4665', class="m">entry_stack</a>);
- <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"><</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">{
- stack_argument[i - 4] = va_arg(parameters, int32_t);
- }</span>
- <span class="i">va_end(parameters);</span>
- <span class="i">set_register(sp, entry_stack);</span>
- // Prepare to execute the code at entry
- <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><<a id='4488' tid='4487', class="m">int32_t</a>>(<a id='4490' tid='4489', class="m">entry</a>));
- // Put down marker for end of simulation. The simulator will stop simulation
- // when the PC reaches this value. By saving the "end simulation" value into
- // the LR the simulation stops when returning to this call point.
- <span class="i">set_register(lr, end_sim_pc);</span>
- // Remember the values of callee-saved registers.
- // The code below assumes that r9 is not used as sb (static base) in
- // simulator code and therefore is regarded as a callee-saved register.
- <span class="i">int32_t r4_val = get_register(r4);</span>
- <span class="i">int32_t r5_val = get_register(r5);</span>
- <span class="i">int32_t r6_val = get_register(r6);</span>
- <span class="i">int32_t r7_val = get_register(r7);</span>
- <span class="i">int32_t r8_val = get_register(r8);</span>
- <span class="i">int32_t r9_val = get_register(r9);</span>
- <span class="i">int32_t r10_val = get_register(r10);</span>
- <span class="i">int32_t r11_val = get_register(r11);</span>
- // Setup the callee-saved registers with a known value. To be able to check
- // that they are preserved properly across JS execution.
- <span class="i">int32_t callee_saved_value = icount_;</span>
- <span class="i">set_register(r4, callee_saved_value);</span>
- <span class="i">set_register(r5, callee_saved_value);</span>
- <span class="i">set_register(r6, callee_saved_value);</span>
- <span class="i">set_register(r7, callee_saved_value);</span>
- <span class="i">set_register(r8, callee_saved_value);</span>
- <span class="i">set_register(r9, callee_saved_value);</span>
- <span class="i">set_register(r10, callee_saved_value);</span>
- <span class="i">set_register(r11, callee_saved_value);</span>
- // Start the simulation
- <span class="i">Execute();</span>
- // Check that the callee-saved registers have been preserved.
- <span class="i">CHECK_EQ(callee_saved_value, get_register(r4));</span>
- <span class="i">CHECK_EQ(callee_saved_value, get_register(r5));</span>
- <span class="i">CHECK_EQ(callee_saved_value, get_register(r6));</span>
- <span class="i">CHECK_EQ(callee_saved_value, get_register(r7));</span>
- <span class="i">CHECK_EQ(callee_saved_value, get_register(r8));</span>
- <span class="i">CHECK_EQ(callee_saved_value, get_register(r9));</span>
- <span class="i">CHECK_EQ(callee_saved_value, get_register(r10));</span>
- <span class="i">CHECK_EQ(callee_saved_value, get_register(r11));</span>
- // Restore callee-saved registers with the original value.
- <span class="i">set_register(r4, r4_val);</span>
- <span class="i">set_register(r5, r5_val);</span>
- <span class="i">set_register(r6, r6_val);</span>
- <span class="i">set_register(r7, r7_val);</span>
- <span class="i">set_register(r8, r8_val);</span>
- <span class="i">set_register(r9, r9_val);</span>
- <span class="i">set_register(r10, r10_val);</span>
- <span class="i">set_register(r11, r11_val);</span>
- // Pop stack passed arguments.
- <span class="i">CHECK_EQ(entry_stack, get_register(sp));</span>
- <span class="i">set_register(sp, original_stack);</span>
- <span class="i">int32_t result = get_register(r0);</span>
- <span class="i">return result;</span>
- }
- <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>) {
- <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>);
- <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><<a id='4596' tid='4595', class="m">uintptr_t</a><a id='4598' tid='4597', class="m">*</a>>(<a id='4600' tid='4599', class="m">new_sp</a>);
- <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>;
- <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>);
- <a id='4616' tid='4615', class="m">return</a> <a id='4618' tid='4617', class="m">new_sp</a>;
- }
- <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>() {
- <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>);
- <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><<a id='4516' tid='4515', class="m">uintptr_t</a><a id='4518' tid='4517', class="m">*</a>>(<a id='4520' tid='4519', class="m">current_sp</a>);
- <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>;
- <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>));
- <a id='4542' tid='4541', class="m">return</a> <a id='4544' tid='4543', class="m">address</a>;
- }
- } } // namespace v8::internal
- <span class="i">#endif</span> // USE_SIMULATOR
- <span class="i">#endif</span> // V8_TARGET_ARCH_ARM
- </pre>
- </div>
- </body>
- </html>