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