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