• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
TraceSim(const char * format,...)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 
SetBits(int msb,int lsb,uint32_t bits)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 
DefaultValueFor(SystemRegister id)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 
Initialize(Isolate * isolate)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.
current(Isolate * isolate)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 
CallVoid(byte * entry,CallArgument * args)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 
CallInt64(byte * entry,CallArgument * args)168 int64_t Simulator::CallInt64(byte* entry, CallArgument* args) {
169   CallVoid(entry, args);
170   return xreg(0);
171 }
172 
173 
CallDouble(byte * entry,CallArgument * args)174 double Simulator::CallDouble(byte* entry, CallArgument* args) {
175   CallVoid(entry, args);
176   return dreg(0);
177 }
178 
179 
CallJS(byte * entry,Object * new_target,Object * target,Object * revc,int64_t argc,Object *** argv)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 
CallRegExp(byte * entry,String * input,int64_t start_offset,const byte * input_start,const byte * input_end,int * output,int64_t output_size,Address stack_base,int64_t direct_call,void * return_address,Isolate * isolate)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 
CheckPCSComplianceAndRun()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.
CorruptRegisters(CPURegList * list,uint64_t value)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 
CorruptAllCallerSavedCPURegisters()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.
PushAddress(uintptr_t address)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 
PopAddress()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.
StackLimit(uintptr_t c_limit) const340 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 
Simulator(Decoder<DispatchingDecoderVisitor> * decoder,Isolate * isolate,FILE * stream)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 
Simulator()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 
Init(FILE * stream)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 
ResetState()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 
~Simulator()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 
Run()443 void Simulator::Run() {
444   pc_modified_ = false;
445   while (pc_ != kEndOfSimAddress) {
446     ExecuteInstruction();
447   }
448 }
449 
450 
RunFrom(Instruction * start)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:
Redirection(Isolate * isolate,void * external_function,ExternalReference::Type type)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 
address_of_redirect_call()476   void* address_of_redirect_call() {
477     return reinterpret_cast<void*>(&redirect_call_);
478   }
479 
480   template <typename T>
external_function()481   T external_function() { return reinterpret_cast<T>(external_function_); }
482 
type()483   ExternalReference::Type type() { return type_; }
484 
Get(Isolate * isolate,void * external_function,ExternalReference::Type type)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 
FromHltInstruction(Instruction * redirect_call)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 
ReverseRedirection(int64_t reg)504   static void* ReverseRedirection(int64_t reg) {
505     Redirection* redirection =
506         FromHltInstruction(reinterpret_cast<Instruction*>(reg));
507     return redirection->external_function<void*>();
508   }
509 
DeleteChain(Redirection * redirection)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
TearDown(base::CustomMatcherHashMap * i_cache,Redirection * first)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 
DoRuntimeCall(Instruction * instr)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 
RedirectExternalReference(Isolate * isolate,void * external_function,ExternalReference::Type type)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 
WRegNameForCode(unsigned code,Reg31Mode mode)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 
XRegNameForCode(unsigned code,Reg31Mode mode)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 
SRegNameForCode(unsigned code)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 
DRegNameForCode(unsigned code)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 
VRegNameForCode(unsigned code)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 
CodeFromName(const char * name)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>
AddWithCarry(bool set_flags,T left,T right,int carry_in)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>
AddSubWithCarry(Instruction * instr)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>
ShiftOperand(T value,Shift shift_type,unsigned amount)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>
ExtendValue(T value,Extend extend_type,unsigned left_shift)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>
Extract(Instruction * instr)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 
FPDefaultNaN() const1019 template<> double Simulator::FPDefaultNaN<double>() const {
1020   return kFP64DefaultNaN;
1021 }
1022 
1023 
FPDefaultNaN() const1024 template<> float Simulator::FPDefaultNaN<float>() const {
1025   return kFP32DefaultNaN;
1026 }
1027 
1028 
FPCompare(double val0,double val1)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 
SetBreakpoint(Instruction * location)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 
ListBreakpoints()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 
CheckBreakpoints()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 
CheckBreakNext()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 
PrintInstructionsAt(Instruction * start,uint64_t count)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 
PrintSystemRegisters()1112 void Simulator::PrintSystemRegisters() {
1113   PrintSystemRegister(NZCV);
1114   PrintSystemRegister(FPCR);
1115 }
1116 
1117 
PrintRegisters()1118 void Simulator::PrintRegisters() {
1119   for (unsigned i = 0; i < kNumberOfRegisters; i++) {
1120     PrintRegister(i);
1121   }
1122 }
1123 
1124 
PrintFPRegisters()1125 void Simulator::PrintFPRegisters() {
1126   for (unsigned i = 0; i < kNumberOfFPRegisters; i++) {
1127     PrintFPRegister(i);
1128   }
1129 }
1130 
1131 
PrintRegister(unsigned code,Reg31Mode r31mode)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 
PrintFPRegister(unsigned code,PrintFPRegisterSizes sizes)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 
PrintSystemRegister(SystemRegister id)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 
PrintRead(uintptr_t address,size_t size,unsigned reg_code)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 
PrintReadFP(uintptr_t address,size_t size,unsigned reg_code)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 
PrintWrite(uintptr_t address,size_t size,unsigned reg_code)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 
PrintWriteFP(uintptr_t address,size_t size,unsigned reg_code)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 
VisitUnimplemented(Instruction * instr)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 
VisitUnallocated(Instruction * instr)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 
VisitPCRelAddressing(Instruction * instr)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 
VisitUnconditionalBranch(Instruction * instr)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 
VisitConditionalBranch(Instruction * instr)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 
VisitUnconditionalBranchToRegister(Instruction * instr)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 
VisitTestBranch(Instruction * instr)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 
VisitCompareBranch(Instruction * instr)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>
AddSubHelper(Instruction * instr,T op2)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 
VisitAddSubShifted(Instruction * instr)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 
VisitAddSubImmediate(Instruction * instr)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 
VisitAddSubExtended(Instruction * instr)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 
VisitAddSubWithCarry(Instruction * instr)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 
VisitLogicalShifted(Instruction * instr)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 
VisitLogicalImmediate(Instruction * instr)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>
LogicalHelper(Instruction * instr,T op2)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 
VisitConditionalCompareRegister(Instruction * instr)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 
VisitConditionalCompareImmediate(Instruction * instr)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>
ConditionalCompareHelper(Instruction * instr,T op2)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 
VisitLoadStoreUnsignedOffset(Instruction * instr)1592 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) {
1593   int offset = instr->ImmLSUnsigned() << instr->SizeLS();
1594   LoadStoreHelper(instr, offset, Offset);
1595 }
1596 
1597 
VisitLoadStoreUnscaledOffset(Instruction * instr)1598 void Simulator::VisitLoadStoreUnscaledOffset(Instruction* instr) {
1599   LoadStoreHelper(instr, instr->ImmLS(), Offset);
1600 }
1601 
1602 
VisitLoadStorePreIndex(Instruction * instr)1603 void Simulator::VisitLoadStorePreIndex(Instruction* instr) {
1604   LoadStoreHelper(instr, instr->ImmLS(), PreIndex);
1605 }
1606 
1607 
VisitLoadStorePostIndex(Instruction * instr)1608 void Simulator::VisitLoadStorePostIndex(Instruction* instr) {
1609   LoadStoreHelper(instr, instr->ImmLS(), PostIndex);
1610 }
1611 
1612 
VisitLoadStoreRegisterOffset(Instruction * instr)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 
LoadStoreHelper(Instruction * instr,int64_t offset,AddrMode addrmode)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 
VisitLoadStorePairOffset(Instruction * instr)1707 void Simulator::VisitLoadStorePairOffset(Instruction* instr) {
1708   LoadStorePairHelper(instr, Offset);
1709 }
1710 
1711 
VisitLoadStorePairPreIndex(Instruction * instr)1712 void Simulator::VisitLoadStorePairPreIndex(Instruction* instr) {
1713   LoadStorePairHelper(instr, PreIndex);
1714 }
1715 
1716 
VisitLoadStorePairPostIndex(Instruction * instr)1717 void Simulator::VisitLoadStorePairPostIndex(Instruction* instr) {
1718   LoadStorePairHelper(instr, PostIndex);
1719 }
1720 
1721 
LoadStorePairHelper(Instruction * instr,AddrMode addrmode)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 
VisitLoadLiteral(Instruction * instr)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 
LoadStoreAddress(unsigned addr_reg,int64_t offset,AddrMode addrmode)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 
LoadStoreWriteBack(unsigned addr_reg,int64_t offset,AddrMode addrmode)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 
VisitLoadStoreAcquireRelease(Instruction * instr)1909 void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) {
1910   // TODO(binji)
1911 }
1912 
CheckMemoryAccess(uintptr_t address,uintptr_t stack)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 
VisitMoveWideImmediate(Instruction * instr)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 
VisitConditionalSelect(Instruction * instr)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 
VisitDataProcessing1Source(Instruction * instr)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>
DataProcessing2Source(Instruction * instr)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 
VisitDataProcessing2Source(Instruction * instr)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.
MultiplyHighSigned(int64_t u,int64_t v)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 
VisitDataProcessing3Source(Instruction * instr)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>
BitfieldHelper(Instruction * instr)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 
VisitBitfield(Instruction * instr)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 
VisitExtract(Instruction * instr)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 
VisitFPImmediate(Instruction * instr)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 
VisitFPIntegerConvert(Instruction * instr)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 
VisitFPFixedPointConvert(Instruction * instr)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 
FPToInt32(double value,FPRounding rmode)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 
FPToInt64(double value,FPRounding rmode)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 
FPToUInt32(double value,FPRounding rmode)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 
FPToUInt64(double value,FPRounding rmode)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 
VisitFPCompare(Instruction * instr)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 
VisitFPConditionalCompare(Instruction * instr)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 
VisitFPConditionalSelect(Instruction * instr)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 
VisitFPDataProcessing1Source(Instruction * instr)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>
FPRound(int64_t sign,int64_t exponent,uint64_t mantissa,FPRounding round_mode)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.
FPRoundToDouble(int64_t sign,int64_t exponent,uint64_t mantissa,FPRounding round_mode)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.
FPRoundToFloat(int64_t sign,int64_t exponent,uint64_t mantissa,FPRounding round_mode)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 
FixedToDouble(int64_t src,int fbits,FPRounding round)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 
UFixedToDouble(uint64_t src,int fbits,FPRounding round)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 
FixedToFloat(int64_t src,int fbits,FPRounding round)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 
UFixedToFloat(uint64_t src,int fbits,FPRounding round)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 
FPRoundInt(double value,FPRounding round_mode)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 
FPToDouble(float value)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 
FPToFloat(double value,FPRounding round_mode)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 
VisitFPDataProcessing2Source(Instruction * instr)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 
VisitFPDataProcessing3Source(Instruction * instr)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>
FPAdd(T op1,T op2)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>
FPDiv(T op1,T op2)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>
FPMax(T a,T b)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>
FPMaxNM(T a,T b)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>
FPMin(T a,T b)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>
FPMinNM(T a,T b)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>
FPMul(T op1,T op2)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>
FPMulAdd(T a,T op1,T op2)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>
FPSqrt(T op)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>
FPSub(T op1,T op2)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>
FPProcessNaN(T op)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>
FPProcessNaNs(T op1,T op2)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>
FPProcessNaNs3(T op1,T op2,T op3)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 
FPProcessNaNs(Instruction * instr)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 
VisitSystem(Instruction * instr)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 
GetValue(const char * desc,int64_t * value)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 
PrintValue(const char * desc)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 
Debug()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 
VisitException(Instruction * instr)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 
DoPrintf(Instruction * instr)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