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