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
12#include "src/arm64/decoder-arm64-inl.h"
13#include "src/arm64/simulator-arm64.h"
14#include "src/assembler.h"
15#include "src/disasm.h"
16#include "src/macro-assembler.h"
17#include "src/ostreams.h"
18
19namespace v8 {
20namespace 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"
44typedef char const * const TEXT_COLOUR;
45TEXT_COLOUR clr_normal         = FLAG_log_colour ? COLOUR(NORMAL)       : "";
46TEXT_COLOUR clr_flag_name      = FLAG_log_colour ? COLOUR_BOLD(WHITE)   : "";
47TEXT_COLOUR clr_flag_value     = FLAG_log_colour ? COLOUR(NORMAL)       : "";
48TEXT_COLOUR clr_reg_name       = FLAG_log_colour ? COLOUR_BOLD(CYAN)    : "";
49TEXT_COLOUR clr_reg_value      = FLAG_log_colour ? COLOUR(CYAN)         : "";
50TEXT_COLOUR clr_fpreg_name     = FLAG_log_colour ? COLOUR_BOLD(MAGENTA) : "";
51TEXT_COLOUR clr_fpreg_value    = FLAG_log_colour ? COLOUR(MAGENTA)      : "";
52TEXT_COLOUR clr_memory_address = FLAG_log_colour ? COLOUR_BOLD(BLUE)    : "";
53TEXT_COLOUR clr_debug_number   = FLAG_log_colour ? COLOUR_BOLD(YELLOW)  : "";
54TEXT_COLOUR clr_debug_message  = FLAG_log_colour ? COLOUR(YELLOW)       : "";
55TEXT_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.
59void 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
69const Instruction* Simulator::kEndOfSimAddress = NULL;
70
71
72void 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
84SimSystemRegister 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
97void 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.
105Simulator* 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
124void 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]);
145  if (base::OS::ActivationFrameAlignment() != 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
167int64_t Simulator::CallInt64(byte* entry, CallArgument* args) {
168  CallVoid(entry, args);
169  return xreg(0);
170}
171
172
173double Simulator::CallDouble(byte* entry, CallArgument* args) {
174  CallVoid(entry, args);
175  return dreg(0);
176}
177
178
179int64_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
196int64_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
224void Simulator::CheckPCSComplianceAndRun() {
225#ifdef DEBUG
226  CHECK_EQ(kNumberOfCalleeSavedRegisters, kCalleeSaved.Count());
227  CHECK_EQ(kNumberOfCalleeSavedFPRegisters, kCalleeSavedFP.Count());
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.
283void 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
299void 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.
311uintptr_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
324uintptr_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.
335uintptr_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
342Simulator::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
366Simulator::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
376void 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
397void 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
420Simulator::~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
432void Simulator::Run() {
433  pc_modified_ = false;
434  while (pc_ != kEndOfSimAddress) {
435    ExecuteInstruction();
436  }
437}
438
439
440void 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.
453class 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,
477                          ExternalReference::Type type) {
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_;
505  ExternalReference::Type type_;
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.
515struct ObjectPair {
516  int64_t res0;
517  int64_t res1;
518};
519
520
521typedef 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
530typedef int64_t (*SimulatorRuntimeCompareCall)(double arg1, double arg2);
531typedef double (*SimulatorRuntimeFPFPCall)(double arg1, double arg2);
532typedef double (*SimulatorRuntimeFPCall)(double arg1);
533typedef 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).
537typedef void (*SimulatorRuntimeDirectApiCall)(int64_t arg0);
538typedef void (*SimulatorRuntimeProfilingApiCall)(int64_t arg0, void* arg1);
539
540// This signature supports direct call to accessor getter callback.
541typedef void (*SimulatorRuntimeDirectGetterCall)(int64_t arg0, int64_t arg1);
542typedef void (*SimulatorRuntimeProfilingGetterCall)(int64_t arg0, int64_t arg1,
543                                                    void* arg2);
544
545void 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
727void* Simulator::RedirectExternalReference(void* external_function,
728                                           ExternalReference::Type type) {
729  Redirection* redirection = Redirection::Get(external_function, type);
730  return redirection->address_of_redirect_call();
731}
732
733
734const 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
740const 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
746const 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
752const 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
758const 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
765const 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
780const 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
793const char* Simulator::SRegNameForCode(unsigned code) {
794  STATIC_ASSERT(arraysize(Simulator::sreg_names) == kNumberOfFPRegisters);
795  DCHECK(code < kNumberOfFPRegisters);
796  return sreg_names[code % kNumberOfFPRegisters];
797}
798
799
800const char* Simulator::DRegNameForCode(unsigned code) {
801  STATIC_ASSERT(arraysize(Simulator::dreg_names) == kNumberOfFPRegisters);
802  DCHECK(code < kNumberOfFPRegisters);
803  return dreg_names[code % kNumberOfFPRegisters];
804}
805
806
807const char* Simulator::VRegNameForCode(unsigned code) {
808  STATIC_ASSERT(arraysize(Simulator::vreg_names) == kNumberOfFPRegisters);
809  DCHECK(code < kNumberOfFPRegisters);
810  return vreg_names[code % kNumberOfFPRegisters];
811}
812
813
814int 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 ---------------------------------------------------------------------
836template <typename T>
837T 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
873template<typename T>
874void 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
890template <typename T>
891T 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
916template <typename T>
917T 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
951template <typename T>
952void 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
965template<> double Simulator::FPDefaultNaN<double>() const {
966  return kFP64DefaultNaN;
967}
968
969
970template<> float Simulator::FPDefaultNaN<float>() const {
971  return kFP32DefaultNaN;
972}
973
974
975void 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
995void 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
1013void 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
1023void 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
1041void 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
1050void 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
1058void Simulator::PrintSystemRegisters() {
1059  PrintSystemRegister(NZCV);
1060  PrintSystemRegister(FPCR);
1061}
1062
1063
1064void Simulator::PrintRegisters() {
1065  for (unsigned i = 0; i < kNumberOfRegisters; i++) {
1066    PrintRegister(i);
1067  }
1068}
1069
1070
1071void Simulator::PrintFPRegisters() {
1072  for (unsigned i = 0; i < kNumberOfFPRegisters; i++) {
1073    PrintFPRegister(i);
1074  }
1075}
1076
1077
1078void 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
1091void 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
1125void 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
1154void 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
1169void 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
1197void 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
1232void 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
1263void 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
1270void 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
1277void 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
1292void 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
1306void 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
1314void 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
1333void 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
1348void 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
1364template<typename T>
1365void 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
1393void 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
1407void 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
1417void 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
1430void Simulator::VisitAddSubWithCarry(Instruction* instr) {
1431  if (instr->SixtyFourBits()) {
1432    AddSubWithCarry<int64_t>(instr);
1433  } else {
1434    AddSubWithCarry<int32_t>(instr);
1435  }
1436}
1437
1438
1439void 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
1455void 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
1464template<typename T>
1465void 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
1493void 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
1502void 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
1511template<typename T>
1512void 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
1532void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) {
1533  int offset = instr->ImmLSUnsigned() << instr->SizeLS();
1534  LoadStoreHelper(instr, offset, Offset);
1535}
1536
1537
1538void Simulator::VisitLoadStoreUnscaledOffset(Instruction* instr) {
1539  LoadStoreHelper(instr, instr->ImmLS(), Offset);
1540}
1541
1542
1543void Simulator::VisitLoadStorePreIndex(Instruction* instr) {
1544  LoadStoreHelper(instr, instr->ImmLS(), PreIndex);
1545}
1546
1547
1548void Simulator::VisitLoadStorePostIndex(Instruction* instr) {
1549  LoadStoreHelper(instr, instr->ImmLS(), PostIndex);
1550}
1551
1552
1553void 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
1563void 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
1647void Simulator::VisitLoadStorePairOffset(Instruction* instr) {
1648  LoadStorePairHelper(instr, Offset);
1649}
1650
1651
1652void Simulator::VisitLoadStorePairPreIndex(Instruction* instr) {
1653  LoadStorePairHelper(instr, PreIndex);
1654}
1655
1656
1657void Simulator::VisitLoadStorePairPostIndex(Instruction* instr) {
1658  LoadStorePairHelper(instr, PostIndex);
1659}
1660
1661
1662void Simulator::VisitLoadStorePairNonTemporal(Instruction* instr) {
1663  LoadStorePairHelper(instr, Offset);
1664}
1665
1666
1667void 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
1797void 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
1825uintptr_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
1844void 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
1855void 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
1870void 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
1913void 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
1937void 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
1966uint64_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
1977uint64_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
2004template <typename T>
2005void 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) {
2052      shift &= kShiftAmountWRegMask;
2053    } else {
2054      shift &= kShiftAmountXRegMask;
2055    }
2056    result = ShiftOperand(reg<T>(instr->Rn()), shift_op, shift);
2057  }
2058  set_reg<T>(instr->Rd(), result);
2059}
2060
2061
2062void 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.
2074static 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
2093void 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
2128template <typename T>
2129void 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
2183void Simulator::VisitBitfield(Instruction* instr) {
2184  if (instr->SixtyFourBits()) {
2185    BitfieldHelper<int64_t>(instr);
2186  } else {
2187    BitfieldHelper<int32_t>(instr);
2188  }
2189}
2190
2191
2192void Simulator::VisitExtract(Instruction* instr) {
2193  if (instr->SixtyFourBits()) {
2194    Extract<uint64_t>(instr);
2195  } else {
2196    Extract<uint32_t>(instr);
2197  }
2198}
2199
2200
2201void 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
2213void 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
2297void 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
2342int32_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
2353int64_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
2364uint32_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
2375uint64_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
2386void 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
2403void 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
2427void 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
2445void 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.
2492template <class T, int ebits, int mbits>
2493static 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.
2645static 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.
2657static 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
2668double 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
2678double 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
2694float 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
2704float 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
2720double 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
2776double 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
2813float 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
2866void 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
2909void 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
2941template <typename T>
2942T 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
2956template <typename T>
2957T 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
2971template <typename T>
2972T 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
2986template <typename T>
2987T 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
2998template <typename T>
2999T 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
3013template <typename T>
3014T 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
3026template <typename T>
3027T 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
3041template<typename T>
3042T 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
3086template <typename T>
3087T 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
3098template <typename T>
3099T 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
3113template <typename T>
3114T Simulator::FPProcessNaN(T op) {
3115  DCHECK(std::isnan(op));
3116  return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op);
3117}
3118
3119
3120template <typename T>
3121T 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
3138template <typename T>
3139T 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
3161bool 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
3185void 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
3228bool 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
3256bool 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);
3270  STATIC_ASSERT(kNumberOfRegisters == kNumberOfFPRegisters);
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
3310void 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) {
3500              STATIC_ASSERT(kSmiValueSize == 32);
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
3600void 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
3699void 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,
3711         instr + kPrintfArgPatternListOffset,
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
3830