Home | History | Annotate | Download | only in arm
      1 // Copyright 2010 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <stdlib.h>
     29 #include <cstdarg>
     30 #include "v8.h"
     31 
     32 #include "disasm.h"
     33 #include "assembler.h"
     34 #include "arm/constants-arm.h"
     35 #include "arm/simulator-arm.h"
     36 
     37 #if !defined(__arm__)
     38 
     39 // Only build the simulator if not compiling for real ARM hardware.
     40 namespace assembler {
     41 namespace arm {
     42 
     43 using ::v8::internal::Object;
     44 using ::v8::internal::PrintF;
     45 using ::v8::internal::OS;
     46 using ::v8::internal::ReadLine;
     47 using ::v8::internal::DeleteArray;
     48 
     49 // This macro provides a platform independent use of sscanf. The reason for
     50 // SScanF not being implemented in a platform independent way through
     51 // ::v8::internal::OS in the same way as SNPrintF is that the
     52 // Windows C Run-Time Library does not provide vsscanf.
     53 #define SScanF sscanf  // NOLINT
     54 
     55 // The Debugger class is used by the simulator while debugging simulated ARM
     56 // code.
     57 class Debugger {
     58  public:
     59   explicit Debugger(Simulator* sim);
     60   ~Debugger();
     61 
     62   void Stop(Instr* instr);
     63   void Debug();
     64 
     65  private:
     66   static const instr_t kBreakpointInstr =
     67       ((AL << 28) | (7 << 25) | (1 << 24) | break_point);
     68   static const instr_t kNopInstr =
     69       ((AL << 28) | (13 << 21));
     70 
     71   Simulator* sim_;
     72 
     73   int32_t GetRegisterValue(int regnum);
     74   bool GetValue(const char* desc, int32_t* value);
     75 
     76   // Set or delete a breakpoint. Returns true if successful.
     77   bool SetBreakpoint(Instr* breakpc);
     78   bool DeleteBreakpoint(Instr* breakpc);
     79 
     80   // Undo and redo all breakpoints. This is needed to bracket disassembly and
     81   // execution to skip past breakpoints when run from the debugger.
     82   void UndoBreakpoints();
     83   void RedoBreakpoints();
     84 };
     85 
     86 
     87 Debugger::Debugger(Simulator* sim) {
     88   sim_ = sim;
     89 }
     90 
     91 
     92 Debugger::~Debugger() {
     93 }
     94 
     95 
     96 
     97 #ifdef GENERATED_CODE_COVERAGE
     98 static FILE* coverage_log = NULL;
     99 
    100 
    101 static void InitializeCoverage() {
    102   char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
    103   if (file_name != NULL) {
    104     coverage_log = fopen(file_name, "aw+");
    105   }
    106 }
    107 
    108 
    109 void Debugger::Stop(Instr* instr) {
    110   char* str = reinterpret_cast<char*>(instr->InstructionBits() & 0x0fffffff);
    111   if (strlen(str) > 0) {
    112     if (coverage_log != NULL) {
    113       fprintf(coverage_log, "%s\n", str);
    114       fflush(coverage_log);
    115     }
    116     instr->SetInstructionBits(0xe1a00000);  // Overwrite with nop.
    117   }
    118   sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
    119 }
    120 
    121 #else  // ndef GENERATED_CODE_COVERAGE
    122 
    123 static void InitializeCoverage() {
    124 }
    125 
    126 
    127 void Debugger::Stop(Instr* instr) {
    128   const char* str = (const char*)(instr->InstructionBits() & 0x0fffffff);
    129   PrintF("Simulator hit %s\n", str);
    130   sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
    131   Debug();
    132 }
    133 #endif
    134 
    135 
    136 int32_t Debugger::GetRegisterValue(int regnum) {
    137   if (regnum == kPCRegister) {
    138     return sim_->get_pc();
    139   } else {
    140     return sim_->get_register(regnum);
    141   }
    142 }
    143 
    144 
    145 bool Debugger::GetValue(const char* desc, int32_t* value) {
    146   int regnum = Registers::Number(desc);
    147   if (regnum != kNoRegister) {
    148     *value = GetRegisterValue(regnum);
    149     return true;
    150   } else {
    151     return SScanF(desc, "%i", value) == 1;
    152   }
    153   return false;
    154 }
    155 
    156 
    157 bool Debugger::SetBreakpoint(Instr* breakpc) {
    158   // Check if a breakpoint can be set. If not return without any side-effects.
    159   if (sim_->break_pc_ != NULL) {
    160     return false;
    161   }
    162 
    163   // Set the breakpoint.
    164   sim_->break_pc_ = breakpc;
    165   sim_->break_instr_ = breakpc->InstructionBits();
    166   // Not setting the breakpoint instruction in the code itself. It will be set
    167   // when the debugger shell continues.
    168   return true;
    169 }
    170 
    171 
    172 bool Debugger::DeleteBreakpoint(Instr* breakpc) {
    173   if (sim_->break_pc_ != NULL) {
    174     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    175   }
    176 
    177   sim_->break_pc_ = NULL;
    178   sim_->break_instr_ = 0;
    179   return true;
    180 }
    181 
    182 
    183 void Debugger::UndoBreakpoints() {
    184   if (sim_->break_pc_ != NULL) {
    185     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    186   }
    187 }
    188 
    189 
    190 void Debugger::RedoBreakpoints() {
    191   if (sim_->break_pc_ != NULL) {
    192     sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
    193   }
    194 }
    195 
    196 
    197 void Debugger::Debug() {
    198   intptr_t last_pc = -1;
    199   bool done = false;
    200 
    201 #define COMMAND_SIZE 63
    202 #define ARG_SIZE 255
    203 
    204 #define STR(a) #a
    205 #define XSTR(a) STR(a)
    206 
    207   char cmd[COMMAND_SIZE + 1];
    208   char arg1[ARG_SIZE + 1];
    209   char arg2[ARG_SIZE + 1];
    210 
    211   // make sure to have a proper terminating character if reaching the limit
    212   cmd[COMMAND_SIZE] = 0;
    213   arg1[ARG_SIZE] = 0;
    214   arg2[ARG_SIZE] = 0;
    215 
    216   // Undo all set breakpoints while running in the debugger shell. This will
    217   // make them invisible to all commands.
    218   UndoBreakpoints();
    219 
    220   while (!done) {
    221     if (last_pc != sim_->get_pc()) {
    222       disasm::NameConverter converter;
    223       disasm::Disassembler dasm(converter);
    224       // use a reasonably large buffer
    225       v8::internal::EmbeddedVector<char, 256> buffer;
    226       dasm.InstructionDecode(buffer,
    227                              reinterpret_cast<byte*>(sim_->get_pc()));
    228       PrintF("  0x%08x  %s\n", sim_->get_pc(), buffer.start());
    229       last_pc = sim_->get_pc();
    230     }
    231     char* line = ReadLine("sim> ");
    232     if (line == NULL) {
    233       break;
    234     } else {
    235       // Use sscanf to parse the individual parts of the command line. At the
    236       // moment no command expects more than two parameters.
    237       int args = SScanF(line,
    238                         "%" XSTR(COMMAND_SIZE) "s "
    239                         "%" XSTR(ARG_SIZE) "s "
    240                         "%" XSTR(ARG_SIZE) "s",
    241                         cmd, arg1, arg2);
    242       if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
    243         sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
    244       } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
    245         // Execute the one instruction we broke at with breakpoints disabled.
    246         sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
    247         // Leave the debugger shell.
    248         done = true;
    249       } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
    250         if (args == 2) {
    251           int32_t value;
    252           if (strcmp(arg1, "all") == 0) {
    253             for (int i = 0; i < kNumRegisters; i++) {
    254               value = GetRegisterValue(i);
    255               PrintF("%3s: 0x%08x %10d\n", Registers::Name(i), value, value);
    256             }
    257           } else {
    258             if (GetValue(arg1, &value)) {
    259               PrintF("%s: 0x%08x %d \n", arg1, value, value);
    260             } else {
    261               PrintF("%s unrecognized\n", arg1);
    262             }
    263           }
    264         } else {
    265           PrintF("print <register>\n");
    266         }
    267       } else if ((strcmp(cmd, "po") == 0)
    268                  || (strcmp(cmd, "printobject") == 0)) {
    269         if (args == 2) {
    270           int32_t value;
    271           if (GetValue(arg1, &value)) {
    272             Object* obj = reinterpret_cast<Object*>(value);
    273             PrintF("%s: \n", arg1);
    274 #ifdef DEBUG
    275             obj->PrintLn();
    276 #else
    277             obj->ShortPrint();
    278             PrintF("\n");
    279 #endif
    280           } else {
    281             PrintF("%s unrecognized\n", arg1);
    282           }
    283         } else {
    284           PrintF("printobject <value>\n");
    285         }
    286       } else if (strcmp(cmd, "disasm") == 0) {
    287         disasm::NameConverter converter;
    288         disasm::Disassembler dasm(converter);
    289         // use a reasonably large buffer
    290         v8::internal::EmbeddedVector<char, 256> buffer;
    291 
    292         byte* cur = NULL;
    293         byte* end = NULL;
    294 
    295         if (args == 1) {
    296           cur = reinterpret_cast<byte*>(sim_->get_pc());
    297           end = cur + (10 * Instr::kInstrSize);
    298         } else if (args == 2) {
    299           int32_t value;
    300           if (GetValue(arg1, &value)) {
    301             cur = reinterpret_cast<byte*>(value);
    302             // no length parameter passed, assume 10 instructions
    303             end = cur + (10 * Instr::kInstrSize);
    304           }
    305         } else {
    306           int32_t value1;
    307           int32_t value2;
    308           if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
    309             cur = reinterpret_cast<byte*>(value1);
    310             end = cur + (value2 * Instr::kInstrSize);
    311           }
    312         }
    313 
    314         while (cur < end) {
    315           dasm.InstructionDecode(buffer, cur);
    316           PrintF("  0x%08x  %s\n", cur, buffer.start());
    317           cur += Instr::kInstrSize;
    318         }
    319       } else if (strcmp(cmd, "gdb") == 0) {
    320         PrintF("relinquishing control to gdb\n");
    321         v8::internal::OS::DebugBreak();
    322         PrintF("regaining control from gdb\n");
    323       } else if (strcmp(cmd, "break") == 0) {
    324         if (args == 2) {
    325           int32_t value;
    326           if (GetValue(arg1, &value)) {
    327             if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) {
    328               PrintF("setting breakpoint failed\n");
    329             }
    330           } else {
    331             PrintF("%s unrecognized\n", arg1);
    332           }
    333         } else {
    334           PrintF("break <address>\n");
    335         }
    336       } else if (strcmp(cmd, "del") == 0) {
    337         if (!DeleteBreakpoint(NULL)) {
    338           PrintF("deleting breakpoint failed\n");
    339         }
    340       } else if (strcmp(cmd, "flags") == 0) {
    341         PrintF("N flag: %d; ", sim_->n_flag_);
    342         PrintF("Z flag: %d; ", sim_->z_flag_);
    343         PrintF("C flag: %d; ", sim_->c_flag_);
    344         PrintF("V flag: %d\n", sim_->v_flag_);
    345         PrintF("INVALID OP flag: %d; ", sim_->inv_op_vfp_flag_);
    346         PrintF("DIV BY ZERO flag: %d; ", sim_->div_zero_vfp_flag_);
    347         PrintF("OVERFLOW flag: %d; ", sim_->overflow_vfp_flag_);
    348         PrintF("UNDERFLOW flag: %d; ", sim_->underflow_vfp_flag_);
    349         PrintF("INEXACT flag: %d; ", sim_->inexact_vfp_flag_);
    350       } else if (strcmp(cmd, "unstop") == 0) {
    351         intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
    352         Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
    353         if (stop_instr->ConditionField() == special_condition) {
    354           stop_instr->SetInstructionBits(kNopInstr);
    355         } else {
    356           PrintF("Not at debugger stop.");
    357         }
    358       } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) {
    359         ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
    360         PrintF("Trace of executed instructions is %s\n",
    361                ::v8::internal::FLAG_trace_sim ? "on" : "off");
    362       } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
    363         PrintF("cont\n");
    364         PrintF("  continue execution (alias 'c')\n");
    365         PrintF("stepi\n");
    366         PrintF("  step one instruction (alias 'si')\n");
    367         PrintF("print <register>\n");
    368         PrintF("  print register content (alias 'p')\n");
    369         PrintF("  use register name 'all' to print all registers\n");
    370         PrintF("printobject <register>\n");
    371         PrintF("  print an object from a register (alias 'po')\n");
    372         PrintF("flags\n");
    373         PrintF("  print flags\n");
    374         PrintF("disasm [<instructions>]\n");
    375         PrintF("disasm [[<address>] <instructions>]\n");
    376         PrintF("  disassemble code, default is 10 instructions from pc\n");
    377         PrintF("gdb\n");
    378         PrintF("  enter gdb\n");
    379         PrintF("break <address>\n");
    380         PrintF("  set a break point on the address\n");
    381         PrintF("del\n");
    382         PrintF("  delete the breakpoint\n");
    383         PrintF("unstop\n");
    384         PrintF("  ignore the stop instruction at the current location");
    385         PrintF("  from now on\n");
    386         PrintF("trace (alias 't')\n");
    387         PrintF("  toogle the tracing of all executed statements");
    388       } else {
    389         PrintF("Unknown command: %s\n", cmd);
    390       }
    391     }
    392     DeleteArray(line);
    393   }
    394 
    395   // Add all the breakpoints back to stop execution and enter the debugger
    396   // shell when hit.
    397   RedoBreakpoints();
    398 
    399 #undef COMMAND_SIZE
    400 #undef ARG_SIZE
    401 
    402 #undef STR
    403 #undef XSTR
    404 }
    405 
    406 
    407 // Create one simulator per thread and keep it in thread local storage.
    408 static v8::internal::Thread::LocalStorageKey simulator_key;
    409 
    410 
    411 bool Simulator::initialized_ = false;
    412 
    413 
    414 void Simulator::Initialize() {
    415   if (initialized_) return;
    416   simulator_key = v8::internal::Thread::CreateThreadLocalKey();
    417   initialized_ = true;
    418   ::v8::internal::ExternalReference::set_redirector(&RedirectExternalReference);
    419 }
    420 
    421 
    422 Simulator::Simulator() {
    423   Initialize();
    424   // Setup simulator support first. Some of this information is needed to
    425   // setup the architecture state.
    426   size_t stack_size = 1 * 1024*1024;  // allocate 1MB for stack
    427   stack_ = reinterpret_cast<char*>(malloc(stack_size));
    428   pc_modified_ = false;
    429   icount_ = 0;
    430   break_pc_ = NULL;
    431   break_instr_ = 0;
    432 
    433   // Setup architecture state.
    434   // All registers are initialized to zero to start with.
    435   for (int i = 0; i < num_registers; i++) {
    436     registers_[i] = 0;
    437   }
    438   n_flag_ = false;
    439   z_flag_ = false;
    440   c_flag_ = false;
    441   v_flag_ = false;
    442 
    443   // Initializing VFP registers.
    444   // All registers are initialized to zero to start with
    445   // even though s_registers_ & d_registers_ share the same
    446   // physical registers in the target.
    447   for (int i = 0; i < num_s_registers; i++) {
    448     vfp_register[i] = 0;
    449   }
    450   n_flag_FPSCR_ = false;
    451   z_flag_FPSCR_ = false;
    452   c_flag_FPSCR_ = false;
    453   v_flag_FPSCR_ = false;
    454 
    455   inv_op_vfp_flag_ = false;
    456   div_zero_vfp_flag_ = false;
    457   overflow_vfp_flag_ = false;
    458   underflow_vfp_flag_ = false;
    459   inexact_vfp_flag_ = false;
    460 
    461   // The sp is initialized to point to the bottom (high address) of the
    462   // allocated stack area. To be safe in potential stack underflows we leave
    463   // some buffer below.
    464   registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64;
    465   // The lr and pc are initialized to a known bad value that will cause an
    466   // access violation if the simulator ever tries to execute it.
    467   registers_[pc] = bad_lr;
    468   registers_[lr] = bad_lr;
    469   InitializeCoverage();
    470 }
    471 
    472 
    473 // When the generated code calls an external reference we need to catch that in
    474 // the simulator.  The external reference will be a function compiled for the
    475 // host architecture.  We need to call that function instead of trying to
    476 // execute it with the simulator.  We do that by redirecting the external
    477 // reference to a swi (software-interrupt) instruction that is handled by
    478 // the simulator.  We write the original destination of the jump just at a known
    479 // offset from the swi instruction so the simulator knows what to call.
    480 class Redirection {
    481  public:
    482   Redirection(void* external_function, bool fp_return)
    483       : external_function_(external_function),
    484         swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
    485         fp_return_(fp_return),
    486         next_(list_) {
    487     list_ = this;
    488   }
    489 
    490   void* address_of_swi_instruction() {
    491     return reinterpret_cast<void*>(&swi_instruction_);
    492   }
    493 
    494   void* external_function() { return external_function_; }
    495   bool fp_return() { return fp_return_; }
    496 
    497   static Redirection* Get(void* external_function, bool fp_return) {
    498     Redirection* current;
    499     for (current = list_; current != NULL; current = current->next_) {
    500       if (current->external_function_ == external_function) return current;
    501     }
    502     return new Redirection(external_function, fp_return);
    503   }
    504 
    505   static Redirection* FromSwiInstruction(Instr* swi_instruction) {
    506     char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
    507     char* addr_of_redirection =
    508         addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
    509     return reinterpret_cast<Redirection*>(addr_of_redirection);
    510   }
    511 
    512  private:
    513   void* external_function_;
    514   uint32_t swi_instruction_;
    515   bool fp_return_;
    516   Redirection* next_;
    517   static Redirection* list_;
    518 };
    519 
    520 
    521 Redirection* Redirection::list_ = NULL;
    522 
    523 
    524 void* Simulator::RedirectExternalReference(void* external_function,
    525                                            bool fp_return) {
    526   Redirection* redirection = Redirection::Get(external_function, fp_return);
    527   return redirection->address_of_swi_instruction();
    528 }
    529 
    530 
    531 // Get the active Simulator for the current thread.
    532 Simulator* Simulator::current() {
    533   Initialize();
    534   Simulator* sim = reinterpret_cast<Simulator*>(
    535       v8::internal::Thread::GetThreadLocal(simulator_key));
    536   if (sim == NULL) {
    537     // TODO(146): delete the simulator object when a thread goes away.
    538     sim = new Simulator();
    539     v8::internal::Thread::SetThreadLocal(simulator_key, sim);
    540   }
    541   return sim;
    542 }
    543 
    544 
    545 // Sets the register in the architecture state. It will also deal with updating
    546 // Simulator internal state for special registers such as PC.
    547 void Simulator::set_register(int reg, int32_t value) {
    548   ASSERT((reg >= 0) && (reg < num_registers));
    549   if (reg == pc) {
    550     pc_modified_ = true;
    551   }
    552   registers_[reg] = value;
    553 }
    554 
    555 
    556 // Get the register from the architecture state. This function does handle
    557 // the special case of accessing the PC register.
    558 int32_t Simulator::get_register(int reg) const {
    559   ASSERT((reg >= 0) && (reg < num_registers));
    560   return registers_[reg] + ((reg == pc) ? Instr::kPCReadOffset : 0);
    561 }
    562 
    563 
    564 // Raw access to the PC register.
    565 void Simulator::set_pc(int32_t value) {
    566   pc_modified_ = true;
    567   registers_[pc] = value;
    568 }
    569 
    570 
    571 // Raw access to the PC register without the special adjustment when reading.
    572 int32_t Simulator::get_pc() const {
    573   return registers_[pc];
    574 }
    575 
    576 
    577 // Getting from and setting into VFP registers.
    578 void Simulator::set_s_register(int sreg, unsigned int value) {
    579   ASSERT((sreg >= 0) && (sreg < num_s_registers));
    580   vfp_register[sreg] = value;
    581 }
    582 
    583 
    584 unsigned int Simulator::get_s_register(int sreg) const {
    585   ASSERT((sreg >= 0) && (sreg < num_s_registers));
    586   return vfp_register[sreg];
    587 }
    588 
    589 
    590 void Simulator::set_s_register_from_float(int sreg, const float flt) {
    591   ASSERT((sreg >= 0) && (sreg < num_s_registers));
    592   // Read the bits from the single precision floating point value
    593   // into the unsigned integer element of vfp_register[] given by index=sreg.
    594   char buffer[sizeof(vfp_register[0])];
    595   memcpy(buffer, &flt, sizeof(vfp_register[0]));
    596   memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
    597 }
    598 
    599 
    600 void Simulator::set_s_register_from_sinteger(int sreg, const int sint) {
    601   ASSERT((sreg >= 0) && (sreg < num_s_registers));
    602   // Read the bits from the integer value into the unsigned integer element of
    603   // vfp_register[] given by index=sreg.
    604   char buffer[sizeof(vfp_register[0])];
    605   memcpy(buffer, &sint, sizeof(vfp_register[0]));
    606   memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0]));
    607 }
    608 
    609 
    610 void Simulator::set_d_register_from_double(int dreg, const double& dbl) {
    611   ASSERT((dreg >= 0) && (dreg < num_d_registers));
    612   // Read the bits from the double precision floating point value into the two
    613   // consecutive unsigned integer elements of vfp_register[] given by index
    614   // 2*sreg and 2*sreg+1.
    615   char buffer[2 * sizeof(vfp_register[0])];
    616   memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0]));
    617 #ifndef BIG_ENDIAN_FLOATING_POINT
    618   memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0]));
    619 #else
    620   memcpy(&vfp_register[dreg * 2], &buffer[4], sizeof(vfp_register[0]));
    621   memcpy(&vfp_register[dreg * 2 + 1], &buffer[0], sizeof(vfp_register[0]));
    622 #endif
    623 }
    624 
    625 
    626 float Simulator::get_float_from_s_register(int sreg) {
    627   ASSERT((sreg >= 0) && (sreg < num_s_registers));
    628 
    629   float sm_val = 0.0;
    630   // Read the bits from the unsigned integer vfp_register[] array
    631   // into the single precision floating point value and return it.
    632   char buffer[sizeof(vfp_register[0])];
    633   memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
    634   memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
    635   return(sm_val);
    636 }
    637 
    638 
    639 int Simulator::get_sinteger_from_s_register(int sreg) {
    640   ASSERT((sreg >= 0) && (sreg < num_s_registers));
    641 
    642   int sm_val = 0;
    643   // Read the bits from the unsigned integer vfp_register[] array
    644   // into the single precision floating point value and return it.
    645   char buffer[sizeof(vfp_register[0])];
    646   memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0]));
    647   memcpy(&sm_val, buffer, sizeof(vfp_register[0]));
    648   return(sm_val);
    649 }
    650 
    651 
    652 double Simulator::get_double_from_d_register(int dreg) {
    653   ASSERT((dreg >= 0) && (dreg < num_d_registers));
    654 
    655   double dm_val = 0.0;
    656   // Read the bits from the unsigned integer vfp_register[] array
    657   // into the double precision floating point value and return it.
    658   char buffer[2 * sizeof(vfp_register[0])];
    659 #ifdef BIG_ENDIAN_FLOATING_POINT
    660   memcpy(&buffer[0], &vfp_register[2 * dreg + 1], sizeof(vfp_register[0]));
    661   memcpy(&buffer[4], &vfp_register[2 * dreg], sizeof(vfp_register[0]));
    662 #else
    663   memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0]));
    664 #endif
    665   memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0]));
    666   return(dm_val);
    667 }
    668 
    669 
    670 // For use in calls that take two double values, constructed from r0, r1, r2
    671 // and r3.
    672 void Simulator::GetFpArgs(double* x, double* y) {
    673   // We use a char buffer to get around the strict-aliasing rules which
    674   // otherwise allow the compiler to optimize away the copy.
    675   char buffer[2 * sizeof(registers_[0])];
    676   // Registers 0 and 1 -> x.
    677   memcpy(buffer, registers_, sizeof(buffer));
    678   memcpy(x, buffer, sizeof(buffer));
    679   // Registers 2 and 3 -> y.
    680   memcpy(buffer, registers_ + 2, sizeof(buffer));
    681   memcpy(y, buffer, sizeof(buffer));
    682 }
    683 
    684 
    685 void Simulator::SetFpResult(const double& result) {
    686   char buffer[2 * sizeof(registers_[0])];
    687   memcpy(buffer, &result, sizeof(buffer));
    688   // result -> registers 0 and 1.
    689   memcpy(registers_, buffer, sizeof(buffer));
    690 }
    691 
    692 
    693 void Simulator::TrashCallerSaveRegisters() {
    694   // We don't trash the registers with the return value.
    695   registers_[2] = 0x50Bad4U;
    696   registers_[3] = 0x50Bad4U;
    697   registers_[12] = 0x50Bad4U;
    698 }
    699 
    700 
    701 // The ARM cannot do unaligned reads and writes.  On some ARM platforms an
    702 // interrupt is caused.  On others it does a funky rotation thing.  For now we
    703 // simply disallow unaligned reads, but at some point we may want to move to
    704 // emulating the rotate behaviour.  Note that simulator runs have the runtime
    705 // system running directly on the host system and only generated code is
    706 // executed in the simulator.  Since the host is typically IA32 we will not
    707 // get the correct ARM-like behaviour on unaligned accesses.
    708 
    709 int Simulator::ReadW(int32_t addr, Instr* instr) {
    710   if ((addr & 3) == 0) {
    711     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
    712     return *ptr;
    713   }
    714   PrintF("Unaligned read at 0x%08x\n", addr);
    715   UNIMPLEMENTED();
    716   return 0;
    717 }
    718 
    719 
    720 void Simulator::WriteW(int32_t addr, int value, Instr* instr) {
    721   if ((addr & 3) == 0) {
    722     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
    723     *ptr = value;
    724     return;
    725   }
    726   PrintF("Unaligned write at 0x%08x, pc=%p\n", addr, instr);
    727   UNIMPLEMENTED();
    728 }
    729 
    730 
    731 uint16_t Simulator::ReadHU(int32_t addr, Instr* instr) {
    732   if ((addr & 1) == 0) {
    733     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
    734     return *ptr;
    735   }
    736   PrintF("Unaligned unsigned halfword read at 0x%08x, pc=%p\n", addr, instr);
    737   UNIMPLEMENTED();
    738   return 0;
    739 }
    740 
    741 
    742 int16_t Simulator::ReadH(int32_t addr, Instr* instr) {
    743   if ((addr & 1) == 0) {
    744     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
    745     return *ptr;
    746   }
    747   PrintF("Unaligned signed halfword read at 0x%08x\n", addr);
    748   UNIMPLEMENTED();
    749   return 0;
    750 }
    751 
    752 
    753 void Simulator::WriteH(int32_t addr, uint16_t value, Instr* instr) {
    754   if ((addr & 1) == 0) {
    755     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
    756     *ptr = value;
    757     return;
    758   }
    759   PrintF("Unaligned unsigned halfword write at 0x%08x, pc=%p\n", addr, instr);
    760   UNIMPLEMENTED();
    761 }
    762 
    763 
    764 void Simulator::WriteH(int32_t addr, int16_t value, Instr* instr) {
    765   if ((addr & 1) == 0) {
    766     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
    767     *ptr = value;
    768     return;
    769   }
    770   PrintF("Unaligned halfword write at 0x%08x, pc=%p\n", addr, instr);
    771   UNIMPLEMENTED();
    772 }
    773 
    774 
    775 uint8_t Simulator::ReadBU(int32_t addr) {
    776   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
    777   return *ptr;
    778 }
    779 
    780 
    781 int8_t Simulator::ReadB(int32_t addr) {
    782   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
    783   return *ptr;
    784 }
    785 
    786 
    787 void Simulator::WriteB(int32_t addr, uint8_t value) {
    788   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
    789   *ptr = value;
    790 }
    791 
    792 
    793 void Simulator::WriteB(int32_t addr, int8_t value) {
    794   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
    795   *ptr = value;
    796 }
    797 
    798 
    799 // Returns the limit of the stack area to enable checking for stack overflows.
    800 uintptr_t Simulator::StackLimit() const {
    801   // Leave a safety margin of 256 bytes to prevent overrunning the stack when
    802   // pushing values.
    803   return reinterpret_cast<uintptr_t>(stack_) + 256;
    804 }
    805 
    806 
    807 // Unsupported instructions use Format to print an error and stop execution.
    808 void Simulator::Format(Instr* instr, const char* format) {
    809   PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
    810          instr, format);
    811   UNIMPLEMENTED();
    812 }
    813 
    814 
    815 // Checks if the current instruction should be executed based on its
    816 // condition bits.
    817 bool Simulator::ConditionallyExecute(Instr* instr) {
    818   switch (instr->ConditionField()) {
    819     case EQ: return z_flag_;
    820     case NE: return !z_flag_;
    821     case CS: return c_flag_;
    822     case CC: return !c_flag_;
    823     case MI: return n_flag_;
    824     case PL: return !n_flag_;
    825     case VS: return v_flag_;
    826     case VC: return !v_flag_;
    827     case HI: return c_flag_ && !z_flag_;
    828     case LS: return !c_flag_ || z_flag_;
    829     case GE: return n_flag_ == v_flag_;
    830     case LT: return n_flag_ != v_flag_;
    831     case GT: return !z_flag_ && (n_flag_ == v_flag_);
    832     case LE: return z_flag_ || (n_flag_ != v_flag_);
    833     case AL: return true;
    834     default: UNREACHABLE();
    835   }
    836   return false;
    837 }
    838 
    839 
    840 // Calculate and set the Negative and Zero flags.
    841 void Simulator::SetNZFlags(int32_t val) {
    842   n_flag_ = (val < 0);
    843   z_flag_ = (val == 0);
    844 }
    845 
    846 
    847 // Set the Carry flag.
    848 void Simulator::SetCFlag(bool val) {
    849   c_flag_ = val;
    850 }
    851 
    852 
    853 // Set the oVerflow flag.
    854 void Simulator::SetVFlag(bool val) {
    855   v_flag_ = val;
    856 }
    857 
    858 
    859 // Calculate C flag value for additions.
    860 bool Simulator::CarryFrom(int32_t left, int32_t right) {
    861   uint32_t uleft = static_cast<uint32_t>(left);
    862   uint32_t uright = static_cast<uint32_t>(right);
    863   uint32_t urest  = 0xffffffffU - uleft;
    864 
    865   return (uright > urest);
    866 }
    867 
    868 
    869 // Calculate C flag value for subtractions.
    870 bool Simulator::BorrowFrom(int32_t left, int32_t right) {
    871   uint32_t uleft = static_cast<uint32_t>(left);
    872   uint32_t uright = static_cast<uint32_t>(right);
    873 
    874   return (uright > uleft);
    875 }
    876 
    877 
    878 // Calculate V flag value for additions and subtractions.
    879 bool Simulator::OverflowFrom(int32_t alu_out,
    880                              int32_t left, int32_t right, bool addition) {
    881   bool overflow;
    882   if (addition) {
    883                // operands have the same sign
    884     overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
    885                // and operands and result have different sign
    886                && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
    887   } else {
    888                // operands have different signs
    889     overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
    890                // and first operand and result have different signs
    891                && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
    892   }
    893   return overflow;
    894 }
    895 
    896 
    897 // Support for VFP comparisons.
    898 void Simulator::Compute_FPSCR_Flags(double val1, double val2) {
    899   if (isnan(val1) || isnan(val2)) {
    900     n_flag_FPSCR_ = false;
    901     z_flag_FPSCR_ = false;
    902     c_flag_FPSCR_ = true;
    903     v_flag_FPSCR_ = true;
    904   // All non-NaN cases.
    905   } else if (val1 == val2) {
    906     n_flag_FPSCR_ = false;
    907     z_flag_FPSCR_ = true;
    908     c_flag_FPSCR_ = true;
    909     v_flag_FPSCR_ = false;
    910   } else if (val1 < val2) {
    911     n_flag_FPSCR_ = true;
    912     z_flag_FPSCR_ = false;
    913     c_flag_FPSCR_ = false;
    914     v_flag_FPSCR_ = false;
    915   } else {
    916     // Case when (val1 > val2).
    917     n_flag_FPSCR_ = false;
    918     z_flag_FPSCR_ = false;
    919     c_flag_FPSCR_ = true;
    920     v_flag_FPSCR_ = false;
    921   }
    922 }
    923 
    924 
    925 void Simulator::Copy_FPSCR_to_APSR() {
    926   n_flag_ = n_flag_FPSCR_;
    927   z_flag_ = z_flag_FPSCR_;
    928   c_flag_ = c_flag_FPSCR_;
    929   v_flag_ = v_flag_FPSCR_;
    930 }
    931 
    932 
    933 // Addressing Mode 1 - Data-processing operands:
    934 // Get the value based on the shifter_operand with register.
    935 int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) {
    936   Shift shift = instr->ShiftField();
    937   int shift_amount = instr->ShiftAmountField();
    938   int32_t result = get_register(instr->RmField());
    939   if (instr->Bit(4) == 0) {
    940     // by immediate
    941     if ((shift == ROR) && (shift_amount == 0)) {
    942       UNIMPLEMENTED();
    943       return result;
    944     } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
    945       shift_amount = 32;
    946     }
    947     switch (shift) {
    948       case ASR: {
    949         if (shift_amount == 0) {
    950           if (result < 0) {
    951             result = 0xffffffff;
    952             *carry_out = true;
    953           } else {
    954             result = 0;
    955             *carry_out = false;
    956           }
    957         } else {
    958           result >>= (shift_amount - 1);
    959           *carry_out = (result & 1) == 1;
    960           result >>= 1;
    961         }
    962         break;
    963       }
    964 
    965       case LSL: {
    966         if (shift_amount == 0) {
    967           *carry_out = c_flag_;
    968         } else {
    969           result <<= (shift_amount - 1);
    970           *carry_out = (result < 0);
    971           result <<= 1;
    972         }
    973         break;
    974       }
    975 
    976       case LSR: {
    977         if (shift_amount == 0) {
    978           result = 0;
    979           *carry_out = c_flag_;
    980         } else {
    981           uint32_t uresult = static_cast<uint32_t>(result);
    982           uresult >>= (shift_amount - 1);
    983           *carry_out = (uresult & 1) == 1;
    984           uresult >>= 1;
    985           result = static_cast<int32_t>(uresult);
    986         }
    987         break;
    988       }
    989 
    990       case ROR: {
    991         UNIMPLEMENTED();
    992         break;
    993       }
    994 
    995       default: {
    996         UNREACHABLE();
    997         break;
    998       }
    999     }
   1000   } else {
   1001     // by register
   1002     int rs = instr->RsField();
   1003     shift_amount = get_register(rs) &0xff;
   1004     switch (shift) {
   1005       case ASR: {
   1006         if (shift_amount == 0) {
   1007           *carry_out = c_flag_;
   1008         } else if (shift_amount < 32) {
   1009           result >>= (shift_amount - 1);
   1010           *carry_out = (result & 1) == 1;
   1011           result >>= 1;
   1012         } else {
   1013           ASSERT(shift_amount >= 32);
   1014           if (result < 0) {
   1015             *carry_out = true;
   1016             result = 0xffffffff;
   1017           } else {
   1018             *carry_out = false;
   1019             result = 0;
   1020           }
   1021         }
   1022         break;
   1023       }
   1024 
   1025       case LSL: {
   1026         if (shift_amount == 0) {
   1027           *carry_out = c_flag_;
   1028         } else if (shift_amount < 32) {
   1029           result <<= (shift_amount - 1);
   1030           *carry_out = (result < 0);
   1031           result <<= 1;
   1032         } else if (shift_amount == 32) {
   1033           *carry_out = (result & 1) == 1;
   1034           result = 0;
   1035         } else {
   1036           ASSERT(shift_amount > 32);
   1037           *carry_out = false;
   1038           result = 0;
   1039         }
   1040         break;
   1041       }
   1042 
   1043       case LSR: {
   1044         if (shift_amount == 0) {
   1045           *carry_out = c_flag_;
   1046         } else if (shift_amount < 32) {
   1047           uint32_t uresult = static_cast<uint32_t>(result);
   1048           uresult >>= (shift_amount - 1);
   1049           *carry_out = (uresult & 1) == 1;
   1050           uresult >>= 1;
   1051           result = static_cast<int32_t>(uresult);
   1052         } else if (shift_amount == 32) {
   1053           *carry_out = (result < 0);
   1054           result = 0;
   1055         } else {
   1056           *carry_out = false;
   1057           result = 0;
   1058         }
   1059         break;
   1060       }
   1061 
   1062       case ROR: {
   1063         UNIMPLEMENTED();
   1064         break;
   1065       }
   1066 
   1067       default: {
   1068         UNREACHABLE();
   1069         break;
   1070       }
   1071     }
   1072   }
   1073   return result;
   1074 }
   1075 
   1076 
   1077 // Addressing Mode 1 - Data-processing operands:
   1078 // Get the value based on the shifter_operand with immediate.
   1079 int32_t Simulator::GetImm(Instr* instr, bool* carry_out) {
   1080   int rotate = instr->RotateField() * 2;
   1081   int immed8 = instr->Immed8Field();
   1082   int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
   1083   *carry_out = (rotate == 0) ? c_flag_ : (imm < 0);
   1084   return imm;
   1085 }
   1086 
   1087 
   1088 static int count_bits(int bit_vector) {
   1089   int count = 0;
   1090   while (bit_vector != 0) {
   1091     if ((bit_vector & 1) != 0) {
   1092       count++;
   1093     }
   1094     bit_vector >>= 1;
   1095   }
   1096   return count;
   1097 }
   1098 
   1099 
   1100 // Addressing Mode 4 - Load and Store Multiple
   1101 void Simulator::HandleRList(Instr* instr, bool load) {
   1102   int rn = instr->RnField();
   1103   int32_t rn_val = get_register(rn);
   1104   int rlist = instr->RlistField();
   1105   int num_regs = count_bits(rlist);
   1106 
   1107   intptr_t start_address = 0;
   1108   intptr_t end_address = 0;
   1109   switch (instr->PUField()) {
   1110     case 0: {
   1111       // Print("da");
   1112       UNIMPLEMENTED();
   1113       break;
   1114     }
   1115     case 1: {
   1116       // Print("ia");
   1117       start_address = rn_val;
   1118       end_address = rn_val + (num_regs * 4) - 4;
   1119       rn_val = rn_val + (num_regs * 4);
   1120       break;
   1121     }
   1122     case 2: {
   1123       // Print("db");
   1124       start_address = rn_val - (num_regs * 4);
   1125       end_address = rn_val - 4;
   1126       rn_val = start_address;
   1127       break;
   1128     }
   1129     case 3: {
   1130       // Print("ib");
   1131       UNIMPLEMENTED();
   1132       break;
   1133     }
   1134     default: {
   1135       UNREACHABLE();
   1136       break;
   1137     }
   1138   }
   1139   if (instr->HasW()) {
   1140     set_register(rn, rn_val);
   1141   }
   1142   intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
   1143   int reg = 0;
   1144   while (rlist != 0) {
   1145     if ((rlist & 1) != 0) {
   1146       if (load) {
   1147         set_register(reg, *address);
   1148       } else {
   1149         *address = get_register(reg);
   1150       }
   1151       address += 1;
   1152     }
   1153     reg++;
   1154     rlist >>= 1;
   1155   }
   1156   ASSERT(end_address == ((intptr_t)address) - 4);
   1157 }
   1158 
   1159 
   1160 // Calls into the V8 runtime are based on this very simple interface.
   1161 // Note: To be able to return two values from some calls the code in runtime.cc
   1162 // uses the ObjectPair which is essentially two 32-bit values stuffed into a
   1163 // 64-bit value. With the code below we assume that all runtime calls return
   1164 // 64 bits of result. If they don't, the r1 result register contains a bogus
   1165 // value, which is fine because it is caller-saved.
   1166 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
   1167                                         int32_t arg1,
   1168                                         int32_t arg2,
   1169                                         int32_t arg3);
   1170 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
   1171                                          int32_t arg1,
   1172                                          int32_t arg2,
   1173                                          int32_t arg3);
   1174 
   1175 
   1176 // Software interrupt instructions are used by the simulator to call into the
   1177 // C-based V8 runtime.
   1178 void Simulator::SoftwareInterrupt(Instr* instr) {
   1179   int swi = instr->SwiField();
   1180   switch (swi) {
   1181     case call_rt_redirected: {
   1182       Redirection* redirection = Redirection::FromSwiInstruction(instr);
   1183       int32_t arg0 = get_register(r0);
   1184       int32_t arg1 = get_register(r1);
   1185       int32_t arg2 = get_register(r2);
   1186       int32_t arg3 = get_register(r3);
   1187       // This is dodgy but it works because the C entry stubs are never moved.
   1188       // See comment in codegen-arm.cc and bug 1242173.
   1189       int32_t saved_lr = get_register(lr);
   1190       if (redirection->fp_return()) {
   1191         intptr_t external =
   1192             reinterpret_cast<intptr_t>(redirection->external_function());
   1193         SimulatorRuntimeFPCall target =
   1194             reinterpret_cast<SimulatorRuntimeFPCall>(external);
   1195         if (::v8::internal::FLAG_trace_sim) {
   1196           double x, y;
   1197           GetFpArgs(&x, &y);
   1198           PrintF("Call to host function at %p with args %f, %f\n",
   1199                  FUNCTION_ADDR(target), x, y);
   1200         }
   1201         double result = target(arg0, arg1, arg2, arg3);
   1202         SetFpResult(result);
   1203       } else {
   1204         intptr_t external =
   1205             reinterpret_cast<int32_t>(redirection->external_function());
   1206         SimulatorRuntimeCall target =
   1207             reinterpret_cast<SimulatorRuntimeCall>(external);
   1208         if (::v8::internal::FLAG_trace_sim) {
   1209           PrintF(
   1210               "Call to host function at %p with args %08x, %08x, %08x, %08x\n",
   1211               FUNCTION_ADDR(target),
   1212               arg0,
   1213               arg1,
   1214               arg2,
   1215               arg3);
   1216         }
   1217         int64_t result = target(arg0, arg1, arg2, arg3);
   1218         int32_t lo_res = static_cast<int32_t>(result);
   1219         int32_t hi_res = static_cast<int32_t>(result >> 32);
   1220         if (::v8::internal::FLAG_trace_sim) {
   1221           PrintF("Returned %08x\n", lo_res);
   1222         }
   1223         set_register(r0, lo_res);
   1224         set_register(r1, hi_res);
   1225       }
   1226       set_register(lr, saved_lr);
   1227       set_pc(get_register(lr));
   1228       break;
   1229     }
   1230     case break_point: {
   1231       Debugger dbg(this);
   1232       dbg.Debug();
   1233       break;
   1234     }
   1235     default: {
   1236       UNREACHABLE();
   1237       break;
   1238     }
   1239   }
   1240 }
   1241 
   1242 
   1243 // Handle execution based on instruction types.
   1244 
   1245 // Instruction types 0 and 1 are both rolled into one function because they
   1246 // only differ in the handling of the shifter_operand.
   1247 void Simulator::DecodeType01(Instr* instr) {
   1248   int type = instr->TypeField();
   1249   if ((type == 0) && instr->IsSpecialType0()) {
   1250     // multiply instruction or extra loads and stores
   1251     if (instr->Bits(7, 4) == 9) {
   1252       if (instr->Bit(24) == 0) {
   1253         // Raw field decoding here. Multiply instructions have their Rd in
   1254         // funny places.
   1255         int rn = instr->RnField();
   1256         int rm = instr->RmField();
   1257         int rs = instr->RsField();
   1258         int32_t rs_val = get_register(rs);
   1259         int32_t rm_val = get_register(rm);
   1260         if (instr->Bit(23) == 0) {
   1261           if (instr->Bit(21) == 0) {
   1262             // The MUL instruction description (A 4.1.33) refers to Rd as being
   1263             // the destination for the operation, but it confusingly uses the
   1264             // Rn field to encode it.
   1265             // Format(instr, "mul'cond's 'rn, 'rm, 'rs");
   1266             int rd = rn;  // Remap the rn field to the Rd register.
   1267             int32_t alu_out = rm_val * rs_val;
   1268             set_register(rd, alu_out);
   1269             if (instr->HasS()) {
   1270               SetNZFlags(alu_out);
   1271             }
   1272           } else {
   1273             // The MLA instruction description (A 4.1.28) refers to the order
   1274             // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
   1275             // Rn field to encode the Rd register and the Rd field to encode
   1276             // the Rn register.
   1277             Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
   1278           }
   1279         } else {
   1280           // The signed/long multiply instructions use the terms RdHi and RdLo
   1281           // when referring to the target registers. They are mapped to the Rn
   1282           // and Rd fields as follows:
   1283           // RdLo == Rd
   1284           // RdHi == Rn (This is confusingly stored in variable rd here
   1285           //             because the mul instruction from above uses the
   1286           //             Rn field to encode the Rd register. Good luck figuring
   1287           //             this out without reading the ARM instruction manual
   1288           //             at a very detailed level.)
   1289           // Format(instr, "'um'al'cond's 'rd, 'rn, 'rs, 'rm");
   1290           int rd_hi = rn;  // Remap the rn field to the RdHi register.
   1291           int rd_lo = instr->RdField();
   1292           int32_t hi_res = 0;
   1293           int32_t lo_res = 0;
   1294           if (instr->Bit(22) == 1) {
   1295             int64_t left_op  = static_cast<int32_t>(rm_val);
   1296             int64_t right_op = static_cast<int32_t>(rs_val);
   1297             uint64_t result = left_op * right_op;
   1298             hi_res = static_cast<int32_t>(result >> 32);
   1299             lo_res = static_cast<int32_t>(result & 0xffffffff);
   1300           } else {
   1301             // unsigned multiply
   1302             uint64_t left_op  = static_cast<uint32_t>(rm_val);
   1303             uint64_t right_op = static_cast<uint32_t>(rs_val);
   1304             uint64_t result = left_op * right_op;
   1305             hi_res = static_cast<int32_t>(result >> 32);
   1306             lo_res = static_cast<int32_t>(result & 0xffffffff);
   1307           }
   1308           set_register(rd_lo, lo_res);
   1309           set_register(rd_hi, hi_res);
   1310           if (instr->HasS()) {
   1311             UNIMPLEMENTED();
   1312           }
   1313         }
   1314       } else {
   1315         UNIMPLEMENTED();  // Not used by V8.
   1316       }
   1317     } else {
   1318       // extra load/store instructions
   1319       int rd = instr->RdField();
   1320       int rn = instr->RnField();
   1321       int32_t rn_val = get_register(rn);
   1322       int32_t addr = 0;
   1323       if (instr->Bit(22) == 0) {
   1324         int rm = instr->RmField();
   1325         int32_t rm_val = get_register(rm);
   1326         switch (instr->PUField()) {
   1327           case 0: {
   1328             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
   1329             ASSERT(!instr->HasW());
   1330             addr = rn_val;
   1331             rn_val -= rm_val;
   1332             set_register(rn, rn_val);
   1333             break;
   1334           }
   1335           case 1: {
   1336             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
   1337             ASSERT(!instr->HasW());
   1338             addr = rn_val;
   1339             rn_val += rm_val;
   1340             set_register(rn, rn_val);
   1341             break;
   1342           }
   1343           case 2: {
   1344             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
   1345             rn_val -= rm_val;
   1346             addr = rn_val;
   1347             if (instr->HasW()) {
   1348               set_register(rn, rn_val);
   1349             }
   1350             break;
   1351           }
   1352           case 3: {
   1353             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
   1354             rn_val += rm_val;
   1355             addr = rn_val;
   1356             if (instr->HasW()) {
   1357               set_register(rn, rn_val);
   1358             }
   1359             break;
   1360           }
   1361           default: {
   1362             // The PU field is a 2-bit field.
   1363             UNREACHABLE();
   1364             break;
   1365           }
   1366         }
   1367       } else {
   1368         int32_t imm_val = (instr->ImmedHField() << 4) | instr->ImmedLField();
   1369         switch (instr->PUField()) {
   1370           case 0: {
   1371             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
   1372             ASSERT(!instr->HasW());
   1373             addr = rn_val;
   1374             rn_val -= imm_val;
   1375             set_register(rn, rn_val);
   1376             break;
   1377           }
   1378           case 1: {
   1379             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
   1380             ASSERT(!instr->HasW());
   1381             addr = rn_val;
   1382             rn_val += imm_val;
   1383             set_register(rn, rn_val);
   1384             break;
   1385           }
   1386           case 2: {
   1387             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
   1388             rn_val -= imm_val;
   1389             addr = rn_val;
   1390             if (instr->HasW()) {
   1391               set_register(rn, rn_val);
   1392             }
   1393             break;
   1394           }
   1395           case 3: {
   1396             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
   1397             rn_val += imm_val;
   1398             addr = rn_val;
   1399             if (instr->HasW()) {
   1400               set_register(rn, rn_val);
   1401             }
   1402             break;
   1403           }
   1404           default: {
   1405             // The PU field is a 2-bit field.
   1406             UNREACHABLE();
   1407             break;
   1408           }
   1409         }
   1410       }
   1411       if (instr->HasH()) {
   1412         if (instr->HasSign()) {
   1413           if (instr->HasL()) {
   1414             int16_t val = ReadH(addr, instr);
   1415             set_register(rd, val);
   1416           } else {
   1417             int16_t val = get_register(rd);
   1418             WriteH(addr, val, instr);
   1419           }
   1420         } else {
   1421           if (instr->HasL()) {
   1422             uint16_t val = ReadHU(addr, instr);
   1423             set_register(rd, val);
   1424           } else {
   1425             uint16_t val = get_register(rd);
   1426             WriteH(addr, val, instr);
   1427           }
   1428         }
   1429       } else {
   1430         // signed byte loads
   1431         ASSERT(instr->HasSign());
   1432         ASSERT(instr->HasL());
   1433         int8_t val = ReadB(addr);
   1434         set_register(rd, val);
   1435       }
   1436       return;
   1437     }
   1438   } else {
   1439     int rd = instr->RdField();
   1440     int rn = instr->RnField();
   1441     int32_t rn_val = get_register(rn);
   1442     int32_t shifter_operand = 0;
   1443     bool shifter_carry_out = 0;
   1444     if (type == 0) {
   1445       shifter_operand = GetShiftRm(instr, &shifter_carry_out);
   1446     } else {
   1447       ASSERT(instr->TypeField() == 1);
   1448       shifter_operand = GetImm(instr, &shifter_carry_out);
   1449     }
   1450     int32_t alu_out;
   1451 
   1452     switch (instr->OpcodeField()) {
   1453       case AND: {
   1454         // Format(instr, "and'cond's 'rd, 'rn, 'shift_rm");
   1455         // Format(instr, "and'cond's 'rd, 'rn, 'imm");
   1456         alu_out = rn_val & shifter_operand;
   1457         set_register(rd, alu_out);
   1458         if (instr->HasS()) {
   1459           SetNZFlags(alu_out);
   1460           SetCFlag(shifter_carry_out);
   1461         }
   1462         break;
   1463       }
   1464 
   1465       case EOR: {
   1466         // Format(instr, "eor'cond's 'rd, 'rn, 'shift_rm");
   1467         // Format(instr, "eor'cond's 'rd, 'rn, 'imm");
   1468         alu_out = rn_val ^ shifter_operand;
   1469         set_register(rd, alu_out);
   1470         if (instr->HasS()) {
   1471           SetNZFlags(alu_out);
   1472           SetCFlag(shifter_carry_out);
   1473         }
   1474         break;
   1475       }
   1476 
   1477       case SUB: {
   1478         // Format(instr, "sub'cond's 'rd, 'rn, 'shift_rm");
   1479         // Format(instr, "sub'cond's 'rd, 'rn, 'imm");
   1480         alu_out = rn_val - shifter_operand;
   1481         set_register(rd, alu_out);
   1482         if (instr->HasS()) {
   1483           SetNZFlags(alu_out);
   1484           SetCFlag(!BorrowFrom(rn_val, shifter_operand));
   1485           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
   1486         }
   1487         break;
   1488       }
   1489 
   1490       case RSB: {
   1491         // Format(instr, "rsb'cond's 'rd, 'rn, 'shift_rm");
   1492         // Format(instr, "rsb'cond's 'rd, 'rn, 'imm");
   1493         alu_out = shifter_operand - rn_val;
   1494         set_register(rd, alu_out);
   1495         if (instr->HasS()) {
   1496           SetNZFlags(alu_out);
   1497           SetCFlag(!BorrowFrom(shifter_operand, rn_val));
   1498           SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));
   1499         }
   1500         break;
   1501       }
   1502 
   1503       case ADD: {
   1504         // Format(instr, "add'cond's 'rd, 'rn, 'shift_rm");
   1505         // Format(instr, "add'cond's 'rd, 'rn, 'imm");
   1506         alu_out = rn_val + shifter_operand;
   1507         set_register(rd, alu_out);
   1508         if (instr->HasS()) {
   1509           SetNZFlags(alu_out);
   1510           SetCFlag(CarryFrom(rn_val, shifter_operand));
   1511           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
   1512         }
   1513         break;
   1514       }
   1515 
   1516       case ADC: {
   1517         Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm");
   1518         Format(instr, "adc'cond's 'rd, 'rn, 'imm");
   1519         break;
   1520       }
   1521 
   1522       case SBC: {
   1523         Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm");
   1524         Format(instr, "sbc'cond's 'rd, 'rn, 'imm");
   1525         break;
   1526       }
   1527 
   1528       case RSC: {
   1529         Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm");
   1530         Format(instr, "rsc'cond's 'rd, 'rn, 'imm");
   1531         break;
   1532       }
   1533 
   1534       case TST: {
   1535         if (instr->HasS()) {
   1536           // Format(instr, "tst'cond 'rn, 'shift_rm");
   1537           // Format(instr, "tst'cond 'rn, 'imm");
   1538           alu_out = rn_val & shifter_operand;
   1539           SetNZFlags(alu_out);
   1540           SetCFlag(shifter_carry_out);
   1541         } else {
   1542           UNIMPLEMENTED();
   1543         }
   1544         break;
   1545       }
   1546 
   1547       case TEQ: {
   1548         if (instr->HasS()) {
   1549           // Format(instr, "teq'cond 'rn, 'shift_rm");
   1550           // Format(instr, "teq'cond 'rn, 'imm");
   1551           alu_out = rn_val ^ shifter_operand;
   1552           SetNZFlags(alu_out);
   1553           SetCFlag(shifter_carry_out);
   1554         } else {
   1555           ASSERT(type == 0);
   1556           int rm = instr->RmField();
   1557           switch (instr->Bits(7, 4)) {
   1558             case BX:
   1559               set_pc(get_register(rm));
   1560               break;
   1561             case BLX: {
   1562               uint32_t old_pc = get_pc();
   1563               set_pc(get_register(rm));
   1564               set_register(lr, old_pc + Instr::kInstrSize);
   1565               break;
   1566             }
   1567             default:
   1568               UNIMPLEMENTED();
   1569           }
   1570         }
   1571         break;
   1572       }
   1573 
   1574       case CMP: {
   1575         if (instr->HasS()) {
   1576           // Format(instr, "cmp'cond 'rn, 'shift_rm");
   1577           // Format(instr, "cmp'cond 'rn, 'imm");
   1578           alu_out = rn_val - shifter_operand;
   1579           SetNZFlags(alu_out);
   1580           SetCFlag(!BorrowFrom(rn_val, shifter_operand));
   1581           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
   1582         } else {
   1583           UNIMPLEMENTED();
   1584         }
   1585         break;
   1586       }
   1587 
   1588       case CMN: {
   1589         if (instr->HasS()) {
   1590           // Format(instr, "cmn'cond 'rn, 'shift_rm");
   1591           // Format(instr, "cmn'cond 'rn, 'imm");
   1592           alu_out = rn_val + shifter_operand;
   1593           SetNZFlags(alu_out);
   1594           SetCFlag(!CarryFrom(rn_val, shifter_operand));
   1595           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
   1596         } else {
   1597           ASSERT(type == 0);
   1598           int rm = instr->RmField();
   1599           int rd = instr->RdField();
   1600           switch (instr->Bits(7, 4)) {
   1601             case CLZ: {
   1602               uint32_t bits = get_register(rm);
   1603               int leading_zeros = 0;
   1604               if (bits == 0) {
   1605                 leading_zeros = 32;
   1606               } else {
   1607                 while ((bits & 0x80000000u) == 0) {
   1608                   bits <<= 1;
   1609                   leading_zeros++;
   1610                 }
   1611               }
   1612               set_register(rd, leading_zeros);
   1613               break;
   1614             }
   1615             default:
   1616               UNIMPLEMENTED();
   1617           }
   1618         }
   1619         break;
   1620       }
   1621 
   1622       case ORR: {
   1623         // Format(instr, "orr'cond's 'rd, 'rn, 'shift_rm");
   1624         // Format(instr, "orr'cond's 'rd, 'rn, 'imm");
   1625         alu_out = rn_val | shifter_operand;
   1626         set_register(rd, alu_out);
   1627         if (instr->HasS()) {
   1628           SetNZFlags(alu_out);
   1629           SetCFlag(shifter_carry_out);
   1630         }
   1631         break;
   1632       }
   1633 
   1634       case MOV: {
   1635         // Format(instr, "mov'cond's 'rd, 'shift_rm");
   1636         // Format(instr, "mov'cond's 'rd, 'imm");
   1637         alu_out = shifter_operand;
   1638         set_register(rd, alu_out);
   1639         if (instr->HasS()) {
   1640           SetNZFlags(alu_out);
   1641           SetCFlag(shifter_carry_out);
   1642         }
   1643         break;
   1644       }
   1645 
   1646       case BIC: {
   1647         // Format(instr, "bic'cond's 'rd, 'rn, 'shift_rm");
   1648         // Format(instr, "bic'cond's 'rd, 'rn, 'imm");
   1649         alu_out = rn_val & ~shifter_operand;
   1650         set_register(rd, alu_out);
   1651         if (instr->HasS()) {
   1652           SetNZFlags(alu_out);
   1653           SetCFlag(shifter_carry_out);
   1654         }
   1655         break;
   1656       }
   1657 
   1658       case MVN: {
   1659         // Format(instr, "mvn'cond's 'rd, 'shift_rm");
   1660         // Format(instr, "mvn'cond's 'rd, 'imm");
   1661         alu_out = ~shifter_operand;
   1662         set_register(rd, alu_out);
   1663         if (instr->HasS()) {
   1664           SetNZFlags(alu_out);
   1665           SetCFlag(shifter_carry_out);
   1666         }
   1667         break;
   1668       }
   1669 
   1670       default: {
   1671         UNREACHABLE();
   1672         break;
   1673       }
   1674     }
   1675   }
   1676 }
   1677 
   1678 
   1679 void Simulator::DecodeType2(Instr* instr) {
   1680   int rd = instr->RdField();
   1681   int rn = instr->RnField();
   1682   int32_t rn_val = get_register(rn);
   1683   int32_t im_val = instr->Offset12Field();
   1684   int32_t addr = 0;
   1685   switch (instr->PUField()) {
   1686     case 0: {
   1687       // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
   1688       ASSERT(!instr->HasW());
   1689       addr = rn_val;
   1690       rn_val -= im_val;
   1691       set_register(rn, rn_val);
   1692       break;
   1693     }
   1694     case 1: {
   1695       // Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
   1696       ASSERT(!instr->HasW());
   1697       addr = rn_val;
   1698       rn_val += im_val;
   1699       set_register(rn, rn_val);
   1700       break;
   1701     }
   1702     case 2: {
   1703       // Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
   1704       rn_val -= im_val;
   1705       addr = rn_val;
   1706       if (instr->HasW()) {
   1707         set_register(rn, rn_val);
   1708       }
   1709       break;
   1710     }
   1711     case 3: {
   1712       // Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
   1713       rn_val += im_val;
   1714       addr = rn_val;
   1715       if (instr->HasW()) {
   1716         set_register(rn, rn_val);
   1717       }
   1718       break;
   1719     }
   1720     default: {
   1721       UNREACHABLE();
   1722       break;
   1723     }
   1724   }
   1725   if (instr->HasB()) {
   1726     if (instr->HasL()) {
   1727       byte val = ReadBU(addr);
   1728       set_register(rd, val);
   1729     } else {
   1730       byte val = get_register(rd);
   1731       WriteB(addr, val);
   1732     }
   1733   } else {
   1734     if (instr->HasL()) {
   1735       set_register(rd, ReadW(addr, instr));
   1736     } else {
   1737       WriteW(addr, get_register(rd), instr);
   1738     }
   1739   }
   1740 }
   1741 
   1742 
   1743 void Simulator::DecodeType3(Instr* instr) {
   1744   ASSERT(instr->Bits(6, 4) == 0x5 || instr->Bit(4) == 0);
   1745   int rd = instr->RdField();
   1746   int rn = instr->RnField();
   1747   int32_t rn_val = get_register(rn);
   1748   bool shifter_carry_out = 0;
   1749   int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
   1750   int32_t addr = 0;
   1751   switch (instr->PUField()) {
   1752     case 0: {
   1753       ASSERT(!instr->HasW());
   1754       Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
   1755       break;
   1756     }
   1757     case 1: {
   1758       ASSERT(!instr->HasW());
   1759       Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
   1760       break;
   1761     }
   1762     case 2: {
   1763       // Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
   1764       addr = rn_val - shifter_operand;
   1765       if (instr->HasW()) {
   1766         set_register(rn, addr);
   1767       }
   1768       break;
   1769     }
   1770     case 3: {
   1771       if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
   1772         uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
   1773         uint32_t lsbit = static_cast<uint32_t>(instr->ShiftAmountField());
   1774         uint32_t msbit = widthminus1 + lsbit;
   1775         if (msbit <= 31) {
   1776           uint32_t rm_val =
   1777               static_cast<uint32_t>(get_register(instr->RmField()));
   1778           uint32_t extr_val = rm_val << (31 - msbit);
   1779           extr_val = extr_val >> (31 - widthminus1);
   1780           set_register(instr->RdField(), extr_val);
   1781         } else {
   1782           UNREACHABLE();
   1783         }
   1784         return;
   1785       } else {
   1786         // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
   1787         addr = rn_val + shifter_operand;
   1788         if (instr->HasW()) {
   1789           set_register(rn, addr);
   1790         }
   1791       }
   1792       break;
   1793     }
   1794     default: {
   1795       UNREACHABLE();
   1796       break;
   1797     }
   1798   }
   1799   if (instr->HasB()) {
   1800     if (instr->HasL()) {
   1801       uint8_t byte = ReadB(addr);
   1802       set_register(rd, byte);
   1803     } else {
   1804       uint8_t byte = get_register(rd);
   1805       WriteB(addr, byte);
   1806     }
   1807   } else {
   1808     if (instr->HasL()) {
   1809       set_register(rd, ReadW(addr, instr));
   1810     } else {
   1811       WriteW(addr, get_register(rd), instr);
   1812     }
   1813   }
   1814 }
   1815 
   1816 
   1817 void Simulator::DecodeType4(Instr* instr) {
   1818   ASSERT(instr->Bit(22) == 0);  // only allowed to be set in privileged mode
   1819   if (instr->HasL()) {
   1820     // Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
   1821     HandleRList(instr, true);
   1822   } else {
   1823     // Format(instr, "stm'cond'pu 'rn'w, 'rlist");
   1824     HandleRList(instr, false);
   1825   }
   1826 }
   1827 
   1828 
   1829 void Simulator::DecodeType5(Instr* instr) {
   1830   // Format(instr, "b'l'cond 'target");
   1831   int off = (instr->SImmed24Field() << 2);
   1832   intptr_t pc_address = get_pc();
   1833   if (instr->HasLink()) {
   1834     set_register(lr, pc_address + Instr::kInstrSize);
   1835   }
   1836   int pc_reg = get_register(pc);
   1837   set_pc(pc_reg + off);
   1838 }
   1839 
   1840 
   1841 void Simulator::DecodeType6(Instr* instr) {
   1842   DecodeType6CoprocessorIns(instr);
   1843 }
   1844 
   1845 
   1846 void Simulator::DecodeType7(Instr* instr) {
   1847   if (instr->Bit(24) == 1) {
   1848     SoftwareInterrupt(instr);
   1849   } else {
   1850     DecodeTypeVFP(instr);
   1851   }
   1852 }
   1853 
   1854 
   1855 void Simulator::DecodeUnconditional(Instr* instr) {
   1856   if (instr->Bits(7, 4) == 0x0B && instr->Bits(27, 25) == 0 && instr->HasL()) {
   1857     // Load halfword instruction, either register or immediate offset.
   1858     int rd = instr->RdField();
   1859     int rn = instr->RnField();
   1860     int32_t rn_val = get_register(rn);
   1861     int32_t addr = 0;
   1862     int32_t offset;
   1863     if (instr->Bit(22) == 0) {
   1864       // Register offset.
   1865       int rm = instr->RmField();
   1866       offset = get_register(rm);
   1867     } else {
   1868       // Immediate offset
   1869       offset = instr->Bits(3, 0) + (instr->Bits(11, 8) << 4);
   1870     }
   1871     switch (instr->PUField()) {
   1872       case 0: {
   1873         // Post index, negative.
   1874         ASSERT(!instr->HasW());
   1875         addr = rn_val;
   1876         rn_val -= offset;
   1877         set_register(rn, rn_val);
   1878         break;
   1879       }
   1880       case 1: {
   1881         // Post index, positive.
   1882         ASSERT(!instr->HasW());
   1883         addr = rn_val;
   1884         rn_val += offset;
   1885         set_register(rn, rn_val);
   1886         break;
   1887       }
   1888       case 2: {
   1889         // Pre index or offset, negative.
   1890         rn_val -= offset;
   1891         addr = rn_val;
   1892         if (instr->HasW()) {
   1893           set_register(rn, rn_val);
   1894         }
   1895         break;
   1896       }
   1897       case 3: {
   1898         // Pre index or offset, positive.
   1899         rn_val += offset;
   1900         addr = rn_val;
   1901         if (instr->HasW()) {
   1902           set_register(rn, rn_val);
   1903         }
   1904         break;
   1905       }
   1906       default: {
   1907         // The PU field is a 2-bit field.
   1908         UNREACHABLE();
   1909         break;
   1910       }
   1911     }
   1912     // Not sign extending, so load as unsigned.
   1913     uint16_t halfword = ReadH(addr, instr);
   1914     set_register(rd, halfword);
   1915   } else {
   1916     Debugger dbg(this);
   1917     dbg.Stop(instr);
   1918   }
   1919 }
   1920 
   1921 
   1922 // void Simulator::DecodeTypeVFP(Instr* instr)
   1923 // The Following ARMv7 VFPv instructions are currently supported.
   1924 // vmov :Sn = Rt
   1925 // vmov :Rt = Sn
   1926 // vcvt: Dd = Sm
   1927 // vcvt: Sd = Dm
   1928 // Dd = vadd(Dn, Dm)
   1929 // Dd = vsub(Dn, Dm)
   1930 // Dd = vmul(Dn, Dm)
   1931 // Dd = vdiv(Dn, Dm)
   1932 // vcmp(Dd, Dm)
   1933 // VMRS
   1934 void Simulator::DecodeTypeVFP(Instr* instr) {
   1935   ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
   1936 
   1937   int rt = instr->RtField();
   1938   int vm = instr->VmField();
   1939   int vn = instr->VnField();
   1940   int vd = instr->VdField();
   1941 
   1942   if (instr->Bit(23) == 1) {
   1943     if ((instr->Bits(21, 19) == 0x7) &&
   1944         (instr->Bits(18, 16) == 0x5) &&
   1945         (instr->Bits(11, 9) == 0x5) &&
   1946         (instr->Bit(8) == 1) &&
   1947         (instr->Bit(6) == 1) &&
   1948         (instr->Bit(4) == 0)) {
   1949       double dm_val = get_double_from_d_register(vm);
   1950       int32_t int_value = static_cast<int32_t>(dm_val);
   1951       set_s_register_from_sinteger(((vd<<1) | instr->DField()), int_value);
   1952     } else if ((instr->Bits(21, 19) == 0x7) &&
   1953                (instr->Bits(18, 16) == 0x0) &&
   1954                (instr->Bits(11, 9) == 0x5) &&
   1955                (instr->Bit(8) == 1) &&
   1956                (instr->Bit(7) == 1) &&
   1957                (instr->Bit(6) == 1) &&
   1958                (instr->Bit(4) == 0)) {
   1959       int32_t int_value = get_sinteger_from_s_register(((vm<<1) |
   1960                                                        instr->MField()));
   1961       double dbl_value = static_cast<double>(int_value);
   1962       set_d_register_from_double(vd, dbl_value);
   1963     } else if ((instr->Bit(21) == 0x0) &&
   1964                (instr->Bit(20) == 0x0) &&
   1965                (instr->Bits(11, 9) == 0x5) &&
   1966                (instr->Bit(8) == 1) &&
   1967                (instr->Bit(6) == 0) &&
   1968                (instr->Bit(4) == 0)) {
   1969       double dn_value = get_double_from_d_register(vn);
   1970       double dm_value = get_double_from_d_register(vm);
   1971       double dd_value = dn_value / dm_value;
   1972       set_d_register_from_double(vd, dd_value);
   1973     } else if ((instr->Bits(21, 20) == 0x3) &&
   1974                (instr->Bits(19, 16) == 0x4) &&
   1975                (instr->Bits(11, 9) == 0x5) &&
   1976                (instr->Bit(8) == 0x1) &&
   1977                (instr->Bit(6) == 0x1) &&
   1978                (instr->Bit(4) == 0x0)) {
   1979       double dd_value = get_double_from_d_register(vd);
   1980       double dm_value = get_double_from_d_register(vm);
   1981       Compute_FPSCR_Flags(dd_value, dm_value);
   1982     } else if ((instr->Bits(23, 20) == 0xF) &&
   1983                (instr->Bits(19, 16) == 0x1) &&
   1984                (instr->Bits(11, 8) == 0xA) &&
   1985                (instr->Bits(7, 5) == 0x0) &&
   1986                (instr->Bit(4) == 0x1)    &&
   1987                (instr->Bits(3, 0) == 0x0)) {
   1988       if (instr->Bits(15, 12) == 0xF)
   1989         Copy_FPSCR_to_APSR();
   1990       else
   1991         UNIMPLEMENTED();  // Not used by V8.
   1992     } else {
   1993       UNIMPLEMENTED();  // Not used by V8.
   1994     }
   1995   } else if (instr->Bit(21) == 1) {
   1996     if ((instr->Bit(20) == 0x1) &&
   1997         (instr->Bits(11, 9) == 0x5) &&
   1998         (instr->Bit(8) == 0x1) &&
   1999         (instr->Bit(6) == 0) &&
   2000         (instr->Bit(4) == 0)) {
   2001       double dn_value = get_double_from_d_register(vn);
   2002       double dm_value = get_double_from_d_register(vm);
   2003       double dd_value = dn_value + dm_value;
   2004       set_d_register_from_double(vd, dd_value);
   2005     } else if ((instr->Bit(20) == 0x1) &&
   2006                (instr->Bits(11, 9) == 0x5) &&
   2007                (instr->Bit(8) == 0x1) &&
   2008                (instr->Bit(6) == 1) &&
   2009                (instr->Bit(4) == 0)) {
   2010       double dn_value = get_double_from_d_register(vn);
   2011       double dm_value = get_double_from_d_register(vm);
   2012       double dd_value = dn_value - dm_value;
   2013       set_d_register_from_double(vd, dd_value);
   2014     } else if ((instr->Bit(20) == 0x0) &&
   2015                (instr->Bits(11, 9) == 0x5) &&
   2016                (instr->Bit(8) == 0x1) &&
   2017                (instr->Bit(6) == 0) &&
   2018                (instr->Bit(4) == 0)) {
   2019       double dn_value = get_double_from_d_register(vn);
   2020       double dm_value = get_double_from_d_register(vm);
   2021       double dd_value = dn_value * dm_value;
   2022       set_d_register_from_double(vd, dd_value);
   2023     } else {
   2024       UNIMPLEMENTED();  // Not used by V8.
   2025     }
   2026   } else {
   2027     if ((instr->Bit(20) == 0x0) &&
   2028         (instr->Bits(11, 8) == 0xA) &&
   2029         (instr->Bits(6, 5) == 0x0) &&
   2030         (instr->Bit(4) == 1) &&
   2031         (instr->Bits(3, 0) == 0x0)) {
   2032       int32_t rs_val = get_register(rt);
   2033       set_s_register_from_sinteger(((vn<<1) | instr->NField()), rs_val);
   2034     } else if ((instr->Bit(20) == 0x1) &&
   2035                (instr->Bits(11, 8) == 0xA) &&
   2036                (instr->Bits(6, 5) == 0x0) &&
   2037                (instr->Bit(4) == 1) &&
   2038                (instr->Bits(3, 0) == 0x0)) {
   2039       int32_t int_value = get_sinteger_from_s_register(((vn<<1) |
   2040                                                        instr->NField()));
   2041       set_register(rt, int_value);
   2042     } else {
   2043       UNIMPLEMENTED();  // Not used by V8.
   2044     }
   2045   }
   2046 }
   2047 
   2048 
   2049 // void Simulator::DecodeType6CoprocessorIns(Instr* instr)
   2050 // Decode Type 6 coprocessor instructions.
   2051 // Dm = vmov(Rt, Rt2)
   2052 // <Rt, Rt2> = vmov(Dm)
   2053 // Ddst = MEM(Rbase + 4*offset).
   2054 // MEM(Rbase + 4*offset) = Dsrc.
   2055 void Simulator::DecodeType6CoprocessorIns(Instr* instr) {
   2056   ASSERT((instr->TypeField() == 6));
   2057 
   2058   if (instr->CoprocessorField() != 0xB) {
   2059     UNIMPLEMENTED();  // Not used by V8.
   2060   } else {
   2061     switch (instr->OpcodeField()) {
   2062       case 0x2:
   2063         // Load and store double to two GP registers
   2064         if (instr->Bits(7, 4) != 0x1) {
   2065           UNIMPLEMENTED();  // Not used by V8.
   2066         } else {
   2067           int rt = instr->RtField();
   2068           int rn = instr->RnField();
   2069           int vm = instr->VmField();
   2070           if (instr->HasL()) {
   2071             int32_t rt_int_value = get_sinteger_from_s_register(2*vm);
   2072             int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1);
   2073 
   2074             set_register(rt, rt_int_value);
   2075             set_register(rn, rn_int_value);
   2076           } else {
   2077             int32_t rs_val = get_register(rt);
   2078             int32_t rn_val = get_register(rn);
   2079 
   2080             set_s_register_from_sinteger(2*vm, rs_val);
   2081             set_s_register_from_sinteger((2*vm+1), rn_val);
   2082           }
   2083         }
   2084         break;
   2085       case 0x8:
   2086       case 0xC: {  // Load and store double to memory.
   2087         int rn = instr->RnField();
   2088         int vd = instr->VdField();
   2089         int offset = instr->Immed8Field();
   2090         if (!instr->HasU()) {
   2091           offset = -offset;
   2092         }
   2093         int32_t address = get_register(rn) + 4 * offset;
   2094         if (instr->HasL()) {
   2095           // Load double from memory: vldr.
   2096           set_s_register_from_sinteger(2*vd, ReadW(address, instr));
   2097           set_s_register_from_sinteger(2*vd + 1, ReadW(address + 4, instr));
   2098         } else {
   2099           // Store double to memory: vstr.
   2100           WriteW(address, get_sinteger_from_s_register(2*vd), instr);
   2101           WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr);
   2102         }
   2103         break;
   2104       }
   2105       default:
   2106         UNIMPLEMENTED();  // Not used by V8.
   2107         break;
   2108     }
   2109   }
   2110 }
   2111 
   2112 
   2113 // Executes the current instruction.
   2114 void Simulator::InstructionDecode(Instr* instr) {
   2115   pc_modified_ = false;
   2116   if (::v8::internal::FLAG_trace_sim) {
   2117     disasm::NameConverter converter;
   2118     disasm::Disassembler dasm(converter);
   2119     // use a reasonably large buffer
   2120     v8::internal::EmbeddedVector<char, 256> buffer;
   2121     dasm.InstructionDecode(buffer,
   2122                            reinterpret_cast<byte*>(instr));
   2123     PrintF("  0x%08x  %s\n", instr, buffer.start());
   2124   }
   2125   if (instr->ConditionField() == special_condition) {
   2126     DecodeUnconditional(instr);
   2127   } else if (ConditionallyExecute(instr)) {
   2128     switch (instr->TypeField()) {
   2129       case 0:
   2130       case 1: {
   2131         DecodeType01(instr);
   2132         break;
   2133       }
   2134       case 2: {
   2135         DecodeType2(instr);
   2136         break;
   2137       }
   2138       case 3: {
   2139         DecodeType3(instr);
   2140         break;
   2141       }
   2142       case 4: {
   2143         DecodeType4(instr);
   2144         break;
   2145       }
   2146       case 5: {
   2147         DecodeType5(instr);
   2148         break;
   2149       }
   2150       case 6: {
   2151         DecodeType6(instr);
   2152         break;
   2153       }
   2154       case 7: {
   2155         DecodeType7(instr);
   2156         break;
   2157       }
   2158       default: {
   2159         UNIMPLEMENTED();
   2160         break;
   2161       }
   2162     }
   2163   }
   2164   if (!pc_modified_) {
   2165     set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
   2166   }
   2167 }
   2168 
   2169 
   2170 void Simulator::Execute() {
   2171   // Get the PC to simulate. Cannot use the accessor here as we need the
   2172   // raw PC value and not the one used as input to arithmetic instructions.
   2173   int program_counter = get_pc();
   2174 
   2175   if (::v8::internal::FLAG_stop_sim_at == 0) {
   2176     // Fast version of the dispatch loop without checking whether the simulator
   2177     // should be stopping at a particular executed instruction.
   2178     while (program_counter != end_sim_pc) {
   2179       Instr* instr = reinterpret_cast<Instr*>(program_counter);
   2180       icount_++;
   2181       InstructionDecode(instr);
   2182       program_counter = get_pc();
   2183     }
   2184   } else {
   2185     // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
   2186     // we reach the particular instuction count.
   2187     while (program_counter != end_sim_pc) {
   2188       Instr* instr = reinterpret_cast<Instr*>(program_counter);
   2189       icount_++;
   2190       if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
   2191         Debugger dbg(this);
   2192         dbg.Debug();
   2193       } else {
   2194         InstructionDecode(instr);
   2195       }
   2196       program_counter = get_pc();
   2197     }
   2198   }
   2199 }
   2200 
   2201 
   2202 int32_t Simulator::Call(byte* entry, int argument_count, ...) {
   2203   va_list parameters;
   2204   va_start(parameters, argument_count);
   2205   // Setup arguments
   2206 
   2207   // First four arguments passed in registers.
   2208   ASSERT(argument_count >= 4);
   2209   set_register(r0, va_arg(parameters, int32_t));
   2210   set_register(r1, va_arg(parameters, int32_t));
   2211   set_register(r2, va_arg(parameters, int32_t));
   2212   set_register(r3, va_arg(parameters, int32_t));
   2213 
   2214   // Remaining arguments passed on stack.
   2215   int original_stack = get_register(sp);
   2216   // Compute position of stack on entry to generated code.
   2217   int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t));
   2218   if (OS::ActivationFrameAlignment() != 0) {
   2219     entry_stack &= -OS::ActivationFrameAlignment();
   2220   }
   2221   // Store remaining arguments on stack, from low to high memory.
   2222   intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
   2223   for (int i = 4; i < argument_count; i++) {
   2224     stack_argument[i - 4] = va_arg(parameters, int32_t);
   2225   }
   2226   va_end(parameters);
   2227   set_register(sp, entry_stack);
   2228 
   2229   // Prepare to execute the code at entry
   2230   set_register(pc, reinterpret_cast<int32_t>(entry));
   2231   // Put down marker for end of simulation. The simulator will stop simulation
   2232   // when the PC reaches this value. By saving the "end simulation" value into
   2233   // the LR the simulation stops when returning to this call point.
   2234   set_register(lr, end_sim_pc);
   2235 
   2236   // Remember the values of callee-saved registers.
   2237   // The code below assumes that r9 is not used as sb (static base) in
   2238   // simulator code and therefore is regarded as a callee-saved register.
   2239   int32_t r4_val = get_register(r4);
   2240   int32_t r5_val = get_register(r5);
   2241   int32_t r6_val = get_register(r6);
   2242   int32_t r7_val = get_register(r7);
   2243   int32_t r8_val = get_register(r8);
   2244   int32_t r9_val = get_register(r9);
   2245   int32_t r10_val = get_register(r10);
   2246   int32_t r11_val = get_register(r11);
   2247 
   2248   // Setup the callee-saved registers with a known value. To be able to check
   2249   // that they are preserved properly across JS execution.
   2250   int32_t callee_saved_value = icount_;
   2251   set_register(r4, callee_saved_value);
   2252   set_register(r5, callee_saved_value);
   2253   set_register(r6, callee_saved_value);
   2254   set_register(r7, callee_saved_value);
   2255   set_register(r8, callee_saved_value);
   2256   set_register(r9, callee_saved_value);
   2257   set_register(r10, callee_saved_value);
   2258   set_register(r11, callee_saved_value);
   2259 
   2260   // Start the simulation
   2261   Execute();
   2262 
   2263   // Check that the callee-saved registers have been preserved.
   2264   CHECK_EQ(callee_saved_value, get_register(r4));
   2265   CHECK_EQ(callee_saved_value, get_register(r5));
   2266   CHECK_EQ(callee_saved_value, get_register(r6));
   2267   CHECK_EQ(callee_saved_value, get_register(r7));
   2268   CHECK_EQ(callee_saved_value, get_register(r8));
   2269   CHECK_EQ(callee_saved_value, get_register(r9));
   2270   CHECK_EQ(callee_saved_value, get_register(r10));
   2271   CHECK_EQ(callee_saved_value, get_register(r11));
   2272 
   2273   // Restore callee-saved registers with the original value.
   2274   set_register(r4, r4_val);
   2275   set_register(r5, r5_val);
   2276   set_register(r6, r6_val);
   2277   set_register(r7, r7_val);
   2278   set_register(r8, r8_val);
   2279   set_register(r9, r9_val);
   2280   set_register(r10, r10_val);
   2281   set_register(r11, r11_val);
   2282 
   2283   // Pop stack passed arguments.
   2284   CHECK_EQ(entry_stack, get_register(sp));
   2285   set_register(sp, original_stack);
   2286 
   2287   int32_t result = get_register(r0);
   2288   return result;
   2289 }
   2290 
   2291 
   2292 uintptr_t Simulator::PushAddress(uintptr_t address) {
   2293   int new_sp = get_register(sp) - sizeof(uintptr_t);
   2294   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
   2295   *stack_slot = address;
   2296   set_register(sp, new_sp);
   2297   return new_sp;
   2298 }
   2299 
   2300 
   2301 uintptr_t Simulator::PopAddress() {
   2302   int current_sp = get_register(sp);
   2303   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
   2304   uintptr_t address = *stack_slot;
   2305   set_register(sp, current_sp + sizeof(uintptr_t));
   2306   return address;
   2307 }
   2308 
   2309 
   2310 } }  // namespace assembler::arm
   2311 
   2312 #endif  // !defined(__arm__)
   2313