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