V8 Project
simulator-arm64.cc
Go to the documentation of this file.
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stdlib.h>
6 #include <cmath>
7 #include <cstdarg>
8 #include "src/v8.h"
9 
10 #if V8_TARGET_ARCH_ARM64
11 
14 #include "src/assembler.h"
15 #include "src/disasm.h"
16 #include "src/macro-assembler.h"
17 #include "src/ostreams.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 #if defined(USE_SIMULATOR)
23 
24 
25 // This macro provides a platform independent use of sscanf. The reason for
26 // SScanF not being implemented in a platform independent way through
27 // ::v8::internal::OS in the same way as SNPrintF is that the
28 // Windows C Run-Time Library does not provide vsscanf.
29 #define SScanF sscanf // NOLINT
30 
31 
32 // Helpers for colors.
33 #define COLOUR(colour_code) "\033[0;" colour_code "m"
34 #define COLOUR_BOLD(colour_code) "\033[1;" colour_code "m"
35 #define NORMAL ""
36 #define GREY "30"
37 #define RED "31"
38 #define GREEN "32"
39 #define YELLOW "33"
40 #define BLUE "34"
41 #define MAGENTA "35"
42 #define CYAN "36"
43 #define WHITE "37"
44 typedef char const * const TEXT_COLOUR;
45 TEXT_COLOUR clr_normal = FLAG_log_colour ? COLOUR(NORMAL) : "";
46 TEXT_COLOUR clr_flag_name = FLAG_log_colour ? COLOUR_BOLD(WHITE) : "";
47 TEXT_COLOUR clr_flag_value = FLAG_log_colour ? COLOUR(NORMAL) : "";
48 TEXT_COLOUR clr_reg_name = FLAG_log_colour ? COLOUR_BOLD(CYAN) : "";
49 TEXT_COLOUR clr_reg_value = FLAG_log_colour ? COLOUR(CYAN) : "";
50 TEXT_COLOUR clr_fpreg_name = FLAG_log_colour ? COLOUR_BOLD(MAGENTA) : "";
51 TEXT_COLOUR clr_fpreg_value = FLAG_log_colour ? COLOUR(MAGENTA) : "";
52 TEXT_COLOUR clr_memory_address = FLAG_log_colour ? COLOUR_BOLD(BLUE) : "";
53 TEXT_COLOUR clr_debug_number = FLAG_log_colour ? COLOUR_BOLD(YELLOW) : "";
54 TEXT_COLOUR clr_debug_message = FLAG_log_colour ? COLOUR(YELLOW) : "";
55 TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : "";
56 
57 
58 // This is basically the same as PrintF, with a guard for FLAG_trace_sim.
59 void Simulator::TraceSim(const char* format, ...) {
60  if (FLAG_trace_sim) {
61  va_list arguments;
62  va_start(arguments, format);
63  base::OS::VFPrint(stream_, format, arguments);
64  va_end(arguments);
65  }
66 }
67 
68 
69 const Instruction* Simulator::kEndOfSimAddress = NULL;
70 
71 
72 void SimSystemRegister::SetBits(int msb, int lsb, uint32_t bits) {
73  int width = msb - lsb + 1;
74  DCHECK(is_uintn(bits, width) || is_intn(bits, width));
75 
76  bits <<= lsb;
77  uint32_t mask = ((1 << width) - 1) << lsb;
78  DCHECK((mask & write_ignore_mask_) == 0);
79 
80  value_ = (value_ & ~mask) | (bits & mask);
81 }
82 
83 
84 SimSystemRegister SimSystemRegister::DefaultValueFor(SystemRegister id) {
85  switch (id) {
86  case NZCV:
87  return SimSystemRegister(0x00000000, NZCVWriteIgnoreMask);
88  case FPCR:
89  return SimSystemRegister(0x00000000, FPCRWriteIgnoreMask);
90  default:
91  UNREACHABLE();
92  return SimSystemRegister();
93  }
94 }
95 
96 
97 void Simulator::Initialize(Isolate* isolate) {
98  if (isolate->simulator_initialized()) return;
99  isolate->set_simulator_initialized(true);
100  ExternalReference::set_redirector(isolate, &RedirectExternalReference);
101 }
102 
103 
104 // Get the active Simulator for the current thread.
105 Simulator* Simulator::current(Isolate* isolate) {
106  Isolate::PerIsolateThreadData* isolate_data =
107  isolate->FindOrAllocatePerThreadDataForThisThread();
108  DCHECK(isolate_data != NULL);
109 
110  Simulator* sim = isolate_data->simulator();
111  if (sim == NULL) {
112  if (FLAG_trace_sim || FLAG_log_instruction_stats || FLAG_debug_sim) {
113  sim = new Simulator(new Decoder<DispatchingDecoderVisitor>(), isolate);
114  } else {
115  sim = new Decoder<Simulator>();
116  sim->isolate_ = isolate;
117  }
118  isolate_data->set_simulator(sim);
119  }
120  return sim;
121 }
122 
123 
124 void Simulator::CallVoid(byte* entry, CallArgument* args) {
125  int index_x = 0;
126  int index_d = 0;
127 
128  std::vector<int64_t> stack_args(0);
129  for (int i = 0; !args[i].IsEnd(); i++) {
130  CallArgument arg = args[i];
131  if (arg.IsX() && (index_x < 8)) {
132  set_xreg(index_x++, arg.bits());
133  } else if (arg.IsD() && (index_d < 8)) {
134  set_dreg_bits(index_d++, arg.bits());
135  } else {
136  DCHECK(arg.IsD() || arg.IsX());
137  stack_args.push_back(arg.bits());
138  }
139  }
140 
141  // Process stack arguments, and make sure the stack is suitably aligned.
142  uintptr_t original_stack = sp();
143  uintptr_t entry_stack = original_stack -
144  stack_args.size() * sizeof(stack_args[0]);
146  entry_stack &= -base::OS::ActivationFrameAlignment();
147  }
148  char * stack = reinterpret_cast<char*>(entry_stack);
149  std::vector<int64_t>::const_iterator it;
150  for (it = stack_args.begin(); it != stack_args.end(); it++) {
151  memcpy(stack, &(*it), sizeof(*it));
152  stack += sizeof(*it);
153  }
154 
155  DCHECK(reinterpret_cast<uintptr_t>(stack) <= original_stack);
156  set_sp(entry_stack);
157 
158  // Call the generated code.
159  set_pc(entry);
160  set_lr(kEndOfSimAddress);
161  CheckPCSComplianceAndRun();
162 
163  set_sp(original_stack);
164 }
165 
166 
167 int64_t Simulator::CallInt64(byte* entry, CallArgument* args) {
168  CallVoid(entry, args);
169  return xreg(0);
170 }
171 
172 
173 double Simulator::CallDouble(byte* entry, CallArgument* args) {
174  CallVoid(entry, args);
175  return dreg(0);
176 }
177 
178 
179 int64_t Simulator::CallJS(byte* entry,
180  byte* function_entry,
181  JSFunction* func,
182  Object* revc,
183  int64_t argc,
184  Object*** argv) {
185  CallArgument args[] = {
186  CallArgument(function_entry),
187  CallArgument(func),
188  CallArgument(revc),
189  CallArgument(argc),
190  CallArgument(argv),
191  CallArgument::End()
192  };
193  return CallInt64(entry, args);
194 }
195 
196 int64_t Simulator::CallRegExp(byte* entry,
197  String* input,
198  int64_t start_offset,
199  const byte* input_start,
200  const byte* input_end,
201  int* output,
202  int64_t output_size,
203  Address stack_base,
204  int64_t direct_call,
205  void* return_address,
206  Isolate* isolate) {
207  CallArgument args[] = {
208  CallArgument(input),
209  CallArgument(start_offset),
210  CallArgument(input_start),
211  CallArgument(input_end),
212  CallArgument(output),
213  CallArgument(output_size),
214  CallArgument(stack_base),
215  CallArgument(direct_call),
216  CallArgument(return_address),
217  CallArgument(isolate),
218  CallArgument::End()
219  };
220  return CallInt64(entry, args);
221 }
222 
223 
224 void Simulator::CheckPCSComplianceAndRun() {
225 #ifdef DEBUG
228 
229  int64_t saved_registers[kNumberOfCalleeSavedRegisters];
230  uint64_t saved_fpregisters[kNumberOfCalleeSavedFPRegisters];
231 
232  CPURegList register_list = kCalleeSaved;
233  CPURegList fpregister_list = kCalleeSavedFP;
234 
235  for (int i = 0; i < kNumberOfCalleeSavedRegisters; i++) {
236  // x31 is not a caller saved register, so no need to specify if we want
237  // the stack or zero.
238  saved_registers[i] = xreg(register_list.PopLowestIndex().code());
239  }
240  for (int i = 0; i < kNumberOfCalleeSavedFPRegisters; i++) {
241  saved_fpregisters[i] =
242  dreg_bits(fpregister_list.PopLowestIndex().code());
243  }
244  int64_t original_stack = sp();
245 #endif
246  // Start the simulation!
247  Run();
248 #ifdef DEBUG
249  CHECK_EQ(original_stack, sp());
250  // Check that callee-saved registers have been preserved.
251  register_list = kCalleeSaved;
252  fpregister_list = kCalleeSavedFP;
253  for (int i = 0; i < kNumberOfCalleeSavedRegisters; i++) {
254  CHECK_EQ(saved_registers[i], xreg(register_list.PopLowestIndex().code()));
255  }
256  for (int i = 0; i < kNumberOfCalleeSavedFPRegisters; i++) {
257  DCHECK(saved_fpregisters[i] ==
258  dreg_bits(fpregister_list.PopLowestIndex().code()));
259  }
260 
261  // Corrupt caller saved register minus the return regiters.
262 
263  // In theory x0 to x7 can be used for return values, but V8 only uses x0, x1
264  // for now .
265  register_list = kCallerSaved;
266  register_list.Remove(x0);
267  register_list.Remove(x1);
268 
269  // In theory d0 to d7 can be used for return values, but V8 only uses d0
270  // for now .
271  fpregister_list = kCallerSavedFP;
272  fpregister_list.Remove(d0);
273 
274  CorruptRegisters(&register_list, kCallerSavedRegisterCorruptionValue);
275  CorruptRegisters(&fpregister_list, kCallerSavedFPRegisterCorruptionValue);
276 #endif
277 }
278 
279 
280 #ifdef DEBUG
281 // The least significant byte of the curruption value holds the corresponding
282 // register's code.
283 void Simulator::CorruptRegisters(CPURegList* list, uint64_t value) {
284  if (list->type() == CPURegister::kRegister) {
285  while (!list->IsEmpty()) {
286  unsigned code = list->PopLowestIndex().code();
287  set_xreg(code, value | code);
288  }
289  } else {
290  DCHECK(list->type() == CPURegister::kFPRegister);
291  while (!list->IsEmpty()) {
292  unsigned code = list->PopLowestIndex().code();
293  set_dreg_bits(code, value | code);
294  }
295  }
296 }
297 
298 
299 void Simulator::CorruptAllCallerSavedCPURegisters() {
300  // Corrupt alters its parameter so copy them first.
301  CPURegList register_list = kCallerSaved;
302  CPURegList fpregister_list = kCallerSavedFP;
303 
304  CorruptRegisters(&register_list, kCallerSavedRegisterCorruptionValue);
305  CorruptRegisters(&fpregister_list, kCallerSavedFPRegisterCorruptionValue);
306 }
307 #endif
308 
309 
310 // Extending the stack by 2 * 64 bits is required for stack alignment purposes.
311 uintptr_t Simulator::PushAddress(uintptr_t address) {
312  DCHECK(sizeof(uintptr_t) < 2 * kXRegSize);
313  intptr_t new_sp = sp() - 2 * kXRegSize;
314  uintptr_t* alignment_slot =
315  reinterpret_cast<uintptr_t*>(new_sp + kXRegSize);
316  memcpy(alignment_slot, &kSlotsZapValue, kPointerSize);
317  uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
318  memcpy(stack_slot, &address, kPointerSize);
319  set_sp(new_sp);
320  return new_sp;
321 }
322 
323 
324 uintptr_t Simulator::PopAddress() {
325  intptr_t current_sp = sp();
326  uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
327  uintptr_t address = *stack_slot;
328  DCHECK(sizeof(uintptr_t) < 2 * kXRegSize);
329  set_sp(current_sp + 2 * kXRegSize);
330  return address;
331 }
332 
333 
334 // Returns the limit of the stack area to enable checking for stack overflows.
335 uintptr_t Simulator::StackLimit() const {
336  // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
337  // pushing values.
338  return stack_limit_ + 1024;
339 }
340 
341 
342 Simulator::Simulator(Decoder<DispatchingDecoderVisitor>* decoder,
343  Isolate* isolate, FILE* stream)
344  : decoder_(decoder),
345  last_debugger_input_(NULL),
346  log_parameters_(NO_PARAM),
347  isolate_(isolate) {
348  // Setup the decoder.
349  decoder_->AppendVisitor(this);
350 
351  Init(stream);
352 
353  if (FLAG_trace_sim) {
354  decoder_->InsertVisitorBefore(print_disasm_, this);
355  log_parameters_ = LOG_ALL;
356  }
357 
358  if (FLAG_log_instruction_stats) {
359  instrument_ = new Instrument(FLAG_log_instruction_file,
360  FLAG_log_instruction_period);
361  decoder_->AppendVisitor(instrument_);
362  }
363 }
364 
365 
366 Simulator::Simulator()
367  : decoder_(NULL),
368  last_debugger_input_(NULL),
369  log_parameters_(NO_PARAM),
370  isolate_(NULL) {
371  Init(stdout);
372  CHECK(!FLAG_trace_sim && !FLAG_log_instruction_stats);
373 }
374 
375 
376 void Simulator::Init(FILE* stream) {
377  ResetState();
378 
379  // Allocate and setup the simulator stack.
380  stack_size_ = (FLAG_sim_stack_size * KB) + (2 * stack_protection_size_);
381  stack_ = reinterpret_cast<uintptr_t>(new byte[stack_size_]);
382  stack_limit_ = stack_ + stack_protection_size_;
383  uintptr_t tos = stack_ + stack_size_ - stack_protection_size_;
384  // The stack pointer must be 16-byte aligned.
385  set_sp(tos & ~0xfUL);
386 
387  stream_ = stream;
388  print_disasm_ = new PrintDisassembler(stream_);
389 
390  // The debugger needs to disassemble code without the simulator executing an
391  // instruction, so we create a dedicated decoder.
392  disassembler_decoder_ = new Decoder<DispatchingDecoderVisitor>();
393  disassembler_decoder_->AppendVisitor(print_disasm_);
394 }
395 
396 
397 void Simulator::ResetState() {
398  // Reset the system registers.
399  nzcv_ = SimSystemRegister::DefaultValueFor(NZCV);
400  fpcr_ = SimSystemRegister::DefaultValueFor(FPCR);
401 
402  // Reset registers to 0.
403  pc_ = NULL;
404  for (unsigned i = 0; i < kNumberOfRegisters; i++) {
405  set_xreg(i, 0xbadbeef);
406  }
407  for (unsigned i = 0; i < kNumberOfFPRegisters; i++) {
408  // Set FP registers to a value that is NaN in both 32-bit and 64-bit FP.
409  set_dreg_bits(i, 0x7ff000007f800001UL);
410  }
411  // Returning to address 0 exits the Simulator.
412  set_lr(kEndOfSimAddress);
413 
414  // Reset debug helpers.
415  breakpoints_.empty();
416  break_on_next_= false;
417 }
418 
419 
420 Simulator::~Simulator() {
421  delete[] reinterpret_cast<byte*>(stack_);
422  if (FLAG_log_instruction_stats) {
423  delete instrument_;
424  }
425  delete disassembler_decoder_;
426  delete print_disasm_;
427  DeleteArray(last_debugger_input_);
428  delete decoder_;
429 }
430 
431 
432 void Simulator::Run() {
433  pc_modified_ = false;
434  while (pc_ != kEndOfSimAddress) {
435  ExecuteInstruction();
436  }
437 }
438 
439 
440 void Simulator::RunFrom(Instruction* start) {
441  set_pc(start);
442  Run();
443 }
444 
445 
446 // When the generated code calls an external reference we need to catch that in
447 // the simulator. The external reference will be a function compiled for the
448 // host architecture. We need to call that function instead of trying to
449 // execute it with the simulator. We do that by redirecting the external
450 // reference to a svc (Supervisor Call) instruction that is handled by
451 // the simulator. We write the original destination of the jump just at a known
452 // offset from the svc instruction so the simulator knows what to call.
453 class Redirection {
454  public:
455  Redirection(void* external_function, ExternalReference::Type type)
456  : external_function_(external_function),
457  type_(type),
458  next_(NULL) {
459  redirect_call_.SetInstructionBits(
460  HLT | Assembler::ImmException(kImmExceptionIsRedirectedCall));
461  Isolate* isolate = Isolate::Current();
462  next_ = isolate->simulator_redirection();
463  // TODO(all): Simulator flush I cache
464  isolate->set_simulator_redirection(this);
465  }
466 
467  void* address_of_redirect_call() {
468  return reinterpret_cast<void*>(&redirect_call_);
469  }
470 
471  template <typename T>
472  T external_function() { return reinterpret_cast<T>(external_function_); }
473 
474  ExternalReference::Type type() { return type_; }
475 
476  static Redirection* Get(void* external_function,
478  Isolate* isolate = Isolate::Current();
479  Redirection* current = isolate->simulator_redirection();
480  for (; current != NULL; current = current->next_) {
481  if (current->external_function_ == external_function) {
482  DCHECK_EQ(current->type(), type);
483  return current;
484  }
485  }
486  return new Redirection(external_function, type);
487  }
488 
489  static Redirection* FromHltInstruction(Instruction* redirect_call) {
490  char* addr_of_hlt = reinterpret_cast<char*>(redirect_call);
491  char* addr_of_redirection =
492  addr_of_hlt - OFFSET_OF(Redirection, redirect_call_);
493  return reinterpret_cast<Redirection*>(addr_of_redirection);
494  }
495 
496  static void* ReverseRedirection(int64_t reg) {
497  Redirection* redirection =
498  FromHltInstruction(reinterpret_cast<Instruction*>(reg));
499  return redirection->external_function<void*>();
500  }
501 
502  private:
503  void* external_function_;
504  Instruction redirect_call_;
506  Redirection* next_;
507 };
508 
509 
510 // Calls into the V8 runtime are based on this very simple interface.
511 // Note: To be able to return two values from some calls the code in runtime.cc
512 // uses the ObjectPair structure.
513 // The simulator assumes all runtime calls return two 64-bits values. If they
514 // don't, register x1 is clobbered. This is fine because x1 is caller-saved.
515 struct ObjectPair {
516  int64_t res0;
517  int64_t res1;
518 };
519 
520 
521 typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0,
522  int64_t arg1,
523  int64_t arg2,
524  int64_t arg3,
525  int64_t arg4,
526  int64_t arg5,
527  int64_t arg6,
528  int64_t arg7);
529 
530 typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2);
531 typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2);
532 typedef double (*SimulatorRuntimeFPCall)(double arg1);
533 typedef double (*SimulatorRuntimeFPIntCall)(double arg1, int32_t arg2);
534 
535 // This signature supports direct call in to API function native callback
536 // (refer to InvocationCallback in v8.h).
537 typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0);
538 typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1);
539 
540 // This signature supports direct call to accessor getter callback.
541 typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1);
542 typedef void (*SimulatorRuntimeProfilingGetterCall)(int64_t arg0, int64_t arg1,
543  void* arg2);
544 
545 void Simulator::DoRuntimeCall(Instruction* instr) {
546  Redirection* redirection = Redirection::FromHltInstruction(instr);
547 
548  // The called C code might itself call simulated code, so any
549  // caller-saved registers (including lr) could still be clobbered by a
550  // redirected call.
551  Instruction* return_address = lr();
552 
553  int64_t external = redirection->external_function<int64_t>();
554 
555  TraceSim("Call to host function at %p\n",
556  redirection->external_function<void*>());
557 
558  // SP must be 16-byte-aligned at the call interface.
559  bool stack_alignment_exception = ((sp() & 0xf) != 0);
560  if (stack_alignment_exception) {
561  TraceSim(" with unaligned stack 0x%016" PRIx64 ".\n", sp());
562  FATAL("ALIGNMENT EXCEPTION");
563  }
564 
565  switch (redirection->type()) {
566  default:
567  TraceSim("Type: Unknown.\n");
568  UNREACHABLE();
569  break;
570 
571  case ExternalReference::BUILTIN_CALL: {
572  // Object* f(v8::internal::Arguments).
573  TraceSim("Type: BUILTIN_CALL\n");
574  SimulatorRuntimeCall target =
575  reinterpret_cast<SimulatorRuntimeCall>(external);
576 
577  // We don't know how many arguments are being passed, but we can
578  // pass 8 without touching the stack. They will be ignored by the
579  // host function if they aren't used.
580  TraceSim("Arguments: "
581  "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
582  "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
583  "0x%016" PRIx64 ", 0x%016" PRIx64 ", "
584  "0x%016" PRIx64 ", 0x%016" PRIx64,
585  xreg(0), xreg(1), xreg(2), xreg(3),
586  xreg(4), xreg(5), xreg(6), xreg(7));
587  ObjectPair result = target(xreg(0), xreg(1), xreg(2), xreg(3),
588  xreg(4), xreg(5), xreg(6), xreg(7));
589  TraceSim("Returned: {0x%" PRIx64 ", 0x%" PRIx64 "}\n",
590  result.res0, result.res1);
591 #ifdef DEBUG
592  CorruptAllCallerSavedCPURegisters();
593 #endif
594  set_xreg(0, result.res0);
595  set_xreg(1, result.res1);
596  break;
597  }
598 
599  case ExternalReference::DIRECT_API_CALL: {
600  // void f(v8::FunctionCallbackInfo&)
601  TraceSim("Type: DIRECT_API_CALL\n");
602  SimulatorRuntimeDirectApiCall target =
603  reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
604  TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0));
605  target(xreg(0));
606  TraceSim("No return value.");
607 #ifdef DEBUG
608  CorruptAllCallerSavedCPURegisters();
609 #endif
610  break;
611  }
612 
613  case ExternalReference::BUILTIN_COMPARE_CALL: {
614  // int f(double, double)
615  TraceSim("Type: BUILTIN_COMPARE_CALL\n");
616  SimulatorRuntimeCompareCall target =
617  reinterpret_cast<SimulatorRuntimeCompareCall>(external);
618  TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1));
619  int64_t result = target(dreg(0), dreg(1));
620  TraceSim("Returned: %" PRId64 "\n", result);
621 #ifdef DEBUG
622  CorruptAllCallerSavedCPURegisters();
623 #endif
624  set_xreg(0, result);
625  break;
626  }
627 
628  case ExternalReference::BUILTIN_FP_CALL: {
629  // double f(double)
630  TraceSim("Type: BUILTIN_FP_CALL\n");
631  SimulatorRuntimeFPCall target =
632  reinterpret_cast<SimulatorRuntimeFPCall>(external);
633  TraceSim("Argument: %f\n", dreg(0));
634  double result = target(dreg(0));
635  TraceSim("Returned: %f\n", result);
636 #ifdef DEBUG
637  CorruptAllCallerSavedCPURegisters();
638 #endif
639  set_dreg(0, result);
640  break;
641  }
642 
643  case ExternalReference::BUILTIN_FP_FP_CALL: {
644  // double f(double, double)
645  TraceSim("Type: BUILTIN_FP_FP_CALL\n");
646  SimulatorRuntimeFPFPCall target =
647  reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
648  TraceSim("Arguments: %f, %f\n", dreg(0), dreg(1));
649  double result = target(dreg(0), dreg(1));
650  TraceSim("Returned: %f\n", result);
651 #ifdef DEBUG
652  CorruptAllCallerSavedCPURegisters();
653 #endif
654  set_dreg(0, result);
655  break;
656  }
657 
658  case ExternalReference::BUILTIN_FP_INT_CALL: {
659  // double f(double, int)
660  TraceSim("Type: BUILTIN_FP_INT_CALL\n");
661  SimulatorRuntimeFPIntCall target =
662  reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
663  TraceSim("Arguments: %f, %d\n", dreg(0), wreg(0));
664  double result = target(dreg(0), wreg(0));
665  TraceSim("Returned: %f\n", result);
666 #ifdef DEBUG
667  CorruptAllCallerSavedCPURegisters();
668 #endif
669  set_dreg(0, result);
670  break;
671  }
672 
673  case ExternalReference::DIRECT_GETTER_CALL: {
674  // void f(Local<String> property, PropertyCallbackInfo& info)
675  TraceSim("Type: DIRECT_GETTER_CALL\n");
676  SimulatorRuntimeDirectGetterCall target =
677  reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
678  TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 "\n",
679  xreg(0), xreg(1));
680  target(xreg(0), xreg(1));
681  TraceSim("No return value.");
682 #ifdef DEBUG
683  CorruptAllCallerSavedCPURegisters();
684 #endif
685  break;
686  }
687 
688  case ExternalReference::PROFILING_API_CALL: {
689  // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
690  TraceSim("Type: PROFILING_API_CALL\n");
691  SimulatorRuntimeProfilingApiCall target =
692  reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
693  void* arg1 = Redirection::ReverseRedirection(xreg(1));
694  TraceSim("Arguments: 0x%016" PRIx64 ", %p\n", xreg(0), arg1);
695  target(xreg(0), arg1);
696  TraceSim("No return value.");
697 #ifdef DEBUG
698  CorruptAllCallerSavedCPURegisters();
699 #endif
700  break;
701  }
702 
703  case ExternalReference::PROFILING_GETTER_CALL: {
704  // void f(Local<String> property, PropertyCallbackInfo& info,
705  // AccessorNameGetterCallback callback)
706  TraceSim("Type: PROFILING_GETTER_CALL\n");
707  SimulatorRuntimeProfilingGetterCall target =
708  reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(
709  external);
710  void* arg2 = Redirection::ReverseRedirection(xreg(2));
711  TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 ", %p\n",
712  xreg(0), xreg(1), arg2);
713  target(xreg(0), xreg(1), arg2);
714  TraceSim("No return value.");
715 #ifdef DEBUG
716  CorruptAllCallerSavedCPURegisters();
717 #endif
718  break;
719  }
720  }
721 
722  set_lr(return_address);
723  set_pc(return_address);
724 }
725 
726 
727 void* Simulator::RedirectExternalReference(void* external_function,
729  Redirection* redirection = Redirection::Get(external_function, type);
730  return redirection->address_of_redirect_call();
731 }
732 
733 
734 const char* Simulator::xreg_names[] = {
735 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
736 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
737 "ip0", "ip1", "x18", "x19", "x20", "x21", "x22", "x23",
738 "x24", "x25", "x26", "cp", "jssp", "fp", "lr", "xzr", "csp"};
739 
740 const char* Simulator::wreg_names[] = {
741 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7",
742 "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15",
743 "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
744 "w24", "w25", "w26", "wcp", "wjssp", "wfp", "wlr", "wzr", "wcsp"};
745 
746 const char* Simulator::sreg_names[] = {
747 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
748 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
749 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
750 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"};
751 
752 const char* Simulator::dreg_names[] = {
753 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
754 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
755 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
756 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
757 
758 const char* Simulator::vreg_names[] = {
759 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
760 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
761 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
762 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
763 
764 
765 const char* Simulator::WRegNameForCode(unsigned code, Reg31Mode mode) {
766  STATIC_ASSERT(arraysize(Simulator::wreg_names) == (kNumberOfRegisters + 1));
767  DCHECK(code < kNumberOfRegisters);
768  // The modulo operator has no effect here, but it silences a broken GCC
769  // warning about out-of-bounds array accesses.
770  code %= kNumberOfRegisters;
771 
772  // If the code represents the stack pointer, index the name after zr.
773  if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
774  code = kZeroRegCode + 1;
775  }
776  return wreg_names[code];
777 }
778 
779 
780 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) {
781  STATIC_ASSERT(arraysize(Simulator::xreg_names) == (kNumberOfRegisters + 1));
782  DCHECK(code < kNumberOfRegisters);
783  code %= kNumberOfRegisters;
784 
785  // If the code represents the stack pointer, index the name after zr.
786  if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
787  code = kZeroRegCode + 1;
788  }
789  return xreg_names[code];
790 }
791 
792 
793 const char* Simulator::SRegNameForCode(unsigned code) {
794  STATIC_ASSERT(arraysize(Simulator::sreg_names) == kNumberOfFPRegisters);
796  return sreg_names[code % kNumberOfFPRegisters];
797 }
798 
799 
800 const char* Simulator::DRegNameForCode(unsigned code) {
801  STATIC_ASSERT(arraysize(Simulator::dreg_names) == kNumberOfFPRegisters);
803  return dreg_names[code % kNumberOfFPRegisters];
804 }
805 
806 
807 const char* Simulator::VRegNameForCode(unsigned code) {
808  STATIC_ASSERT(arraysize(Simulator::vreg_names) == kNumberOfFPRegisters);
810  return vreg_names[code % kNumberOfFPRegisters];
811 }
812 
813 
814 int Simulator::CodeFromName(const char* name) {
815  for (unsigned i = 0; i < kNumberOfRegisters; i++) {
816  if ((strcmp(xreg_names[i], name) == 0) ||
817  (strcmp(wreg_names[i], name) == 0)) {
818  return i;
819  }
820  }
821  for (unsigned i = 0; i < kNumberOfFPRegisters; i++) {
822  if ((strcmp(vreg_names[i], name) == 0) ||
823  (strcmp(dreg_names[i], name) == 0) ||
824  (strcmp(sreg_names[i], name) == 0)) {
825  return i;
826  }
827  }
828  if ((strcmp("csp", name) == 0) || (strcmp("wcsp", name) == 0)) {
829  return kSPRegInternalCode;
830  }
831  return -1;
832 }
833 
834 
835 // Helpers ---------------------------------------------------------------------
836 template <typename T>
837 T Simulator::AddWithCarry(bool set_flags,
838  T src1,
839  T src2,
840  T carry_in) {
841  typedef typename make_unsigned<T>::type unsignedT;
842  DCHECK((carry_in == 0) || (carry_in == 1));
843 
844  T signed_sum = src1 + src2 + carry_in;
845  T result = signed_sum;
846 
847  bool N, Z, C, V;
848 
849  // Compute the C flag
850  unsignedT u1 = static_cast<unsignedT>(src1);
851  unsignedT u2 = static_cast<unsignedT>(src2);
852  unsignedT urest = std::numeric_limits<unsignedT>::max() - u1;
853  C = (u2 > urest) || (carry_in && (((u2 + 1) > urest) || (u2 > (urest - 1))));
854 
855  // Overflow iff the sign bit is the same for the two inputs and different
856  // for the result.
857  V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0);
858 
859  N = CalcNFlag(result);
860  Z = CalcZFlag(result);
861 
862  if (set_flags) {
863  nzcv().SetN(N);
864  nzcv().SetZ(Z);
865  nzcv().SetC(C);
866  nzcv().SetV(V);
867  LogSystemRegister(NZCV);
868  }
869  return result;
870 }
871 
872 
873 template<typename T>
874 void Simulator::AddSubWithCarry(Instruction* instr) {
875  T op2 = reg<T>(instr->Rm());
876  T new_val;
877 
878  if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) {
879  op2 = ~op2;
880  }
881 
882  new_val = AddWithCarry<T>(instr->FlagsUpdate(),
883  reg<T>(instr->Rn()),
884  op2,
885  nzcv().C());
886 
887  set_reg<T>(instr->Rd(), new_val);
888 }
889 
890 template <typename T>
891 T Simulator::ShiftOperand(T value, Shift shift_type, unsigned amount) {
892  typedef typename make_unsigned<T>::type unsignedT;
893 
894  if (amount == 0) {
895  return value;
896  }
897 
898  switch (shift_type) {
899  case LSL:
900  return value << amount;
901  case LSR:
902  return static_cast<unsignedT>(value) >> amount;
903  case ASR:
904  return value >> amount;
905  case ROR:
906  return (static_cast<unsignedT>(value) >> amount) |
907  ((value & ((1L << amount) - 1L)) <<
908  (sizeof(unsignedT) * 8 - amount));
909  default:
910  UNIMPLEMENTED();
911  return 0;
912  }
913 }
914 
915 
916 template <typename T>
917 T Simulator::ExtendValue(T value, Extend extend_type, unsigned left_shift) {
918  const unsigned kSignExtendBShift = (sizeof(T) - 1) * 8;
919  const unsigned kSignExtendHShift = (sizeof(T) - 2) * 8;
920  const unsigned kSignExtendWShift = (sizeof(T) - 4) * 8;
921 
922  switch (extend_type) {
923  case UXTB:
924  value &= kByteMask;
925  break;
926  case UXTH:
927  value &= kHalfWordMask;
928  break;
929  case UXTW:
930  value &= kWordMask;
931  break;
932  case SXTB:
933  value = (value << kSignExtendBShift) >> kSignExtendBShift;
934  break;
935  case SXTH:
936  value = (value << kSignExtendHShift) >> kSignExtendHShift;
937  break;
938  case SXTW:
939  value = (value << kSignExtendWShift) >> kSignExtendWShift;
940  break;
941  case UXTX:
942  case SXTX:
943  break;
944  default:
945  UNREACHABLE();
946  }
947  return value << left_shift;
948 }
949 
950 
951 template <typename T>
952 void Simulator::Extract(Instruction* instr) {
953  unsigned lsb = instr->ImmS();
954  T op2 = reg<T>(instr->Rm());
955  T result = op2;
956 
957  if (lsb) {
958  T op1 = reg<T>(instr->Rn());
959  result = op2 >> lsb | (op1 << ((sizeof(T) * 8) - lsb));
960  }
961  set_reg<T>(instr->Rd(), result);
962 }
963 
964 
965 template<> double Simulator::FPDefaultNaN<double>() const {
966  return kFP64DefaultNaN;
967 }
968 
969 
970 template<> float Simulator::FPDefaultNaN<float>() const {
971  return kFP32DefaultNaN;
972 }
973 
974 
975 void Simulator::FPCompare(double val0, double val1) {
976  AssertSupportedFPCR();
977 
978  // TODO(jbramley): This assumes that the C++ implementation handles
979  // comparisons in the way that we expect (as per AssertSupportedFPCR()).
980  if ((std::isnan(val0) != 0) || (std::isnan(val1) != 0)) {
981  nzcv().SetRawValue(FPUnorderedFlag);
982  } else if (val0 < val1) {
983  nzcv().SetRawValue(FPLessThanFlag);
984  } else if (val0 > val1) {
985  nzcv().SetRawValue(FPGreaterThanFlag);
986  } else if (val0 == val1) {
987  nzcv().SetRawValue(FPEqualFlag);
988  } else {
989  UNREACHABLE();
990  }
991  LogSystemRegister(NZCV);
992 }
993 
994 
995 void Simulator::SetBreakpoint(Instruction* location) {
996  for (unsigned i = 0; i < breakpoints_.size(); i++) {
997  if (breakpoints_.at(i).location == location) {
998  PrintF(stream_,
999  "Existing breakpoint at %p was %s\n",
1000  reinterpret_cast<void*>(location),
1001  breakpoints_.at(i).enabled ? "disabled" : "enabled");
1002  breakpoints_.at(i).enabled = !breakpoints_.at(i).enabled;
1003  return;
1004  }
1005  }
1006  Breakpoint new_breakpoint = {location, true};
1007  breakpoints_.push_back(new_breakpoint);
1008  PrintF(stream_,
1009  "Set a breakpoint at %p\n", reinterpret_cast<void*>(location));
1010 }
1011 
1012 
1013 void Simulator::ListBreakpoints() {
1014  PrintF(stream_, "Breakpoints:\n");
1015  for (unsigned i = 0; i < breakpoints_.size(); i++) {
1016  PrintF(stream_, "%p : %s\n",
1017  reinterpret_cast<void*>(breakpoints_.at(i).location),
1018  breakpoints_.at(i).enabled ? "enabled" : "disabled");
1019  }
1020 }
1021 
1022 
1023 void Simulator::CheckBreakpoints() {
1024  bool hit_a_breakpoint = false;
1025  for (unsigned i = 0; i < breakpoints_.size(); i++) {
1026  if ((breakpoints_.at(i).location == pc_) &&
1027  breakpoints_.at(i).enabled) {
1028  hit_a_breakpoint = true;
1029  // Disable this breakpoint.
1030  breakpoints_.at(i).enabled = false;
1031  }
1032  }
1033  if (hit_a_breakpoint) {
1034  PrintF(stream_, "Hit and disabled a breakpoint at %p.\n",
1035  reinterpret_cast<void*>(pc_));
1036  Debug();
1037  }
1038 }
1039 
1040 
1041 void Simulator::CheckBreakNext() {
1042  // If the current instruction is a BL, insert a breakpoint just after it.
1043  if (break_on_next_ && pc_->IsBranchAndLinkToRegister()) {
1044  SetBreakpoint(pc_->following());
1045  break_on_next_ = false;
1046  }
1047 }
1048 
1049 
1050 void Simulator::PrintInstructionsAt(Instruction* start, uint64_t count) {
1051  Instruction* end = start->InstructionAtOffset(count * kInstructionSize);
1052  for (Instruction* pc = start; pc < end; pc = pc->following()) {
1053  disassembler_decoder_->Decode(pc);
1054  }
1055 }
1056 
1057 
1058 void Simulator::PrintSystemRegisters() {
1059  PrintSystemRegister(NZCV);
1060  PrintSystemRegister(FPCR);
1061 }
1062 
1063 
1064 void Simulator::PrintRegisters() {
1065  for (unsigned i = 0; i < kNumberOfRegisters; i++) {
1066  PrintRegister(i);
1067  }
1068 }
1069 
1070 
1071 void Simulator::PrintFPRegisters() {
1072  for (unsigned i = 0; i < kNumberOfFPRegisters; i++) {
1073  PrintFPRegister(i);
1074  }
1075 }
1076 
1077 
1078 void Simulator::PrintRegister(unsigned code, Reg31Mode r31mode) {
1079  // Don't print writes into xzr.
1080  if ((code == kZeroRegCode) && (r31mode == Reg31IsZeroRegister)) {
1081  return;
1082  }
1083 
1084  // The template is "# x<code>:value".
1085  fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s\n",
1086  clr_reg_name, XRegNameForCode(code, r31mode),
1087  clr_reg_value, reg<uint64_t>(code, r31mode), clr_normal);
1088 }
1089 
1090 
1091 void Simulator::PrintFPRegister(unsigned code, PrintFPRegisterSizes sizes) {
1092  // The template is "# v<code>:bits (d<code>:value, ...)".
1093 
1094  DCHECK(sizes != 0);
1095  DCHECK((sizes & kPrintAllFPRegValues) == sizes);
1096 
1097  // Print the raw bits.
1098  fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (",
1099  clr_fpreg_name, VRegNameForCode(code),
1100  clr_fpreg_value, fpreg<uint64_t>(code), clr_normal);
1101 
1102  // Print all requested value interpretations.
1103  bool need_separator = false;
1104  if (sizes & kPrintDRegValue) {
1105  fprintf(stream_, "%s%s%s: %s%g%s",
1106  need_separator ? ", " : "",
1107  clr_fpreg_name, DRegNameForCode(code),
1108  clr_fpreg_value, fpreg<double>(code), clr_normal);
1109  need_separator = true;
1110  }
1111 
1112  if (sizes & kPrintSRegValue) {
1113  fprintf(stream_, "%s%s%s: %s%g%s",
1114  need_separator ? ", " : "",
1115  clr_fpreg_name, SRegNameForCode(code),
1116  clr_fpreg_value, fpreg<float>(code), clr_normal);
1117  need_separator = true;
1118  }
1119 
1120  // End the value list.
1121  fprintf(stream_, ")\n");
1122 }
1123 
1124 
1125 void Simulator::PrintSystemRegister(SystemRegister id) {
1126  switch (id) {
1127  case NZCV:
1128  fprintf(stream_, "# %sNZCV: %sN:%d Z:%d C:%d V:%d%s\n",
1129  clr_flag_name, clr_flag_value,
1130  nzcv().N(), nzcv().Z(), nzcv().C(), nzcv().V(),
1131  clr_normal);
1132  break;
1133  case FPCR: {
1134  static const char * rmode[] = {
1135  "0b00 (Round to Nearest)",
1136  "0b01 (Round towards Plus Infinity)",
1137  "0b10 (Round towards Minus Infinity)",
1138  "0b11 (Round towards Zero)"
1139  };
1140  DCHECK(fpcr().RMode() < arraysize(rmode));
1141  fprintf(stream_,
1142  "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n",
1143  clr_flag_name, clr_flag_value,
1144  fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()],
1145  clr_normal);
1146  break;
1147  }
1148  default:
1149  UNREACHABLE();
1150  }
1151 }
1152 
1153 
1154 void Simulator::PrintRead(uintptr_t address,
1155  size_t size,
1156  unsigned reg_code) {
1157  USE(size); // Size is unused here.
1158 
1159  // The template is "# x<code>:value <- address".
1160  fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s",
1161  clr_reg_name, XRegNameForCode(reg_code),
1162  clr_reg_value, reg<uint64_t>(reg_code), clr_normal);
1163 
1164  fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n",
1165  clr_memory_address, address, clr_normal);
1166 }
1167 
1168 
1169 void Simulator::PrintReadFP(uintptr_t address,
1170  size_t size,
1171  unsigned reg_code) {
1172  // The template is "# reg:bits (reg:value) <- address".
1173  switch (size) {
1174  case kSRegSize:
1175  fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%gf%s)",
1176  clr_fpreg_name, VRegNameForCode(reg_code),
1177  clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1178  clr_fpreg_name, SRegNameForCode(reg_code),
1179  clr_fpreg_value, fpreg<float>(reg_code), clr_normal);
1180  break;
1181  case kDRegSize:
1182  fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%g%s)",
1183  clr_fpreg_name, VRegNameForCode(reg_code),
1184  clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1185  clr_fpreg_name, DRegNameForCode(reg_code),
1186  clr_fpreg_value, fpreg<double>(reg_code), clr_normal);
1187  break;
1188  default:
1189  UNREACHABLE();
1190  }
1191 
1192  fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n",
1193  clr_memory_address, address, clr_normal);
1194 }
1195 
1196 
1197 void Simulator::PrintWrite(uintptr_t address,
1198  size_t size,
1199  unsigned reg_code) {
1200  // The template is "# reg:value -> address". To keep the trace tidy and
1201  // readable, the value is aligned with the values in the register trace.
1202  switch (size) {
1203  case kByteSizeInBytes:
1204  fprintf(stream_, "# %s%5s<7:0>: %s0x%02" PRIx8 "%s",
1205  clr_reg_name, WRegNameForCode(reg_code),
1206  clr_reg_value, reg<uint8_t>(reg_code), clr_normal);
1207  break;
1208  case kHalfWordSizeInBytes:
1209  fprintf(stream_, "# %s%5s<15:0>: %s0x%04" PRIx16 "%s",
1210  clr_reg_name, WRegNameForCode(reg_code),
1211  clr_reg_value, reg<uint16_t>(reg_code), clr_normal);
1212  break;
1213  case kWRegSize:
1214  fprintf(stream_, "# %s%5s: %s0x%08" PRIx32 "%s",
1215  clr_reg_name, WRegNameForCode(reg_code),
1216  clr_reg_value, reg<uint32_t>(reg_code), clr_normal);
1217  break;
1218  case kXRegSize:
1219  fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s",
1220  clr_reg_name, XRegNameForCode(reg_code),
1221  clr_reg_value, reg<uint64_t>(reg_code), clr_normal);
1222  break;
1223  default:
1224  UNREACHABLE();
1225  }
1226 
1227  fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n",
1228  clr_memory_address, address, clr_normal);
1229 }
1230 
1231 
1232 void Simulator::PrintWriteFP(uintptr_t address,
1233  size_t size,
1234  unsigned reg_code) {
1235  // The template is "# reg:bits (reg:value) -> address". To keep the trace tidy
1236  // and readable, the value is aligned with the values in the register trace.
1237  switch (size) {
1238  case kSRegSize:
1239  fprintf(stream_, "# %s%5s<31:0>: %s0x%08" PRIx32 "%s (%s%s: %s%gf%s)",
1240  clr_fpreg_name, VRegNameForCode(reg_code),
1241  clr_fpreg_value, fpreg<uint32_t>(reg_code), clr_normal,
1242  clr_fpreg_name, SRegNameForCode(reg_code),
1243  clr_fpreg_value, fpreg<float>(reg_code), clr_normal);
1244  break;
1245  case kDRegSize:
1246  fprintf(stream_, "# %s%5s: %s0x%016" PRIx64 "%s (%s%s: %s%g%s)",
1247  clr_fpreg_name, VRegNameForCode(reg_code),
1248  clr_fpreg_value, fpreg<uint64_t>(reg_code), clr_normal,
1249  clr_fpreg_name, DRegNameForCode(reg_code),
1250  clr_fpreg_value, fpreg<double>(reg_code), clr_normal);
1251  break;
1252  default:
1253  UNREACHABLE();
1254  }
1255 
1256  fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n",
1257  clr_memory_address, address, clr_normal);
1258 }
1259 
1260 
1261 // Visitors---------------------------------------------------------------------
1262 
1263 void Simulator::VisitUnimplemented(Instruction* instr) {
1264  fprintf(stream_, "Unimplemented instruction at %p: 0x%08" PRIx32 "\n",
1265  reinterpret_cast<void*>(instr), instr->InstructionBits());
1266  UNIMPLEMENTED();
1267 }
1268 
1269 
1270 void Simulator::VisitUnallocated(Instruction* instr) {
1271  fprintf(stream_, "Unallocated instruction at %p: 0x%08" PRIx32 "\n",
1272  reinterpret_cast<void*>(instr), instr->InstructionBits());
1273  UNIMPLEMENTED();
1274 }
1275 
1276 
1277 void Simulator::VisitPCRelAddressing(Instruction* instr) {
1278  switch (instr->Mask(PCRelAddressingMask)) {
1279  case ADR:
1280  set_reg(instr->Rd(), instr->ImmPCOffsetTarget());
1281  break;
1282  case ADRP: // Not implemented in the assembler.
1283  UNIMPLEMENTED();
1284  break;
1285  default:
1286  UNREACHABLE();
1287  break;
1288  }
1289 }
1290 
1291 
1292 void Simulator::VisitUnconditionalBranch(Instruction* instr) {
1293  switch (instr->Mask(UnconditionalBranchMask)) {
1294  case BL:
1295  set_lr(instr->following());
1296  // Fall through.
1297  case B:
1298  set_pc(instr->ImmPCOffsetTarget());
1299  break;
1300  default:
1301  UNREACHABLE();
1302  }
1303 }
1304 
1305 
1306 void Simulator::VisitConditionalBranch(Instruction* instr) {
1307  DCHECK(instr->Mask(ConditionalBranchMask) == B_cond);
1308  if (ConditionPassed(static_cast<Condition>(instr->ConditionBranch()))) {
1309  set_pc(instr->ImmPCOffsetTarget());
1310  }
1311 }
1312 
1313 
1314 void Simulator::VisitUnconditionalBranchToRegister(Instruction* instr) {
1315  Instruction* target = reg<Instruction*>(instr->Rn());
1316  switch (instr->Mask(UnconditionalBranchToRegisterMask)) {
1317  case BLR: {
1318  set_lr(instr->following());
1319  if (instr->Rn() == 31) {
1320  // BLR XZR is used as a guard for the constant pool. We should never hit
1321  // this, but if we do trap to allow debugging.
1322  Debug();
1323  }
1324  // Fall through.
1325  }
1326  case BR:
1327  case RET: set_pc(target); break;
1328  default: UNIMPLEMENTED();
1329  }
1330 }
1331 
1332 
1333 void Simulator::VisitTestBranch(Instruction* instr) {
1334  unsigned bit_pos = (instr->ImmTestBranchBit5() << 5) |
1335  instr->ImmTestBranchBit40();
1336  bool take_branch = ((xreg(instr->Rt()) & (1UL << bit_pos)) == 0);
1337  switch (instr->Mask(TestBranchMask)) {
1338  case TBZ: break;
1339  case TBNZ: take_branch = !take_branch; break;
1340  default: UNIMPLEMENTED();
1341  }
1342  if (take_branch) {
1343  set_pc(instr->ImmPCOffsetTarget());
1344  }
1345 }
1346 
1347 
1348 void Simulator::VisitCompareBranch(Instruction* instr) {
1349  unsigned rt = instr->Rt();
1350  bool take_branch = false;
1351  switch (instr->Mask(CompareBranchMask)) {
1352  case CBZ_w: take_branch = (wreg(rt) == 0); break;
1353  case CBZ_x: take_branch = (xreg(rt) == 0); break;
1354  case CBNZ_w: take_branch = (wreg(rt) != 0); break;
1355  case CBNZ_x: take_branch = (xreg(rt) != 0); break;
1356  default: UNIMPLEMENTED();
1357  }
1358  if (take_branch) {
1359  set_pc(instr->ImmPCOffsetTarget());
1360  }
1361 }
1362 
1363 
1364 template<typename T>
1365 void Simulator::AddSubHelper(Instruction* instr, T op2) {
1366  bool set_flags = instr->FlagsUpdate();
1367  T new_val = 0;
1368  Instr operation = instr->Mask(AddSubOpMask);
1369 
1370  switch (operation) {
1371  case ADD:
1372  case ADDS: {
1373  new_val = AddWithCarry<T>(set_flags,
1374  reg<T>(instr->Rn(), instr->RnMode()),
1375  op2);
1376  break;
1377  }
1378  case SUB:
1379  case SUBS: {
1380  new_val = AddWithCarry<T>(set_flags,
1381  reg<T>(instr->Rn(), instr->RnMode()),
1382  ~op2,
1383  1);
1384  break;
1385  }
1386  default: UNREACHABLE();
1387  }
1388 
1389  set_reg<T>(instr->Rd(), new_val, instr->RdMode());
1390 }
1391 
1392 
1393 void Simulator::VisitAddSubShifted(Instruction* instr) {
1394  Shift shift_type = static_cast<Shift>(instr->ShiftDP());
1395  unsigned shift_amount = instr->ImmDPShift();
1396 
1397  if (instr->SixtyFourBits()) {
1398  int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount);
1399  AddSubHelper(instr, op2);
1400  } else {
1401  int32_t op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount);
1402  AddSubHelper(instr, op2);
1403  }
1404 }
1405 
1406 
1407 void Simulator::VisitAddSubImmediate(Instruction* instr) {
1408  int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0);
1409  if (instr->SixtyFourBits()) {
1410  AddSubHelper<int64_t>(instr, op2);
1411  } else {
1412  AddSubHelper<int32_t>(instr, op2);
1413  }
1414 }
1415 
1416 
1417 void Simulator::VisitAddSubExtended(Instruction* instr) {
1418  Extend ext = static_cast<Extend>(instr->ExtendMode());
1419  unsigned left_shift = instr->ImmExtendShift();
1420  if (instr->SixtyFourBits()) {
1421  int64_t op2 = ExtendValue(xreg(instr->Rm()), ext, left_shift);
1422  AddSubHelper(instr, op2);
1423  } else {
1424  int32_t op2 = ExtendValue(wreg(instr->Rm()), ext, left_shift);
1425  AddSubHelper(instr, op2);
1426  }
1427 }
1428 
1429 
1430 void Simulator::VisitAddSubWithCarry(Instruction* instr) {
1431  if (instr->SixtyFourBits()) {
1432  AddSubWithCarry<int64_t>(instr);
1433  } else {
1434  AddSubWithCarry<int32_t>(instr);
1435  }
1436 }
1437 
1438 
1439 void Simulator::VisitLogicalShifted(Instruction* instr) {
1440  Shift shift_type = static_cast<Shift>(instr->ShiftDP());
1441  unsigned shift_amount = instr->ImmDPShift();
1442 
1443  if (instr->SixtyFourBits()) {
1444  int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount);
1445  op2 = (instr->Mask(NOT) == NOT) ? ~op2 : op2;
1446  LogicalHelper<int64_t>(instr, op2);
1447  } else {
1448  int32_t op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount);
1449  op2 = (instr->Mask(NOT) == NOT) ? ~op2 : op2;
1450  LogicalHelper<int32_t>(instr, op2);
1451  }
1452 }
1453 
1454 
1455 void Simulator::VisitLogicalImmediate(Instruction* instr) {
1456  if (instr->SixtyFourBits()) {
1457  LogicalHelper<int64_t>(instr, instr->ImmLogical());
1458  } else {
1459  LogicalHelper<int32_t>(instr, instr->ImmLogical());
1460  }
1461 }
1462 
1463 
1464 template<typename T>
1465 void Simulator::LogicalHelper(Instruction* instr, T op2) {
1466  T op1 = reg<T>(instr->Rn());
1467  T result = 0;
1468  bool update_flags = false;
1469 
1470  // Switch on the logical operation, stripping out the NOT bit, as it has a
1471  // different meaning for logical immediate instructions.
1472  switch (instr->Mask(LogicalOpMask & ~NOT)) {
1473  case ANDS: update_flags = true; // Fall through.
1474  case AND: result = op1 & op2; break;
1475  case ORR: result = op1 | op2; break;
1476  case EOR: result = op1 ^ op2; break;
1477  default:
1478  UNIMPLEMENTED();
1479  }
1480 
1481  if (update_flags) {
1482  nzcv().SetN(CalcNFlag(result));
1483  nzcv().SetZ(CalcZFlag(result));
1484  nzcv().SetC(0);
1485  nzcv().SetV(0);
1486  LogSystemRegister(NZCV);
1487  }
1488 
1489  set_reg<T>(instr->Rd(), result, instr->RdMode());
1490 }
1491 
1492 
1493 void Simulator::VisitConditionalCompareRegister(Instruction* instr) {
1494  if (instr->SixtyFourBits()) {
1495  ConditionalCompareHelper(instr, xreg(instr->Rm()));
1496  } else {
1497  ConditionalCompareHelper(instr, wreg(instr->Rm()));
1498  }
1499 }
1500 
1501 
1502 void Simulator::VisitConditionalCompareImmediate(Instruction* instr) {
1503  if (instr->SixtyFourBits()) {
1504  ConditionalCompareHelper<int64_t>(instr, instr->ImmCondCmp());
1505  } else {
1506  ConditionalCompareHelper<int32_t>(instr, instr->ImmCondCmp());
1507  }
1508 }
1509 
1510 
1511 template<typename T>
1512 void Simulator::ConditionalCompareHelper(Instruction* instr, T op2) {
1513  T op1 = reg<T>(instr->Rn());
1514 
1515  if (ConditionPassed(static_cast<Condition>(instr->Condition()))) {
1516  // If the condition passes, set the status flags to the result of comparing
1517  // the operands.
1518  if (instr->Mask(ConditionalCompareMask) == CCMP) {
1519  AddWithCarry<T>(true, op1, ~op2, 1);
1520  } else {
1521  DCHECK(instr->Mask(ConditionalCompareMask) == CCMN);
1522  AddWithCarry<T>(true, op1, op2, 0);
1523  }
1524  } else {
1525  // If the condition fails, set the status flags to the nzcv immediate.
1526  nzcv().SetFlags(instr->Nzcv());
1527  LogSystemRegister(NZCV);
1528  }
1529 }
1530 
1531 
1532 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) {
1533  int offset = instr->ImmLSUnsigned() << instr->SizeLS();
1534  LoadStoreHelper(instr, offset, Offset);
1535 }
1536 
1537 
1538 void Simulator::VisitLoadStoreUnscaledOffset(Instruction* instr) {
1539  LoadStoreHelper(instr, instr->ImmLS(), Offset);
1540 }
1541 
1542 
1543 void Simulator::VisitLoadStorePreIndex(Instruction* instr) {
1544  LoadStoreHelper(instr, instr->ImmLS(), PreIndex);
1545 }
1546 
1547 
1548 void Simulator::VisitLoadStorePostIndex(Instruction* instr) {
1549  LoadStoreHelper(instr, instr->ImmLS(), PostIndex);
1550 }
1551 
1552 
1553 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) {
1554  Extend ext = static_cast<Extend>(instr->ExtendMode());
1555  DCHECK((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX));
1556  unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS();
1557 
1558  int64_t offset = ExtendValue(xreg(instr->Rm()), ext, shift_amount);
1559  LoadStoreHelper(instr, offset, Offset);
1560 }
1561 
1562 
1563 void Simulator::LoadStoreHelper(Instruction* instr,
1564  int64_t offset,
1565  AddrMode addrmode) {
1566  unsigned srcdst = instr->Rt();
1567  unsigned addr_reg = instr->Rn();
1568  uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode);
1569  uintptr_t stack = 0;
1570 
1571  // Handle the writeback for stores before the store. On a CPU the writeback
1572  // and the store are atomic, but when running on the simulator it is possible
1573  // to be interrupted in between. The simulator is not thread safe and V8 does
1574  // not require it to be to run JavaScript therefore the profiler may sample
1575  // the "simulated" CPU in the middle of load/store with writeback. The code
1576  // below ensures that push operations are safe even when interrupted: the
1577  // stack pointer will be decremented before adding an element to the stack.
1578  if (instr->IsStore()) {
1579  LoadStoreWriteBack(addr_reg, offset, addrmode);
1580 
1581  // For store the address post writeback is used to check access below the
1582  // stack.
1583  stack = sp();
1584  }
1585 
1586  LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask));
1587  switch (op) {
1588  // Use _no_log variants to suppress the register trace (LOG_REGS,
1589  // LOG_FP_REGS). We will print a more detailed log.
1590  case LDRB_w: set_wreg_no_log(srcdst, MemoryRead<uint8_t>(address)); break;
1591  case LDRH_w: set_wreg_no_log(srcdst, MemoryRead<uint16_t>(address)); break;
1592  case LDR_w: set_wreg_no_log(srcdst, MemoryRead<uint32_t>(address)); break;
1593  case LDR_x: set_xreg_no_log(srcdst, MemoryRead<uint64_t>(address)); break;
1594  case LDRSB_w: set_wreg_no_log(srcdst, MemoryRead<int8_t>(address)); break;
1595  case LDRSH_w: set_wreg_no_log(srcdst, MemoryRead<int16_t>(address)); break;
1596  case LDRSB_x: set_xreg_no_log(srcdst, MemoryRead<int8_t>(address)); break;
1597  case LDRSH_x: set_xreg_no_log(srcdst, MemoryRead<int16_t>(address)); break;
1598  case LDRSW_x: set_xreg_no_log(srcdst, MemoryRead<int32_t>(address)); break;
1599  case LDR_s: set_sreg_no_log(srcdst, MemoryRead<float>(address)); break;
1600  case LDR_d: set_dreg_no_log(srcdst, MemoryRead<double>(address)); break;
1601 
1602  case STRB_w: MemoryWrite<uint8_t>(address, wreg(srcdst)); break;
1603  case STRH_w: MemoryWrite<uint16_t>(address, wreg(srcdst)); break;
1604  case STR_w: MemoryWrite<uint32_t>(address, wreg(srcdst)); break;
1605  case STR_x: MemoryWrite<uint64_t>(address, xreg(srcdst)); break;
1606  case STR_s: MemoryWrite<float>(address, sreg(srcdst)); break;
1607  case STR_d: MemoryWrite<double>(address, dreg(srcdst)); break;
1608 
1609  default: UNIMPLEMENTED();
1610  }
1611 
1612  // Print a detailed trace (including the memory address) instead of the basic
1613  // register:value trace generated by set_*reg().
1614  size_t access_size = 1 << instr->SizeLS();
1615  if (instr->IsLoad()) {
1616  if ((op == LDR_s) || (op == LDR_d)) {
1617  LogReadFP(address, access_size, srcdst);
1618  } else {
1619  LogRead(address, access_size, srcdst);
1620  }
1621  } else {
1622  if ((op == STR_s) || (op == STR_d)) {
1623  LogWriteFP(address, access_size, srcdst);
1624  } else {
1625  LogWrite(address, access_size, srcdst);
1626  }
1627  }
1628 
1629  // Handle the writeback for loads after the load to ensure safe pop
1630  // operation even when interrupted in the middle of it. The stack pointer
1631  // is only updated after the load so pop(fp) will never break the invariant
1632  // sp <= fp expected while walking the stack in the sampler.
1633  if (instr->IsLoad()) {
1634  // For loads the address pre writeback is used to check access below the
1635  // stack.
1636  stack = sp();
1637 
1638  LoadStoreWriteBack(addr_reg, offset, addrmode);
1639  }
1640 
1641  // Accesses below the stack pointer (but above the platform stack limit) are
1642  // not allowed in the ABI.
1643  CheckMemoryAccess(address, stack);
1644 }
1645 
1646 
1647 void Simulator::VisitLoadStorePairOffset(Instruction* instr) {
1648  LoadStorePairHelper(instr, Offset);
1649 }
1650 
1651 
1652 void Simulator::VisitLoadStorePairPreIndex(Instruction* instr) {
1653  LoadStorePairHelper(instr, PreIndex);
1654 }
1655 
1656 
1657 void Simulator::VisitLoadStorePairPostIndex(Instruction* instr) {
1658  LoadStorePairHelper(instr, PostIndex);
1659 }
1660 
1661 
1662 void Simulator::VisitLoadStorePairNonTemporal(Instruction* instr) {
1663  LoadStorePairHelper(instr, Offset);
1664 }
1665 
1666 
1667 void Simulator::LoadStorePairHelper(Instruction* instr,
1668  AddrMode addrmode) {
1669  unsigned rt = instr->Rt();
1670  unsigned rt2 = instr->Rt2();
1671  unsigned addr_reg = instr->Rn();
1672  size_t access_size = 1 << instr->SizeLSPair();
1673  int64_t offset = instr->ImmLSPair() * access_size;
1674  uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode);
1675  uintptr_t address2 = address + access_size;
1676  uintptr_t stack = 0;
1677 
1678  // Handle the writeback for stores before the store. On a CPU the writeback
1679  // and the store are atomic, but when running on the simulator it is possible
1680  // to be interrupted in between. The simulator is not thread safe and V8 does
1681  // not require it to be to run JavaScript therefore the profiler may sample
1682  // the "simulated" CPU in the middle of load/store with writeback. The code
1683  // below ensures that push operations are safe even when interrupted: the
1684  // stack pointer will be decremented before adding an element to the stack.
1685  if (instr->IsStore()) {
1686  LoadStoreWriteBack(addr_reg, offset, addrmode);
1687 
1688  // For store the address post writeback is used to check access below the
1689  // stack.
1690  stack = sp();
1691  }
1692 
1693  LoadStorePairOp op =
1694  static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask));
1695 
1696  // 'rt' and 'rt2' can only be aliased for stores.
1697  DCHECK(((op & LoadStorePairLBit) == 0) || (rt != rt2));
1698 
1699  switch (op) {
1700  // Use _no_log variants to suppress the register trace (LOG_REGS,
1701  // LOG_FP_REGS). We will print a more detailed log.
1702  case LDP_w: {
1703  DCHECK(access_size == kWRegSize);
1704  set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
1705  set_wreg_no_log(rt2, MemoryRead<uint32_t>(address2));
1706  break;
1707  }
1708  case LDP_s: {
1709  DCHECK(access_size == kSRegSize);
1710  set_sreg_no_log(rt, MemoryRead<float>(address));
1711  set_sreg_no_log(rt2, MemoryRead<float>(address2));
1712  break;
1713  }
1714  case LDP_x: {
1715  DCHECK(access_size == kXRegSize);
1716  set_xreg_no_log(rt, MemoryRead<uint64_t>(address));
1717  set_xreg_no_log(rt2, MemoryRead<uint64_t>(address2));
1718  break;
1719  }
1720  case LDP_d: {
1721  DCHECK(access_size == kDRegSize);
1722  set_dreg_no_log(rt, MemoryRead<double>(address));
1723  set_dreg_no_log(rt2, MemoryRead<double>(address2));
1724  break;
1725  }
1726  case LDPSW_x: {
1727  DCHECK(access_size == kWRegSize);
1728  set_xreg_no_log(rt, MemoryRead<int32_t>(address));
1729  set_xreg_no_log(rt2, MemoryRead<int32_t>(address2));
1730  break;
1731  }
1732  case STP_w: {
1733  DCHECK(access_size == kWRegSize);
1734  MemoryWrite<uint32_t>(address, wreg(rt));
1735  MemoryWrite<uint32_t>(address2, wreg(rt2));
1736  break;
1737  }
1738  case STP_s: {
1739  DCHECK(access_size == kSRegSize);
1740  MemoryWrite<float>(address, sreg(rt));
1741  MemoryWrite<float>(address2, sreg(rt2));
1742  break;
1743  }
1744  case STP_x: {
1745  DCHECK(access_size == kXRegSize);
1746  MemoryWrite<uint64_t>(address, xreg(rt));
1747  MemoryWrite<uint64_t>(address2, xreg(rt2));
1748  break;
1749  }
1750  case STP_d: {
1751  DCHECK(access_size == kDRegSize);
1752  MemoryWrite<double>(address, dreg(rt));
1753  MemoryWrite<double>(address2, dreg(rt2));
1754  break;
1755  }
1756  default: UNREACHABLE();
1757  }
1758 
1759  // Print a detailed trace (including the memory address) instead of the basic
1760  // register:value trace generated by set_*reg().
1761  if (instr->IsLoad()) {
1762  if ((op == LDP_s) || (op == LDP_d)) {
1763  LogReadFP(address, access_size, rt);
1764  LogReadFP(address2, access_size, rt2);
1765  } else {
1766  LogRead(address, access_size, rt);
1767  LogRead(address2, access_size, rt2);
1768  }
1769  } else {
1770  if ((op == STP_s) || (op == STP_d)) {
1771  LogWriteFP(address, access_size, rt);
1772  LogWriteFP(address2, access_size, rt2);
1773  } else {
1774  LogWrite(address, access_size, rt);
1775  LogWrite(address2, access_size, rt2);
1776  }
1777  }
1778 
1779  // Handle the writeback for loads after the load to ensure safe pop
1780  // operation even when interrupted in the middle of it. The stack pointer
1781  // is only updated after the load so pop(fp) will never break the invariant
1782  // sp <= fp expected while walking the stack in the sampler.
1783  if (instr->IsLoad()) {
1784  // For loads the address pre writeback is used to check access below the
1785  // stack.
1786  stack = sp();
1787 
1788  LoadStoreWriteBack(addr_reg, offset, addrmode);
1789  }
1790 
1791  // Accesses below the stack pointer (but above the platform stack limit) are
1792  // not allowed in the ABI.
1793  CheckMemoryAccess(address, stack);
1794 }
1795 
1796 
1797 void Simulator::VisitLoadLiteral(Instruction* instr) {
1798  uintptr_t address = instr->LiteralAddress();
1799  unsigned rt = instr->Rt();
1800 
1801  switch (instr->Mask(LoadLiteralMask)) {
1802  // Use _no_log variants to suppress the register trace (LOG_REGS,
1803  // LOG_FP_REGS), then print a more detailed log.
1804  case LDR_w_lit:
1805  set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
1806  LogRead(address, kWRegSize, rt);
1807  break;
1808  case LDR_x_lit:
1809  set_xreg_no_log(rt, MemoryRead<uint64_t>(address));
1810  LogRead(address, kXRegSize, rt);
1811  break;
1812  case LDR_s_lit:
1813  set_sreg_no_log(rt, MemoryRead<float>(address));
1814  LogReadFP(address, kSRegSize, rt);
1815  break;
1816  case LDR_d_lit:
1817  set_dreg_no_log(rt, MemoryRead<double>(address));
1818  LogReadFP(address, kDRegSize, rt);
1819  break;
1820  default: UNREACHABLE();
1821  }
1822 }
1823 
1824 
1825 uintptr_t Simulator::LoadStoreAddress(unsigned addr_reg, int64_t offset,
1826  AddrMode addrmode) {
1827  const unsigned kSPRegCode = kSPRegInternalCode & kRegCodeMask;
1828  uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1829  if ((addr_reg == kSPRegCode) && ((address % 16) != 0)) {
1830  // When the base register is SP the stack pointer is required to be
1831  // quadword aligned prior to the address calculation and write-backs.
1832  // Misalignment will cause a stack alignment fault.
1833  FATAL("ALIGNMENT EXCEPTION");
1834  }
1835 
1836  if ((addrmode == Offset) || (addrmode == PreIndex)) {
1837  address += offset;
1838  }
1839 
1840  return address;
1841 }
1842 
1843 
1844 void Simulator::LoadStoreWriteBack(unsigned addr_reg,
1845  int64_t offset,
1846  AddrMode addrmode) {
1847  if ((addrmode == PreIndex) || (addrmode == PostIndex)) {
1848  DCHECK(offset != 0);
1849  uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1850  set_reg(addr_reg, address + offset, Reg31IsStackPointer);
1851  }
1852 }
1853 
1854 
1855 void Simulator::CheckMemoryAccess(uintptr_t address, uintptr_t stack) {
1856  if ((address >= stack_limit_) && (address < stack)) {
1857  fprintf(stream_, "ACCESS BELOW STACK POINTER:\n");
1858  fprintf(stream_, " sp is here: 0x%016" PRIx64 "\n",
1859  static_cast<uint64_t>(stack));
1860  fprintf(stream_, " access was here: 0x%016" PRIx64 "\n",
1861  static_cast<uint64_t>(address));
1862  fprintf(stream_, " stack limit is here: 0x%016" PRIx64 "\n",
1863  static_cast<uint64_t>(stack_limit_));
1864  fprintf(stream_, "\n");
1865  FATAL("ACCESS BELOW STACK POINTER");
1866  }
1867 }
1868 
1869 
1870 void Simulator::VisitMoveWideImmediate(Instruction* instr) {
1871  MoveWideImmediateOp mov_op =
1872  static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask));
1873  int64_t new_xn_val = 0;
1874 
1875  bool is_64_bits = instr->SixtyFourBits() == 1;
1876  // Shift is limited for W operations.
1877  DCHECK(is_64_bits || (instr->ShiftMoveWide() < 2));
1878 
1879  // Get the shifted immediate.
1880  int64_t shift = instr->ShiftMoveWide() * 16;
1881  int64_t shifted_imm16 = instr->ImmMoveWide() << shift;
1882 
1883  // Compute the new value.
1884  switch (mov_op) {
1885  case MOVN_w:
1886  case MOVN_x: {
1887  new_xn_val = ~shifted_imm16;
1888  if (!is_64_bits) new_xn_val &= kWRegMask;
1889  break;
1890  }
1891  case MOVK_w:
1892  case MOVK_x: {
1893  unsigned reg_code = instr->Rd();
1894  int64_t prev_xn_val = is_64_bits ? xreg(reg_code)
1895  : wreg(reg_code);
1896  new_xn_val = (prev_xn_val & ~(0xffffL << shift)) | shifted_imm16;
1897  break;
1898  }
1899  case MOVZ_w:
1900  case MOVZ_x: {
1901  new_xn_val = shifted_imm16;
1902  break;
1903  }
1904  default:
1905  UNREACHABLE();
1906  }
1907 
1908  // Update the destination register.
1909  set_xreg(instr->Rd(), new_xn_val);
1910 }
1911 
1912 
1913 void Simulator::VisitConditionalSelect(Instruction* instr) {
1914  if (ConditionFailed(static_cast<Condition>(instr->Condition()))) {
1915  uint64_t new_val = xreg(instr->Rm());
1916  switch (instr->Mask(ConditionalSelectMask)) {
1917  case CSEL_w: set_wreg(instr->Rd(), new_val); break;
1918  case CSEL_x: set_xreg(instr->Rd(), new_val); break;
1919  case CSINC_w: set_wreg(instr->Rd(), new_val + 1); break;
1920  case CSINC_x: set_xreg(instr->Rd(), new_val + 1); break;
1921  case CSINV_w: set_wreg(instr->Rd(), ~new_val); break;
1922  case CSINV_x: set_xreg(instr->Rd(), ~new_val); break;
1923  case CSNEG_w: set_wreg(instr->Rd(), -new_val); break;
1924  case CSNEG_x: set_xreg(instr->Rd(), -new_val); break;
1925  default: UNIMPLEMENTED();
1926  }
1927  } else {
1928  if (instr->SixtyFourBits()) {
1929  set_xreg(instr->Rd(), xreg(instr->Rn()));
1930  } else {
1931  set_wreg(instr->Rd(), wreg(instr->Rn()));
1932  }
1933  }
1934 }
1935 
1936 
1937 void Simulator::VisitDataProcessing1Source(Instruction* instr) {
1938  unsigned dst = instr->Rd();
1939  unsigned src = instr->Rn();
1940 
1941  switch (instr->Mask(DataProcessing1SourceMask)) {
1942  case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSizeInBits)); break;
1943  case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSizeInBits)); break;
1944  case REV16_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse16)); break;
1945  case REV16_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse16)); break;
1946  case REV_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse32)); break;
1947  case REV32_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse32)); break;
1948  case REV_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse64)); break;
1949  case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src), kWRegSizeInBits));
1950  break;
1951  case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src), kXRegSizeInBits));
1952  break;
1953  case CLS_w: {
1954  set_wreg(dst, CountLeadingSignBits(wreg(src), kWRegSizeInBits));
1955  break;
1956  }
1957  case CLS_x: {
1958  set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSizeInBits));
1959  break;
1960  }
1961  default: UNIMPLEMENTED();
1962  }
1963 }
1964 
1965 
1966 uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) {
1967  DCHECK((num_bits == kWRegSizeInBits) || (num_bits == kXRegSizeInBits));
1968  uint64_t result = 0;
1969  for (unsigned i = 0; i < num_bits; i++) {
1970  result = (result << 1) | (value & 1);
1971  value >>= 1;
1972  }
1973  return result;
1974 }
1975 
1976 
1977 uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) {
1978  // Split the 64-bit value into an 8-bit array, where b[0] is the least
1979  // significant byte, and b[7] is the most significant.
1980  uint8_t bytes[8];
1981  uint64_t mask = 0xff00000000000000UL;
1982  for (int i = 7; i >= 0; i--) {
1983  bytes[i] = (value & mask) >> (i * 8);
1984  mask >>= 8;
1985  }
1986 
1987  // Permutation tables for REV instructions.
1988  // permute_table[Reverse16] is used by REV16_x, REV16_w
1989  // permute_table[Reverse32] is used by REV32_x, REV_w
1990  // permute_table[Reverse64] is used by REV_x
1991  DCHECK((Reverse16 == 0) && (Reverse32 == 1) && (Reverse64 == 2));
1992  static const uint8_t permute_table[3][8] = { {6, 7, 4, 5, 2, 3, 0, 1},
1993  {4, 5, 6, 7, 0, 1, 2, 3},
1994  {0, 1, 2, 3, 4, 5, 6, 7} };
1995  uint64_t result = 0;
1996  for (int i = 0; i < 8; i++) {
1997  result <<= 8;
1998  result |= bytes[permute_table[mode][i]];
1999  }
2000  return result;
2001 }
2002 
2003 
2004 template <typename T>
2005 void Simulator::DataProcessing2Source(Instruction* instr) {
2006  Shift shift_op = NO_SHIFT;
2007  T result = 0;
2008  switch (instr->Mask(DataProcessing2SourceMask)) {
2009  case SDIV_w:
2010  case SDIV_x: {
2011  T rn = reg<T>(instr->Rn());
2012  T rm = reg<T>(instr->Rm());
2013  if ((rn == std::numeric_limits<T>::min()) && (rm == -1)) {
2014  result = std::numeric_limits<T>::min();
2015  } else if (rm == 0) {
2016  // Division by zero can be trapped, but not on A-class processors.
2017  result = 0;
2018  } else {
2019  result = rn / rm;
2020  }
2021  break;
2022  }
2023  case UDIV_w:
2024  case UDIV_x: {
2025  typedef typename make_unsigned<T>::type unsignedT;
2026  unsignedT rn = static_cast<unsignedT>(reg<T>(instr->Rn()));
2027  unsignedT rm = static_cast<unsignedT>(reg<T>(instr->Rm()));
2028  if (rm == 0) {
2029  // Division by zero can be trapped, but not on A-class processors.
2030  result = 0;
2031  } else {
2032  result = rn / rm;
2033  }
2034  break;
2035  }
2036  case LSLV_w:
2037  case LSLV_x: shift_op = LSL; break;
2038  case LSRV_w:
2039  case LSRV_x: shift_op = LSR; break;
2040  case ASRV_w:
2041  case ASRV_x: shift_op = ASR; break;
2042  case RORV_w:
2043  case RORV_x: shift_op = ROR; break;
2044  default: UNIMPLEMENTED();
2045  }
2046 
2047  if (shift_op != NO_SHIFT) {
2048  // Shift distance encoded in the least-significant five/six bits of the
2049  // register.
2050  unsigned shift = wreg(instr->Rm());
2051  if (sizeof(T) == kWRegSize) {
2053  } else {
2055  }
2056  result = ShiftOperand(reg<T>(instr->Rn()), shift_op, shift);
2057  }
2058  set_reg<T>(instr->Rd(), result);
2059 }
2060 
2061 
2062 void Simulator::VisitDataProcessing2Source(Instruction* instr) {
2063  if (instr->SixtyFourBits()) {
2064  DataProcessing2Source<int64_t>(instr);
2065  } else {
2066  DataProcessing2Source<int32_t>(instr);
2067  }
2068 }
2069 
2070 
2071 // The algorithm used is described in section 8.2 of
2072 // Hacker's Delight, by Henry S. Warren, Jr.
2073 // It assumes that a right shift on a signed integer is an arithmetic shift.
2074 static int64_t MultiplyHighSigned(int64_t u, int64_t v) {
2075  uint64_t u0, v0, w0;
2076  int64_t u1, v1, w1, w2, t;
2077 
2078  u0 = u & 0xffffffffL;
2079  u1 = u >> 32;
2080  v0 = v & 0xffffffffL;
2081  v1 = v >> 32;
2082 
2083  w0 = u0 * v0;
2084  t = u1 * v0 + (w0 >> 32);
2085  w1 = t & 0xffffffffL;
2086  w2 = t >> 32;
2087  w1 = u0 * v1 + w1;
2088 
2089  return u1 * v1 + w2 + (w1 >> 32);
2090 }
2091 
2092 
2093 void Simulator::VisitDataProcessing3Source(Instruction* instr) {
2094  int64_t result = 0;
2095  // Extract and sign- or zero-extend 32-bit arguments for widening operations.
2096  uint64_t rn_u32 = reg<uint32_t>(instr->Rn());
2097  uint64_t rm_u32 = reg<uint32_t>(instr->Rm());
2098  int64_t rn_s32 = reg<int32_t>(instr->Rn());
2099  int64_t rm_s32 = reg<int32_t>(instr->Rm());
2100  switch (instr->Mask(DataProcessing3SourceMask)) {
2101  case MADD_w:
2102  case MADD_x:
2103  result = xreg(instr->Ra()) + (xreg(instr->Rn()) * xreg(instr->Rm()));
2104  break;
2105  case MSUB_w:
2106  case MSUB_x:
2107  result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm()));
2108  break;
2109  case SMADDL_x: result = xreg(instr->Ra()) + (rn_s32 * rm_s32); break;
2110  case SMSUBL_x: result = xreg(instr->Ra()) - (rn_s32 * rm_s32); break;
2111  case UMADDL_x: result = xreg(instr->Ra()) + (rn_u32 * rm_u32); break;
2112  case UMSUBL_x: result = xreg(instr->Ra()) - (rn_u32 * rm_u32); break;
2113  case SMULH_x:
2114  DCHECK(instr->Ra() == kZeroRegCode);
2115  result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm()));
2116  break;
2117  default: UNIMPLEMENTED();
2118  }
2119 
2120  if (instr->SixtyFourBits()) {
2121  set_xreg(instr->Rd(), result);
2122  } else {
2123  set_wreg(instr->Rd(), result);
2124  }
2125 }
2126 
2127 
2128 template <typename T>
2129 void Simulator::BitfieldHelper(Instruction* instr) {
2130  typedef typename make_unsigned<T>::type unsignedT;
2131  T reg_size = sizeof(T) * 8;
2132  T R = instr->ImmR();
2133  T S = instr->ImmS();
2134  T diff = S - R;
2135  T mask;
2136  if (diff >= 0) {
2137  mask = diff < reg_size - 1 ? (static_cast<T>(1) << (diff + 1)) - 1
2138  : static_cast<T>(-1);
2139  } else {
2140  mask = ((1L << (S + 1)) - 1);
2141  mask = (static_cast<uint64_t>(mask) >> R) | (mask << (reg_size - R));
2142  diff += reg_size;
2143  }
2144 
2145  // inzero indicates if the extracted bitfield is inserted into the
2146  // destination register value or in zero.
2147  // If extend is true, extend the sign of the extracted bitfield.
2148  bool inzero = false;
2149  bool extend = false;
2150  switch (instr->Mask(BitfieldMask)) {
2151  case BFM_x:
2152  case BFM_w:
2153  break;
2154  case SBFM_x:
2155  case SBFM_w:
2156  inzero = true;
2157  extend = true;
2158  break;
2159  case UBFM_x:
2160  case UBFM_w:
2161  inzero = true;
2162  break;
2163  default:
2164  UNIMPLEMENTED();
2165  }
2166 
2167  T dst = inzero ? 0 : reg<T>(instr->Rd());
2168  T src = reg<T>(instr->Rn());
2169  // Rotate source bitfield into place.
2170  T result = (static_cast<unsignedT>(src) >> R) | (src << (reg_size - R));
2171  // Determine the sign extension.
2172  T topbits_preshift = (static_cast<T>(1) << (reg_size - diff - 1)) - 1;
2173  T signbits = (extend && ((src >> S) & 1) ? topbits_preshift : 0)
2174  << (diff + 1);
2175 
2176  // Merge sign extension, dest/zero and bitfield.
2177  result = signbits | (result & mask) | (dst & ~mask);
2178 
2179  set_reg<T>(instr->Rd(), result);
2180 }
2181 
2182 
2183 void Simulator::VisitBitfield(Instruction* instr) {
2184  if (instr->SixtyFourBits()) {
2185  BitfieldHelper<int64_t>(instr);
2186  } else {
2187  BitfieldHelper<int32_t>(instr);
2188  }
2189 }
2190 
2191 
2192 void Simulator::VisitExtract(Instruction* instr) {
2193  if (instr->SixtyFourBits()) {
2194  Extract<uint64_t>(instr);
2195  } else {
2196  Extract<uint32_t>(instr);
2197  }
2198 }
2199 
2200 
2201 void Simulator::VisitFPImmediate(Instruction* instr) {
2202  AssertSupportedFPCR();
2203 
2204  unsigned dest = instr->Rd();
2205  switch (instr->Mask(FPImmediateMask)) {
2206  case FMOV_s_imm: set_sreg(dest, instr->ImmFP32()); break;
2207  case FMOV_d_imm: set_dreg(dest, instr->ImmFP64()); break;
2208  default: UNREACHABLE();
2209  }
2210 }
2211 
2212 
2213 void Simulator::VisitFPIntegerConvert(Instruction* instr) {
2214  AssertSupportedFPCR();
2215 
2216  unsigned dst = instr->Rd();
2217  unsigned src = instr->Rn();
2218 
2219  FPRounding round = fpcr().RMode();
2220 
2221  switch (instr->Mask(FPIntegerConvertMask)) {
2222  case FCVTAS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieAway)); break;
2223  case FCVTAS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieAway)); break;
2224  case FCVTAS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieAway)); break;
2225  case FCVTAS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieAway)); break;
2226  case FCVTAU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieAway)); break;
2227  case FCVTAU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieAway)); break;
2228  case FCVTAU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieAway)); break;
2229  case FCVTAU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieAway)); break;
2230  case FCVTMS_ws:
2231  set_wreg(dst, FPToInt32(sreg(src), FPNegativeInfinity));
2232  break;
2233  case FCVTMS_xs:
2234  set_xreg(dst, FPToInt64(sreg(src), FPNegativeInfinity));
2235  break;
2236  case FCVTMS_wd:
2237  set_wreg(dst, FPToInt32(dreg(src), FPNegativeInfinity));
2238  break;
2239  case FCVTMS_xd:
2240  set_xreg(dst, FPToInt64(dreg(src), FPNegativeInfinity));
2241  break;
2242  case FCVTMU_ws:
2243  set_wreg(dst, FPToUInt32(sreg(src), FPNegativeInfinity));
2244  break;
2245  case FCVTMU_xs:
2246  set_xreg(dst, FPToUInt64(sreg(src), FPNegativeInfinity));
2247  break;
2248  case FCVTMU_wd:
2249  set_wreg(dst, FPToUInt32(dreg(src), FPNegativeInfinity));
2250  break;
2251  case FCVTMU_xd:
2252  set_xreg(dst, FPToUInt64(dreg(src), FPNegativeInfinity));
2253  break;
2254  case FCVTNS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieEven)); break;
2255  case FCVTNS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieEven)); break;
2256  case FCVTNS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieEven)); break;
2257  case FCVTNS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieEven)); break;
2258  case FCVTNU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieEven)); break;
2259  case FCVTNU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieEven)); break;
2260  case FCVTNU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieEven)); break;
2261  case FCVTNU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieEven)); break;
2262  case FCVTZS_ws: set_wreg(dst, FPToInt32(sreg(src), FPZero)); break;
2263  case FCVTZS_xs: set_xreg(dst, FPToInt64(sreg(src), FPZero)); break;
2264  case FCVTZS_wd: set_wreg(dst, FPToInt32(dreg(src), FPZero)); break;
2265  case FCVTZS_xd: set_xreg(dst, FPToInt64(dreg(src), FPZero)); break;
2266  case FCVTZU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPZero)); break;
2267  case FCVTZU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPZero)); break;
2268  case FCVTZU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPZero)); break;
2269  case FCVTZU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPZero)); break;
2270  case FMOV_ws: set_wreg(dst, sreg_bits(src)); break;
2271  case FMOV_xd: set_xreg(dst, dreg_bits(src)); break;
2272  case FMOV_sw: set_sreg_bits(dst, wreg(src)); break;
2273  case FMOV_dx: set_dreg_bits(dst, xreg(src)); break;
2274 
2275  // A 32-bit input can be handled in the same way as a 64-bit input, since
2276  // the sign- or zero-extension will not affect the conversion.
2277  case SCVTF_dx: set_dreg(dst, FixedToDouble(xreg(src), 0, round)); break;
2278  case SCVTF_dw: set_dreg(dst, FixedToDouble(wreg(src), 0, round)); break;
2279  case UCVTF_dx: set_dreg(dst, UFixedToDouble(xreg(src), 0, round)); break;
2280  case UCVTF_dw: {
2281  set_dreg(dst, UFixedToDouble(reg<uint32_t>(src), 0, round));
2282  break;
2283  }
2284  case SCVTF_sx: set_sreg(dst, FixedToFloat(xreg(src), 0, round)); break;
2285  case SCVTF_sw: set_sreg(dst, FixedToFloat(wreg(src), 0, round)); break;
2286  case UCVTF_sx: set_sreg(dst, UFixedToFloat(xreg(src), 0, round)); break;
2287  case UCVTF_sw: {
2288  set_sreg(dst, UFixedToFloat(reg<uint32_t>(src), 0, round));
2289  break;
2290  }
2291 
2292  default: UNREACHABLE();
2293  }
2294 }
2295 
2296 
2297 void Simulator::VisitFPFixedPointConvert(Instruction* instr) {
2298  AssertSupportedFPCR();
2299 
2300  unsigned dst = instr->Rd();
2301  unsigned src = instr->Rn();
2302  int fbits = 64 - instr->FPScale();
2303 
2304  FPRounding round = fpcr().RMode();
2305 
2306  switch (instr->Mask(FPFixedPointConvertMask)) {
2307  // A 32-bit input can be handled in the same way as a 64-bit input, since
2308  // the sign- or zero-extension will not affect the conversion.
2309  case SCVTF_dx_fixed:
2310  set_dreg(dst, FixedToDouble(xreg(src), fbits, round));
2311  break;
2312  case SCVTF_dw_fixed:
2313  set_dreg(dst, FixedToDouble(wreg(src), fbits, round));
2314  break;
2315  case UCVTF_dx_fixed:
2316  set_dreg(dst, UFixedToDouble(xreg(src), fbits, round));
2317  break;
2318  case UCVTF_dw_fixed: {
2319  set_dreg(dst,
2320  UFixedToDouble(reg<uint32_t>(src), fbits, round));
2321  break;
2322  }
2323  case SCVTF_sx_fixed:
2324  set_sreg(dst, FixedToFloat(xreg(src), fbits, round));
2325  break;
2326  case SCVTF_sw_fixed:
2327  set_sreg(dst, FixedToFloat(wreg(src), fbits, round));
2328  break;
2329  case UCVTF_sx_fixed:
2330  set_sreg(dst, UFixedToFloat(xreg(src), fbits, round));
2331  break;
2332  case UCVTF_sw_fixed: {
2333  set_sreg(dst,
2334  UFixedToFloat(reg<uint32_t>(src), fbits, round));
2335  break;
2336  }
2337  default: UNREACHABLE();
2338  }
2339 }
2340 
2341 
2342 int32_t Simulator::FPToInt32(double value, FPRounding rmode) {
2343  value = FPRoundInt(value, rmode);
2344  if (value >= kWMaxInt) {
2345  return kWMaxInt;
2346  } else if (value < kWMinInt) {
2347  return kWMinInt;
2348  }
2349  return std::isnan(value) ? 0 : static_cast<int32_t>(value);
2350 }
2351 
2352 
2353 int64_t Simulator::FPToInt64(double value, FPRounding rmode) {
2354  value = FPRoundInt(value, rmode);
2355  if (value >= kXMaxInt) {
2356  return kXMaxInt;
2357  } else if (value < kXMinInt) {
2358  return kXMinInt;
2359  }
2360  return std::isnan(value) ? 0 : static_cast<int64_t>(value);
2361 }
2362 
2363 
2364 uint32_t Simulator::FPToUInt32(double value, FPRounding rmode) {
2365  value = FPRoundInt(value, rmode);
2366  if (value >= kWMaxUInt) {
2367  return kWMaxUInt;
2368  } else if (value < 0.0) {
2369  return 0;
2370  }
2371  return std::isnan(value) ? 0 : static_cast<uint32_t>(value);
2372 }
2373 
2374 
2375 uint64_t Simulator::FPToUInt64(double value, FPRounding rmode) {
2376  value = FPRoundInt(value, rmode);
2377  if (value >= kXMaxUInt) {
2378  return kXMaxUInt;
2379  } else if (value < 0.0) {
2380  return 0;
2381  }
2382  return std::isnan(value) ? 0 : static_cast<uint64_t>(value);
2383 }
2384 
2385 
2386 void Simulator::VisitFPCompare(Instruction* instr) {
2387  AssertSupportedFPCR();
2388 
2389  unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSizeInBits
2390  : kSRegSizeInBits;
2391  double fn_val = fpreg(reg_size, instr->Rn());
2392 
2393  switch (instr->Mask(FPCompareMask)) {
2394  case FCMP_s:
2395  case FCMP_d: FPCompare(fn_val, fpreg(reg_size, instr->Rm())); break;
2396  case FCMP_s_zero:
2397  case FCMP_d_zero: FPCompare(fn_val, 0.0); break;
2398  default: UNIMPLEMENTED();
2399  }
2400 }
2401 
2402 
2403 void Simulator::VisitFPConditionalCompare(Instruction* instr) {
2404  AssertSupportedFPCR();
2405 
2406  switch (instr->Mask(FPConditionalCompareMask)) {
2407  case FCCMP_s:
2408  case FCCMP_d: {
2409  if (ConditionPassed(static_cast<Condition>(instr->Condition()))) {
2410  // If the condition passes, set the status flags to the result of
2411  // comparing the operands.
2412  unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSizeInBits
2413  : kSRegSizeInBits;
2414  FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm()));
2415  } else {
2416  // If the condition fails, set the status flags to the nzcv immediate.
2417  nzcv().SetFlags(instr->Nzcv());
2418  LogSystemRegister(NZCV);
2419  }
2420  break;
2421  }
2422  default: UNIMPLEMENTED();
2423  }
2424 }
2425 
2426 
2427 void Simulator::VisitFPConditionalSelect(Instruction* instr) {
2428  AssertSupportedFPCR();
2429 
2430  Instr selected;
2431  if (ConditionPassed(static_cast<Condition>(instr->Condition()))) {
2432  selected = instr->Rn();
2433  } else {
2434  selected = instr->Rm();
2435  }
2436 
2437  switch (instr->Mask(FPConditionalSelectMask)) {
2438  case FCSEL_s: set_sreg(instr->Rd(), sreg(selected)); break;
2439  case FCSEL_d: set_dreg(instr->Rd(), dreg(selected)); break;
2440  default: UNIMPLEMENTED();
2441  }
2442 }
2443 
2444 
2445 void Simulator::VisitFPDataProcessing1Source(Instruction* instr) {
2446  AssertSupportedFPCR();
2447 
2448  unsigned fd = instr->Rd();
2449  unsigned fn = instr->Rn();
2450 
2451  switch (instr->Mask(FPDataProcessing1SourceMask)) {
2452  case FMOV_s: set_sreg(fd, sreg(fn)); break;
2453  case FMOV_d: set_dreg(fd, dreg(fn)); break;
2454  case FABS_s: set_sreg(fd, std::fabs(sreg(fn))); break;
2455  case FABS_d: set_dreg(fd, std::fabs(dreg(fn))); break;
2456  case FNEG_s: set_sreg(fd, -sreg(fn)); break;
2457  case FNEG_d: set_dreg(fd, -dreg(fn)); break;
2458  case FSQRT_s: set_sreg(fd, FPSqrt(sreg(fn))); break;
2459  case FSQRT_d: set_dreg(fd, FPSqrt(dreg(fn))); break;
2460  case FRINTA_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieAway)); break;
2461  case FRINTA_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieAway)); break;
2462  case FRINTM_s:
2463  set_sreg(fd, FPRoundInt(sreg(fn), FPNegativeInfinity)); break;
2464  case FRINTM_d:
2465  set_dreg(fd, FPRoundInt(dreg(fn), FPNegativeInfinity)); break;
2466  case FRINTN_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieEven)); break;
2467  case FRINTN_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieEven)); break;
2468  case FRINTZ_s: set_sreg(fd, FPRoundInt(sreg(fn), FPZero)); break;
2469  case FRINTZ_d: set_dreg(fd, FPRoundInt(dreg(fn), FPZero)); break;
2470  case FCVT_ds: set_dreg(fd, FPToDouble(sreg(fn))); break;
2471  case FCVT_sd: set_sreg(fd, FPToFloat(dreg(fn), FPTieEven)); break;
2472  default: UNIMPLEMENTED();
2473  }
2474 }
2475 
2476 
2477 // Assemble the specified IEEE-754 components into the target type and apply
2478 // appropriate rounding.
2479 // sign: 0 = positive, 1 = negative
2480 // exponent: Unbiased IEEE-754 exponent.
2481 // mantissa: The mantissa of the input. The top bit (which is not encoded for
2482 // normal IEEE-754 values) must not be omitted. This bit has the
2483 // value 'pow(2, exponent)'.
2484 //
2485 // The input value is assumed to be a normalized value. That is, the input may
2486 // not be infinity or NaN. If the source value is subnormal, it must be
2487 // normalized before calling this function such that the highest set bit in the
2488 // mantissa has the value 'pow(2, exponent)'.
2489 //
2490 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than
2491 // calling a templated FPRound.
2492 template <class T, int ebits, int mbits>
2493 static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa,
2494  FPRounding round_mode) {
2495  DCHECK((sign == 0) || (sign == 1));
2496 
2497  // Only the FPTieEven rounding mode is implemented.
2498  DCHECK(round_mode == FPTieEven);
2499  USE(round_mode);
2500 
2501  // Rounding can promote subnormals to normals, and normals to infinities. For
2502  // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be
2503  // encodable as a float, but rounding based on the low-order mantissa bits
2504  // could make it overflow. With ties-to-even rounding, this value would become
2505  // an infinity.
2506 
2507  // ---- Rounding Method ----
2508  //
2509  // The exponent is irrelevant in the rounding operation, so we treat the
2510  // lowest-order bit that will fit into the result ('onebit') as having
2511  // the value '1'. Similarly, the highest-order bit that won't fit into
2512  // the result ('halfbit') has the value '0.5'. The 'point' sits between
2513  // 'onebit' and 'halfbit':
2514  //
2515  // These bits fit into the result.
2516  // |---------------------|
2517  // mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2518  // ||
2519  // / |
2520  // / halfbit
2521  // onebit
2522  //
2523  // For subnormal outputs, the range of representable bits is smaller and
2524  // the position of onebit and halfbit depends on the exponent of the
2525  // input, but the method is otherwise similar.
2526  //
2527  // onebit(frac)
2528  // |
2529  // | halfbit(frac) halfbit(adjusted)
2530  // | / /
2531  // | | |
2532  // 0b00.0 (exact) -> 0b00.0 (exact) -> 0b00
2533  // 0b00.0... -> 0b00.0... -> 0b00
2534  // 0b00.1 (exact) -> 0b00.0111..111 -> 0b00
2535  // 0b00.1... -> 0b00.1... -> 0b01
2536  // 0b01.0 (exact) -> 0b01.0 (exact) -> 0b01
2537  // 0b01.0... -> 0b01.0... -> 0b01
2538  // 0b01.1 (exact) -> 0b01.1 (exact) -> 0b10
2539  // 0b01.1... -> 0b01.1... -> 0b10
2540  // 0b10.0 (exact) -> 0b10.0 (exact) -> 0b10
2541  // 0b10.0... -> 0b10.0... -> 0b10
2542  // 0b10.1 (exact) -> 0b10.0111..111 -> 0b10
2543  // 0b10.1... -> 0b10.1... -> 0b11
2544  // 0b11.0 (exact) -> 0b11.0 (exact) -> 0b11
2545  // ... / | / |
2546  // / | / |
2547  // / |
2548  // adjusted = frac - (halfbit(mantissa) & ~onebit(frac)); / |
2549  //
2550  // mantissa = (mantissa >> shift) + halfbit(adjusted);
2551 
2552  static const int mantissa_offset = 0;
2553  static const int exponent_offset = mantissa_offset + mbits;
2554  static const int sign_offset = exponent_offset + ebits;
2555  STATIC_ASSERT(sign_offset == (sizeof(T) * kByteSize - 1));
2556 
2557  // Bail out early for zero inputs.
2558  if (mantissa == 0) {
2559  return sign << sign_offset;
2560  }
2561 
2562  // If all bits in the exponent are set, the value is infinite or NaN.
2563  // This is true for all binary IEEE-754 formats.
2564  static const int infinite_exponent = (1 << ebits) - 1;
2565  static const int max_normal_exponent = infinite_exponent - 1;
2566 
2567  // Apply the exponent bias to encode it for the result. Doing this early makes
2568  // it easy to detect values that will be infinite or subnormal.
2569  exponent += max_normal_exponent >> 1;
2570 
2571  if (exponent > max_normal_exponent) {
2572  // Overflow: The input is too large for the result type to represent. The
2573  // FPTieEven rounding mode handles overflows using infinities.
2574  exponent = infinite_exponent;
2575  mantissa = 0;
2576  return (sign << sign_offset) |
2577  (exponent << exponent_offset) |
2578  (mantissa << mantissa_offset);
2579  }
2580 
2581  // Calculate the shift required to move the top mantissa bit to the proper
2582  // place in the destination type.
2583  const int highest_significant_bit = 63 - CountLeadingZeros(mantissa, 64);
2584  int shift = highest_significant_bit - mbits;
2585 
2586  if (exponent <= 0) {
2587  // The output will be subnormal (before rounding).
2588 
2589  // For subnormal outputs, the shift must be adjusted by the exponent. The +1
2590  // is necessary because the exponent of a subnormal value (encoded as 0) is
2591  // the same as the exponent of the smallest normal value (encoded as 1).
2592  shift += -exponent + 1;
2593 
2594  // Handle inputs that would produce a zero output.
2595  //
2596  // Shifts higher than highest_significant_bit+1 will always produce a zero
2597  // result. A shift of exactly highest_significant_bit+1 might produce a
2598  // non-zero result after rounding.
2599  if (shift > (highest_significant_bit + 1)) {
2600  // The result will always be +/-0.0.
2601  return sign << sign_offset;
2602  }
2603 
2604  // Properly encode the exponent for a subnormal output.
2605  exponent = 0;
2606  } else {
2607  // Clear the topmost mantissa bit, since this is not encoded in IEEE-754
2608  // normal values.
2609  mantissa &= ~(1UL << highest_significant_bit);
2610  }
2611 
2612  if (shift > 0) {
2613  // We have to shift the mantissa to the right. Some precision is lost, so we
2614  // need to apply rounding.
2615  uint64_t onebit_mantissa = (mantissa >> (shift)) & 1;
2616  uint64_t halfbit_mantissa = (mantissa >> (shift-1)) & 1;
2617  uint64_t adjusted = mantissa - (halfbit_mantissa & ~onebit_mantissa);
2618  T halfbit_adjusted = (adjusted >> (shift-1)) & 1;
2619 
2620  T result = (sign << sign_offset) |
2621  (exponent << exponent_offset) |
2622  ((mantissa >> shift) << mantissa_offset);
2623 
2624  // A very large mantissa can overflow during rounding. If this happens, the
2625  // exponent should be incremented and the mantissa set to 1.0 (encoded as
2626  // 0). Applying halfbit_adjusted after assembling the float has the nice
2627  // side-effect that this case is handled for free.
2628  //
2629  // This also handles cases where a very large finite value overflows to
2630  // infinity, or where a very large subnormal value overflows to become
2631  // normal.
2632  return result + halfbit_adjusted;
2633  } else {
2634  // We have to shift the mantissa to the left (or not at all). The input
2635  // mantissa is exactly representable in the output mantissa, so apply no
2636  // rounding correction.
2637  return (sign << sign_offset) |
2638  (exponent << exponent_offset) |
2639  ((mantissa << -shift) << mantissa_offset);
2640  }
2641 }
2642 
2643 
2644 // See FPRound for a description of this function.
2645 static inline double FPRoundToDouble(int64_t sign, int64_t exponent,
2646  uint64_t mantissa, FPRounding round_mode) {
2647  int64_t bits =
2648  FPRound<int64_t, kDoubleExponentBits, kDoubleMantissaBits>(sign,
2649  exponent,
2650  mantissa,
2651  round_mode);
2652  return rawbits_to_double(bits);
2653 }
2654 
2655 
2656 // See FPRound for a description of this function.
2657 static inline float FPRoundToFloat(int64_t sign, int64_t exponent,
2658  uint64_t mantissa, FPRounding round_mode) {
2659  int32_t bits =
2660  FPRound<int32_t, kFloatExponentBits, kFloatMantissaBits>(sign,
2661  exponent,
2662  mantissa,
2663  round_mode);
2664  return rawbits_to_float(bits);
2665 }
2666 
2667 
2668 double Simulator::FixedToDouble(int64_t src, int fbits, FPRounding round) {
2669  if (src >= 0) {
2670  return UFixedToDouble(src, fbits, round);
2671  } else {
2672  // This works for all negative values, including INT64_MIN.
2673  return -UFixedToDouble(-src, fbits, round);
2674  }
2675 }
2676 
2677 
2678 double Simulator::UFixedToDouble(uint64_t src, int fbits, FPRounding round) {
2679  // An input of 0 is a special case because the result is effectively
2680  // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
2681  if (src == 0) {
2682  return 0.0;
2683  }
2684 
2685  // Calculate the exponent. The highest significant bit will have the value
2686  // 2^exponent.
2687  const int highest_significant_bit = 63 - CountLeadingZeros(src, 64);
2688  const int64_t exponent = highest_significant_bit - fbits;
2689 
2690  return FPRoundToDouble(0, exponent, src, round);
2691 }
2692 
2693 
2694 float Simulator::FixedToFloat(int64_t src, int fbits, FPRounding round) {
2695  if (src >= 0) {
2696  return UFixedToFloat(src, fbits, round);
2697  } else {
2698  // This works for all negative values, including INT64_MIN.
2699  return -UFixedToFloat(-src, fbits, round);
2700  }
2701 }
2702 
2703 
2704 float Simulator::UFixedToFloat(uint64_t src, int fbits, FPRounding round) {
2705  // An input of 0 is a special case because the result is effectively
2706  // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
2707  if (src == 0) {
2708  return 0.0f;
2709  }
2710 
2711  // Calculate the exponent. The highest significant bit will have the value
2712  // 2^exponent.
2713  const int highest_significant_bit = 63 - CountLeadingZeros(src, 64);
2714  const int32_t exponent = highest_significant_bit - fbits;
2715 
2716  return FPRoundToFloat(0, exponent, src, round);
2717 }
2718 
2719 
2720 double Simulator::FPRoundInt(double value, FPRounding round_mode) {
2721  if ((value == 0.0) || (value == kFP64PositiveInfinity) ||
2722  (value == kFP64NegativeInfinity)) {
2723  return value;
2724  } else if (std::isnan(value)) {
2725  return FPProcessNaN(value);
2726  }
2727 
2728  double int_result = floor(value);
2729  double error = value - int_result;
2730  switch (round_mode) {
2731  case FPTieAway: {
2732  // Take care of correctly handling the range ]-0.5, -0.0], which must
2733  // yield -0.0.
2734  if ((-0.5 < value) && (value < 0.0)) {
2735  int_result = -0.0;
2736 
2737  } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
2738  // If the error is greater than 0.5, or is equal to 0.5 and the integer
2739  // result is positive, round up.
2740  int_result++;
2741  }
2742  break;
2743  }
2744  case FPTieEven: {
2745  // Take care of correctly handling the range [-0.5, -0.0], which must
2746  // yield -0.0.
2747  if ((-0.5 <= value) && (value < 0.0)) {
2748  int_result = -0.0;
2749 
2750  // If the error is greater than 0.5, or is equal to 0.5 and the integer
2751  // result is odd, round up.
2752  } else if ((error > 0.5) ||
2753  ((error == 0.5) && (fmod(int_result, 2) != 0))) {
2754  int_result++;
2755  }
2756  break;
2757  }
2758  case FPZero: {
2759  // If value > 0 then we take floor(value)
2760  // otherwise, ceil(value)
2761  if (value < 0) {
2762  int_result = ceil(value);
2763  }
2764  break;
2765  }
2766  case FPNegativeInfinity: {
2767  // We always use floor(value).
2768  break;
2769  }
2770  default: UNIMPLEMENTED();
2771  }
2772  return int_result;
2773 }
2774 
2775 
2776 double Simulator::FPToDouble(float value) {
2777  switch (std::fpclassify(value)) {
2778  case FP_NAN: {
2779  if (fpcr().DN()) return kFP64DefaultNaN;
2780 
2781  // Convert NaNs as the processor would:
2782  // - The sign is propagated.
2783  // - The payload (mantissa) is transferred entirely, except that the top
2784  // bit is forced to '1', making the result a quiet NaN. The unused
2785  // (low-order) payload bits are set to 0.
2786  uint32_t raw = float_to_rawbits(value);
2787 
2788  uint64_t sign = raw >> 31;
2789  uint64_t exponent = (1 << 11) - 1;
2790  uint64_t payload = unsigned_bitextract_64(21, 0, raw);
2791  payload <<= (52 - 23); // The unused low-order bits should be 0.
2792  payload |= (1L << 51); // Force a quiet NaN.
2793 
2794  return rawbits_to_double((sign << 63) | (exponent << 52) | payload);
2795  }
2796 
2797  case FP_ZERO:
2798  case FP_NORMAL:
2799  case FP_SUBNORMAL:
2800  case FP_INFINITE: {
2801  // All other inputs are preserved in a standard cast, because every value
2802  // representable using an IEEE-754 float is also representable using an
2803  // IEEE-754 double.
2804  return static_cast<double>(value);
2805  }
2806  }
2807 
2808  UNREACHABLE();
2809  return static_cast<double>(value);
2810 }
2811 
2812 
2813 float Simulator::FPToFloat(double value, FPRounding round_mode) {
2814  // Only the FPTieEven rounding mode is implemented.
2815  DCHECK(round_mode == FPTieEven);
2816  USE(round_mode);
2817 
2818  switch (std::fpclassify(value)) {
2819  case FP_NAN: {
2820  if (fpcr().DN()) return kFP32DefaultNaN;
2821 
2822  // Convert NaNs as the processor would:
2823  // - The sign is propagated.
2824  // - The payload (mantissa) is transferred as much as possible, except
2825  // that the top bit is forced to '1', making the result a quiet NaN.
2826  uint64_t raw = double_to_rawbits(value);
2827 
2828  uint32_t sign = raw >> 63;
2829  uint32_t exponent = (1 << 8) - 1;
2830  uint32_t payload = unsigned_bitextract_64(50, 52 - 23, raw);
2831  payload |= (1 << 22); // Force a quiet NaN.
2832 
2833  return rawbits_to_float((sign << 31) | (exponent << 23) | payload);
2834  }
2835 
2836  case FP_ZERO:
2837  case FP_INFINITE: {
2838  // In a C++ cast, any value representable in the target type will be
2839  // unchanged. This is always the case for +/-0.0 and infinities.
2840  return static_cast<float>(value);
2841  }
2842 
2843  case FP_NORMAL:
2844  case FP_SUBNORMAL: {
2845  // Convert double-to-float as the processor would, assuming that FPCR.FZ
2846  // (flush-to-zero) is not set.
2847  uint64_t raw = double_to_rawbits(value);
2848  // Extract the IEEE-754 double components.
2849  uint32_t sign = raw >> 63;
2850  // Extract the exponent and remove the IEEE-754 encoding bias.
2851  int32_t exponent = unsigned_bitextract_64(62, 52, raw) - 1023;
2852  // Extract the mantissa and add the implicit '1' bit.
2853  uint64_t mantissa = unsigned_bitextract_64(51, 0, raw);
2854  if (std::fpclassify(value) == FP_NORMAL) {
2855  mantissa |= (1UL << 52);
2856  }
2857  return FPRoundToFloat(sign, exponent, mantissa, round_mode);
2858  }
2859  }
2860 
2861  UNREACHABLE();
2862  return value;
2863 }
2864 
2865 
2866 void Simulator::VisitFPDataProcessing2Source(Instruction* instr) {
2867  AssertSupportedFPCR();
2868 
2869  unsigned fd = instr->Rd();
2870  unsigned fn = instr->Rn();
2871  unsigned fm = instr->Rm();
2872 
2873  // Fmaxnm and Fminnm have special NaN handling.
2874  switch (instr->Mask(FPDataProcessing2SourceMask)) {
2875  case FMAXNM_s: set_sreg(fd, FPMaxNM(sreg(fn), sreg(fm))); return;
2876  case FMAXNM_d: set_dreg(fd, FPMaxNM(dreg(fn), dreg(fm))); return;
2877  case FMINNM_s: set_sreg(fd, FPMinNM(sreg(fn), sreg(fm))); return;
2878  case FMINNM_d: set_dreg(fd, FPMinNM(dreg(fn), dreg(fm))); return;
2879  default:
2880  break; // Fall through.
2881  }
2882 
2883  if (FPProcessNaNs(instr)) return;
2884 
2885  switch (instr->Mask(FPDataProcessing2SourceMask)) {
2886  case FADD_s: set_sreg(fd, FPAdd(sreg(fn), sreg(fm))); break;
2887  case FADD_d: set_dreg(fd, FPAdd(dreg(fn), dreg(fm))); break;
2888  case FSUB_s: set_sreg(fd, FPSub(sreg(fn), sreg(fm))); break;
2889  case FSUB_d: set_dreg(fd, FPSub(dreg(fn), dreg(fm))); break;
2890  case FMUL_s: set_sreg(fd, FPMul(sreg(fn), sreg(fm))); break;
2891  case FMUL_d: set_dreg(fd, FPMul(dreg(fn), dreg(fm))); break;
2892  case FDIV_s: set_sreg(fd, FPDiv(sreg(fn), sreg(fm))); break;
2893  case FDIV_d: set_dreg(fd, FPDiv(dreg(fn), dreg(fm))); break;
2894  case FMAX_s: set_sreg(fd, FPMax(sreg(fn), sreg(fm))); break;
2895  case FMAX_d: set_dreg(fd, FPMax(dreg(fn), dreg(fm))); break;
2896  case FMIN_s: set_sreg(fd, FPMin(sreg(fn), sreg(fm))); break;
2897  case FMIN_d: set_dreg(fd, FPMin(dreg(fn), dreg(fm))); break;
2898  case FMAXNM_s:
2899  case FMAXNM_d:
2900  case FMINNM_s:
2901  case FMINNM_d:
2902  // These were handled before the standard FPProcessNaNs() stage.
2903  UNREACHABLE();
2904  default: UNIMPLEMENTED();
2905  }
2906 }
2907 
2908 
2909 void Simulator::VisitFPDataProcessing3Source(Instruction* instr) {
2910  AssertSupportedFPCR();
2911 
2912  unsigned fd = instr->Rd();
2913  unsigned fn = instr->Rn();
2914  unsigned fm = instr->Rm();
2915  unsigned fa = instr->Ra();
2916 
2917  switch (instr->Mask(FPDataProcessing3SourceMask)) {
2918  // fd = fa +/- (fn * fm)
2919  case FMADD_s: set_sreg(fd, FPMulAdd(sreg(fa), sreg(fn), sreg(fm))); break;
2920  case FMSUB_s: set_sreg(fd, FPMulAdd(sreg(fa), -sreg(fn), sreg(fm))); break;
2921  case FMADD_d: set_dreg(fd, FPMulAdd(dreg(fa), dreg(fn), dreg(fm))); break;
2922  case FMSUB_d: set_dreg(fd, FPMulAdd(dreg(fa), -dreg(fn), dreg(fm))); break;
2923  // Negated variants of the above.
2924  case FNMADD_s:
2925  set_sreg(fd, FPMulAdd(-sreg(fa), -sreg(fn), sreg(fm)));
2926  break;
2927  case FNMSUB_s:
2928  set_sreg(fd, FPMulAdd(-sreg(fa), sreg(fn), sreg(fm)));
2929  break;
2930  case FNMADD_d:
2931  set_dreg(fd, FPMulAdd(-dreg(fa), -dreg(fn), dreg(fm)));
2932  break;
2933  case FNMSUB_d:
2934  set_dreg(fd, FPMulAdd(-dreg(fa), dreg(fn), dreg(fm)));
2935  break;
2936  default: UNIMPLEMENTED();
2937  }
2938 }
2939 
2940 
2941 template <typename T>
2942 T Simulator::FPAdd(T op1, T op2) {
2943  // NaNs should be handled elsewhere.
2944  DCHECK(!std::isnan(op1) && !std::isnan(op2));
2945 
2946  if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) {
2947  // inf + -inf returns the default NaN.
2948  return FPDefaultNaN<T>();
2949  } else {
2950  // Other cases should be handled by standard arithmetic.
2951  return op1 + op2;
2952  }
2953 }
2954 
2955 
2956 template <typename T>
2957 T Simulator::FPDiv(T op1, T op2) {
2958  // NaNs should be handled elsewhere.
2959  DCHECK(!std::isnan(op1) && !std::isnan(op2));
2960 
2961  if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) {
2962  // inf / inf and 0.0 / 0.0 return the default NaN.
2963  return FPDefaultNaN<T>();
2964  } else {
2965  // Other cases should be handled by standard arithmetic.
2966  return op1 / op2;
2967  }
2968 }
2969 
2970 
2971 template <typename T>
2972 T Simulator::FPMax(T a, T b) {
2973  // NaNs should be handled elsewhere.
2974  DCHECK(!std::isnan(a) && !std::isnan(b));
2975 
2976  if ((a == 0.0) && (b == 0.0) &&
2977  (copysign(1.0, a) != copysign(1.0, b))) {
2978  // a and b are zero, and the sign differs: return +0.0.
2979  return 0.0;
2980  } else {
2981  return (a > b) ? a : b;
2982  }
2983 }
2984 
2985 
2986 template <typename T>
2987 T Simulator::FPMaxNM(T a, T b) {
2988  if (IsQuietNaN(a) && !IsQuietNaN(b)) {
2989  a = kFP64NegativeInfinity;
2990  } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
2991  b = kFP64NegativeInfinity;
2992  }
2993 
2994  T result = FPProcessNaNs(a, b);
2995  return std::isnan(result) ? result : FPMax(a, b);
2996 }
2997 
2998 template <typename T>
2999 T Simulator::FPMin(T a, T b) {
3000  // NaNs should be handled elsewhere.
3001  DCHECK(!std::isnan(a) && !std::isnan(b));
3002 
3003  if ((a == 0.0) && (b == 0.0) &&
3004  (copysign(1.0, a) != copysign(1.0, b))) {
3005  // a and b are zero, and the sign differs: return -0.0.
3006  return -0.0;
3007  } else {
3008  return (a < b) ? a : b;
3009  }
3010 }
3011 
3012 
3013 template <typename T>
3014 T Simulator::FPMinNM(T a, T b) {
3015  if (IsQuietNaN(a) && !IsQuietNaN(b)) {
3016  a = kFP64PositiveInfinity;
3017  } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
3018  b = kFP64PositiveInfinity;
3019  }
3020 
3021  T result = FPProcessNaNs(a, b);
3022  return std::isnan(result) ? result : FPMin(a, b);
3023 }
3024 
3025 
3026 template <typename T>
3027 T Simulator::FPMul(T op1, T op2) {
3028  // NaNs should be handled elsewhere.
3029  DCHECK(!std::isnan(op1) && !std::isnan(op2));
3030 
3031  if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
3032  // inf * 0.0 returns the default NaN.
3033  return FPDefaultNaN<T>();
3034  } else {
3035  // Other cases should be handled by standard arithmetic.
3036  return op1 * op2;
3037  }
3038 }
3039 
3040 
3041 template<typename T>
3042 T Simulator::FPMulAdd(T a, T op1, T op2) {
3043  T result = FPProcessNaNs3(a, op1, op2);
3044 
3045  T sign_a = copysign(1.0, a);
3046  T sign_prod = copysign(1.0, op1) * copysign(1.0, op2);
3047  bool isinf_prod = std::isinf(op1) || std::isinf(op2);
3048  bool operation_generates_nan =
3049  (std::isinf(op1) && (op2 == 0.0)) || // inf * 0.0
3050  (std::isinf(op2) && (op1 == 0.0)) || // 0.0 * inf
3051  (std::isinf(a) && isinf_prod && (sign_a != sign_prod)); // inf - inf
3052 
3053  if (std::isnan(result)) {
3054  // Generated NaNs override quiet NaNs propagated from a.
3055  if (operation_generates_nan && IsQuietNaN(a)) {
3056  return FPDefaultNaN<T>();
3057  } else {
3058  return result;
3059  }
3060  }
3061 
3062  // If the operation would produce a NaN, return the default NaN.
3063  if (operation_generates_nan) {
3064  return FPDefaultNaN<T>();
3065  }
3066 
3067  // Work around broken fma implementations for exact zero results: The sign of
3068  // exact 0.0 results is positive unless both a and op1 * op2 are negative.
3069  if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) {
3070  return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0;
3071  }
3072 
3073  result = FusedMultiplyAdd(op1, op2, a);
3074  DCHECK(!std::isnan(result));
3075 
3076  // Work around broken fma implementations for rounded zero results: If a is
3077  // 0.0, the sign of the result is the sign of op1 * op2 before rounding.
3078  if ((a == 0.0) && (result == 0.0)) {
3079  return copysign(0.0, sign_prod);
3080  }
3081 
3082  return result;
3083 }
3084 
3085 
3086 template <typename T>
3087 T Simulator::FPSqrt(T op) {
3088  if (std::isnan(op)) {
3089  return FPProcessNaN(op);
3090  } else if (op < 0.0) {
3091  return FPDefaultNaN<T>();
3092  } else {
3093  return std::sqrt(op);
3094  }
3095 }
3096 
3097 
3098 template <typename T>
3099 T Simulator::FPSub(T op1, T op2) {
3100  // NaNs should be handled elsewhere.
3101  DCHECK(!std::isnan(op1) && !std::isnan(op2));
3102 
3103  if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) {
3104  // inf - inf returns the default NaN.
3105  return FPDefaultNaN<T>();
3106  } else {
3107  // Other cases should be handled by standard arithmetic.
3108  return op1 - op2;
3109  }
3110 }
3111 
3112 
3113 template <typename T>
3114 T Simulator::FPProcessNaN(T op) {
3115  DCHECK(std::isnan(op));
3116  return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op);
3117 }
3118 
3119 
3120 template <typename T>
3121 T Simulator::FPProcessNaNs(T op1, T op2) {
3122  if (IsSignallingNaN(op1)) {
3123  return FPProcessNaN(op1);
3124  } else if (IsSignallingNaN(op2)) {
3125  return FPProcessNaN(op2);
3126  } else if (std::isnan(op1)) {
3127  DCHECK(IsQuietNaN(op1));
3128  return FPProcessNaN(op1);
3129  } else if (std::isnan(op2)) {
3130  DCHECK(IsQuietNaN(op2));
3131  return FPProcessNaN(op2);
3132  } else {
3133  return 0.0;
3134  }
3135 }
3136 
3137 
3138 template <typename T>
3139 T Simulator::FPProcessNaNs3(T op1, T op2, T op3) {
3140  if (IsSignallingNaN(op1)) {
3141  return FPProcessNaN(op1);
3142  } else if (IsSignallingNaN(op2)) {
3143  return FPProcessNaN(op2);
3144  } else if (IsSignallingNaN(op3)) {
3145  return FPProcessNaN(op3);
3146  } else if (std::isnan(op1)) {
3147  DCHECK(IsQuietNaN(op1));
3148  return FPProcessNaN(op1);
3149  } else if (std::isnan(op2)) {
3150  DCHECK(IsQuietNaN(op2));
3151  return FPProcessNaN(op2);
3152  } else if (std::isnan(op3)) {
3153  DCHECK(IsQuietNaN(op3));
3154  return FPProcessNaN(op3);
3155  } else {
3156  return 0.0;
3157  }
3158 }
3159 
3160 
3161 bool Simulator::FPProcessNaNs(Instruction* instr) {
3162  unsigned fd = instr->Rd();
3163  unsigned fn = instr->Rn();
3164  unsigned fm = instr->Rm();
3165  bool done = false;
3166 
3167  if (instr->Mask(FP64) == FP64) {
3168  double result = FPProcessNaNs(dreg(fn), dreg(fm));
3169  if (std::isnan(result)) {
3170  set_dreg(fd, result);
3171  done = true;
3172  }
3173  } else {
3174  float result = FPProcessNaNs(sreg(fn), sreg(fm));
3175  if (std::isnan(result)) {
3176  set_sreg(fd, result);
3177  done = true;
3178  }
3179  }
3180 
3181  return done;
3182 }
3183 
3184 
3185 void Simulator::VisitSystem(Instruction* instr) {
3186  // Some system instructions hijack their Op and Cp fields to represent a
3187  // range of immediates instead of indicating a different instruction. This
3188  // makes the decoding tricky.
3189  if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) {
3190  switch (instr->Mask(SystemSysRegMask)) {
3191  case MRS: {
3192  switch (instr->ImmSystemRegister()) {
3193  case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break;
3194  case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break;
3195  default: UNIMPLEMENTED();
3196  }
3197  break;
3198  }
3199  case MSR: {
3200  switch (instr->ImmSystemRegister()) {
3201  case NZCV:
3202  nzcv().SetRawValue(xreg(instr->Rt()));
3203  LogSystemRegister(NZCV);
3204  break;
3205  case FPCR:
3206  fpcr().SetRawValue(xreg(instr->Rt()));
3207  LogSystemRegister(FPCR);
3208  break;
3209  default: UNIMPLEMENTED();
3210  }
3211  break;
3212  }
3213  }
3214  } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
3215  DCHECK(instr->Mask(SystemHintMask) == HINT);
3216  switch (instr->ImmHint()) {
3217  case NOP: break;
3218  default: UNIMPLEMENTED();
3219  }
3220  } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) {
3221  __sync_synchronize();
3222  } else {
3223  UNIMPLEMENTED();
3224  }
3225 }
3226 
3227 
3228 bool Simulator::GetValue(const char* desc, int64_t* value) {
3229  int regnum = CodeFromName(desc);
3230  if (regnum >= 0) {
3231  unsigned code = regnum;
3232  if (code == kZeroRegCode) {
3233  // Catch the zero register and return 0.
3234  *value = 0;
3235  return true;
3236  } else if (code == kSPRegInternalCode) {
3237  // Translate the stack pointer code to 31, for Reg31IsStackPointer.
3238  code = 31;
3239  }
3240  if (desc[0] == 'w') {
3241  *value = wreg(code, Reg31IsStackPointer);
3242  } else {
3243  *value = xreg(code, Reg31IsStackPointer);
3244  }
3245  return true;
3246  } else if (strncmp(desc, "0x", 2) == 0) {
3247  return SScanF(desc + 2, "%" SCNx64,
3248  reinterpret_cast<uint64_t*>(value)) == 1;
3249  } else {
3250  return SScanF(desc, "%" SCNu64,
3251  reinterpret_cast<uint64_t*>(value)) == 1;
3252  }
3253 }
3254 
3255 
3256 bool Simulator::PrintValue(const char* desc) {
3257  if (strcmp(desc, "csp") == 0) {
3258  DCHECK(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode));
3259  PrintF(stream_, "%s csp:%s 0x%016" PRIx64 "%s\n",
3260  clr_reg_name, clr_reg_value, xreg(31, Reg31IsStackPointer), clr_normal);
3261  return true;
3262  } else if (strcmp(desc, "wcsp") == 0) {
3263  DCHECK(CodeFromName(desc) == static_cast<int>(kSPRegInternalCode));
3264  PrintF(stream_, "%s wcsp:%s 0x%08" PRIx32 "%s\n",
3265  clr_reg_name, clr_reg_value, wreg(31, Reg31IsStackPointer), clr_normal);
3266  return true;
3267  }
3268 
3269  int i = CodeFromName(desc);
3271  if (i < 0 || static_cast<unsigned>(i) >= kNumberOfFPRegisters) return false;
3272 
3273  if (desc[0] == 'v') {
3274  PrintF(stream_, "%s %s:%s 0x%016" PRIx64 "%s (%s%s:%s %g%s %s:%s %g%s)\n",
3275  clr_fpreg_name, VRegNameForCode(i),
3276  clr_fpreg_value, double_to_rawbits(dreg(i)),
3277  clr_normal,
3278  clr_fpreg_name, DRegNameForCode(i),
3279  clr_fpreg_value, dreg(i),
3280  clr_fpreg_name, SRegNameForCode(i),
3281  clr_fpreg_value, sreg(i),
3282  clr_normal);
3283  return true;
3284  } else if (desc[0] == 'd') {
3285  PrintF(stream_, "%s %s:%s %g%s\n",
3286  clr_fpreg_name, DRegNameForCode(i),
3287  clr_fpreg_value, dreg(i),
3288  clr_normal);
3289  return true;
3290  } else if (desc[0] == 's') {
3291  PrintF(stream_, "%s %s:%s %g%s\n",
3292  clr_fpreg_name, SRegNameForCode(i),
3293  clr_fpreg_value, sreg(i),
3294  clr_normal);
3295  return true;
3296  } else if (desc[0] == 'w') {
3297  PrintF(stream_, "%s %s:%s 0x%08" PRIx32 "%s\n",
3298  clr_reg_name, WRegNameForCode(i), clr_reg_value, wreg(i), clr_normal);
3299  return true;
3300  } else {
3301  // X register names have a wide variety of starting characters, but anything
3302  // else will be an X register.
3303  PrintF(stream_, "%s %s:%s 0x%016" PRIx64 "%s\n",
3304  clr_reg_name, XRegNameForCode(i), clr_reg_value, xreg(i), clr_normal);
3305  return true;
3306  }
3307 }
3308 
3309 
3310 void Simulator::Debug() {
3311 #define COMMAND_SIZE 63
3312 #define ARG_SIZE 255
3313 
3314 #define STR(a) #a
3315 #define XSTR(a) STR(a)
3316 
3317  char cmd[COMMAND_SIZE + 1];
3318  char arg1[ARG_SIZE + 1];
3319  char arg2[ARG_SIZE + 1];
3320  char* argv[3] = { cmd, arg1, arg2 };
3321 
3322  // Make sure to have a proper terminating character if reaching the limit.
3323  cmd[COMMAND_SIZE] = 0;
3324  arg1[ARG_SIZE] = 0;
3325  arg2[ARG_SIZE] = 0;
3326 
3327  bool done = false;
3328  bool cleared_log_disasm_bit = false;
3329 
3330  while (!done) {
3331  // Disassemble the next instruction to execute before doing anything else.
3332  PrintInstructionsAt(pc_, 1);
3333  // Read the command line.
3334  char* line = ReadLine("sim> ");
3335  if (line == NULL) {
3336  break;
3337  } else {
3338  // Repeat last command by default.
3339  char* last_input = last_debugger_input();
3340  if (strcmp(line, "\n") == 0 && (last_input != NULL)) {
3341  DeleteArray(line);
3342  line = last_input;
3343  } else {
3344  // Update the latest command ran
3345  set_last_debugger_input(line);
3346  }
3347 
3348  // Use sscanf to parse the individual parts of the command line. At the
3349  // moment no command expects more than two parameters.
3350  int argc = SScanF(line,
3351  "%" XSTR(COMMAND_SIZE) "s "
3352  "%" XSTR(ARG_SIZE) "s "
3353  "%" XSTR(ARG_SIZE) "s",
3354  cmd, arg1, arg2);
3355 
3356  // stepi / si ------------------------------------------------------------
3357  if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
3358  // We are about to execute instructions, after which by default we
3359  // should increment the pc_. If it was set when reaching this debug
3360  // instruction, it has not been cleared because this instruction has not
3361  // completed yet. So clear it manually.
3362  pc_modified_ = false;
3363 
3364  if (argc == 1) {
3365  ExecuteInstruction();
3366  } else {
3367  int64_t number_of_instructions_to_execute = 1;
3368  GetValue(arg1, &number_of_instructions_to_execute);
3369 
3370  set_log_parameters(log_parameters() | LOG_DISASM);
3371  while (number_of_instructions_to_execute-- > 0) {
3372  ExecuteInstruction();
3373  }
3374  set_log_parameters(log_parameters() & ~LOG_DISASM);
3375  PrintF("\n");
3376  }
3377 
3378  // If it was necessary, the pc has already been updated or incremented
3379  // when executing the instruction. So we do not want it to be updated
3380  // again. It will be cleared when exiting.
3381  pc_modified_ = true;
3382 
3383  // next / n --------------------------------------------------------------
3384  } else if ((strcmp(cmd, "next") == 0) || (strcmp(cmd, "n") == 0)) {
3385  // Tell the simulator to break after the next executed BL.
3386  break_on_next_ = true;
3387  // Continue.
3388  done = true;
3389 
3390  // continue / cont / c ---------------------------------------------------
3391  } else if ((strcmp(cmd, "continue") == 0) ||
3392  (strcmp(cmd, "cont") == 0) ||
3393  (strcmp(cmd, "c") == 0)) {
3394  // Leave the debugger shell.
3395  done = true;
3396 
3397  // disassemble / disasm / di ---------------------------------------------
3398  } else if (strcmp(cmd, "disassemble") == 0 ||
3399  strcmp(cmd, "disasm") == 0 ||
3400  strcmp(cmd, "di") == 0) {
3401  int64_t n_of_instrs_to_disasm = 10; // default value.
3402  int64_t address = reinterpret_cast<int64_t>(pc_); // default value.
3403  if (argc >= 2) { // disasm <n of instrs>
3404  GetValue(arg1, &n_of_instrs_to_disasm);
3405  }
3406  if (argc >= 3) { // disasm <n of instrs> <address>
3407  GetValue(arg2, &address);
3408  }
3409 
3410  // Disassemble.
3411  PrintInstructionsAt(reinterpret_cast<Instruction*>(address),
3412  n_of_instrs_to_disasm);
3413  PrintF("\n");
3414 
3415  // print / p -------------------------------------------------------------
3416  } else if ((strcmp(cmd, "print") == 0) || (strcmp(cmd, "p") == 0)) {
3417  if (argc == 2) {
3418  if (strcmp(arg1, "all") == 0) {
3419  PrintRegisters();
3420  PrintFPRegisters();
3421  } else {
3422  if (!PrintValue(arg1)) {
3423  PrintF("%s unrecognized\n", arg1);
3424  }
3425  }
3426  } else {
3427  PrintF(
3428  "print <register>\n"
3429  " Print the content of a register. (alias 'p')\n"
3430  " 'print all' will print all registers.\n"
3431  " Use 'printobject' to get more details about the value.\n");
3432  }
3433 
3434  // printobject / po ------------------------------------------------------
3435  } else if ((strcmp(cmd, "printobject") == 0) ||
3436  (strcmp(cmd, "po") == 0)) {
3437  if (argc == 2) {
3438  int64_t value;
3439  OFStream os(stdout);
3440  if (GetValue(arg1, &value)) {
3441  Object* obj = reinterpret_cast<Object*>(value);
3442  os << arg1 << ": \n";
3443 #ifdef DEBUG
3444  obj->Print(os);
3445  os << "\n";
3446 #else
3447  os << Brief(obj) << "\n";
3448 #endif
3449  } else {
3450  os << arg1 << " unrecognized\n";
3451  }
3452  } else {
3453  PrintF("printobject <value>\n"
3454  "printobject <register>\n"
3455  " Print details about the value. (alias 'po')\n");
3456  }
3457 
3458  // stack / mem ----------------------------------------------------------
3459  } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
3460  int64_t* cur = NULL;
3461  int64_t* end = NULL;
3462  int next_arg = 1;
3463 
3464  if (strcmp(cmd, "stack") == 0) {
3465  cur = reinterpret_cast<int64_t*>(jssp());
3466 
3467  } else { // "mem"
3468  int64_t value;
3469  if (!GetValue(arg1, &value)) {
3470  PrintF("%s unrecognized\n", arg1);
3471  continue;
3472  }
3473  cur = reinterpret_cast<int64_t*>(value);
3474  next_arg++;
3475  }
3476 
3477  int64_t words = 0;
3478  if (argc == next_arg) {
3479  words = 10;
3480  } else if (argc == next_arg + 1) {
3481  if (!GetValue(argv[next_arg], &words)) {
3482  PrintF("%s unrecognized\n", argv[next_arg]);
3483  PrintF("Printing 10 double words by default");
3484  words = 10;
3485  }
3486  } else {
3487  UNREACHABLE();
3488  }
3489  end = cur + words;
3490 
3491  while (cur < end) {
3492  PrintF(" 0x%016" PRIx64 ": 0x%016" PRIx64 " %10" PRId64,
3493  reinterpret_cast<uint64_t>(cur), *cur, *cur);
3494  HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
3495  int64_t value = *cur;
3496  Heap* current_heap = v8::internal::Isolate::Current()->heap();
3497  if (((value & 1) == 0) || current_heap->Contains(obj)) {
3498  PrintF(" (");
3499  if ((value & kSmiTagMask) == 0) {
3501  int32_t untagged = (value >> kSmiShift) & 0xffffffff;
3502  PrintF("smi %" PRId32, untagged);
3503  } else {
3504  obj->ShortPrint();
3505  }
3506  PrintF(")");
3507  }
3508  PrintF("\n");
3509  cur++;
3510  }
3511 
3512  // trace / t -------------------------------------------------------------
3513  } else if (strcmp(cmd, "trace") == 0 || strcmp(cmd, "t") == 0) {
3514  if ((log_parameters() & (LOG_DISASM | LOG_REGS)) !=
3515  (LOG_DISASM | LOG_REGS)) {
3516  PrintF("Enabling disassembly and registers tracing\n");
3517  set_log_parameters(log_parameters() | LOG_DISASM | LOG_REGS);
3518  } else {
3519  PrintF("Disabling disassembly and registers tracing\n");
3520  set_log_parameters(log_parameters() & ~(LOG_DISASM | LOG_REGS));
3521  }
3522 
3523  // break / b -------------------------------------------------------------
3524  } else if (strcmp(cmd, "break") == 0 || strcmp(cmd, "b") == 0) {
3525  if (argc == 2) {
3526  int64_t value;
3527  if (GetValue(arg1, &value)) {
3528  SetBreakpoint(reinterpret_cast<Instruction*>(value));
3529  } else {
3530  PrintF("%s unrecognized\n", arg1);
3531  }
3532  } else {
3533  ListBreakpoints();
3534  PrintF("Use `break <address>` to set or disable a breakpoint\n");
3535  }
3536 
3537  // gdb -------------------------------------------------------------------
3538  } else if (strcmp(cmd, "gdb") == 0) {
3539  PrintF("Relinquishing control to gdb.\n");
3540  base::OS::DebugBreak();
3541  PrintF("Regaining control from gdb.\n");
3542 
3543  // sysregs ---------------------------------------------------------------
3544  } else if (strcmp(cmd, "sysregs") == 0) {
3545  PrintSystemRegisters();
3546 
3547  // help / h --------------------------------------------------------------
3548  } else if (strcmp(cmd, "help") == 0 || strcmp(cmd, "h") == 0) {
3549  PrintF(
3550  "stepi / si\n"
3551  " stepi <n>\n"
3552  " Step <n> instructions.\n"
3553  "next / n\n"
3554  " Continue execution until a BL instruction is reached.\n"
3555  " At this point a breakpoint is set just after this BL.\n"
3556  " Then execution is resumed. It will probably later hit the\n"
3557  " breakpoint just set.\n"
3558  "continue / cont / c\n"
3559  " Continue execution from here.\n"
3560  "disassemble / disasm / di\n"
3561  " disassemble <n> <address>\n"
3562  " Disassemble <n> instructions from current <address>.\n"
3563  " By default <n> is 20 and <address> is the current pc.\n"
3564  "print / p\n"
3565  " print <register>\n"
3566  " Print the content of a register.\n"
3567  " 'print all' will print all registers.\n"
3568  " Use 'printobject' to get more details about the value.\n"
3569  "printobject / po\n"
3570  " printobject <value>\n"
3571  " printobject <register>\n"
3572  " Print details about the value.\n"
3573  "stack\n"
3574  " stack [<words>]\n"
3575  " Dump stack content, default dump 10 words\n"
3576  "mem\n"
3577  " mem <address> [<words>]\n"
3578  " Dump memory content, default dump 10 words\n"
3579  "trace / t\n"
3580  " Toggle disassembly and register tracing\n"
3581  "break / b\n"
3582  " break : list all breakpoints\n"
3583  " break <address> : set / enable / disable a breakpoint.\n"
3584  "gdb\n"
3585  " Enter gdb.\n"
3586  "sysregs\n"
3587  " Print all system registers (including NZCV).\n");
3588  } else {
3589  PrintF("Unknown command: %s\n", cmd);
3590  PrintF("Use 'help' for more information.\n");
3591  }
3592  }
3593  if (cleared_log_disasm_bit == true) {
3594  set_log_parameters(log_parameters_ | LOG_DISASM);
3595  }
3596  }
3597 }
3598 
3599 
3600 void Simulator::VisitException(Instruction* instr) {
3601  switch (instr->Mask(ExceptionMask)) {
3602  case HLT: {
3603  if (instr->ImmException() == kImmExceptionIsDebug) {
3604  // Read the arguments encoded inline in the instruction stream.
3605  uint32_t code;
3606  uint32_t parameters;
3607 
3608  memcpy(&code,
3609  pc_->InstructionAtOffset(kDebugCodeOffset),
3610  sizeof(code));
3611  memcpy(&parameters,
3612  pc_->InstructionAtOffset(kDebugParamsOffset),
3613  sizeof(parameters));
3614  char const *message =
3615  reinterpret_cast<char const*>(
3616  pc_->InstructionAtOffset(kDebugMessageOffset));
3617 
3618  // Always print something when we hit a debug point that breaks.
3619  // We are going to break, so printing something is not an issue in
3620  // terms of speed.
3621  if (FLAG_trace_sim_messages || FLAG_trace_sim || (parameters & BREAK)) {
3622  if (message != NULL) {
3623  PrintF(stream_,
3624  "# %sDebugger hit %d: %s%s%s\n",
3625  clr_debug_number,
3626  code,
3627  clr_debug_message,
3628  message,
3629  clr_normal);
3630  } else {
3631  PrintF(stream_,
3632  "# %sDebugger hit %d.%s\n",
3633  clr_debug_number,
3634  code,
3635  clr_normal);
3636  }
3637  }
3638 
3639  // Other options.
3640  switch (parameters & kDebuggerTracingDirectivesMask) {
3641  case TRACE_ENABLE:
3642  set_log_parameters(log_parameters() | parameters);
3643  if (parameters & LOG_SYS_REGS) { PrintSystemRegisters(); }
3644  if (parameters & LOG_REGS) { PrintRegisters(); }
3645  if (parameters & LOG_FP_REGS) { PrintFPRegisters(); }
3646  break;
3647  case TRACE_DISABLE:
3648  set_log_parameters(log_parameters() & ~parameters);
3649  break;
3650  case TRACE_OVERRIDE:
3651  set_log_parameters(parameters);
3652  break;
3653  default:
3654  // We don't support a one-shot LOG_DISASM.
3655  DCHECK((parameters & LOG_DISASM) == 0);
3656  // Don't print information that is already being traced.
3657  parameters &= ~log_parameters();
3658  // Print the requested information.
3659  if (parameters & LOG_SYS_REGS) PrintSystemRegisters();
3660  if (parameters & LOG_REGS) PrintRegisters();
3661  if (parameters & LOG_FP_REGS) PrintFPRegisters();
3662  }
3663 
3664  // The stop parameters are inlined in the code. Skip them:
3665  // - Skip to the end of the message string.
3666  size_t size = kDebugMessageOffset + strlen(message) + 1;
3667  pc_ = pc_->InstructionAtOffset(RoundUp(size, kInstructionSize));
3668  // - Verify that the unreachable marker is present.
3669  DCHECK(pc_->Mask(ExceptionMask) == HLT);
3670  DCHECK(pc_->ImmException() == kImmExceptionIsUnreachable);
3671  // - Skip past the unreachable marker.
3672  set_pc(pc_->following());
3673 
3674  // Check if the debugger should break.
3675  if (parameters & BREAK) Debug();
3676 
3677  } else if (instr->ImmException() == kImmExceptionIsRedirectedCall) {
3678  DoRuntimeCall(instr);
3679  } else if (instr->ImmException() == kImmExceptionIsPrintf) {
3680  DoPrintf(instr);
3681 
3682  } else if (instr->ImmException() == kImmExceptionIsUnreachable) {
3683  fprintf(stream_, "Hit UNREACHABLE marker at PC=%p.\n",
3684  reinterpret_cast<void*>(pc_));
3685  abort();
3686 
3687  } else {
3688  base::OS::DebugBreak();
3689  }
3690  break;
3691  }
3692 
3693  default:
3694  UNIMPLEMENTED();
3695  }
3696 }
3697 
3698 
3699 void Simulator::DoPrintf(Instruction* instr) {
3700  DCHECK((instr->Mask(ExceptionMask) == HLT) &&
3701  (instr->ImmException() == kImmExceptionIsPrintf));
3702 
3703  // Read the arguments encoded inline in the instruction stream.
3704  uint32_t arg_count;
3705  uint32_t arg_pattern_list;
3706  STATIC_ASSERT(sizeof(*instr) == 1);
3707  memcpy(&arg_count,
3708  instr + kPrintfArgCountOffset,
3709  sizeof(arg_count));
3710  memcpy(&arg_pattern_list,
3712  sizeof(arg_pattern_list));
3713 
3714  DCHECK(arg_count <= kPrintfMaxArgCount);
3715  DCHECK((arg_pattern_list >> (kPrintfArgPatternBits * arg_count)) == 0);
3716 
3717  // We need to call the host printf function with a set of arguments defined by
3718  // arg_pattern_list. Because we don't know the types and sizes of the
3719  // arguments, this is very difficult to do in a robust and portable way. To
3720  // work around the problem, we pick apart the format string, and print one
3721  // format placeholder at a time.
3722 
3723  // Allocate space for the format string. We take a copy, so we can modify it.
3724  // Leave enough space for one extra character per expected argument (plus the
3725  // '\0' termination).
3726  const char * format_base = reg<const char *>(0);
3727  DCHECK(format_base != NULL);
3728  size_t length = strlen(format_base) + 1;
3729  char * const format = new char[length + arg_count];
3730 
3731  // A list of chunks, each with exactly one format placeholder.
3732  const char * chunks[kPrintfMaxArgCount];
3733 
3734  // Copy the format string and search for format placeholders.
3735  uint32_t placeholder_count = 0;
3736  char * format_scratch = format;
3737  for (size_t i = 0; i < length; i++) {
3738  if (format_base[i] != '%') {
3739  *format_scratch++ = format_base[i];
3740  } else {
3741  if (format_base[i + 1] == '%') {
3742  // Ignore explicit "%%" sequences.
3743  *format_scratch++ = format_base[i];
3744 
3745  if (placeholder_count == 0) {
3746  // The first chunk is passed to printf using "%s", so we need to
3747  // unescape "%%" sequences in this chunk. (Just skip the next '%'.)
3748  i++;
3749  } else {
3750  // Otherwise, pass through "%%" unchanged.
3751  *format_scratch++ = format_base[++i];
3752  }
3753  } else {
3754  CHECK(placeholder_count < arg_count);
3755  // Insert '\0' before placeholders, and store their locations.
3756  *format_scratch++ = '\0';
3757  chunks[placeholder_count++] = format_scratch;
3758  *format_scratch++ = format_base[i];
3759  }
3760  }
3761  }
3762  DCHECK(format_scratch <= (format + length + arg_count));
3763  CHECK(placeholder_count == arg_count);
3764 
3765  // Finally, call printf with each chunk, passing the appropriate register
3766  // argument. Normally, printf returns the number of bytes transmitted, so we
3767  // can emulate a single printf call by adding the result from each chunk. If
3768  // any call returns a negative (error) value, though, just return that value.
3769 
3770  fprintf(stream_, "%s", clr_printf);
3771 
3772  // Because '\0' is inserted before each placeholder, the first string in
3773  // 'format' contains no format placeholders and should be printed literally.
3774  int result = fprintf(stream_, "%s", format);
3775  int pcs_r = 1; // Start at x1. x0 holds the format string.
3776  int pcs_f = 0; // Start at d0.
3777  if (result >= 0) {
3778  for (uint32_t i = 0; i < placeholder_count; i++) {
3779  int part_result = -1;
3780 
3781  uint32_t arg_pattern = arg_pattern_list >> (i * kPrintfArgPatternBits);
3782  arg_pattern &= (1 << kPrintfArgPatternBits) - 1;
3783  switch (arg_pattern) {
3784  case kPrintfArgW:
3785  part_result = fprintf(stream_, chunks[i], wreg(pcs_r++));
3786  break;
3787  case kPrintfArgX:
3788  part_result = fprintf(stream_, chunks[i], xreg(pcs_r++));
3789  break;
3790  case kPrintfArgD:
3791  part_result = fprintf(stream_, chunks[i], dreg(pcs_f++));
3792  break;
3793  default: UNREACHABLE();
3794  }
3795 
3796  if (part_result < 0) {
3797  // Handle error values.
3798  result = part_result;
3799  break;
3800  }
3801 
3802  result += part_result;
3803  }
3804  }
3805 
3806  fprintf(stream_, "%s", clr_normal);
3807 
3808 #ifdef DEBUG
3809  CorruptAllCallerSavedCPURegisters();
3810 #endif
3811 
3812  // Printf returns its result in x0 (just like the C library's printf).
3813  set_xreg(0, result);
3814 
3815  // The printf parameters are inlined in the code, so skip them.
3816  set_pc(instr->InstructionAtOffset(kPrintfLength));
3817 
3818  // Set LR as if we'd just called a native printf function.
3819  set_lr(pc());
3820 
3821  delete[] format;
3822 }
3823 
3824 
3825 #endif // USE_SIMULATOR
3826 
3827 } } // namespace v8::internal
3828 
3829 #endif // V8_TARGET_ARCH_ARM64
#define kCallerSavedFP
#define kCalleeSavedFP
static int ActivationFrameAlignment()
static void VFPrint(FILE *out, const char *format, va_list args)
#define V(NAME, Name, id)
Definition: execution.h:170
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
enable harmony numeric enable harmony object literal extensions Optimize object Array shift
#define UNREACHABLE()
Definition: logging.h:30
#define CHECK_EQ(expected, value)
Definition: logging.h:169
#define CHECK(condition)
Definition: logging.h:36
#define FATAL(msg)
Definition: logging.h:26
#define UNIMPLEMENTED()
Definition: logging.h:28
#define DCHECK(condition)
Definition: logging.h:205
#define DCHECK_EQ(v1, v2)
Definition: logging.h:206
void USE(T)
Definition: macros.h:322
#define STATIC_ASSERT(test)
Definition: macros.h:311
#define OFFSET_OF(type, field)
Definition: macros.h:22
T RoundUp(T x, intptr_t m)
Definition: macros.h:407
#define arraysize(array)
Definition: macros.h:86
int int32_t
Definition: unicode.cc:24
int CountLeadingSignBits(int64_t value, int width)
void DeleteArray(T *array)
Definition: allocation.h:68
const int kPointerSize
Definition: globals.h:129
const int kNumberOfCalleeSavedFPRegisters
char * ReadLine(const char *prompt)
Definition: utils.cc:129
bool IsSignallingNaN(double num)
Definition: utils-arm64.h:65
const unsigned kSRegSize
const int KB
Definition: globals.h:106
const unsigned kDRegSizeInBits
const Instr kImmExceptionIsRedirectedCall
const int kSmiShift
const unsigned kDebuggerTracingDirectivesMask
const unsigned kXRegSizeInBits
TypeImpl< ZoneTypeConfig > Type
static int min(int a, int b)
Definition: liveedit.cc:273
const int64_t kWRegMask
const unsigned kShiftAmountXRegMask
uint64_t ObjectPair
bool is_uintn(int64_t x, unsigned n)
Definition: utils.h:904
const unsigned kSPRegInternalCode
static uint32_t float_to_rawbits(float value)
Definition: utils-arm64.h:27
const RegList kCalleeSaved
Definition: frames-arm.h:38
static const unsigned kPrintfArgPatternBits
const unsigned kShiftAmountWRegMask
const LowDwVfpRegister d0
const unsigned kPrintfLength
const int32_t kWMinInt
const unsigned kDebugParamsOffset
const unsigned kWRegSizeInBits
kSerializedDataOffset Object
Definition: objects-inl.h:5322
double ToQuietNaN(double num)
Definition: utils-arm64.h:90
const Register sp
const unsigned kSRegSizeInBits
const unsigned kPrintfMaxArgCount
const unsigned kNumberOfFPRegisters
bool IsQuietNaN(T num)
Definition: utils-arm64.h:84
const int64_t kHalfWordMask
const Instr kImmExceptionIsPrintf
double FusedMultiplyAdd(double op1, double op2, double a)
Definition: utils-arm64.h:103
static float rawbits_to_float(uint32_t bits)
Definition: utils-arm64.h:41
const unsigned kPrintfArgPatternListOffset
const unsigned kRegCodeMask
const Register pc
static double rawbits_to_double(uint64_t bits)
Definition: utils-arm64.h:48
static uint64_t double_to_rawbits(double value)
Definition: utils-arm64.h:34
const int32_t kWMaxInt
const Register lr
const int64_t kXMaxInt
byte * Address
Definition: globals.h:101
const unsigned kXRegSize
void PrintF(const char *format,...)
Definition: utils.cc:80
int CountLeadingZeros(uint64_t value, int width)
const Instr kImmExceptionIsDebug
const int kNumberOfCalleeSavedRegisters
const int kSmiValueSize
Definition: v8.h:5806
const unsigned kWRegSize
const unsigned kDRegSize
const int64_t kByteMask
const unsigned kZeroRegCode
const int64_t kWordMask
const intptr_t kSmiTagMask
Definition: v8.h:5744
const int64_t kXMinInt
const unsigned kByteSize
uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x)
Definition: utils.h:884
bool is_intn(int64_t x, unsigned n)
Definition: utils.h:898
const unsigned kNumberOfRegisters
const unsigned kByteSizeInBytes
const uint64_t kWMaxUInt
const uint32_t kSlotsZapValue
Definition: globals.h:273
const Instr kImmExceptionIsUnreachable
const uint64_t kXMaxUInt
const unsigned kDebugCodeOffset
const unsigned kInstructionSize
@ UnconditionalBranchToRegisterMask
const unsigned kHalfWordSizeInBytes
const unsigned kPrintfArgCountOffset
const RegList kCallerSaved
Definition: frames-arm.h:50
const unsigned kDebugMessageOffset
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25
#define S(x)
Definition: version.cc:55
@ FP_INFINITE
Definition: win32-math.h:21
@ FP_SUBNORMAL
Definition: win32-math.h:23
@ FP_NORMAL
Definition: win32-math.h:24
@ FP_ZERO
Definition: win32-math.h:22
@ FP_NAN
Definition: win32-math.h:20
int isnan(double x)
int isinf(double x)