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