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