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