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