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