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