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