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