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