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