Home | History | Annotate | Download | only in arm
      1 // Copyright 2012 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 <cmath>
     30 #include <cstdarg>
     31 #include "v8.h"
     32 
     33 #if V8_TARGET_ARCH_ARM
     34 
     35 #include "disasm.h"
     36 #include "assembler.h"
     37 #include "codegen.h"
     38 #include "arm/constants-arm.h"
     39 #include "arm/simulator-arm.h"
     40 
     41 #if defined(USE_SIMULATOR)
     42 
     43 // Only build the simulator if not compiling for real ARM hardware.
     44 namespace v8 {
     45 namespace internal {
     46 
     47 // This macro provides a platform independent use of sscanf. The reason for
     48 // SScanF not being implemented in a platform independent way through
     49 // ::v8::internal::OS in the same way as SNPrintF is that the
     50 // Windows C Run-Time Library does not provide vsscanf.
     51 #define SScanF sscanf  // NOLINT
     52 
     53 // The ArmDebugger class is used by the simulator while debugging simulated ARM
     54 // code.
     55 class ArmDebugger {
     56  public:
     57   explicit ArmDebugger(Simulator* sim) : sim_(sim) { }
     58   ~ArmDebugger();
     59 
     60   void Stop(Instruction* instr);
     61   void Debug();
     62 
     63  private:
     64   static const Instr kBreakpointInstr =
     65       (al | (7*B25) | (1*B24) | kBreakpoint);
     66   static const Instr kNopInstr = (al | (13*B21));
     67 
     68   Simulator* sim_;
     69 
     70   int32_t GetRegisterValue(int regnum);
     71   double GetRegisterPairDoubleValue(int regnum);
     72   double GetVFPDoubleRegisterValue(int regnum);
     73   bool GetValue(const char* desc, int32_t* value);
     74   bool GetVFPSingleValue(const char* desc, float* value);
     75   bool GetVFPDoubleValue(const char* desc, double* value);
     76 
     77   // Set or delete a breakpoint. Returns true if successful.
     78   bool SetBreakpoint(Instruction* breakpc);
     79   bool DeleteBreakpoint(Instruction* breakpc);
     80 
     81   // Undo and redo all breakpoints. This is needed to bracket disassembly and
     82   // execution to skip past breakpoints when run from the debugger.
     83   void UndoBreakpoints();
     84   void RedoBreakpoints();
     85 };
     86 
     87 
     88 ArmDebugger::~ArmDebugger() {
     89 }
     90 
     91 
     92 
     93 #ifdef GENERATED_CODE_COVERAGE
     94 static FILE* coverage_log = NULL;
     95 
     96 
     97 static void InitializeCoverage() {
     98   char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
     99   if (file_name != NULL) {
    100     coverage_log = fopen(file_name, "aw+");
    101   }
    102 }
    103 
    104 
    105 void ArmDebugger::Stop(Instruction* instr) {
    106   // Get the stop code.
    107   uint32_t code = instr->SvcValue() & kStopCodeMask;
    108   // Retrieve the encoded address, which comes just after this stop.
    109   char** msg_address =
    110     reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
    111   char* msg = *msg_address;
    112   ASSERT(msg != NULL);
    113 
    114   // Update this stop description.
    115   if (isWatchedStop(code) && !watched_stops_[code].desc) {
    116     watched_stops_[code].desc = msg;
    117   }
    118 
    119   if (strlen(msg) > 0) {
    120     if (coverage_log != NULL) {
    121       fprintf(coverage_log, "%s\n", msg);
    122       fflush(coverage_log);
    123     }
    124     // Overwrite the instruction and address with nops.
    125     instr->SetInstructionBits(kNopInstr);
    126     reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr);
    127   }
    128   sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
    129 }
    130 
    131 #else  // ndef GENERATED_CODE_COVERAGE
    132 
    133 static void InitializeCoverage() {
    134 }
    135 
    136 
    137 void ArmDebugger::Stop(Instruction* instr) {
    138   // Get the stop code.
    139   uint32_t code = instr->SvcValue() & kStopCodeMask;
    140   // Retrieve the encoded address, which comes just after this stop.
    141   char* msg = *reinterpret_cast<char**>(sim_->get_pc()
    142                                         + Instruction::kInstrSize);
    143   // Update this stop description.
    144   if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) {
    145     sim_->watched_stops_[code].desc = msg;
    146   }
    147   // Print the stop message and code if it is not the default code.
    148   if (code != kMaxStopCode) {
    149     PrintF("Simulator hit stop %u: %s\n", code, msg);
    150   } else {
    151     PrintF("Simulator hit %s\n", msg);
    152   }
    153   sim_->set_pc(sim_->get_pc() + 2 * Instruction::kInstrSize);
    154   Debug();
    155 }
    156 #endif
    157 
    158 
    159 int32_t ArmDebugger::GetRegisterValue(int regnum) {
    160   if (regnum == kPCRegister) {
    161     return sim_->get_pc();
    162   } else {
    163     return sim_->get_register(regnum);
    164   }
    165 }
    166 
    167 
    168 double ArmDebugger::GetRegisterPairDoubleValue(int regnum) {
    169   return sim_->get_double_from_register_pair(regnum);
    170 }
    171 
    172 
    173 double ArmDebugger::GetVFPDoubleRegisterValue(int regnum) {
    174   return sim_->get_double_from_d_register(regnum);
    175 }
    176 
    177 
    178 bool ArmDebugger::GetValue(const char* desc, int32_t* value) {
    179   int regnum = Registers::Number(desc);
    180   if (regnum != kNoRegister) {
    181     *value = GetRegisterValue(regnum);
    182     return true;
    183   } else {
    184     if (strncmp(desc, "0x", 2) == 0) {
    185       return SScanF(desc + 2, "%x", reinterpret_cast<uint32_t*>(value)) == 1;
    186     } else {
    187       return SScanF(desc, "%u", reinterpret_cast<uint32_t*>(value)) == 1;
    188     }
    189   }
    190   return false;
    191 }
    192 
    193 
    194 bool ArmDebugger::GetVFPSingleValue(const char* desc, float* value) {
    195   bool is_double;
    196   int regnum = VFPRegisters::Number(desc, &is_double);
    197   if (regnum != kNoRegister && !is_double) {
    198     *value = sim_->get_float_from_s_register(regnum);
    199     return true;
    200   }
    201   return false;
    202 }
    203 
    204 
    205 bool ArmDebugger::GetVFPDoubleValue(const char* desc, double* value) {
    206   bool is_double;
    207   int regnum = VFPRegisters::Number(desc, &is_double);
    208   if (regnum != kNoRegister && is_double) {
    209     *value = sim_->get_double_from_d_register(regnum);
    210     return true;
    211   }
    212   return false;
    213 }
    214 
    215 
    216 bool ArmDebugger::SetBreakpoint(Instruction* breakpc) {
    217   // Check if a breakpoint can be set. If not return without any side-effects.
    218   if (sim_->break_pc_ != NULL) {
    219     return false;
    220   }
    221 
    222   // Set the breakpoint.
    223   sim_->break_pc_ = breakpc;
    224   sim_->break_instr_ = breakpc->InstructionBits();
    225   // Not setting the breakpoint instruction in the code itself. It will be set
    226   // when the debugger shell continues.
    227   return true;
    228 }
    229 
    230 
    231 bool ArmDebugger::DeleteBreakpoint(Instruction* breakpc) {
    232   if (sim_->break_pc_ != NULL) {
    233     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    234   }
    235 
    236   sim_->break_pc_ = NULL;
    237   sim_->break_instr_ = 0;
    238   return true;
    239 }
    240 
    241 
    242 void ArmDebugger::UndoBreakpoints() {
    243   if (sim_->break_pc_ != NULL) {
    244     sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
    245   }
    246 }
    247 
    248 
    249 void ArmDebugger::RedoBreakpoints() {
    250   if (sim_->break_pc_ != NULL) {
    251     sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
    252   }
    253 }
    254 
    255 
    256 void ArmDebugger::Debug() {
    257   intptr_t last_pc = -1;
    258   bool done = false;
    259 
    260 #define COMMAND_SIZE 63
    261 #define ARG_SIZE 255
    262 
    263 #define STR(a) #a
    264 #define XSTR(a) STR(a)
    265 
    266   char cmd[COMMAND_SIZE + 1];
    267   char arg1[ARG_SIZE + 1];
    268   char arg2[ARG_SIZE + 1];
    269   char* argv[3] = { cmd, arg1, arg2 };
    270 
    271   // make sure to have a proper terminating character if reaching the limit
    272   cmd[COMMAND_SIZE] = 0;
    273   arg1[ARG_SIZE] = 0;
    274   arg2[ARG_SIZE] = 0;
    275 
    276   // Undo all set breakpoints while running in the debugger shell. This will
    277   // make them invisible to all commands.
    278   UndoBreakpoints();
    279 
    280   while (!done && !sim_->has_bad_pc()) {
    281     if (last_pc != sim_->get_pc()) {
    282       disasm::NameConverter converter;
    283       disasm::Disassembler dasm(converter);
    284       // use a reasonably large buffer
    285       v8::internal::EmbeddedVector<char, 256> buffer;
    286       dasm.InstructionDecode(buffer,
    287                              reinterpret_cast<byte*>(sim_->get_pc()));
    288       PrintF("  0x%08x  %s\n", sim_->get_pc(), buffer.start());
    289       last_pc = sim_->get_pc();
    290     }
    291     char* line = ReadLine("sim> ");
    292     if (line == NULL) {
    293       break;
    294     } else {
    295       char* last_input = sim_->last_debugger_input();
    296       if (strcmp(line, "\n") == 0 && last_input != NULL) {
    297         line = last_input;
    298       } else {
    299         // Ownership is transferred to sim_;
    300         sim_->set_last_debugger_input(line);
    301       }
    302       // Use sscanf to parse the individual parts of the command line. At the
    303       // moment no command expects more than two parameters.
    304       int argc = SScanF(line,
    305                         "%" XSTR(COMMAND_SIZE) "s "
    306                         "%" XSTR(ARG_SIZE) "s "
    307                         "%" XSTR(ARG_SIZE) "s",
    308                         cmd, arg1, arg2);
    309       if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
    310         sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
    311       } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
    312         // Execute the one instruction we broke at with breakpoints disabled.
    313         sim_->InstructionDecode(reinterpret_cast<Instruction*>(sim_->get_pc()));
    314         // Leave the debugger shell.
    315         done = true;
    316       } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
    317         if (argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0)) {
    318           int32_t value;
    319           float svalue;
    320           double dvalue;
    321           if (strcmp(arg1, "all") == 0) {
    322             for (int i = 0; i < kNumRegisters; i++) {
    323               value = GetRegisterValue(i);
    324               PrintF("%3s: 0x%08x %10d", Registers::Name(i), value, value);
    325               if ((argc == 3 && strcmp(arg2, "fp") == 0) &&
    326                   i < 8 &&
    327                   (i % 2) == 0) {
    328                 dvalue = GetRegisterPairDoubleValue(i);
    329                 PrintF(" (%f)\n", dvalue);
    330               } else {
    331                 PrintF("\n");
    332               }
    333             }
    334             for (int i = 0; i < DwVfpRegister::NumRegisters(); i++) {
    335               dvalue = GetVFPDoubleRegisterValue(i);
    336               uint64_t as_words = BitCast<uint64_t>(dvalue);
    337               PrintF("%3s: %f 0x%08x %08x\n",
    338                      VFPRegisters::Name(i, true),
    339                      dvalue,
    340                      static_cast<uint32_t>(as_words >> 32),
    341                      static_cast<uint32_t>(as_words & 0xffffffff));
    342             }
    343           } else {
    344             if (GetValue(arg1, &value)) {
    345               PrintF("%s: 0x%08x %d \n", arg1, value, value);
    346             } else if (GetVFPSingleValue(arg1, &svalue)) {
    347               uint32_t as_word = BitCast<uint32_t>(svalue);
    348               PrintF("%s: %f 0x%08x\n", arg1, svalue, as_word);
    349             } else if (GetVFPDoubleValue(arg1, &dvalue)) {
    350               uint64_t as_words = BitCast<uint64_t>(dvalue);
    351               PrintF("%s: %f 0x%08x %08x\n",
    352                      arg1,
    353                      dvalue,
    354                      static_cast<uint32_t>(as_words >> 32),
    355                      static_cast<uint32_t>(as_words & 0xffffffff));
    356             } else {
    357               PrintF("%s unrecognized\n", arg1);
    358             }
    359           }
    360         } else {
    361           PrintF("print <register>\n");
    362         }
    363       } else if ((strcmp(cmd, "po") == 0)
    364                  || (strcmp(cmd, "printobject") == 0)) {
    365         if (argc == 2) {
    366           int32_t value;
    367           if (GetValue(arg1, &value)) {
    368             Object* obj = reinterpret_cast<Object*>(value);
    369             PrintF("%s: \n", arg1);
    370 #ifdef DEBUG
    371             obj->PrintLn();
    372 #else
    373             obj->ShortPrint();
    374             PrintF("\n");
    375 #endif
    376           } else {
    377             PrintF("%s unrecognized\n", arg1);
    378           }
    379         } else {
    380           PrintF("printobject <value>\n");
    381         }
    382       } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
    383         int32_t* cur = NULL;
    384         int32_t* end = NULL;
    385         int next_arg = 1;
    386 
    387         if (strcmp(cmd, "stack") == 0) {
    388           cur = reinterpret_cast<int32_t*>(sim_->get_register(Simulator::sp));
    389         } else {  // "mem"
    390           int32_t value;
    391           if (!GetValue(arg1, &value)) {
    392             PrintF("%s unrecognized\n", arg1);
    393             continue;
    394           }
    395           cur = reinterpret_cast<int32_t*>(value);
    396           next_arg++;
    397         }
    398 
    399         int32_t words;
    400         if (argc == next_arg) {
    401           words = 10;
    402         } else {
    403           if (!GetValue(argv[next_arg], &words)) {
    404             words = 10;
    405           }
    406         }
    407         end = cur + words;
    408 
    409         while (cur < end) {
    410           PrintF("  0x%08x:  0x%08x %10d",
    411                  reinterpret_cast<intptr_t>(cur), *cur, *cur);
    412           HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
    413           int value = *cur;
    414           Heap* current_heap = v8::internal::Isolate::Current()->heap();
    415           if (((value & 1) == 0) || current_heap->Contains(obj)) {
    416             PrintF(" (");
    417             if ((value & 1) == 0) {
    418               PrintF("smi %d", value / 2);
    419             } else {
    420               obj->ShortPrint();
    421             }
    422             PrintF(")");
    423           }
    424           PrintF("\n");
    425           cur++;
    426         }
    427       } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) {
    428         disasm::NameConverter converter;
    429         disasm::Disassembler dasm(converter);
    430         // use a reasonably large buffer
    431         v8::internal::EmbeddedVector<char, 256> buffer;
    432 
    433         byte* prev = NULL;
    434         byte* cur = NULL;
    435         byte* end = NULL;
    436 
    437         if (argc == 1) {
    438           cur = reinterpret_cast<byte*>(sim_->get_pc());
    439           end = cur + (10 * Instruction::kInstrSize);
    440         } else if (argc == 2) {
    441           int regnum = Registers::Number(arg1);
    442           if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) {
    443             // The argument is an address or a register name.
    444             int32_t value;
    445             if (GetValue(arg1, &value)) {
    446               cur = reinterpret_cast<byte*>(value);
    447               // Disassemble 10 instructions at <arg1>.
    448               end = cur + (10 * Instruction::kInstrSize);
    449             }
    450           } else {
    451             // The argument is the number of instructions.
    452             int32_t value;
    453             if (GetValue(arg1, &value)) {
    454               cur = reinterpret_cast<byte*>(sim_->get_pc());
    455               // Disassemble <arg1> instructions.
    456               end = cur + (value * Instruction::kInstrSize);
    457             }
    458           }
    459         } else {
    460           int32_t value1;
    461           int32_t value2;
    462           if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
    463             cur = reinterpret_cast<byte*>(value1);
    464             end = cur + (value2 * Instruction::kInstrSize);
    465           }
    466         }
    467 
    468         while (cur < end) {
    469           prev = cur;
    470           cur += dasm.InstructionDecode(buffer, cur);
    471           PrintF("  0x%08x  %s\n",
    472                  reinterpret_cast<intptr_t>(prev), buffer.start());
    473         }
    474       } else if (strcmp(cmd, "gdb") == 0) {
    475         PrintF("relinquishing control to gdb\n");
    476         v8::internal::OS::DebugBreak();
    477         PrintF("regaining control from gdb\n");
    478       } else if (strcmp(cmd, "break") == 0) {
    479         if (argc == 2) {
    480           int32_t value;
    481           if (GetValue(arg1, &value)) {
    482             if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
    483               PrintF("setting breakpoint failed\n");
    484             }
    485           } else {
    486             PrintF("%s unrecognized\n", arg1);
    487           }
    488         } else {
    489           PrintF("break <address>\n");
    490         }
    491       } else if (strcmp(cmd, "del") == 0) {
    492         if (!DeleteBreakpoint(NULL)) {
    493           PrintF("deleting breakpoint failed\n");
    494         }
    495       } else if (strcmp(cmd, "flags") == 0) {
    496         PrintF("N flag: %d; ", sim_->n_flag_);
    497         PrintF("Z flag: %d; ", sim_->z_flag_);
    498         PrintF("C flag: %d; ", sim_->c_flag_);
    499         PrintF("V flag: %d\n", sim_->v_flag_);
    500         PrintF("INVALID OP flag: %d; ", sim_->inv_op_vfp_flag_);
    501         PrintF("DIV BY ZERO flag: %d; ", sim_->div_zero_vfp_flag_);
    502         PrintF("OVERFLOW flag: %d; ", sim_->overflow_vfp_flag_);
    503         PrintF("UNDERFLOW flag: %d; ", sim_->underflow_vfp_flag_);
    504         PrintF("INEXACT flag: %d;\n", sim_->inexact_vfp_flag_);
    505       } else if (strcmp(cmd, "stop") == 0) {
    506         int32_t value;
    507         intptr_t stop_pc = sim_->get_pc() - 2 * Instruction::kInstrSize;
    508         Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
    509         Instruction* msg_address =
    510           reinterpret_cast<Instruction*>(stop_pc + Instruction::kInstrSize);
    511         if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
    512           // Remove the current stop.
    513           if (sim_->isStopInstruction(stop_instr)) {
    514             stop_instr->SetInstructionBits(kNopInstr);
    515             msg_address->SetInstructionBits(kNopInstr);
    516           } else {
    517             PrintF("Not at debugger stop.\n");
    518           }
    519         } else if (argc == 3) {
    520           // Print information about all/the specified breakpoint(s).
    521           if (strcmp(arg1, "info") == 0) {
    522             if (strcmp(arg2, "all") == 0) {
    523               PrintF("Stop information:\n");
    524               for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
    525                 sim_->PrintStopInfo(i);
    526               }
    527             } else if (GetValue(arg2, &value)) {
    528               sim_->PrintStopInfo(value);
    529             } else {
    530               PrintF("Unrecognized argument.\n");
    531             }
    532           } else if (strcmp(arg1, "enable") == 0) {
    533             // Enable all/the specified breakpoint(s).
    534             if (strcmp(arg2, "all") == 0) {
    535               for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
    536                 sim_->EnableStop(i);
    537               }
    538             } else if (GetValue(arg2, &value)) {
    539               sim_->EnableStop(value);
    540             } else {
    541               PrintF("Unrecognized argument.\n");
    542             }
    543           } else if (strcmp(arg1, "disable") == 0) {
    544             // Disable all/the specified breakpoint(s).
    545             if (strcmp(arg2, "all") == 0) {
    546               for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
    547                 sim_->DisableStop(i);
    548               }
    549             } else if (GetValue(arg2, &value)) {
    550               sim_->DisableStop(value);
    551             } else {
    552               PrintF("Unrecognized argument.\n");
    553             }
    554           }
    555         } else {
    556           PrintF("Wrong usage. Use help command for more information.\n");
    557         }
    558       } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) {
    559         ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
    560         PrintF("Trace of executed instructions is %s\n",
    561                ::v8::internal::FLAG_trace_sim ? "on" : "off");
    562       } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
    563         PrintF("cont\n");
    564         PrintF("  continue execution (alias 'c')\n");
    565         PrintF("stepi\n");
    566         PrintF("  step one instruction (alias 'si')\n");
    567         PrintF("print <register>\n");
    568         PrintF("  print register content (alias 'p')\n");
    569         PrintF("  use register name 'all' to print all registers\n");
    570         PrintF("  add argument 'fp' to print register pair double values\n");
    571         PrintF("printobject <register>\n");
    572         PrintF("  print an object from a register (alias 'po')\n");
    573         PrintF("flags\n");
    574         PrintF("  print flags\n");
    575         PrintF("stack [<words>]\n");
    576         PrintF("  dump stack content, default dump 10 words)\n");
    577         PrintF("mem <address> [<words>]\n");
    578         PrintF("  dump memory content, default dump 10 words)\n");
    579         PrintF("disasm [<instructions>]\n");
    580         PrintF("disasm [<address/register>]\n");
    581         PrintF("disasm [[<address/register>] <instructions>]\n");
    582         PrintF("  disassemble code, default is 10 instructions\n");
    583         PrintF("  from pc (alias 'di')\n");
    584         PrintF("gdb\n");
    585         PrintF("  enter gdb\n");
    586         PrintF("break <address>\n");
    587         PrintF("  set a break point on the address\n");
    588         PrintF("del\n");
    589         PrintF("  delete the breakpoint\n");
    590         PrintF("trace (alias 't')\n");
    591         PrintF("  toogle the tracing of all executed statements\n");
    592         PrintF("stop feature:\n");
    593         PrintF("  Description:\n");
    594         PrintF("    Stops are debug instructions inserted by\n");
    595         PrintF("    the Assembler::stop() function.\n");
    596         PrintF("    When hitting a stop, the Simulator will\n");
    597         PrintF("    stop and and give control to the ArmDebugger.\n");
    598         PrintF("    The first %d stop codes are watched:\n",
    599                Simulator::kNumOfWatchedStops);
    600         PrintF("    - They can be enabled / disabled: the Simulator\n");
    601         PrintF("      will / won't stop when hitting them.\n");
    602         PrintF("    - The Simulator keeps track of how many times they \n");
    603         PrintF("      are met. (See the info command.) Going over a\n");
    604         PrintF("      disabled stop still increases its counter. \n");
    605         PrintF("  Commands:\n");
    606         PrintF("    stop info all/<code> : print infos about number <code>\n");
    607         PrintF("      or all stop(s).\n");
    608         PrintF("    stop enable/disable all/<code> : enables / disables\n");
    609         PrintF("      all or number <code> stop(s)\n");
    610         PrintF("    stop unstop\n");
    611         PrintF("      ignore the stop instruction at the current location\n");
    612         PrintF("      from now on\n");
    613       } else {
    614         PrintF("Unknown command: %s\n", cmd);
    615       }
    616     }
    617   }
    618 
    619   // Add all the breakpoints back to stop execution and enter the debugger
    620   // shell when hit.
    621   RedoBreakpoints();
    622 
    623 #undef COMMAND_SIZE
    624 #undef ARG_SIZE
    625 
    626 #undef STR
    627 #undef XSTR
    628 }
    629 
    630 
    631 static bool ICacheMatch(void* one, void* two) {
    632   ASSERT((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
    633   ASSERT((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
    634   return one == two;
    635 }
    636 
    637 
    638 static uint32_t ICacheHash(void* key) {
    639   return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
    640 }
    641 
    642 
    643 static bool AllOnOnePage(uintptr_t start, int size) {
    644   intptr_t start_page = (start & ~CachePage::kPageMask);
    645   intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
    646   return start_page == end_page;
    647 }
    648 
    649 
    650 void Simulator::set_last_debugger_input(char* input) {
    651   DeleteArray(last_debugger_input_);
    652   last_debugger_input_ = input;
    653 }
    654 
    655 
    656 void Simulator::FlushICache(v8::internal::HashMap* i_cache,
    657                             void* start_addr,
    658                             size_t size) {
    659   intptr_t start = reinterpret_cast<intptr_t>(start_addr);
    660   int intra_line = (start & CachePage::kLineMask);
    661   start -= intra_line;
    662   size += intra_line;
    663   size = ((size - 1) | CachePage::kLineMask) + 1;
    664   int offset = (start & CachePage::kPageMask);
    665   while (!AllOnOnePage(start, size - 1)) {
    666     int bytes_to_flush = CachePage::kPageSize - offset;
    667     FlushOnePage(i_cache, start, bytes_to_flush);
    668     start += bytes_to_flush;
    669     size -= bytes_to_flush;
    670     ASSERT_EQ(0, start & CachePage::kPageMask);
    671     offset = 0;
    672   }
    673   if (size != 0) {
    674     FlushOnePage(i_cache, start, size);
    675   }
    676 }
    677 
    678 
    679 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) {
    680   v8::internal::HashMap::Entry* entry = i_cache->Lookup(page,
    681                                                         ICacheHash(page),
    682                                                         true);
    683   if (entry->value == NULL) {
    684     CachePage* new_page = new CachePage();
    685     entry->value = new_page;
    686   }
    687   return reinterpret_cast<CachePage*>(entry->value);
    688 }
    689 
    690 
    691 // Flush from start up to and not including start + size.
    692 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache,
    693                              intptr_t start,
    694                              int size) {
    695   ASSERT(size <= CachePage::kPageSize);
    696   ASSERT(AllOnOnePage(start, size - 1));
    697   ASSERT((start & CachePage::kLineMask) == 0);
    698   ASSERT((size & CachePage::kLineMask) == 0);
    699   void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
    700   int offset = (start & CachePage::kPageMask);
    701   CachePage* cache_page = GetCachePage(i_cache, page);
    702   char* valid_bytemap = cache_page->ValidityByte(offset);
    703   memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
    704 }
    705 
    706 
    707 void Simulator::CheckICache(v8::internal::HashMap* i_cache,
    708                             Instruction* instr) {
    709   intptr_t address = reinterpret_cast<intptr_t>(instr);
    710   void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
    711   void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
    712   int offset = (address & CachePage::kPageMask);
    713   CachePage* cache_page = GetCachePage(i_cache, page);
    714   char* cache_valid_byte = cache_page->ValidityByte(offset);
    715   bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
    716   char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
    717   if (cache_hit) {
    718     // Check that the data in memory matches the contents of the I-cache.
    719     CHECK(memcmp(reinterpret_cast<void*>(instr),
    720                  cache_page->CachedData(offset),
    721                  Instruction::kInstrSize) == 0);
    722   } else {
    723     // Cache miss.  Load memory into the cache.
    724     OS::MemCopy(cached_line, line, CachePage::kLineLength);
    725     *cache_valid_byte = CachePage::LINE_VALID;
    726   }
    727 }
    728 
    729 
    730 void Simulator::Initialize(Isolate* isolate) {
    731   if (isolate->simulator_initialized()) return;
    732   isolate->set_simulator_initialized(true);
    733   ::v8::internal::ExternalReference::set_redirector(isolate,
    734                                                     &RedirectExternalReference);
    735 }
    736 
    737 
    738 Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
    739   i_cache_ = isolate_->simulator_i_cache();
    740   if (i_cache_ == NULL) {
    741     i_cache_ = new v8::internal::HashMap(&ICacheMatch);
    742     isolate_->set_simulator_i_cache(i_cache_);
    743   }
    744   Initialize(isolate);
    745   // Set up simulator support first. Some of this information is needed to
    746   // setup the architecture state.
    747   size_t stack_size = 1 * 1024*1024;  // allocate 1MB for stack
    748   stack_ = reinterpret_cast<char*>(malloc(stack_size));
    749   pc_modified_ = false;
    750   icount_ = 0;
    751   break_pc_ = NULL;
    752   break_instr_ = 0;
    753 
    754   // Set up architecture state.
    755   // All registers are initialized to zero to start with.
    756   for (int i = 0; i < num_registers; i++) {
    757     registers_[i] = 0;
    758   }
    759   n_flag_ = false;
    760   z_flag_ = false;
    761   c_flag_ = false;
    762   v_flag_ = false;
    763 
    764   // Initializing VFP registers.
    765   // All registers are initialized to zero to start with
    766   // even though s_registers_ & d_registers_ share the same
    767   // physical registers in the target.
    768   for (int i = 0; i < num_d_registers * 2; i++) {
    769     vfp_registers_[i] = 0;
    770   }
    771   n_flag_FPSCR_ = false;
    772   z_flag_FPSCR_ = false;
    773   c_flag_FPSCR_ = false;
    774   v_flag_FPSCR_ = false;
    775   FPSCR_rounding_mode_ = RZ;
    776   FPSCR_default_NaN_mode_ = true;
    777 
    778   inv_op_vfp_flag_ = false;
    779   div_zero_vfp_flag_ = false;
    780   overflow_vfp_flag_ = false;
    781   underflow_vfp_flag_ = false;
    782   inexact_vfp_flag_ = false;
    783 
    784   // The sp is initialized to point to the bottom (high address) of the
    785   // allocated stack area. To be safe in potential stack underflows we leave
    786   // some buffer below.
    787   registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64;
    788   // The lr and pc are initialized to a known bad value that will cause an
    789   // access violation if the simulator ever tries to execute it.
    790   registers_[pc] = bad_lr;
    791   registers_[lr] = bad_lr;
    792   InitializeCoverage();
    793 
    794   last_debugger_input_ = NULL;
    795 }
    796 
    797 
    798 // When the generated code calls an external reference we need to catch that in
    799 // the simulator.  The external reference will be a function compiled for the
    800 // host architecture.  We need to call that function instead of trying to
    801 // execute it with the simulator.  We do that by redirecting the external
    802 // reference to a svc (Supervisor Call) instruction that is handled by
    803 // the simulator.  We write the original destination of the jump just at a known
    804 // offset from the svc instruction so the simulator knows what to call.
    805 class Redirection {
    806  public:
    807   Redirection(void* external_function, ExternalReference::Type type)
    808       : external_function_(external_function),
    809         swi_instruction_(al | (0xf*B24) | kCallRtRedirected),
    810         type_(type),
    811         next_(NULL) {
    812     Isolate* isolate = Isolate::Current();
    813     next_ = isolate->simulator_redirection();
    814     Simulator::current(isolate)->
    815         FlushICache(isolate->simulator_i_cache(),
    816                     reinterpret_cast<void*>(&swi_instruction_),
    817                     Instruction::kInstrSize);
    818     isolate->set_simulator_redirection(this);
    819   }
    820 
    821   void* address_of_swi_instruction() {
    822     return reinterpret_cast<void*>(&swi_instruction_);
    823   }
    824 
    825   void* external_function() { return external_function_; }
    826   ExternalReference::Type type() { return type_; }
    827 
    828   static Redirection* Get(void* external_function,
    829                           ExternalReference::Type type) {
    830     Isolate* isolate = Isolate::Current();
    831     Redirection* current = isolate->simulator_redirection();
    832     for (; current != NULL; current = current->next_) {
    833       if (current->external_function_ == external_function) {
    834         ASSERT_EQ(current->type(), type);
    835         return current;
    836       }
    837     }
    838     return new Redirection(external_function, type);
    839   }
    840 
    841   static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
    842     char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
    843     char* addr_of_redirection =
    844         addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
    845     return reinterpret_cast<Redirection*>(addr_of_redirection);
    846   }
    847 
    848  private:
    849   void* external_function_;
    850   uint32_t swi_instruction_;
    851   ExternalReference::Type type_;
    852   Redirection* next_;
    853 };
    854 
    855 
    856 void* Simulator::RedirectExternalReference(void* external_function,
    857                                            ExternalReference::Type type) {
    858   Redirection* redirection = Redirection::Get(external_function, type);
    859   return redirection->address_of_swi_instruction();
    860 }
    861 
    862 
    863 // Get the active Simulator for the current thread.
    864 Simulator* Simulator::current(Isolate* isolate) {
    865   v8::internal::Isolate::PerIsolateThreadData* isolate_data =
    866       isolate->FindOrAllocatePerThreadDataForThisThread();
    867   ASSERT(isolate_data != NULL);
    868 
    869   Simulator* sim = isolate_data->simulator();
    870   if (sim == NULL) {
    871     // TODO(146): delete the simulator object when a thread/isolate goes away.
    872     sim = new Simulator(isolate);
    873     isolate_data->set_simulator(sim);
    874   }
    875   return sim;
    876 }
    877 
    878 
    879 // Sets the register in the architecture state. It will also deal with updating
    880 // Simulator internal state for special registers such as PC.
    881 void Simulator::set_register(int reg, int32_t value) {
    882   ASSERT((reg >= 0) && (reg < num_registers));
    883   if (reg == pc) {
    884     pc_modified_ = true;
    885   }
    886   registers_[reg] = value;
    887 }
    888 
    889 
    890 // Get the register from the architecture state. This function does handle
    891 // the special case of accessing the PC register.
    892 int32_t Simulator::get_register(int reg) const {
    893   ASSERT((reg >= 0) && (reg < num_registers));
    894   // Stupid code added to avoid bug in GCC.
    895   // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
    896   if (reg >= num_registers) return 0;
    897   // End stupid code.
    898   return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0);
    899 }
    900 
    901 
    902 double Simulator::get_double_from_register_pair(int reg) {
    903   ASSERT((reg >= 0) && (reg < num_registers) && ((reg % 2) == 0));
    904 
    905   double dm_val = 0.0;
    906   // Read the bits from the unsigned integer register_[] array
    907   // into the double precision floating point value and return it.
    908   char buffer[2 * sizeof(vfp_registers_[0])];
    909   OS::MemCopy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
    910   OS::MemCopy(&dm_val, buffer, 2 * sizeof(registers_[0]));
    911   return(dm_val);
    912 }
    913 
    914 
    915 void Simulator::set_register_pair_from_double(int reg, double* value) {
    916   ASSERT((reg >= 0) && (reg < num_registers) && ((reg % 2) == 0));
    917   memcpy(registers_ + reg, value, sizeof(*value));
    918 }
    919 
    920 
    921 void Simulator::set_dw_register(int dreg, const int* dbl) {
    922   ASSERT((dreg >= 0) && (dreg < num_d_registers));
    923   registers_[dreg] = dbl[0];
    924   registers_[dreg + 1] = dbl[1];
    925 }
    926 
    927 
    928 void Simulator::get_d_register(int dreg, uint64_t* value) {
    929   ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
    930   memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value));
    931 }
    932 
    933 
    934 void Simulator::set_d_register(int dreg, const uint64_t* value) {
    935   ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
    936   memcpy(vfp_registers_ + dreg * 2, value, sizeof(*value));
    937 }
    938 
    939 
    940 void Simulator::get_d_register(int dreg, uint32_t* value) {
    941   ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
    942   memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value) * 2);
    943 }
    944 
    945 
    946 void Simulator::set_d_register(int dreg, const uint32_t* value) {
    947   ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
    948   memcpy(vfp_registers_ + dreg * 2, value, sizeof(*value) * 2);
    949 }
    950 
    951 
    952 void Simulator::get_q_register(int qreg, uint64_t* value) {
    953   ASSERT((qreg >= 0) && (qreg < num_q_registers));
    954   memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 2);
    955 }
    956 
    957 
    958 void Simulator::set_q_register(int qreg, const uint64_t* value) {
    959   ASSERT((qreg >= 0) && (qreg < num_q_registers));
    960   memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 2);
    961 }
    962 
    963 
    964 void Simulator::get_q_register(int qreg, uint32_t* value) {
    965   ASSERT((qreg >= 0) && (qreg < num_q_registers));
    966   memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 4);
    967 }
    968 
    969 
    970 void Simulator::set_q_register(int qreg, const uint32_t* value) {
    971   ASSERT((qreg >= 0) && (qreg < num_q_registers));
    972   memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 4);
    973 }
    974 
    975 
    976 // Raw access to the PC register.
    977 void Simulator::set_pc(int32_t value) {
    978   pc_modified_ = true;
    979   registers_[pc] = value;
    980 }
    981 
    982 
    983 bool Simulator::has_bad_pc() const {
    984   return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc));
    985 }
    986 
    987 
    988 // Raw access to the PC register without the special adjustment when reading.
    989 int32_t Simulator::get_pc() const {
    990   return registers_[pc];
    991 }
    992 
    993 
    994 // Getting from and setting into VFP registers.
    995 void Simulator::set_s_register(int sreg, unsigned int value) {
    996   ASSERT((sreg >= 0) && (sreg < num_s_registers));
    997   vfp_registers_[sreg] = value;
    998 }
    999 
   1000 
   1001 unsigned int Simulator::get_s_register(int sreg) const {
   1002   ASSERT((sreg >= 0) && (sreg < num_s_registers));
   1003   return vfp_registers_[sreg];
   1004 }
   1005 
   1006 
   1007 template<class InputType, int register_size>
   1008 void Simulator::SetVFPRegister(int reg_index, const InputType& value) {
   1009   ASSERT(reg_index >= 0);
   1010   if (register_size == 1) ASSERT(reg_index < num_s_registers);
   1011   if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters());
   1012 
   1013   char buffer[register_size * sizeof(vfp_registers_[0])];
   1014   OS::MemCopy(buffer, &value, register_size * sizeof(vfp_registers_[0]));
   1015   OS::MemCopy(&vfp_registers_[reg_index * register_size], buffer,
   1016               register_size * sizeof(vfp_registers_[0]));
   1017 }
   1018 
   1019 
   1020 template<class ReturnType, int register_size>
   1021 ReturnType Simulator::GetFromVFPRegister(int reg_index) {
   1022   ASSERT(reg_index >= 0);
   1023   if (register_size == 1) ASSERT(reg_index < num_s_registers);
   1024   if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters());
   1025 
   1026   ReturnType value = 0;
   1027   char buffer[register_size * sizeof(vfp_registers_[0])];
   1028   OS::MemCopy(buffer, &vfp_registers_[register_size * reg_index],
   1029               register_size * sizeof(vfp_registers_[0]));
   1030   OS::MemCopy(&value, buffer, register_size * sizeof(vfp_registers_[0]));
   1031   return value;
   1032 }
   1033 
   1034 
   1035 // Runtime FP routines take:
   1036 // - two double arguments
   1037 // - one double argument and zero or one integer arguments.
   1038 // All are consructed here from r0-r3 or d0, d1 and r0.
   1039 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
   1040   if (use_eabi_hardfloat()) {
   1041     *x = get_double_from_d_register(0);
   1042     *y = get_double_from_d_register(1);
   1043     *z = get_register(0);
   1044   } else {
   1045     // Registers 0 and 1 -> x.
   1046     *x = get_double_from_register_pair(0);
   1047     // Register 2 and 3 -> y.
   1048     *y = get_double_from_register_pair(2);
   1049     // Register 2 -> z
   1050     *z = get_register(2);
   1051   }
   1052 }
   1053 
   1054 
   1055 // The return value is either in r0/r1 or d0.
   1056 void Simulator::SetFpResult(const double& result) {
   1057   if (use_eabi_hardfloat()) {
   1058     char buffer[2 * sizeof(vfp_registers_[0])];
   1059     OS::MemCopy(buffer, &result, sizeof(buffer));
   1060     // Copy result to d0.
   1061     OS::MemCopy(vfp_registers_, buffer, sizeof(buffer));
   1062   } else {
   1063     char buffer[2 * sizeof(registers_[0])];
   1064     OS::MemCopy(buffer, &result, sizeof(buffer));
   1065     // Copy result to r0 and r1.
   1066     OS::MemCopy(registers_, buffer, sizeof(buffer));
   1067   }
   1068 }
   1069 
   1070 
   1071 void Simulator::TrashCallerSaveRegisters() {
   1072   // We don't trash the registers with the return value.
   1073   registers_[2] = 0x50Bad4U;
   1074   registers_[3] = 0x50Bad4U;
   1075   registers_[12] = 0x50Bad4U;
   1076 }
   1077 
   1078 
   1079 // Some Operating Systems allow unaligned access on ARMv7 targets. We
   1080 // assume that unaligned accesses are not allowed unless the v8 build system
   1081 // defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero.
   1082 // The following statements below describes the behavior of the ARM CPUs
   1083 // that don't support unaligned access.
   1084 // Some ARM platforms raise an interrupt on detecting unaligned access.
   1085 // On others it does a funky rotation thing.  For now we
   1086 // simply disallow unaligned reads.  Note that simulator runs have the runtime
   1087 // system running directly on the host system and only generated code is
   1088 // executed in the simulator.  Since the host is typically IA32 we will not
   1089 // get the correct ARM-like behaviour on unaligned accesses for those ARM
   1090 // targets that don't support unaligned loads and stores.
   1091 
   1092 
   1093 int Simulator::ReadW(int32_t addr, Instruction* instr) {
   1094   if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
   1095     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
   1096     return *ptr;
   1097   } else {
   1098     PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1099            addr,
   1100            reinterpret_cast<intptr_t>(instr));
   1101     UNIMPLEMENTED();
   1102     return 0;
   1103   }
   1104 }
   1105 
   1106 
   1107 void Simulator::WriteW(int32_t addr, int value, Instruction* instr) {
   1108   if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
   1109     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
   1110     *ptr = value;
   1111   } else {
   1112     PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1113            addr,
   1114            reinterpret_cast<intptr_t>(instr));
   1115     UNIMPLEMENTED();
   1116   }
   1117 }
   1118 
   1119 
   1120 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
   1121   if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
   1122     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
   1123     return *ptr;
   1124   } else {
   1125     PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08"
   1126            V8PRIxPTR "\n",
   1127            addr,
   1128            reinterpret_cast<intptr_t>(instr));
   1129     UNIMPLEMENTED();
   1130     return 0;
   1131   }
   1132 }
   1133 
   1134 
   1135 int16_t Simulator::ReadH(int32_t addr, Instruction* instr) {
   1136   if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
   1137     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
   1138     return *ptr;
   1139   } else {
   1140     PrintF("Unaligned signed halfword read at 0x%08x\n", addr);
   1141     UNIMPLEMENTED();
   1142     return 0;
   1143   }
   1144 }
   1145 
   1146 
   1147 void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) {
   1148   if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
   1149     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
   1150     *ptr = value;
   1151   } else {
   1152     PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08"
   1153            V8PRIxPTR "\n",
   1154            addr,
   1155            reinterpret_cast<intptr_t>(instr));
   1156     UNIMPLEMENTED();
   1157   }
   1158 }
   1159 
   1160 
   1161 void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) {
   1162   if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
   1163     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
   1164     *ptr = value;
   1165   } else {
   1166     PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
   1167            addr,
   1168            reinterpret_cast<intptr_t>(instr));
   1169     UNIMPLEMENTED();
   1170   }
   1171 }
   1172 
   1173 
   1174 uint8_t Simulator::ReadBU(int32_t addr) {
   1175   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
   1176   return *ptr;
   1177 }
   1178 
   1179 
   1180 int8_t Simulator::ReadB(int32_t addr) {
   1181   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
   1182   return *ptr;
   1183 }
   1184 
   1185 
   1186 void Simulator::WriteB(int32_t addr, uint8_t value) {
   1187   uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
   1188   *ptr = value;
   1189 }
   1190 
   1191 
   1192 void Simulator::WriteB(int32_t addr, int8_t value) {
   1193   int8_t* ptr = reinterpret_cast<int8_t*>(addr);
   1194   *ptr = value;
   1195 }
   1196 
   1197 
   1198 int32_t* Simulator::ReadDW(int32_t addr) {
   1199   if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
   1200     int32_t* ptr = reinterpret_cast<int32_t*>(addr);
   1201     return ptr;
   1202   } else {
   1203     PrintF("Unaligned read at 0x%08x\n", addr);
   1204     UNIMPLEMENTED();
   1205     return 0;
   1206   }
   1207 }
   1208 
   1209 
   1210 void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) {
   1211   if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
   1212     int32_t* ptr = reinterpret_cast<int32_t*>(addr);
   1213     *ptr++ = value1;
   1214     *ptr = value2;
   1215   } else {
   1216     PrintF("Unaligned write at 0x%08x\n", addr);
   1217     UNIMPLEMENTED();
   1218   }
   1219 }
   1220 
   1221 
   1222 // Returns the limit of the stack area to enable checking for stack overflows.
   1223 uintptr_t Simulator::StackLimit() const {
   1224   // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
   1225   // pushing values.
   1226   return reinterpret_cast<uintptr_t>(stack_) + 1024;
   1227 }
   1228 
   1229 
   1230 // Unsupported instructions use Format to print an error and stop execution.
   1231 void Simulator::Format(Instruction* instr, const char* format) {
   1232   PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
   1233          reinterpret_cast<intptr_t>(instr), format);
   1234   UNIMPLEMENTED();
   1235 }
   1236 
   1237 
   1238 // Checks if the current instruction should be executed based on its
   1239 // condition bits.
   1240 bool Simulator::ConditionallyExecute(Instruction* instr) {
   1241   switch (instr->ConditionField()) {
   1242     case eq: return z_flag_;
   1243     case ne: return !z_flag_;
   1244     case cs: return c_flag_;
   1245     case cc: return !c_flag_;
   1246     case mi: return n_flag_;
   1247     case pl: return !n_flag_;
   1248     case vs: return v_flag_;
   1249     case vc: return !v_flag_;
   1250     case hi: return c_flag_ && !z_flag_;
   1251     case ls: return !c_flag_ || z_flag_;
   1252     case ge: return n_flag_ == v_flag_;
   1253     case lt: return n_flag_ != v_flag_;
   1254     case gt: return !z_flag_ && (n_flag_ == v_flag_);
   1255     case le: return z_flag_ || (n_flag_ != v_flag_);
   1256     case al: return true;
   1257     default: UNREACHABLE();
   1258   }
   1259   return false;
   1260 }
   1261 
   1262 
   1263 // Calculate and set the Negative and Zero flags.
   1264 void Simulator::SetNZFlags(int32_t val) {
   1265   n_flag_ = (val < 0);
   1266   z_flag_ = (val == 0);
   1267 }
   1268 
   1269 
   1270 // Set the Carry flag.
   1271 void Simulator::SetCFlag(bool val) {
   1272   c_flag_ = val;
   1273 }
   1274 
   1275 
   1276 // Set the oVerflow flag.
   1277 void Simulator::SetVFlag(bool val) {
   1278   v_flag_ = val;
   1279 }
   1280 
   1281 
   1282 // Calculate C flag value for additions.
   1283 bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
   1284   uint32_t uleft = static_cast<uint32_t>(left);
   1285   uint32_t uright = static_cast<uint32_t>(right);
   1286   uint32_t urest  = 0xffffffffU - uleft;
   1287 
   1288   return (uright > urest) ||
   1289          (carry && (((uright + 1) > urest) || (uright > (urest - 1))));
   1290 }
   1291 
   1292 
   1293 // Calculate C flag value for subtractions.
   1294 bool Simulator::BorrowFrom(int32_t left, int32_t right) {
   1295   uint32_t uleft = static_cast<uint32_t>(left);
   1296   uint32_t uright = static_cast<uint32_t>(right);
   1297 
   1298   return (uright > uleft);
   1299 }
   1300 
   1301 
   1302 // Calculate V flag value for additions and subtractions.
   1303 bool Simulator::OverflowFrom(int32_t alu_out,
   1304                              int32_t left, int32_t right, bool addition) {
   1305   bool overflow;
   1306   if (addition) {
   1307                // operands have the same sign
   1308     overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
   1309                // and operands and result have different sign
   1310                && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
   1311   } else {
   1312                // operands have different signs
   1313     overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
   1314                // and first operand and result have different signs
   1315                && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
   1316   }
   1317   return overflow;
   1318 }
   1319 
   1320 
   1321 // Support for VFP comparisons.
   1322 void Simulator::Compute_FPSCR_Flags(double val1, double val2) {
   1323   if (std::isnan(val1) || std::isnan(val2)) {
   1324     n_flag_FPSCR_ = false;
   1325     z_flag_FPSCR_ = false;
   1326     c_flag_FPSCR_ = true;
   1327     v_flag_FPSCR_ = true;
   1328   // All non-NaN cases.
   1329   } else if (val1 == val2) {
   1330     n_flag_FPSCR_ = false;
   1331     z_flag_FPSCR_ = true;
   1332     c_flag_FPSCR_ = true;
   1333     v_flag_FPSCR_ = false;
   1334   } else if (val1 < val2) {
   1335     n_flag_FPSCR_ = true;
   1336     z_flag_FPSCR_ = false;
   1337     c_flag_FPSCR_ = false;
   1338     v_flag_FPSCR_ = false;
   1339   } else {
   1340     // Case when (val1 > val2).
   1341     n_flag_FPSCR_ = false;
   1342     z_flag_FPSCR_ = false;
   1343     c_flag_FPSCR_ = true;
   1344     v_flag_FPSCR_ = false;
   1345   }
   1346 }
   1347 
   1348 
   1349 void Simulator::Copy_FPSCR_to_APSR() {
   1350   n_flag_ = n_flag_FPSCR_;
   1351   z_flag_ = z_flag_FPSCR_;
   1352   c_flag_ = c_flag_FPSCR_;
   1353   v_flag_ = v_flag_FPSCR_;
   1354 }
   1355 
   1356 
   1357 // Addressing Mode 1 - Data-processing operands:
   1358 // Get the value based on the shifter_operand with register.
   1359 int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) {
   1360   ShiftOp shift = instr->ShiftField();
   1361   int shift_amount = instr->ShiftAmountValue();
   1362   int32_t result = get_register(instr->RmValue());
   1363   if (instr->Bit(4) == 0) {
   1364     // by immediate
   1365     if ((shift == ROR) && (shift_amount == 0)) {
   1366       UNIMPLEMENTED();
   1367       return result;
   1368     } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
   1369       shift_amount = 32;
   1370     }
   1371     switch (shift) {
   1372       case ASR: {
   1373         if (shift_amount == 0) {
   1374           if (result < 0) {
   1375             result = 0xffffffff;
   1376             *carry_out = true;
   1377           } else {
   1378             result = 0;
   1379             *carry_out = false;
   1380           }
   1381         } else {
   1382           result >>= (shift_amount - 1);
   1383           *carry_out = (result & 1) == 1;
   1384           result >>= 1;
   1385         }
   1386         break;
   1387       }
   1388 
   1389       case LSL: {
   1390         if (shift_amount == 0) {
   1391           *carry_out = c_flag_;
   1392         } else {
   1393           result <<= (shift_amount - 1);
   1394           *carry_out = (result < 0);
   1395           result <<= 1;
   1396         }
   1397         break;
   1398       }
   1399 
   1400       case LSR: {
   1401         if (shift_amount == 0) {
   1402           result = 0;
   1403           *carry_out = c_flag_;
   1404         } else {
   1405           uint32_t uresult = static_cast<uint32_t>(result);
   1406           uresult >>= (shift_amount - 1);
   1407           *carry_out = (uresult & 1) == 1;
   1408           uresult >>= 1;
   1409           result = static_cast<int32_t>(uresult);
   1410         }
   1411         break;
   1412       }
   1413 
   1414       case ROR: {
   1415         if (shift_amount == 0) {
   1416           *carry_out = c_flag_;
   1417         } else {
   1418           uint32_t left = static_cast<uint32_t>(result) >> shift_amount;
   1419           uint32_t right = static_cast<uint32_t>(result) << (32 - shift_amount);
   1420           result = right | left;
   1421           *carry_out = (static_cast<uint32_t>(result) >> 31) != 0;
   1422         }
   1423         break;
   1424       }
   1425 
   1426       default: {
   1427         UNREACHABLE();
   1428         break;
   1429       }
   1430     }
   1431   } else {
   1432     // by register
   1433     int rs = instr->RsValue();
   1434     shift_amount = get_register(rs) &0xff;
   1435     switch (shift) {
   1436       case ASR: {
   1437         if (shift_amount == 0) {
   1438           *carry_out = c_flag_;
   1439         } else if (shift_amount < 32) {
   1440           result >>= (shift_amount - 1);
   1441           *carry_out = (result & 1) == 1;
   1442           result >>= 1;
   1443         } else {
   1444           ASSERT(shift_amount >= 32);
   1445           if (result < 0) {
   1446             *carry_out = true;
   1447             result = 0xffffffff;
   1448           } else {
   1449             *carry_out = false;
   1450             result = 0;
   1451           }
   1452         }
   1453         break;
   1454       }
   1455 
   1456       case LSL: {
   1457         if (shift_amount == 0) {
   1458           *carry_out = c_flag_;
   1459         } else if (shift_amount < 32) {
   1460           result <<= (shift_amount - 1);
   1461           *carry_out = (result < 0);
   1462           result <<= 1;
   1463         } else if (shift_amount == 32) {
   1464           *carry_out = (result & 1) == 1;
   1465           result = 0;
   1466         } else {
   1467           ASSERT(shift_amount > 32);
   1468           *carry_out = false;
   1469           result = 0;
   1470         }
   1471         break;
   1472       }
   1473 
   1474       case LSR: {
   1475         if (shift_amount == 0) {
   1476           *carry_out = c_flag_;
   1477         } else if (shift_amount < 32) {
   1478           uint32_t uresult = static_cast<uint32_t>(result);
   1479           uresult >>= (shift_amount - 1);
   1480           *carry_out = (uresult & 1) == 1;
   1481           uresult >>= 1;
   1482           result = static_cast<int32_t>(uresult);
   1483         } else if (shift_amount == 32) {
   1484           *carry_out = (result < 0);
   1485           result = 0;
   1486         } else {
   1487           *carry_out = false;
   1488           result = 0;
   1489         }
   1490         break;
   1491       }
   1492 
   1493       case ROR: {
   1494         if (shift_amount == 0) {
   1495           *carry_out = c_flag_;
   1496         } else {
   1497           uint32_t left = static_cast<uint32_t>(result) >> shift_amount;
   1498           uint32_t right = static_cast<uint32_t>(result) << (32 - shift_amount);
   1499           result = right | left;
   1500           *carry_out = (static_cast<uint32_t>(result) >> 31) != 0;
   1501         }
   1502         break;
   1503       }
   1504 
   1505       default: {
   1506         UNREACHABLE();
   1507         break;
   1508       }
   1509     }
   1510   }
   1511   return result;
   1512 }
   1513 
   1514 
   1515 // Addressing Mode 1 - Data-processing operands:
   1516 // Get the value based on the shifter_operand with immediate.
   1517 int32_t Simulator::GetImm(Instruction* instr, bool* carry_out) {
   1518   int rotate = instr->RotateValue() * 2;
   1519   int immed8 = instr->Immed8Value();
   1520   int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
   1521   *carry_out = (rotate == 0) ? c_flag_ : (imm < 0);
   1522   return imm;
   1523 }
   1524 
   1525 
   1526 static int count_bits(int bit_vector) {
   1527   int count = 0;
   1528   while (bit_vector != 0) {
   1529     if ((bit_vector & 1) != 0) {
   1530       count++;
   1531     }
   1532     bit_vector >>= 1;
   1533   }
   1534   return count;
   1535 }
   1536 
   1537 
   1538 int32_t Simulator::ProcessPU(Instruction* instr,
   1539                              int num_regs,
   1540                              int reg_size,
   1541                              intptr_t* start_address,
   1542                              intptr_t* end_address) {
   1543   int rn = instr->RnValue();
   1544   int32_t rn_val = get_register(rn);
   1545   switch (instr->PUField()) {
   1546     case da_x: {
   1547       UNIMPLEMENTED();
   1548       break;
   1549     }
   1550     case ia_x: {
   1551       *start_address = rn_val;
   1552       *end_address = rn_val + (num_regs * reg_size) - reg_size;
   1553       rn_val = rn_val + (num_regs * reg_size);
   1554       break;
   1555     }
   1556     case db_x: {
   1557       *start_address = rn_val - (num_regs * reg_size);
   1558       *end_address = rn_val - reg_size;
   1559       rn_val = *start_address;
   1560       break;
   1561     }
   1562     case ib_x: {
   1563       *start_address = rn_val + reg_size;
   1564       *end_address = rn_val + (num_regs * reg_size);
   1565       rn_val = *end_address;
   1566       break;
   1567     }
   1568     default: {
   1569       UNREACHABLE();
   1570       break;
   1571     }
   1572   }
   1573   return rn_val;
   1574 }
   1575 
   1576 
   1577 // Addressing Mode 4 - Load and Store Multiple
   1578 void Simulator::HandleRList(Instruction* instr, bool load) {
   1579   int rlist = instr->RlistValue();
   1580   int num_regs = count_bits(rlist);
   1581 
   1582   intptr_t start_address = 0;
   1583   intptr_t end_address = 0;
   1584   int32_t rn_val =
   1585       ProcessPU(instr, num_regs, kPointerSize, &start_address, &end_address);
   1586 
   1587   intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
   1588   // Catch null pointers a little earlier.
   1589   ASSERT(start_address > 8191 || start_address < 0);
   1590   int reg = 0;
   1591   while (rlist != 0) {
   1592     if ((rlist & 1) != 0) {
   1593       if (load) {
   1594         set_register(reg, *address);
   1595       } else {
   1596         *address = get_register(reg);
   1597       }
   1598       address += 1;
   1599     }
   1600     reg++;
   1601     rlist >>= 1;
   1602   }
   1603   ASSERT(end_address == ((intptr_t)address) - 4);
   1604   if (instr->HasW()) {
   1605     set_register(instr->RnValue(), rn_val);
   1606   }
   1607 }
   1608 
   1609 
   1610 // Addressing Mode 6 - Load and Store Multiple Coprocessor registers.
   1611 void Simulator::HandleVList(Instruction* instr) {
   1612   VFPRegPrecision precision =
   1613       (instr->SzValue() == 0) ? kSinglePrecision : kDoublePrecision;
   1614   int operand_size = (precision == kSinglePrecision) ? 4 : 8;
   1615 
   1616   bool load = (instr->VLValue() == 0x1);
   1617 
   1618   int vd;
   1619   int num_regs;
   1620   vd = instr->VFPDRegValue(precision);
   1621   if (precision == kSinglePrecision) {
   1622     num_regs = instr->Immed8Value();
   1623   } else {
   1624     num_regs = instr->Immed8Value() / 2;
   1625   }
   1626 
   1627   intptr_t start_address = 0;
   1628   intptr_t end_address = 0;
   1629   int32_t rn_val =
   1630       ProcessPU(instr, num_regs, operand_size, &start_address, &end_address);
   1631 
   1632   intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
   1633   for (int reg = vd; reg < vd + num_regs; reg++) {
   1634     if (precision == kSinglePrecision) {
   1635       if (load) {
   1636         set_s_register_from_sinteger(
   1637             reg, ReadW(reinterpret_cast<int32_t>(address), instr));
   1638       } else {
   1639         WriteW(reinterpret_cast<int32_t>(address),
   1640                get_sinteger_from_s_register(reg), instr);
   1641       }
   1642       address += 1;
   1643     } else {
   1644       if (load) {
   1645         int32_t data[] = {
   1646           ReadW(reinterpret_cast<int32_t>(address), instr),
   1647           ReadW(reinterpret_cast<int32_t>(address + 1), instr)
   1648         };
   1649         double d;
   1650         OS::MemCopy(&d, data, 8);
   1651         set_d_register_from_double(reg, d);
   1652       } else {
   1653         int32_t data[2];
   1654         double d = get_double_from_d_register(reg);
   1655         OS::MemCopy(data, &d, 8);
   1656         WriteW(reinterpret_cast<int32_t>(address), data[0], instr);
   1657         WriteW(reinterpret_cast<int32_t>(address + 1), data[1], instr);
   1658       }
   1659       address += 2;
   1660     }
   1661   }
   1662   ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address);
   1663   if (instr->HasW()) {
   1664     set_register(instr->RnValue(), rn_val);
   1665   }
   1666 }
   1667 
   1668 
   1669 // Calls into the V8 runtime are based on this very simple interface.
   1670 // Note: To be able to return two values from some calls the code in runtime.cc
   1671 // uses the ObjectPair which is essentially two 32-bit values stuffed into a
   1672 // 64-bit value. With the code below we assume that all runtime calls return
   1673 // 64 bits of result. If they don't, the r1 result register contains a bogus
   1674 // value, which is fine because it is caller-saved.
   1675 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
   1676                                         int32_t arg1,
   1677                                         int32_t arg2,
   1678                                         int32_t arg3,
   1679                                         int32_t arg4,
   1680                                         int32_t arg5);
   1681 
   1682 // These prototypes handle the four types of FP calls.
   1683 typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
   1684 typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
   1685 typedef double (*SimulatorRuntimeFPCall)(double darg0);
   1686 typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
   1687 
   1688 // This signature supports direct call in to API function native callback
   1689 // (refer to InvocationCallback in v8.h).
   1690 typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
   1691 typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
   1692 
   1693 // This signature supports direct call to accessor getter callback.
   1694 typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
   1695 typedef void (*SimulatorRuntimeProfilingGetterCall)(
   1696     int32_t arg0, int32_t arg1, int32_t arg2);
   1697 
   1698 // Software interrupt instructions are used by the simulator to call into the
   1699 // C-based V8 runtime.
   1700 void Simulator::SoftwareInterrupt(Instruction* instr) {
   1701   int svc = instr->SvcValue();
   1702   switch (svc) {
   1703     case kCallRtRedirected: {
   1704       // Check if stack is aligned. Error if not aligned is reported below to
   1705       // include information on the function called.
   1706       bool stack_aligned =
   1707           (get_register(sp)
   1708            & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0;
   1709       Redirection* redirection = Redirection::FromSwiInstruction(instr);
   1710       int32_t arg0 = get_register(r0);
   1711       int32_t arg1 = get_register(r1);
   1712       int32_t arg2 = get_register(r2);
   1713       int32_t arg3 = get_register(r3);
   1714       int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
   1715       int32_t arg4 = stack_pointer[0];
   1716       int32_t arg5 = stack_pointer[1];
   1717       bool fp_call =
   1718          (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
   1719          (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
   1720          (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
   1721          (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
   1722       // This is dodgy but it works because the C entry stubs are never moved.
   1723       // See comment in codegen-arm.cc and bug 1242173.
   1724       int32_t saved_lr = get_register(lr);
   1725       intptr_t external =
   1726           reinterpret_cast<intptr_t>(redirection->external_function());
   1727       if (fp_call) {
   1728         double dval0, dval1;  // one or two double parameters
   1729         int32_t ival;         // zero or one integer parameters
   1730         int64_t iresult = 0;  // integer return value
   1731         double dresult = 0;   // double return value
   1732         GetFpArgs(&dval0, &dval1, &ival);
   1733         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
   1734           SimulatorRuntimeCall generic_target =
   1735             reinterpret_cast<SimulatorRuntimeCall>(external);
   1736           switch (redirection->type()) {
   1737           case ExternalReference::BUILTIN_FP_FP_CALL:
   1738           case ExternalReference::BUILTIN_COMPARE_CALL:
   1739             PrintF("Call to host function at %p with args %f, %f",
   1740                    FUNCTION_ADDR(generic_target), dval0, dval1);
   1741             break;
   1742           case ExternalReference::BUILTIN_FP_CALL:
   1743             PrintF("Call to host function at %p with arg %f",
   1744                 FUNCTION_ADDR(generic_target), dval0);
   1745             break;
   1746           case ExternalReference::BUILTIN_FP_INT_CALL:
   1747             PrintF("Call to host function at %p with args %f, %d",
   1748                    FUNCTION_ADDR(generic_target), dval0, ival);
   1749             break;
   1750           default:
   1751             UNREACHABLE();
   1752             break;
   1753           }
   1754           if (!stack_aligned) {
   1755             PrintF(" with unaligned stack %08x\n", get_register(sp));
   1756           }
   1757           PrintF("\n");
   1758         }
   1759         CHECK(stack_aligned);
   1760         switch (redirection->type()) {
   1761         case ExternalReference::BUILTIN_COMPARE_CALL: {
   1762           SimulatorRuntimeCompareCall target =
   1763             reinterpret_cast<SimulatorRuntimeCompareCall>(external);
   1764           iresult = target(dval0, dval1);
   1765           set_register(r0, static_cast<int32_t>(iresult));
   1766           set_register(r1, static_cast<int32_t>(iresult >> 32));
   1767           break;
   1768         }
   1769         case ExternalReference::BUILTIN_FP_FP_CALL: {
   1770           SimulatorRuntimeFPFPCall target =
   1771             reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
   1772           dresult = target(dval0, dval1);
   1773           SetFpResult(dresult);
   1774           break;
   1775         }
   1776         case ExternalReference::BUILTIN_FP_CALL: {
   1777           SimulatorRuntimeFPCall target =
   1778             reinterpret_cast<SimulatorRuntimeFPCall>(external);
   1779           dresult = target(dval0);
   1780           SetFpResult(dresult);
   1781           break;
   1782         }
   1783         case ExternalReference::BUILTIN_FP_INT_CALL: {
   1784           SimulatorRuntimeFPIntCall target =
   1785             reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
   1786           dresult = target(dval0, ival);
   1787           SetFpResult(dresult);
   1788           break;
   1789         }
   1790         default:
   1791           UNREACHABLE();
   1792           break;
   1793         }
   1794         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
   1795           switch (redirection->type()) {
   1796           case ExternalReference::BUILTIN_COMPARE_CALL:
   1797             PrintF("Returned %08x\n", static_cast<int32_t>(iresult));
   1798             break;
   1799           case ExternalReference::BUILTIN_FP_FP_CALL:
   1800           case ExternalReference::BUILTIN_FP_CALL:
   1801           case ExternalReference::BUILTIN_FP_INT_CALL:
   1802             PrintF("Returned %f\n", dresult);
   1803             break;
   1804           default:
   1805             UNREACHABLE();
   1806             break;
   1807           }
   1808         }
   1809       } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
   1810         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
   1811           PrintF("Call to host function at %p args %08x",
   1812               reinterpret_cast<void*>(external), arg0);
   1813           if (!stack_aligned) {
   1814             PrintF(" with unaligned stack %08x\n", get_register(sp));
   1815           }
   1816           PrintF("\n");
   1817         }
   1818         CHECK(stack_aligned);
   1819         SimulatorRuntimeDirectApiCall target =
   1820             reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
   1821         target(arg0);
   1822       } else if (
   1823           redirection->type() == ExternalReference::PROFILING_API_CALL) {
   1824         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
   1825           PrintF("Call to host function at %p args %08x %08x",
   1826               reinterpret_cast<void*>(external), arg0, arg1);
   1827           if (!stack_aligned) {
   1828             PrintF(" with unaligned stack %08x\n", get_register(sp));
   1829           }
   1830           PrintF("\n");
   1831         }
   1832         CHECK(stack_aligned);
   1833         SimulatorRuntimeProfilingApiCall target =
   1834             reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
   1835         target(arg0, arg1);
   1836       } else if (
   1837           redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
   1838         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
   1839           PrintF("Call to host function at %p args %08x %08x",
   1840               reinterpret_cast<void*>(external), arg0, arg1);
   1841           if (!stack_aligned) {
   1842             PrintF(" with unaligned stack %08x\n", get_register(sp));
   1843           }
   1844           PrintF("\n");
   1845         }
   1846         CHECK(stack_aligned);
   1847         SimulatorRuntimeDirectGetterCall target =
   1848             reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
   1849         target(arg0, arg1);
   1850       } else if (
   1851           redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
   1852         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
   1853           PrintF("Call to host function at %p args %08x %08x %08x",
   1854               reinterpret_cast<void*>(external), arg0, arg1, arg2);
   1855           if (!stack_aligned) {
   1856             PrintF(" with unaligned stack %08x\n", get_register(sp));
   1857           }
   1858           PrintF("\n");
   1859         }
   1860         CHECK(stack_aligned);
   1861         SimulatorRuntimeProfilingGetterCall target =
   1862             reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(
   1863                 external);
   1864         target(arg0, arg1, arg2);
   1865       } else {
   1866         // builtin call.
   1867         ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
   1868         SimulatorRuntimeCall target =
   1869             reinterpret_cast<SimulatorRuntimeCall>(external);
   1870         if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
   1871           PrintF(
   1872               "Call to host function at %p "
   1873               "args %08x, %08x, %08x, %08x, %08x, %08x",
   1874               FUNCTION_ADDR(target),
   1875               arg0,
   1876               arg1,
   1877               arg2,
   1878               arg3,
   1879               arg4,
   1880               arg5);
   1881           if (!stack_aligned) {
   1882             PrintF(" with unaligned stack %08x\n", get_register(sp));
   1883           }
   1884           PrintF("\n");
   1885         }
   1886         CHECK(stack_aligned);
   1887         int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5);
   1888         int32_t lo_res = static_cast<int32_t>(result);
   1889         int32_t hi_res = static_cast<int32_t>(result >> 32);
   1890         if (::v8::internal::FLAG_trace_sim) {
   1891           PrintF("Returned %08x\n", lo_res);
   1892         }
   1893         set_register(r0, lo_res);
   1894         set_register(r1, hi_res);
   1895       }
   1896       set_register(lr, saved_lr);
   1897       set_pc(get_register(lr));
   1898       break;
   1899     }
   1900     case kBreakpoint: {
   1901       ArmDebugger dbg(this);
   1902       dbg.Debug();
   1903       break;
   1904     }
   1905     // stop uses all codes greater than 1 << 23.
   1906     default: {
   1907       if (svc >= (1 << 23)) {
   1908         uint32_t code = svc & kStopCodeMask;
   1909         if (isWatchedStop(code)) {
   1910           IncreaseStopCounter(code);
   1911         }
   1912         // Stop if it is enabled, otherwise go on jumping over the stop
   1913         // and the message address.
   1914         if (isEnabledStop(code)) {
   1915           ArmDebugger dbg(this);
   1916           dbg.Stop(instr);
   1917         } else {
   1918           set_pc(get_pc() + 2 * Instruction::kInstrSize);
   1919         }
   1920       } else {
   1921         // This is not a valid svc code.
   1922         UNREACHABLE();
   1923         break;
   1924       }
   1925     }
   1926   }
   1927 }
   1928 
   1929 
   1930 double Simulator::canonicalizeNaN(double value) {
   1931   return (FPSCR_default_NaN_mode_ && std::isnan(value)) ?
   1932     FixedDoubleArray::canonical_not_the_hole_nan_as_double() : value;
   1933 }
   1934 
   1935 
   1936 // Stop helper functions.
   1937 bool Simulator::isStopInstruction(Instruction* instr) {
   1938   return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
   1939 }
   1940 
   1941 
   1942 bool Simulator::isWatchedStop(uint32_t code) {
   1943   ASSERT(code <= kMaxStopCode);
   1944   return code < kNumOfWatchedStops;
   1945 }
   1946 
   1947 
   1948 bool Simulator::isEnabledStop(uint32_t code) {
   1949   ASSERT(code <= kMaxStopCode);
   1950   // Unwatched stops are always enabled.
   1951   return !isWatchedStop(code) ||
   1952     !(watched_stops_[code].count & kStopDisabledBit);
   1953 }
   1954 
   1955 
   1956 void Simulator::EnableStop(uint32_t code) {
   1957   ASSERT(isWatchedStop(code));
   1958   if (!isEnabledStop(code)) {
   1959     watched_stops_[code].count &= ~kStopDisabledBit;
   1960   }
   1961 }
   1962 
   1963 
   1964 void Simulator::DisableStop(uint32_t code) {
   1965   ASSERT(isWatchedStop(code));
   1966   if (isEnabledStop(code)) {
   1967     watched_stops_[code].count |= kStopDisabledBit;
   1968   }
   1969 }
   1970 
   1971 
   1972 void Simulator::IncreaseStopCounter(uint32_t code) {
   1973   ASSERT(code <= kMaxStopCode);
   1974   ASSERT(isWatchedStop(code));
   1975   if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
   1976     PrintF("Stop counter for code %i has overflowed.\n"
   1977            "Enabling this code and reseting the counter to 0.\n", code);
   1978     watched_stops_[code].count = 0;
   1979     EnableStop(code);
   1980   } else {
   1981     watched_stops_[code].count++;
   1982   }
   1983 }
   1984 
   1985 
   1986 // Print a stop status.
   1987 void Simulator::PrintStopInfo(uint32_t code) {
   1988   ASSERT(code <= kMaxStopCode);
   1989   if (!isWatchedStop(code)) {
   1990     PrintF("Stop not watched.");
   1991   } else {
   1992     const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
   1993     int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
   1994     // Don't print the state of unused breakpoints.
   1995     if (count != 0) {
   1996       if (watched_stops_[code].desc) {
   1997         PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
   1998                code, code, state, count, watched_stops_[code].desc);
   1999       } else {
   2000         PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n",
   2001                code, code, state, count);
   2002       }
   2003     }
   2004   }
   2005 }
   2006 
   2007 
   2008 // Handle execution based on instruction types.
   2009 
   2010 // Instruction types 0 and 1 are both rolled into one function because they
   2011 // only differ in the handling of the shifter_operand.
   2012 void Simulator::DecodeType01(Instruction* instr) {
   2013   int type = instr->TypeValue();
   2014   if ((type == 0) && instr->IsSpecialType0()) {
   2015     // multiply instruction or extra loads and stores
   2016     if (instr->Bits(7, 4) == 9) {
   2017       if (instr->Bit(24) == 0) {
   2018         // Raw field decoding here. Multiply instructions have their Rd in
   2019         // funny places.
   2020         int rn = instr->RnValue();
   2021         int rm = instr->RmValue();
   2022         int rs = instr->RsValue();
   2023         int32_t rs_val = get_register(rs);
   2024         int32_t rm_val = get_register(rm);
   2025         if (instr->Bit(23) == 0) {
   2026           if (instr->Bit(21) == 0) {
   2027             // The MUL instruction description (A 4.1.33) refers to Rd as being
   2028             // the destination for the operation, but it confusingly uses the
   2029             // Rn field to encode it.
   2030             // Format(instr, "mul'cond's 'rn, 'rm, 'rs");
   2031             int rd = rn;  // Remap the rn field to the Rd register.
   2032             int32_t alu_out = rm_val * rs_val;
   2033             set_register(rd, alu_out);
   2034             if (instr->HasS()) {
   2035               SetNZFlags(alu_out);
   2036             }
   2037           } else {
   2038             int rd = instr->RdValue();
   2039             int32_t acc_value = get_register(rd);
   2040             if (instr->Bit(22) == 0) {
   2041               // The MLA instruction description (A 4.1.28) refers to the order
   2042               // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
   2043               // Rn field to encode the Rd register and the Rd field to encode
   2044               // the Rn register.
   2045               // Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
   2046               int32_t mul_out = rm_val * rs_val;
   2047               int32_t result = acc_value + mul_out;
   2048               set_register(rn, result);
   2049             } else {
   2050               // Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd");
   2051               int32_t mul_out = rm_val * rs_val;
   2052               int32_t result = acc_value - mul_out;
   2053               set_register(rn, result);
   2054             }
   2055           }
   2056         } else {
   2057           // The signed/long multiply instructions use the terms RdHi and RdLo
   2058           // when referring to the target registers. They are mapped to the Rn
   2059           // and Rd fields as follows:
   2060           // RdLo == Rd
   2061           // RdHi == Rn (This is confusingly stored in variable rd here
   2062           //             because the mul instruction from above uses the
   2063           //             Rn field to encode the Rd register. Good luck figuring
   2064           //             this out without reading the ARM instruction manual
   2065           //             at a very detailed level.)
   2066           // Format(instr, "'um'al'cond's 'rd, 'rn, 'rs, 'rm");
   2067           int rd_hi = rn;  // Remap the rn field to the RdHi register.
   2068           int rd_lo = instr->RdValue();
   2069           int32_t hi_res = 0;
   2070           int32_t lo_res = 0;
   2071           if (instr->Bit(22) == 1) {
   2072             int64_t left_op  = static_cast<int32_t>(rm_val);
   2073             int64_t right_op = static_cast<int32_t>(rs_val);
   2074             uint64_t result = left_op * right_op;
   2075             hi_res = static_cast<int32_t>(result >> 32);
   2076             lo_res = static_cast<int32_t>(result & 0xffffffff);
   2077           } else {
   2078             // unsigned multiply
   2079             uint64_t left_op  = static_cast<uint32_t>(rm_val);
   2080             uint64_t right_op = static_cast<uint32_t>(rs_val);
   2081             uint64_t result = left_op * right_op;
   2082             hi_res = static_cast<int32_t>(result >> 32);
   2083             lo_res = static_cast<int32_t>(result & 0xffffffff);
   2084           }
   2085           set_register(rd_lo, lo_res);
   2086           set_register(rd_hi, hi_res);
   2087           if (instr->HasS()) {
   2088             UNIMPLEMENTED();
   2089           }
   2090         }
   2091       } else {
   2092         UNIMPLEMENTED();  // Not used by V8.
   2093       }
   2094     } else {
   2095       // extra load/store instructions
   2096       int rd = instr->RdValue();
   2097       int rn = instr->RnValue();
   2098       int32_t rn_val = get_register(rn);
   2099       int32_t addr = 0;
   2100       if (instr->Bit(22) == 0) {
   2101         int rm = instr->RmValue();
   2102         int32_t rm_val = get_register(rm);
   2103         switch (instr->PUField()) {
   2104           case da_x: {
   2105             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
   2106             ASSERT(!instr->HasW());
   2107             addr = rn_val;
   2108             rn_val -= rm_val;
   2109             set_register(rn, rn_val);
   2110             break;
   2111           }
   2112           case ia_x: {
   2113             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
   2114             ASSERT(!instr->HasW());
   2115             addr = rn_val;
   2116             rn_val += rm_val;
   2117             set_register(rn, rn_val);
   2118             break;
   2119           }
   2120           case db_x: {
   2121             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
   2122             rn_val -= rm_val;
   2123             addr = rn_val;
   2124             if (instr->HasW()) {
   2125               set_register(rn, rn_val);
   2126             }
   2127             break;
   2128           }
   2129           case ib_x: {
   2130             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
   2131             rn_val += rm_val;
   2132             addr = rn_val;
   2133             if (instr->HasW()) {
   2134               set_register(rn, rn_val);
   2135             }
   2136             break;
   2137           }
   2138           default: {
   2139             // The PU field is a 2-bit field.
   2140             UNREACHABLE();
   2141             break;
   2142           }
   2143         }
   2144       } else {
   2145         int32_t imm_val = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
   2146         switch (instr->PUField()) {
   2147           case da_x: {
   2148             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
   2149             ASSERT(!instr->HasW());
   2150             addr = rn_val;
   2151             rn_val -= imm_val;
   2152             set_register(rn, rn_val);
   2153             break;
   2154           }
   2155           case ia_x: {
   2156             // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
   2157             ASSERT(!instr->HasW());
   2158             addr = rn_val;
   2159             rn_val += imm_val;
   2160             set_register(rn, rn_val);
   2161             break;
   2162           }
   2163           case db_x: {
   2164             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
   2165             rn_val -= imm_val;
   2166             addr = rn_val;
   2167             if (instr->HasW()) {
   2168               set_register(rn, rn_val);
   2169             }
   2170             break;
   2171           }
   2172           case ib_x: {
   2173             // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
   2174             rn_val += imm_val;
   2175             addr = rn_val;
   2176             if (instr->HasW()) {
   2177               set_register(rn, rn_val);
   2178             }
   2179             break;
   2180           }
   2181           default: {
   2182             // The PU field is a 2-bit field.
   2183             UNREACHABLE();
   2184             break;
   2185           }
   2186         }
   2187       }
   2188       if (((instr->Bits(7, 4) & 0xd) == 0xd) && (instr->Bit(20) == 0)) {
   2189         ASSERT((rd % 2) == 0);
   2190         if (instr->HasH()) {
   2191           // The strd instruction.
   2192           int32_t value1 = get_register(rd);
   2193           int32_t value2 = get_register(rd+1);
   2194           WriteDW(addr, value1, value2);
   2195         } else {
   2196           // The ldrd instruction.
   2197           int* rn_data = ReadDW(addr);
   2198           set_dw_register(rd, rn_data);
   2199         }
   2200       } else if (instr->HasH()) {
   2201         if (instr->HasSign()) {
   2202           if (instr->HasL()) {
   2203             int16_t val = ReadH(addr, instr);
   2204             set_register(rd, val);
   2205           } else {
   2206             int16_t val = get_register(rd);
   2207             WriteH(addr, val, instr);
   2208           }
   2209         } else {
   2210           if (instr->HasL()) {
   2211             uint16_t val = ReadHU(addr, instr);
   2212             set_register(rd, val);
   2213           } else {
   2214             uint16_t val = get_register(rd);
   2215             WriteH(addr, val, instr);
   2216           }
   2217         }
   2218       } else {
   2219         // signed byte loads
   2220         ASSERT(instr->HasSign());
   2221         ASSERT(instr->HasL());
   2222         int8_t val = ReadB(addr);
   2223         set_register(rd, val);
   2224       }
   2225       return;
   2226     }
   2227   } else if ((type == 0) && instr->IsMiscType0()) {
   2228     if (instr->Bits(22, 21) == 1) {
   2229       int rm = instr->RmValue();
   2230       switch (instr->BitField(7, 4)) {
   2231         case BX:
   2232           set_pc(get_register(rm));
   2233           break;
   2234         case BLX: {
   2235           uint32_t old_pc = get_pc();
   2236           set_pc(get_register(rm));
   2237           set_register(lr, old_pc + Instruction::kInstrSize);
   2238           break;
   2239         }
   2240         case BKPT: {
   2241           ArmDebugger dbg(this);
   2242           PrintF("Simulator hit BKPT.\n");
   2243           dbg.Debug();
   2244           break;
   2245         }
   2246         default:
   2247           UNIMPLEMENTED();
   2248       }
   2249     } else if (instr->Bits(22, 21) == 3) {
   2250       int rm = instr->RmValue();
   2251       int rd = instr->RdValue();
   2252       switch (instr->BitField(7, 4)) {
   2253         case CLZ: {
   2254           uint32_t bits = get_register(rm);
   2255           int leading_zeros = 0;
   2256           if (bits == 0) {
   2257             leading_zeros = 32;
   2258           } else {
   2259             while ((bits & 0x80000000u) == 0) {
   2260               bits <<= 1;
   2261               leading_zeros++;
   2262             }
   2263           }
   2264           set_register(rd, leading_zeros);
   2265           break;
   2266         }
   2267         default:
   2268           UNIMPLEMENTED();
   2269       }
   2270     } else {
   2271       PrintF("%08x\n", instr->InstructionBits());
   2272       UNIMPLEMENTED();
   2273     }
   2274   } else if ((type == 1) && instr->IsNopType1()) {
   2275     // NOP.
   2276   } else {
   2277     int rd = instr->RdValue();
   2278     int rn = instr->RnValue();
   2279     int32_t rn_val = get_register(rn);
   2280     int32_t shifter_operand = 0;
   2281     bool shifter_carry_out = 0;
   2282     if (type == 0) {
   2283       shifter_operand = GetShiftRm(instr, &shifter_carry_out);
   2284     } else {
   2285       ASSERT(instr->TypeValue() == 1);
   2286       shifter_operand = GetImm(instr, &shifter_carry_out);
   2287     }
   2288     int32_t alu_out;
   2289 
   2290     switch (instr->OpcodeField()) {
   2291       case AND: {
   2292         // Format(instr, "and'cond's 'rd, 'rn, 'shift_rm");
   2293         // Format(instr, "and'cond's 'rd, 'rn, 'imm");
   2294         alu_out = rn_val & shifter_operand;
   2295         set_register(rd, alu_out);
   2296         if (instr->HasS()) {
   2297           SetNZFlags(alu_out);
   2298           SetCFlag(shifter_carry_out);
   2299         }
   2300         break;
   2301       }
   2302 
   2303       case EOR: {
   2304         // Format(instr, "eor'cond's 'rd, 'rn, 'shift_rm");
   2305         // Format(instr, "eor'cond's 'rd, 'rn, 'imm");
   2306         alu_out = rn_val ^ shifter_operand;
   2307         set_register(rd, alu_out);
   2308         if (instr->HasS()) {
   2309           SetNZFlags(alu_out);
   2310           SetCFlag(shifter_carry_out);
   2311         }
   2312         break;
   2313       }
   2314 
   2315       case SUB: {
   2316         // Format(instr, "sub'cond's 'rd, 'rn, 'shift_rm");
   2317         // Format(instr, "sub'cond's 'rd, 'rn, 'imm");
   2318         alu_out = rn_val - shifter_operand;
   2319         set_register(rd, alu_out);
   2320         if (instr->HasS()) {
   2321           SetNZFlags(alu_out);
   2322           SetCFlag(!BorrowFrom(rn_val, shifter_operand));
   2323           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
   2324         }
   2325         break;
   2326       }
   2327 
   2328       case RSB: {
   2329         // Format(instr, "rsb'cond's 'rd, 'rn, 'shift_rm");
   2330         // Format(instr, "rsb'cond's 'rd, 'rn, 'imm");
   2331         alu_out = shifter_operand - rn_val;
   2332         set_register(rd, alu_out);
   2333         if (instr->HasS()) {
   2334           SetNZFlags(alu_out);
   2335           SetCFlag(!BorrowFrom(shifter_operand, rn_val));
   2336           SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));
   2337         }
   2338         break;
   2339       }
   2340 
   2341       case ADD: {
   2342         // Format(instr, "add'cond's 'rd, 'rn, 'shift_rm");
   2343         // Format(instr, "add'cond's 'rd, 'rn, 'imm");
   2344         alu_out = rn_val + shifter_operand;
   2345         set_register(rd, alu_out);
   2346         if (instr->HasS()) {
   2347           SetNZFlags(alu_out);
   2348           SetCFlag(CarryFrom(rn_val, shifter_operand));
   2349           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
   2350         }
   2351         break;
   2352       }
   2353 
   2354       case ADC: {
   2355         // Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm");
   2356         // Format(instr, "adc'cond's 'rd, 'rn, 'imm");
   2357         alu_out = rn_val + shifter_operand + GetCarry();
   2358         set_register(rd, alu_out);
   2359         if (instr->HasS()) {
   2360           SetNZFlags(alu_out);
   2361           SetCFlag(CarryFrom(rn_val, shifter_operand, GetCarry()));
   2362           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
   2363         }
   2364         break;
   2365       }
   2366 
   2367       case SBC: {
   2368         Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm");
   2369         Format(instr, "sbc'cond's 'rd, 'rn, 'imm");
   2370         break;
   2371       }
   2372 
   2373       case RSC: {
   2374         Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm");
   2375         Format(instr, "rsc'cond's 'rd, 'rn, 'imm");
   2376         break;
   2377       }
   2378 
   2379       case TST: {
   2380         if (instr->HasS()) {
   2381           // Format(instr, "tst'cond 'rn, 'shift_rm");
   2382           // Format(instr, "tst'cond 'rn, 'imm");
   2383           alu_out = rn_val & shifter_operand;
   2384           SetNZFlags(alu_out);
   2385           SetCFlag(shifter_carry_out);
   2386         } else {
   2387           // Format(instr, "movw'cond 'rd, 'imm").
   2388           alu_out = instr->ImmedMovwMovtValue();
   2389           set_register(rd, alu_out);
   2390         }
   2391         break;
   2392       }
   2393 
   2394       case TEQ: {
   2395         if (instr->HasS()) {
   2396           // Format(instr, "teq'cond 'rn, 'shift_rm");
   2397           // Format(instr, "teq'cond 'rn, 'imm");
   2398           alu_out = rn_val ^ shifter_operand;
   2399           SetNZFlags(alu_out);
   2400           SetCFlag(shifter_carry_out);
   2401         } else {
   2402           // Other instructions matching this pattern are handled in the
   2403           // miscellaneous instructions part above.
   2404           UNREACHABLE();
   2405         }
   2406         break;
   2407       }
   2408 
   2409       case CMP: {
   2410         if (instr->HasS()) {
   2411           // Format(instr, "cmp'cond 'rn, 'shift_rm");
   2412           // Format(instr, "cmp'cond 'rn, 'imm");
   2413           alu_out = rn_val - shifter_operand;
   2414           SetNZFlags(alu_out);
   2415           SetCFlag(!BorrowFrom(rn_val, shifter_operand));
   2416           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
   2417         } else {
   2418           // Format(instr, "movt'cond 'rd, 'imm").
   2419           alu_out = (get_register(rd) & 0xffff) |
   2420               (instr->ImmedMovwMovtValue() << 16);
   2421           set_register(rd, alu_out);
   2422         }
   2423         break;
   2424       }
   2425 
   2426       case CMN: {
   2427         if (instr->HasS()) {
   2428           // Format(instr, "cmn'cond 'rn, 'shift_rm");
   2429           // Format(instr, "cmn'cond 'rn, 'imm");
   2430           alu_out = rn_val + shifter_operand;
   2431           SetNZFlags(alu_out);
   2432           SetCFlag(CarryFrom(rn_val, shifter_operand));
   2433           SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
   2434         } else {
   2435           // Other instructions matching this pattern are handled in the
   2436           // miscellaneous instructions part above.
   2437           UNREACHABLE();
   2438         }
   2439         break;
   2440       }
   2441 
   2442       case ORR: {
   2443         // Format(instr, "orr'cond's 'rd, 'rn, 'shift_rm");
   2444         // Format(instr, "orr'cond's 'rd, 'rn, 'imm");
   2445         alu_out = rn_val | shifter_operand;
   2446         set_register(rd, alu_out);
   2447         if (instr->HasS()) {
   2448           SetNZFlags(alu_out);
   2449           SetCFlag(shifter_carry_out);
   2450         }
   2451         break;
   2452       }
   2453 
   2454       case MOV: {
   2455         // Format(instr, "mov'cond's 'rd, 'shift_rm");
   2456         // Format(instr, "mov'cond's 'rd, 'imm");
   2457         alu_out = shifter_operand;
   2458         set_register(rd, alu_out);
   2459         if (instr->HasS()) {
   2460           SetNZFlags(alu_out);
   2461           SetCFlag(shifter_carry_out);
   2462         }
   2463         break;
   2464       }
   2465 
   2466       case BIC: {
   2467         // Format(instr, "bic'cond's 'rd, 'rn, 'shift_rm");
   2468         // Format(instr, "bic'cond's 'rd, 'rn, 'imm");
   2469         alu_out = rn_val & ~shifter_operand;
   2470         set_register(rd, alu_out);
   2471         if (instr->HasS()) {
   2472           SetNZFlags(alu_out);
   2473           SetCFlag(shifter_carry_out);
   2474         }
   2475         break;
   2476       }
   2477 
   2478       case MVN: {
   2479         // Format(instr, "mvn'cond's 'rd, 'shift_rm");
   2480         // Format(instr, "mvn'cond's 'rd, 'imm");
   2481         alu_out = ~shifter_operand;
   2482         set_register(rd, alu_out);
   2483         if (instr->HasS()) {
   2484           SetNZFlags(alu_out);
   2485           SetCFlag(shifter_carry_out);
   2486         }
   2487         break;
   2488       }
   2489 
   2490       default: {
   2491         UNREACHABLE();
   2492         break;
   2493       }
   2494     }
   2495   }
   2496 }
   2497 
   2498 
   2499 void Simulator::DecodeType2(Instruction* instr) {
   2500   int rd = instr->RdValue();
   2501   int rn = instr->RnValue();
   2502   int32_t rn_val = get_register(rn);
   2503   int32_t im_val = instr->Offset12Value();
   2504   int32_t addr = 0;
   2505   switch (instr->PUField()) {
   2506     case da_x: {
   2507       // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
   2508       ASSERT(!instr->HasW());
   2509       addr = rn_val;
   2510       rn_val -= im_val;
   2511       set_register(rn, rn_val);
   2512       break;
   2513     }
   2514     case ia_x: {
   2515       // Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
   2516       ASSERT(!instr->HasW());
   2517       addr = rn_val;
   2518       rn_val += im_val;
   2519       set_register(rn, rn_val);
   2520       break;
   2521     }
   2522     case db_x: {
   2523       // Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
   2524       rn_val -= im_val;
   2525       addr = rn_val;
   2526       if (instr->HasW()) {
   2527         set_register(rn, rn_val);
   2528       }
   2529       break;
   2530     }
   2531     case ib_x: {
   2532       // Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
   2533       rn_val += im_val;
   2534       addr = rn_val;
   2535       if (instr->HasW()) {
   2536         set_register(rn, rn_val);
   2537       }
   2538       break;
   2539     }
   2540     default: {
   2541       UNREACHABLE();
   2542       break;
   2543     }
   2544   }
   2545   if (instr->HasB()) {
   2546     if (instr->HasL()) {
   2547       byte val = ReadBU(addr);
   2548       set_register(rd, val);
   2549     } else {
   2550       byte val = get_register(rd);
   2551       WriteB(addr, val);
   2552     }
   2553   } else {
   2554     if (instr->HasL()) {
   2555       set_register(rd, ReadW(addr, instr));
   2556     } else {
   2557       WriteW(addr, get_register(rd), instr);
   2558     }
   2559   }
   2560 }
   2561 
   2562 
   2563 void Simulator::DecodeType3(Instruction* instr) {
   2564   int rd = instr->RdValue();
   2565   int rn = instr->RnValue();
   2566   int32_t rn_val = get_register(rn);
   2567   bool shifter_carry_out = 0;
   2568   int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
   2569   int32_t addr = 0;
   2570   switch (instr->PUField()) {
   2571     case da_x: {
   2572       ASSERT(!instr->HasW());
   2573       Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
   2574       UNIMPLEMENTED();
   2575       break;
   2576     }
   2577     case ia_x: {
   2578       if (instr->Bit(4) == 0) {
   2579         // Memop.
   2580       } else {
   2581         if (instr->Bit(5) == 0) {
   2582           switch (instr->Bits(22, 21)) {
   2583             case 0:
   2584               if (instr->Bit(20) == 0) {
   2585                 if (instr->Bit(6) == 0) {
   2586                   // Pkhbt.
   2587                   uint32_t rn_val = get_register(rn);
   2588                   uint32_t rm_val = get_register(instr->RmValue());
   2589                   int32_t shift = instr->Bits(11, 7);
   2590                   rm_val <<= shift;
   2591                   set_register(rd, (rn_val & 0xFFFF) | (rm_val & 0xFFFF0000U));
   2592                 } else {
   2593                   // Pkhtb.
   2594                   uint32_t rn_val = get_register(rn);
   2595                   int32_t rm_val = get_register(instr->RmValue());
   2596                   int32_t shift = instr->Bits(11, 7);
   2597                   if (shift == 0) {
   2598                     shift = 32;
   2599                   }
   2600                   rm_val >>= shift;
   2601                   set_register(rd, (rn_val & 0xFFFF0000U) | (rm_val & 0xFFFF));
   2602                 }
   2603               } else {
   2604                 UNIMPLEMENTED();
   2605               }
   2606               break;
   2607             case 1:
   2608               UNIMPLEMENTED();
   2609               break;
   2610             case 2:
   2611               UNIMPLEMENTED();
   2612               break;
   2613             case 3: {
   2614               // Usat.
   2615               int32_t sat_pos = instr->Bits(20, 16);
   2616               int32_t sat_val = (1 << sat_pos) - 1;
   2617               int32_t shift = instr->Bits(11, 7);
   2618               int32_t shift_type = instr->Bit(6);
   2619               int32_t rm_val = get_register(instr->RmValue());
   2620               if (shift_type == 0) {  // LSL
   2621                 rm_val <<= shift;
   2622               } else {  // ASR
   2623                 rm_val >>= shift;
   2624               }
   2625               // If saturation occurs, the Q flag should be set in the CPSR.
   2626               // There is no Q flag yet, and no instruction (MRS) to read the
   2627               // CPSR directly.
   2628               if (rm_val > sat_val) {
   2629                 rm_val = sat_val;
   2630               } else if (rm_val < 0) {
   2631                 rm_val = 0;
   2632               }
   2633               set_register(rd, rm_val);
   2634               break;
   2635             }
   2636           }
   2637         } else {
   2638           switch (instr->Bits(22, 21)) {
   2639             case 0:
   2640               UNIMPLEMENTED();
   2641               break;
   2642             case 1:
   2643               UNIMPLEMENTED();
   2644               break;
   2645             case 2:
   2646               if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
   2647                 if (instr->Bits(19, 16) == 0xF) {
   2648                   // Uxtb16.
   2649                   uint32_t rm_val = get_register(instr->RmValue());
   2650                   int32_t rotate = instr->Bits(11, 10);
   2651                   switch (rotate) {
   2652                     case 0:
   2653                       break;
   2654                     case 1:
   2655                       rm_val = (rm_val >> 8) | (rm_val << 24);
   2656                       break;
   2657                     case 2:
   2658                       rm_val = (rm_val >> 16) | (rm_val << 16);
   2659                       break;
   2660                     case 3:
   2661                       rm_val = (rm_val >> 24) | (rm_val << 8);
   2662                       break;
   2663                   }
   2664                   set_register(rd,
   2665                                (rm_val & 0xFF) | (rm_val & 0xFF0000));
   2666                 } else {
   2667                   UNIMPLEMENTED();
   2668                 }
   2669               } else {
   2670                 UNIMPLEMENTED();
   2671               }
   2672               break;
   2673             case 3:
   2674               if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
   2675                 if (instr->Bits(19, 16) == 0xF) {
   2676                   // Uxtb.
   2677                   uint32_t rm_val = get_register(instr->RmValue());
   2678                   int32_t rotate = instr->Bits(11, 10);
   2679                   switch (rotate) {
   2680                     case 0:
   2681                       break;
   2682                     case 1:
   2683                       rm_val = (rm_val >> 8) | (rm_val << 24);
   2684                       break;
   2685                     case 2:
   2686                       rm_val = (rm_val >> 16) | (rm_val << 16);
   2687                       break;
   2688                     case 3:
   2689                       rm_val = (rm_val >> 24) | (rm_val << 8);
   2690                       break;
   2691                   }
   2692                   set_register(rd, (rm_val & 0xFF));
   2693                 } else {
   2694                   // Uxtab.
   2695                   uint32_t rn_val = get_register(rn);
   2696                   uint32_t rm_val = get_register(instr->RmValue());
   2697                   int32_t rotate = instr->Bits(11, 10);
   2698                   switch (rotate) {
   2699                     case 0:
   2700                       break;
   2701                     case 1:
   2702                       rm_val = (rm_val >> 8) | (rm_val << 24);
   2703                       break;
   2704                     case 2:
   2705                       rm_val = (rm_val >> 16) | (rm_val << 16);
   2706                       break;
   2707                     case 3:
   2708                       rm_val = (rm_val >> 24) | (rm_val << 8);
   2709                       break;
   2710                   }
   2711                   set_register(rd, rn_val + (rm_val & 0xFF));
   2712                 }
   2713               } else {
   2714                 UNIMPLEMENTED();
   2715               }
   2716               break;
   2717           }
   2718         }
   2719         return;
   2720       }
   2721       break;
   2722     }
   2723     case db_x: {
   2724       if (FLAG_enable_sudiv) {
   2725         if (!instr->HasW()) {
   2726           if (instr->Bits(5, 4) == 0x1) {
   2727              if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
   2728                // sdiv (in V8 notation matching ARM ISA format) rn = rm/rs
   2729                // Format(instr, "'sdiv'cond'b 'rn, 'rm, 'rs);
   2730                int rm = instr->RmValue();
   2731                int32_t rm_val = get_register(rm);
   2732                int rs = instr->RsValue();
   2733                int32_t rs_val = get_register(rs);
   2734                int32_t ret_val = 0;
   2735                ASSERT(rs_val != 0);
   2736                ret_val = rm_val/rs_val;
   2737                set_register(rn, ret_val);
   2738                return;
   2739              }
   2740            }
   2741          }
   2742        }
   2743       // Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
   2744       addr = rn_val - shifter_operand;
   2745       if (instr->HasW()) {
   2746         set_register(rn, addr);
   2747       }
   2748       break;
   2749     }
   2750     case ib_x: {
   2751       if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
   2752         uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
   2753         uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
   2754         uint32_t msbit = widthminus1 + lsbit;
   2755         if (msbit <= 31) {
   2756           if (instr->Bit(22)) {
   2757             // ubfx - unsigned bitfield extract.
   2758             uint32_t rm_val =
   2759                 static_cast<uint32_t>(get_register(instr->RmValue()));
   2760             uint32_t extr_val = rm_val << (31 - msbit);
   2761             extr_val = extr_val >> (31 - widthminus1);
   2762             set_register(instr->RdValue(), extr_val);
   2763           } else {
   2764             // sbfx - signed bitfield extract.
   2765             int32_t rm_val = get_register(instr->RmValue());
   2766             int32_t extr_val = rm_val << (31 - msbit);
   2767             extr_val = extr_val >> (31 - widthminus1);
   2768             set_register(instr->RdValue(), extr_val);
   2769           }
   2770         } else {
   2771           UNREACHABLE();
   2772         }
   2773         return;
   2774       } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) {
   2775         uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
   2776         uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16));
   2777         if (msbit >= lsbit) {
   2778           // bfc or bfi - bitfield clear/insert.
   2779           uint32_t rd_val =
   2780               static_cast<uint32_t>(get_register(instr->RdValue()));
   2781           uint32_t bitcount = msbit - lsbit + 1;
   2782           uint32_t mask = (1 << bitcount) - 1;
   2783           rd_val &= ~(mask << lsbit);
   2784           if (instr->RmValue() != 15) {
   2785             // bfi - bitfield insert.
   2786             uint32_t rm_val =
   2787                 static_cast<uint32_t>(get_register(instr->RmValue()));
   2788             rm_val &= mask;
   2789             rd_val |= rm_val << lsbit;
   2790           }
   2791           set_register(instr->RdValue(), rd_val);
   2792         } else {
   2793           UNREACHABLE();
   2794         }
   2795         return;
   2796       } else {
   2797         // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
   2798         addr = rn_val + shifter_operand;
   2799         if (instr->HasW()) {
   2800           set_register(rn, addr);
   2801         }
   2802       }
   2803       break;
   2804     }
   2805     default: {
   2806       UNREACHABLE();
   2807       break;
   2808     }
   2809   }
   2810   if (instr->HasB()) {
   2811     if (instr->HasL()) {
   2812       uint8_t byte = ReadB(addr);
   2813       set_register(rd, byte);
   2814     } else {
   2815       uint8_t byte = get_register(rd);
   2816       WriteB(addr, byte);
   2817     }
   2818   } else {
   2819     if (instr->HasL()) {
   2820       set_register(rd, ReadW(addr, instr));
   2821     } else {
   2822       WriteW(addr, get_register(rd), instr);
   2823     }
   2824   }
   2825 }
   2826 
   2827 
   2828 void Simulator::DecodeType4(Instruction* instr) {
   2829   ASSERT(instr->Bit(22) == 0);  // only allowed to be set in privileged mode
   2830   if (instr->HasL()) {
   2831     // Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
   2832     HandleRList(instr, true);
   2833   } else {
   2834     // Format(instr, "stm'cond'pu 'rn'w, 'rlist");
   2835     HandleRList(instr, false);
   2836   }
   2837 }
   2838 
   2839 
   2840 void Simulator::DecodeType5(Instruction* instr) {
   2841   // Format(instr, "b'l'cond 'target");
   2842   int off = (instr->SImmed24Value() << 2);
   2843   intptr_t pc_address = get_pc();
   2844   if (instr->HasLink()) {
   2845     set_register(lr, pc_address + Instruction::kInstrSize);
   2846   }
   2847   int pc_reg = get_register(pc);
   2848   set_pc(pc_reg + off);
   2849 }
   2850 
   2851 
   2852 void Simulator::DecodeType6(Instruction* instr) {
   2853   DecodeType6CoprocessorIns(instr);
   2854 }
   2855 
   2856 
   2857 void Simulator::DecodeType7(Instruction* instr) {
   2858   if (instr->Bit(24) == 1) {
   2859     SoftwareInterrupt(instr);
   2860   } else {
   2861     DecodeTypeVFP(instr);
   2862   }
   2863 }
   2864 
   2865 
   2866 // void Simulator::DecodeTypeVFP(Instruction* instr)
   2867 // The Following ARMv7 VFPv instructions are currently supported.
   2868 // vmov :Sn = Rt
   2869 // vmov :Rt = Sn
   2870 // vcvt: Dd = Sm
   2871 // vcvt: Sd = Dm
   2872 // vcvt.f64.s32 Dd, Dd, #<fbits>
   2873 // Dd = vabs(Dm)
   2874 // Dd = vneg(Dm)
   2875 // Dd = vadd(Dn, Dm)
   2876 // Dd = vsub(Dn, Dm)
   2877 // Dd = vmul(Dn, Dm)
   2878 // Dd = vdiv(Dn, Dm)
   2879 // vcmp(Dd, Dm)
   2880 // vmrs
   2881 // Dd = vsqrt(Dm)
   2882 void Simulator::DecodeTypeVFP(Instruction* instr) {
   2883   ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
   2884   ASSERT(instr->Bits(11, 9) == 0x5);
   2885 
   2886   // Obtain double precision register codes.
   2887   int vm = instr->VFPMRegValue(kDoublePrecision);
   2888   int vd = instr->VFPDRegValue(kDoublePrecision);
   2889   int vn = instr->VFPNRegValue(kDoublePrecision);
   2890 
   2891   if (instr->Bit(4) == 0) {
   2892     if (instr->Opc1Value() == 0x7) {
   2893       // Other data processing instructions
   2894       if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
   2895         // vmov register to register.
   2896         if (instr->SzValue() == 0x1) {
   2897           int m = instr->VFPMRegValue(kDoublePrecision);
   2898           int d = instr->VFPDRegValue(kDoublePrecision);
   2899           set_d_register_from_double(d, get_double_from_d_register(m));
   2900         } else {
   2901           int m = instr->VFPMRegValue(kSinglePrecision);
   2902           int d = instr->VFPDRegValue(kSinglePrecision);
   2903           set_s_register_from_float(d, get_float_from_s_register(m));
   2904         }
   2905       } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
   2906         // vabs
   2907         double dm_value = get_double_from_d_register(vm);
   2908         double dd_value = fabs(dm_value);
   2909         dd_value = canonicalizeNaN(dd_value);
   2910         set_d_register_from_double(vd, dd_value);
   2911       } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
   2912         // vneg
   2913         double dm_value = get_double_from_d_register(vm);
   2914         double dd_value = -dm_value;
   2915         dd_value = canonicalizeNaN(dd_value);
   2916         set_d_register_from_double(vd, dd_value);
   2917       } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
   2918         DecodeVCVTBetweenDoubleAndSingle(instr);
   2919       } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
   2920         DecodeVCVTBetweenFloatingPointAndInteger(instr);
   2921       } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
   2922                  (instr->Bit(8) == 1)) {
   2923         // vcvt.f64.s32 Dd, Dd, #<fbits>
   2924         int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0));
   2925         int fixed_value = get_sinteger_from_s_register(vd * 2);
   2926         double divide = 1 << fraction_bits;
   2927         set_d_register_from_double(vd, fixed_value / divide);
   2928       } else if (((instr->Opc2Value() >> 1) == 0x6) &&
   2929                  (instr->Opc3Value() & 0x1)) {
   2930         DecodeVCVTBetweenFloatingPointAndInteger(instr);
   2931       } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
   2932                  (instr->Opc3Value() & 0x1)) {
   2933         DecodeVCMP(instr);
   2934       } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
   2935         // vsqrt
   2936         double dm_value = get_double_from_d_register(vm);
   2937         double dd_value = sqrt(dm_value);
   2938         dd_value = canonicalizeNaN(dd_value);
   2939         set_d_register_from_double(vd, dd_value);
   2940       } else if (instr->Opc3Value() == 0x0) {
   2941         // vmov immediate.
   2942         if (instr->SzValue() == 0x1) {
   2943           set_d_register_from_double(vd, instr->DoubleImmedVmov());
   2944         } else {
   2945           UNREACHABLE();  // Not used by v8.
   2946         }
   2947       } else {
   2948         UNREACHABLE();  // Not used by V8.
   2949       }
   2950     } else if (instr->Opc1Value() == 0x3) {
   2951       if (instr->SzValue() != 0x1) {
   2952         UNREACHABLE();  // Not used by V8.
   2953       }
   2954 
   2955       if (instr->Opc3Value() & 0x1) {
   2956         // vsub
   2957         double dn_value = get_double_from_d_register(vn);
   2958         double dm_value = get_double_from_d_register(vm);
   2959         double dd_value = dn_value - dm_value;
   2960         dd_value = canonicalizeNaN(dd_value);
   2961         set_d_register_from_double(vd, dd_value);
   2962       } else {
   2963         // vadd
   2964         double dn_value = get_double_from_d_register(vn);
   2965         double dm_value = get_double_from_d_register(vm);
   2966         double dd_value = dn_value + dm_value;
   2967         dd_value = canonicalizeNaN(dd_value);
   2968         set_d_register_from_double(vd, dd_value);
   2969       }
   2970     } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
   2971       // vmul
   2972       if (instr->SzValue() != 0x1) {
   2973         UNREACHABLE();  // Not used by V8.
   2974       }
   2975 
   2976       double dn_value = get_double_from_d_register(vn);
   2977       double dm_value = get_double_from_d_register(vm);
   2978       double dd_value = dn_value * dm_value;
   2979       dd_value = canonicalizeNaN(dd_value);
   2980       set_d_register_from_double(vd, dd_value);
   2981     } else if ((instr->Opc1Value() == 0x0)) {
   2982       // vmla, vmls
   2983       const bool is_vmls = (instr->Opc3Value() & 0x1);
   2984 
   2985       if (instr->SzValue() != 0x1) {
   2986         UNREACHABLE();  // Not used by V8.
   2987       }
   2988 
   2989       const double dd_val = get_double_from_d_register(vd);
   2990       const double dn_val = get_double_from_d_register(vn);
   2991       const double dm_val = get_double_from_d_register(vm);
   2992 
   2993       // Note: we do the mul and add/sub in separate steps to avoid getting a
   2994       // result with too high precision.
   2995       set_d_register_from_double(vd, dn_val * dm_val);
   2996       if (is_vmls) {
   2997         set_d_register_from_double(
   2998           vd,
   2999           canonicalizeNaN(dd_val - get_double_from_d_register(vd)));
   3000       } else {
   3001         set_d_register_from_double(
   3002           vd,
   3003           canonicalizeNaN(dd_val + get_double_from_d_register(vd)));
   3004       }
   3005     } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
   3006       // vdiv
   3007       if (instr->SzValue() != 0x1) {
   3008         UNREACHABLE();  // Not used by V8.
   3009       }
   3010 
   3011       double dn_value = get_double_from_d_register(vn);
   3012       double dm_value = get_double_from_d_register(vm);
   3013       double dd_value = dn_value / dm_value;
   3014       div_zero_vfp_flag_ = (dm_value == 0);
   3015       dd_value = canonicalizeNaN(dd_value);
   3016       set_d_register_from_double(vd, dd_value);
   3017     } else {
   3018       UNIMPLEMENTED();  // Not used by V8.
   3019     }
   3020   } else {
   3021     if ((instr->VCValue() == 0x0) &&
   3022         (instr->VAValue() == 0x0)) {
   3023       DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
   3024     } else if ((instr->VLValue() == 0x0) &&
   3025                (instr->VCValue() == 0x1) &&
   3026                (instr->Bit(23) == 0x0)) {
   3027       // vmov (ARM core register to scalar)
   3028       int vd = instr->Bits(19, 16) | (instr->Bit(7) << 4);
   3029       double dd_value = get_double_from_d_register(vd);
   3030       int32_t data[2];
   3031       OS::MemCopy(data, &dd_value, 8);
   3032       data[instr->Bit(21)] = get_register(instr->RtValue());
   3033       OS::MemCopy(&dd_value, data, 8);
   3034       set_d_register_from_double(vd, dd_value);
   3035     } else if ((instr->VLValue() == 0x1) &&
   3036                (instr->VCValue() == 0x1) &&
   3037                (instr->Bit(23) == 0x0)) {
   3038       // vmov (scalar to ARM core register)
   3039       int vn = instr->Bits(19, 16) | (instr->Bit(7) << 4);
   3040       double dn_value = get_double_from_d_register(vn);
   3041       int32_t data[2];
   3042       OS::MemCopy(data, &dn_value, 8);
   3043       set_register(instr->RtValue(), data[instr->Bit(21)]);
   3044     } else if ((instr->VLValue() == 0x1) &&
   3045                (instr->VCValue() == 0x0) &&
   3046                (instr->VAValue() == 0x7) &&
   3047                (instr->Bits(19, 16) == 0x1)) {
   3048       // vmrs
   3049       uint32_t rt = instr->RtValue();
   3050       if (rt == 0xF) {
   3051         Copy_FPSCR_to_APSR();
   3052       } else {
   3053         // Emulate FPSCR from the Simulator flags.
   3054         uint32_t fpscr = (n_flag_FPSCR_ << 31) |
   3055                          (z_flag_FPSCR_ << 30) |
   3056                          (c_flag_FPSCR_ << 29) |
   3057                          (v_flag_FPSCR_ << 28) |
   3058                          (FPSCR_default_NaN_mode_ << 25) |
   3059                          (inexact_vfp_flag_ << 4) |
   3060                          (underflow_vfp_flag_ << 3) |
   3061                          (overflow_vfp_flag_ << 2) |
   3062                          (div_zero_vfp_flag_ << 1) |
   3063                          (inv_op_vfp_flag_ << 0) |
   3064                          (FPSCR_rounding_mode_);
   3065         set_register(rt, fpscr);
   3066       }
   3067     } else if ((instr->VLValue() == 0x0) &&
   3068                (instr->VCValue() == 0x0) &&
   3069                (instr->VAValue() == 0x7) &&
   3070                (instr->Bits(19, 16) == 0x1)) {
   3071       // vmsr
   3072       uint32_t rt = instr->RtValue();
   3073       if (rt == pc) {
   3074         UNREACHABLE();
   3075       } else {
   3076         uint32_t rt_value = get_register(rt);
   3077         n_flag_FPSCR_ = (rt_value >> 31) & 1;
   3078         z_flag_FPSCR_ = (rt_value >> 30) & 1;
   3079         c_flag_FPSCR_ = (rt_value >> 29) & 1;
   3080         v_flag_FPSCR_ = (rt_value >> 28) & 1;
   3081         FPSCR_default_NaN_mode_ = (rt_value >> 25) & 1;
   3082         inexact_vfp_flag_ = (rt_value >> 4) & 1;
   3083         underflow_vfp_flag_ = (rt_value >> 3) & 1;
   3084         overflow_vfp_flag_ = (rt_value >> 2) & 1;
   3085         div_zero_vfp_flag_ = (rt_value >> 1) & 1;
   3086         inv_op_vfp_flag_ = (rt_value >> 0) & 1;
   3087         FPSCR_rounding_mode_ =
   3088             static_cast<VFPRoundingMode>((rt_value) & kVFPRoundingModeMask);
   3089       }
   3090     } else {
   3091       UNIMPLEMENTED();  // Not used by V8.
   3092     }
   3093   }
   3094 }
   3095 
   3096 
   3097 void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
   3098     Instruction* instr) {
   3099   ASSERT((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
   3100          (instr->VAValue() == 0x0));
   3101 
   3102   int t = instr->RtValue();
   3103   int n = instr->VFPNRegValue(kSinglePrecision);
   3104   bool to_arm_register = (instr->VLValue() == 0x1);
   3105 
   3106   if (to_arm_register) {
   3107     int32_t int_value = get_sinteger_from_s_register(n);
   3108     set_register(t, int_value);
   3109   } else {
   3110     int32_t rs_val = get_register(t);
   3111     set_s_register_from_sinteger(n, rs_val);
   3112   }
   3113 }
   3114 
   3115 
   3116 void Simulator::DecodeVCMP(Instruction* instr) {
   3117   ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
   3118   ASSERT(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
   3119          (instr->Opc3Value() & 0x1));
   3120   // Comparison.
   3121 
   3122   VFPRegPrecision precision = kSinglePrecision;
   3123   if (instr->SzValue() == 1) {
   3124     precision = kDoublePrecision;
   3125   }
   3126 
   3127   int d = instr->VFPDRegValue(precision);
   3128   int m = 0;
   3129   if (instr->Opc2Value() == 0x4) {
   3130     m = instr->VFPMRegValue(precision);
   3131   }
   3132 
   3133   if (precision == kDoublePrecision) {
   3134     double dd_value = get_double_from_d_register(d);
   3135     double dm_value = 0.0;
   3136     if (instr->Opc2Value() == 0x4) {
   3137       dm_value = get_double_from_d_register(m);
   3138     }
   3139 
   3140     // Raise exceptions for quiet NaNs if necessary.
   3141     if (instr->Bit(7) == 1) {
   3142       if (std::isnan(dd_value)) {
   3143         inv_op_vfp_flag_ = true;
   3144       }
   3145     }
   3146 
   3147     Compute_FPSCR_Flags(dd_value, dm_value);
   3148   } else {
   3149     UNIMPLEMENTED();  // Not used by V8.
   3150   }
   3151 }
   3152 
   3153 
   3154 void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
   3155   ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
   3156   ASSERT((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
   3157 
   3158   VFPRegPrecision dst_precision = kDoublePrecision;
   3159   VFPRegPrecision src_precision = kSinglePrecision;
   3160   if (instr->SzValue() == 1) {
   3161     dst_precision = kSinglePrecision;
   3162     src_precision = kDoublePrecision;
   3163   }
   3164 
   3165   int dst = instr->VFPDRegValue(dst_precision);
   3166   int src = instr->VFPMRegValue(src_precision);
   3167 
   3168   if (dst_precision == kSinglePrecision) {
   3169     double val = get_double_from_d_register(src);
   3170     set_s_register_from_float(dst, static_cast<float>(val));
   3171   } else {
   3172     float val = get_float_from_s_register(src);
   3173     set_d_register_from_double(dst, static_cast<double>(val));
   3174   }
   3175 }
   3176 
   3177 bool get_inv_op_vfp_flag(VFPRoundingMode mode,
   3178                          double val,
   3179                          bool unsigned_) {
   3180   ASSERT((mode == RN) || (mode == RM) || (mode == RZ));
   3181   double max_uint = static_cast<double>(0xffffffffu);
   3182   double max_int = static_cast<double>(kMaxInt);
   3183   double min_int = static_cast<double>(kMinInt);
   3184 
   3185   // Check for NaN.
   3186   if (val != val) {
   3187     return true;
   3188   }
   3189 
   3190   // Check for overflow. This code works because 32bit integers can be
   3191   // exactly represented by ieee-754 64bit floating-point values.
   3192   switch (mode) {
   3193     case RN:
   3194       return  unsigned_ ? (val >= (max_uint + 0.5)) ||
   3195                           (val < -0.5)
   3196                         : (val >= (max_int + 0.5)) ||
   3197                           (val < (min_int - 0.5));
   3198 
   3199     case RM:
   3200       return  unsigned_ ? (val >= (max_uint + 1.0)) ||
   3201                           (val < 0)
   3202                         : (val >= (max_int + 1.0)) ||
   3203                           (val < min_int);
   3204 
   3205     case RZ:
   3206       return  unsigned_ ? (val >= (max_uint + 1.0)) ||
   3207                           (val <= -1)
   3208                         : (val >= (max_int + 1.0)) ||
   3209                           (val <= (min_int - 1.0));
   3210     default:
   3211       UNREACHABLE();
   3212       return true;
   3213   }
   3214 }
   3215 
   3216 
   3217 // We call this function only if we had a vfp invalid exception.
   3218 // It returns the correct saturated value.
   3219 int VFPConversionSaturate(double val, bool unsigned_res) {
   3220   if (val != val) {
   3221     return 0;
   3222   } else {
   3223     if (unsigned_res) {
   3224       return (val < 0) ? 0 : 0xffffffffu;
   3225     } else {
   3226       return (val < 0) ? kMinInt : kMaxInt;
   3227     }
   3228   }
   3229 }
   3230 
   3231 
   3232 void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
   3233   ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7) &&
   3234          (instr->Bits(27, 23) == 0x1D));
   3235   ASSERT(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
   3236          (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
   3237 
   3238   // Conversion between floating-point and integer.
   3239   bool to_integer = (instr->Bit(18) == 1);
   3240 
   3241   VFPRegPrecision src_precision = (instr->SzValue() == 1) ? kDoublePrecision
   3242                                                           : kSinglePrecision;
   3243 
   3244   if (to_integer) {
   3245     // We are playing with code close to the C++ standard's limits below,
   3246     // hence the very simple code and heavy checks.
   3247     //
   3248     // Note:
   3249     // C++ defines default type casting from floating point to integer as
   3250     // (close to) rounding toward zero ("fractional part discarded").
   3251 
   3252     int dst = instr->VFPDRegValue(kSinglePrecision);
   3253     int src = instr->VFPMRegValue(src_precision);
   3254 
   3255     // Bit 7 in vcvt instructions indicates if we should use the FPSCR rounding
   3256     // mode or the default Round to Zero mode.
   3257     VFPRoundingMode mode = (instr->Bit(7) != 1) ? FPSCR_rounding_mode_
   3258                                                 : RZ;
   3259     ASSERT((mode == RM) || (mode == RZ) || (mode == RN));
   3260 
   3261     bool unsigned_integer = (instr->Bit(16) == 0);
   3262     bool double_precision = (src_precision == kDoublePrecision);
   3263 
   3264     double val = double_precision ? get_double_from_d_register(src)
   3265                                   : get_float_from_s_register(src);
   3266 
   3267     int temp = unsigned_integer ? static_cast<uint32_t>(val)
   3268                                 : static_cast<int32_t>(val);
   3269 
   3270     inv_op_vfp_flag_ = get_inv_op_vfp_flag(mode, val, unsigned_integer);
   3271 
   3272     double abs_diff =
   3273       unsigned_integer ? fabs(val - static_cast<uint32_t>(temp))
   3274                        : fabs(val - temp);
   3275 
   3276     inexact_vfp_flag_ = (abs_diff != 0);
   3277 
   3278     if (inv_op_vfp_flag_) {
   3279       temp = VFPConversionSaturate(val, unsigned_integer);
   3280     } else {
   3281       switch (mode) {
   3282         case RN: {
   3283           int val_sign = (val > 0) ? 1 : -1;
   3284           if (abs_diff > 0.5) {
   3285             temp += val_sign;
   3286           } else if (abs_diff == 0.5) {
   3287             // Round to even if exactly halfway.
   3288             temp = ((temp % 2) == 0) ? temp : temp + val_sign;
   3289           }
   3290           break;
   3291         }
   3292 
   3293         case RM:
   3294           temp = temp > val ? temp - 1 : temp;
   3295           break;
   3296 
   3297         case RZ:
   3298           // Nothing to do.
   3299           break;
   3300 
   3301         default:
   3302           UNREACHABLE();
   3303       }
   3304     }
   3305 
   3306     // Update the destination register.
   3307     set_s_register_from_sinteger(dst, temp);
   3308 
   3309   } else {
   3310     bool unsigned_integer = (instr->Bit(7) == 0);
   3311 
   3312     int dst = instr->VFPDRegValue(src_precision);
   3313     int src = instr->VFPMRegValue(kSinglePrecision);
   3314 
   3315     int val = get_sinteger_from_s_register(src);
   3316 
   3317     if (src_precision == kDoublePrecision) {
   3318       if (unsigned_integer) {
   3319         set_d_register_from_double(
   3320             dst, static_cast<double>(static_cast<uint32_t>(val)));
   3321       } else {
   3322         set_d_register_from_double(dst, static_cast<double>(val));
   3323       }
   3324     } else {
   3325       if (unsigned_integer) {
   3326         set_s_register_from_float(
   3327             dst, static_cast<float>(static_cast<uint32_t>(val)));
   3328       } else {
   3329         set_s_register_from_float(dst, static_cast<float>(val));
   3330       }
   3331     }
   3332   }
   3333 }
   3334 
   3335 
   3336 // void Simulator::DecodeType6CoprocessorIns(Instruction* instr)
   3337 // Decode Type 6 coprocessor instructions.
   3338 // Dm = vmov(Rt, Rt2)
   3339 // <Rt, Rt2> = vmov(Dm)
   3340 // Ddst = MEM(Rbase + 4*offset).
   3341 // MEM(Rbase + 4*offset) = Dsrc.
   3342 void Simulator::DecodeType6CoprocessorIns(Instruction* instr) {
   3343   ASSERT((instr->TypeValue() == 6));
   3344 
   3345   if (instr->CoprocessorValue() == 0xA) {
   3346     switch (instr->OpcodeValue()) {
   3347       case 0x8:
   3348       case 0xA:
   3349       case 0xC:
   3350       case 0xE: {  // Load and store single precision float to memory.
   3351         int rn = instr->RnValue();
   3352         int vd = instr->VFPDRegValue(kSinglePrecision);
   3353         int offset = instr->Immed8Value();
   3354         if (!instr->HasU()) {
   3355           offset = -offset;
   3356         }
   3357 
   3358         int32_t address = get_register(rn) + 4 * offset;
   3359         if (instr->HasL()) {
   3360           // Load double from memory: vldr.
   3361           set_s_register_from_sinteger(vd, ReadW(address, instr));
   3362         } else {
   3363           // Store double to memory: vstr.
   3364           WriteW(address, get_sinteger_from_s_register(vd), instr);
   3365         }
   3366         break;
   3367       }
   3368       case 0x4:
   3369       case 0x5:
   3370       case 0x6:
   3371       case 0x7:
   3372       case 0x9:
   3373       case 0xB:
   3374         // Load/store multiple single from memory: vldm/vstm.
   3375         HandleVList(instr);
   3376         break;
   3377       default:
   3378         UNIMPLEMENTED();  // Not used by V8.
   3379     }
   3380   } else if (instr->CoprocessorValue() == 0xB) {
   3381     switch (instr->OpcodeValue()) {
   3382       case 0x2:
   3383         // Load and store double to two GP registers
   3384         if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) {
   3385           UNIMPLEMENTED();  // Not used by V8.
   3386         } else {
   3387           int rt = instr->RtValue();
   3388           int rn = instr->RnValue();
   3389           int vm = instr->VFPMRegValue(kDoublePrecision);
   3390           if (instr->HasL()) {
   3391             int32_t data[2];
   3392             double d = get_double_from_d_register(vm);
   3393             OS::MemCopy(data, &d, 8);
   3394             set_register(rt, data[0]);
   3395             set_register(rn, data[1]);
   3396           } else {
   3397             int32_t data[] = { get_register(rt), get_register(rn) };
   3398             double d;
   3399             OS::MemCopy(&d, data, 8);
   3400             set_d_register_from_double(vm, d);
   3401           }
   3402         }
   3403         break;
   3404       case 0x8:
   3405       case 0xA:
   3406       case 0xC:
   3407       case 0xE: {  // Load and store double to memory.
   3408         int rn = instr->RnValue();
   3409         int vd = instr->VFPDRegValue(kDoublePrecision);
   3410         int offset = instr->Immed8Value();
   3411         if (!instr->HasU()) {
   3412           offset = -offset;
   3413         }
   3414         int32_t address = get_register(rn) + 4 * offset;
   3415         if (instr->HasL()) {
   3416           // Load double from memory: vldr.
   3417           int32_t data[] = {
   3418             ReadW(address, instr),
   3419             ReadW(address + 4, instr)
   3420           };
   3421           double val;
   3422           OS::MemCopy(&val, data, 8);
   3423           set_d_register_from_double(vd, val);
   3424         } else {
   3425           // Store double to memory: vstr.
   3426           int32_t data[2];
   3427           double val = get_double_from_d_register(vd);
   3428           OS::MemCopy(data, &val, 8);
   3429           WriteW(address, data[0], instr);
   3430           WriteW(address + 4, data[1], instr);
   3431         }
   3432         break;
   3433       }
   3434       case 0x4:
   3435       case 0x5:
   3436       case 0x6:
   3437       case 0x7:
   3438       case 0x9:
   3439       case 0xB:
   3440         // Load/store multiple double from memory: vldm/vstm.
   3441         HandleVList(instr);
   3442         break;
   3443       default:
   3444         UNIMPLEMENTED();  // Not used by V8.
   3445     }
   3446   } else {
   3447     UNIMPLEMENTED();  // Not used by V8.
   3448   }
   3449 }
   3450 
   3451 
   3452 void Simulator::DecodeSpecialCondition(Instruction* instr) {
   3453   switch (instr->SpecialValue()) {
   3454     case 5:
   3455       if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
   3456           (instr->Bit(4) == 1)) {
   3457         // vmovl signed
   3458         int Vd = (instr->Bit(22) << 4) | instr->VdValue();
   3459         int Vm = (instr->Bit(5) << 4) | instr->VmValue();
   3460         int imm3 = instr->Bits(21, 19);
   3461         if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED();
   3462         int esize = 8 * imm3;
   3463         int elements = 64 / esize;
   3464         int8_t from[8];
   3465         get_d_register(Vm, reinterpret_cast<uint64_t*>(from));
   3466         int16_t to[8];
   3467         int e = 0;
   3468         while (e < elements) {
   3469           to[e] = from[e];
   3470           e++;
   3471         }
   3472         set_q_register(Vd, reinterpret_cast<uint64_t*>(to));
   3473       } else {
   3474         UNIMPLEMENTED();
   3475       }
   3476       break;
   3477     case 7:
   3478       if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
   3479           (instr->Bit(4) == 1)) {
   3480         // vmovl unsigned
   3481         int Vd = (instr->Bit(22) << 4) | instr->VdValue();
   3482         int Vm = (instr->Bit(5) << 4) | instr->VmValue();
   3483         int imm3 = instr->Bits(21, 19);
   3484         if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED();
   3485         int esize = 8 * imm3;
   3486         int elements = 64 / esize;
   3487         uint8_t from[8];
   3488         get_d_register(Vm, reinterpret_cast<uint64_t*>(from));
   3489         uint16_t to[8];
   3490         int e = 0;
   3491         while (e < elements) {
   3492           to[e] = from[e];
   3493           e++;
   3494         }
   3495         set_q_register(Vd, reinterpret_cast<uint64_t*>(to));
   3496       } else {
   3497         UNIMPLEMENTED();
   3498       }
   3499       break;
   3500     case 8:
   3501       if (instr->Bits(21, 20) == 0) {
   3502         // vst1
   3503         int Vd = (instr->Bit(22) << 4) | instr->VdValue();
   3504         int Rn = instr->VnValue();
   3505         int type = instr->Bits(11, 8);
   3506         int Rm = instr->VmValue();
   3507         int32_t address = get_register(Rn);
   3508         int regs = 0;
   3509         switch (type) {
   3510           case nlt_1:
   3511             regs = 1;
   3512             break;
   3513           case nlt_2:
   3514             regs = 2;
   3515             break;
   3516           case nlt_3:
   3517             regs = 3;
   3518             break;
   3519           case nlt_4:
   3520             regs = 4;
   3521             break;
   3522           default:
   3523             UNIMPLEMENTED();
   3524             break;
   3525         }
   3526         int r = 0;
   3527         while (r < regs) {
   3528           uint32_t data[2];
   3529           get_d_register(Vd + r, data);
   3530           WriteW(address, data[0], instr);
   3531           WriteW(address + 4, data[1], instr);
   3532           address += 8;
   3533           r++;
   3534         }
   3535         if (Rm != 15) {
   3536           if (Rm == 13) {
   3537             set_register(Rn, address);
   3538           } else {
   3539             set_register(Rn, get_register(Rn) + get_register(Rm));
   3540           }
   3541         }
   3542       } else if (instr->Bits(21, 20) == 2) {
   3543         // vld1
   3544         int Vd = (instr->Bit(22) << 4) | instr->VdValue();
   3545         int Rn = instr->VnValue();
   3546         int type = instr->Bits(11, 8);
   3547         int Rm = instr->VmValue();
   3548         int32_t address = get_register(Rn);
   3549         int regs = 0;
   3550         switch (type) {
   3551           case nlt_1:
   3552             regs = 1;
   3553             break;
   3554           case nlt_2:
   3555             regs = 2;
   3556             break;
   3557           case nlt_3:
   3558             regs = 3;
   3559             break;
   3560           case nlt_4:
   3561             regs = 4;
   3562             break;
   3563           default:
   3564             UNIMPLEMENTED();
   3565             break;
   3566         }
   3567         int r = 0;
   3568         while (r < regs) {
   3569           uint32_t data[2];
   3570           data[0] = ReadW(address, instr);
   3571           data[1] = ReadW(address + 4, instr);
   3572           set_d_register(Vd + r, data);
   3573           address += 8;
   3574           r++;
   3575         }
   3576         if (Rm != 15) {
   3577           if (Rm == 13) {
   3578             set_register(Rn, address);
   3579           } else {
   3580             set_register(Rn, get_register(Rn) + get_register(Rm));
   3581           }
   3582         }
   3583       } else {
   3584         UNIMPLEMENTED();
   3585       }
   3586       break;
   3587     case 0xA:
   3588     case 0xB:
   3589       if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) {
   3590         // pld: ignore instruction.
   3591       } else {
   3592         UNIMPLEMENTED();
   3593       }
   3594       break;
   3595     default:
   3596       UNIMPLEMENTED();
   3597       break;
   3598   }
   3599 }
   3600 
   3601 
   3602 // Executes the current instruction.
   3603 void Simulator::InstructionDecode(Instruction* instr) {
   3604   if (v8::internal::FLAG_check_icache) {
   3605     CheckICache(isolate_->simulator_i_cache(), instr);
   3606   }
   3607   pc_modified_ = false;
   3608   if (::v8::internal::FLAG_trace_sim) {
   3609     disasm::NameConverter converter;
   3610     disasm::Disassembler dasm(converter);
   3611     // use a reasonably large buffer
   3612     v8::internal::EmbeddedVector<char, 256> buffer;
   3613     dasm.InstructionDecode(buffer,
   3614                            reinterpret_cast<byte*>(instr));
   3615     PrintF("  0x%08x  %s\n", reinterpret_cast<intptr_t>(instr), buffer.start());
   3616   }
   3617   if (instr->ConditionField() == kSpecialCondition) {
   3618     DecodeSpecialCondition(instr);
   3619   } else if (ConditionallyExecute(instr)) {
   3620     switch (instr->TypeValue()) {
   3621       case 0:
   3622       case 1: {
   3623         DecodeType01(instr);
   3624         break;
   3625       }
   3626       case 2: {
   3627         DecodeType2(instr);
   3628         break;
   3629       }
   3630       case 3: {
   3631         DecodeType3(instr);
   3632         break;
   3633       }
   3634       case 4: {
   3635         DecodeType4(instr);
   3636         break;
   3637       }
   3638       case 5: {
   3639         DecodeType5(instr);
   3640         break;
   3641       }
   3642       case 6: {
   3643         DecodeType6(instr);
   3644         break;
   3645       }
   3646       case 7: {
   3647         DecodeType7(instr);
   3648         break;
   3649       }
   3650       default: {
   3651         UNIMPLEMENTED();
   3652         break;
   3653       }
   3654     }
   3655   // If the instruction is a non taken conditional stop, we need to skip the
   3656   // inlined message address.
   3657   } else if (instr->IsStop()) {
   3658     set_pc(get_pc() + 2 * Instruction::kInstrSize);
   3659   }
   3660   if (!pc_modified_) {
   3661     set_register(pc, reinterpret_cast<int32_t>(instr)
   3662                          + Instruction::kInstrSize);
   3663   }
   3664 }
   3665 
   3666 
   3667 void Simulator::Execute() {
   3668   // Get the PC to simulate. Cannot use the accessor here as we need the
   3669   // raw PC value and not the one used as input to arithmetic instructions.
   3670   int program_counter = get_pc();
   3671 
   3672   if (::v8::internal::FLAG_stop_sim_at == 0) {
   3673     // Fast version of the dispatch loop without checking whether the simulator
   3674     // should be stopping at a particular executed instruction.
   3675     while (program_counter != end_sim_pc) {
   3676       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
   3677       icount_++;
   3678       InstructionDecode(instr);
   3679       program_counter = get_pc();
   3680     }
   3681   } else {
   3682     // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
   3683     // we reach the particular instuction count.
   3684     while (program_counter != end_sim_pc) {
   3685       Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
   3686       icount_++;
   3687       if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
   3688         ArmDebugger dbg(this);
   3689         dbg.Debug();
   3690       } else {
   3691         InstructionDecode(instr);
   3692       }
   3693       program_counter = get_pc();
   3694     }
   3695   }
   3696 }
   3697 
   3698 
   3699 void Simulator::CallInternal(byte* entry) {
   3700   // Prepare to execute the code at entry
   3701   set_register(pc, reinterpret_cast<int32_t>(entry));
   3702   // Put down marker for end of simulation. The simulator will stop simulation
   3703   // when the PC reaches this value. By saving the "end simulation" value into
   3704   // the LR the simulation stops when returning to this call point.
   3705   set_register(lr, end_sim_pc);
   3706 
   3707   // Remember the values of callee-saved registers.
   3708   // The code below assumes that r9 is not used as sb (static base) in
   3709   // simulator code and therefore is regarded as a callee-saved register.
   3710   int32_t r4_val = get_register(r4);
   3711   int32_t r5_val = get_register(r5);
   3712   int32_t r6_val = get_register(r6);
   3713   int32_t r7_val = get_register(r7);
   3714   int32_t r8_val = get_register(r8);
   3715   int32_t r9_val = get_register(r9);
   3716   int32_t r10_val = get_register(r10);
   3717   int32_t r11_val = get_register(r11);
   3718 
   3719   // Set up the callee-saved registers with a known value. To be able to check
   3720   // that they are preserved properly across JS execution.
   3721   int32_t callee_saved_value = icount_;
   3722   set_register(r4, callee_saved_value);
   3723   set_register(r5, callee_saved_value);
   3724   set_register(r6, callee_saved_value);
   3725   set_register(r7, callee_saved_value);
   3726   set_register(r8, callee_saved_value);
   3727   set_register(r9, callee_saved_value);
   3728   set_register(r10, callee_saved_value);
   3729   set_register(r11, callee_saved_value);
   3730 
   3731   // Start the simulation
   3732   Execute();
   3733 
   3734   // Check that the callee-saved registers have been preserved.
   3735   CHECK_EQ(callee_saved_value, get_register(r4));
   3736   CHECK_EQ(callee_saved_value, get_register(r5));
   3737   CHECK_EQ(callee_saved_value, get_register(r6));
   3738   CHECK_EQ(callee_saved_value, get_register(r7));
   3739   CHECK_EQ(callee_saved_value, get_register(r8));
   3740   CHECK_EQ(callee_saved_value, get_register(r9));
   3741   CHECK_EQ(callee_saved_value, get_register(r10));
   3742   CHECK_EQ(callee_saved_value, get_register(r11));
   3743 
   3744   // Restore callee-saved registers with the original value.
   3745   set_register(r4, r4_val);
   3746   set_register(r5, r5_val);
   3747   set_register(r6, r6_val);
   3748   set_register(r7, r7_val);
   3749   set_register(r8, r8_val);
   3750   set_register(r9, r9_val);
   3751   set_register(r10, r10_val);
   3752   set_register(r11, r11_val);
   3753 }
   3754 
   3755 
   3756 int32_t Simulator::Call(byte* entry, int argument_count, ...) {
   3757   va_list parameters;
   3758   va_start(parameters, argument_count);
   3759   // Set up arguments
   3760 
   3761   // First four arguments passed in registers.
   3762   ASSERT(argument_count >= 4);
   3763   set_register(r0, va_arg(parameters, int32_t));
   3764   set_register(r1, va_arg(parameters, int32_t));
   3765   set_register(r2, va_arg(parameters, int32_t));
   3766   set_register(r3, va_arg(parameters, int32_t));
   3767 
   3768   // Remaining arguments passed on stack.
   3769   int original_stack = get_register(sp);
   3770   // Compute position of stack on entry to generated code.
   3771   int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t));
   3772   if (OS::ActivationFrameAlignment() != 0) {
   3773     entry_stack &= -OS::ActivationFrameAlignment();
   3774   }
   3775   // Store remaining arguments on stack, from low to high memory.
   3776   intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
   3777   for (int i = 4; i < argument_count; i++) {
   3778     stack_argument[i - 4] = va_arg(parameters, int32_t);
   3779   }
   3780   va_end(parameters);
   3781   set_register(sp, entry_stack);
   3782 
   3783   CallInternal(entry);
   3784 
   3785   // Pop stack passed arguments.
   3786   CHECK_EQ(entry_stack, get_register(sp));
   3787   set_register(sp, original_stack);
   3788 
   3789   int32_t result = get_register(r0);
   3790   return result;
   3791 }
   3792 
   3793 
   3794 void Simulator::CallFP(byte* entry, double d0, double d1) {
   3795   if (use_eabi_hardfloat()) {
   3796     set_d_register_from_double(0, d0);
   3797     set_d_register_from_double(1, d1);
   3798   } else {
   3799     set_register_pair_from_double(0, &d0);
   3800     set_register_pair_from_double(2, &d1);
   3801   }
   3802   CallInternal(entry);
   3803 }
   3804 
   3805 
   3806 int32_t Simulator::CallFPReturnsInt(byte* entry, double d0, double d1) {
   3807   CallFP(entry, d0, d1);
   3808   int32_t result = get_register(r0);
   3809   return result;
   3810 }
   3811 
   3812 
   3813 double Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) {
   3814   CallFP(entry, d0, d1);
   3815   if (use_eabi_hardfloat()) {
   3816     return get_double_from_d_register(0);
   3817   } else {
   3818     return get_double_from_register_pair(0);
   3819   }
   3820 }
   3821 
   3822 
   3823 uintptr_t Simulator::PushAddress(uintptr_t address) {
   3824   int new_sp = get_register(sp) - sizeof(uintptr_t);
   3825   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
   3826   *stack_slot = address;
   3827   set_register(sp, new_sp);
   3828   return new_sp;
   3829 }
   3830 
   3831 
   3832 uintptr_t Simulator::PopAddress() {
   3833   int current_sp = get_register(sp);
   3834   uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
   3835   uintptr_t address = *stack_slot;
   3836   set_register(sp, current_sp + sizeof(uintptr_t));
   3837   return address;
   3838 }
   3839 
   3840 } }  // namespace v8::internal
   3841 
   3842 #endif  // USE_SIMULATOR
   3843 
   3844 #endif  // V8_TARGET_ARCH_ARM
   3845