1 // Copyright 2015, ARM Limited
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include "js-config.h"
28 
29 #ifdef JS_SIMULATOR_ARM64
30 
31 #include "jit/arm64/vixl/Simulator-vixl.h"
32 
33 #include <cmath>
34 #include <string.h>
35 
36 namespace vixl {
37 
38 const Instruction* Simulator::kEndOfSimAddress = NULL;
39 
40 void SimSystemRegister::SetBits(int msb, int lsb, uint32_t bits) {
41   int width = msb - lsb + 1;
42   VIXL_ASSERT(is_uintn(width, bits) || is_intn(width, bits));
43 
44   bits <<= lsb;
45   uint32_t mask = ((1 << width) - 1) << lsb;
46   VIXL_ASSERT((mask & write_ignore_mask_) == 0);
47 
48   value_ = (value_ & ~mask) | (bits & mask);
49 }
50 
51 
52 SimSystemRegister SimSystemRegister::DefaultValueFor(SystemRegister id) {
53   switch (id) {
54     case NZCV:
55       return SimSystemRegister(0x00000000, NZCVWriteIgnoreMask);
56     case FPCR:
57       return SimSystemRegister(0x00000000, FPCRWriteIgnoreMask);
58     default:
59       VIXL_UNREACHABLE();
60       return SimSystemRegister();
61   }
62 }
63 
64 
65 void Simulator::Run() {
66   pc_modified_ = false;
67   while (pc_ != kEndOfSimAddress) {
68     ExecuteInstruction();
69     LogAllWrittenRegisters();
70   }
71 }
72 
73 
74 void Simulator::RunFrom(const Instruction* first) {
75   set_pc(first);
76   Run();
77 }
78 
79 
80 const char* Simulator::xreg_names[] = {
81 "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",
82 "x8",  "x9",  "x10", "x11", "x12", "x13", "x14", "x15",
83 "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
84 "x24", "x25", "x26", "x27", "x28", "x29", "lr",  "xzr", "sp"};
85 
86 const char* Simulator::wreg_names[] = {
87 "w0",  "w1",  "w2",  "w3",  "w4",  "w5",  "w6",  "w7",
88 "w8",  "w9",  "w10", "w11", "w12", "w13", "w14", "w15",
89 "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
90 "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wzr", "wsp"};
91 
92 const char* Simulator::sreg_names[] = {
93 "s0",  "s1",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",
94 "s8",  "s9",  "s10", "s11", "s12", "s13", "s14", "s15",
95 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
96 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"};
97 
98 const char* Simulator::dreg_names[] = {
99 "d0",  "d1",  "d2",  "d3",  "d4",  "d5",  "d6",  "d7",
100 "d8",  "d9",  "d10", "d11", "d12", "d13", "d14", "d15",
101 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
102 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
103 
104 const char* Simulator::vreg_names[] = {
105 "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
106 "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
107 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
108 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
109 
110 
111 
112 const char* Simulator::WRegNameForCode(unsigned code, Reg31Mode mode) {
113   VIXL_ASSERT(code < kNumberOfRegisters);
114   // If the code represents the stack pointer, index the name after zr.
115   if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
116     code = kZeroRegCode + 1;
117   }
118   return wreg_names[code];
119 }
120 
121 
122 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) {
123   VIXL_ASSERT(code < kNumberOfRegisters);
124   // If the code represents the stack pointer, index the name after zr.
125   if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) {
126     code = kZeroRegCode + 1;
127   }
128   return xreg_names[code];
129 }
130 
131 
132 const char* Simulator::SRegNameForCode(unsigned code) {
133   VIXL_ASSERT(code < kNumberOfFPRegisters);
134   return sreg_names[code];
135 }
136 
137 
138 const char* Simulator::DRegNameForCode(unsigned code) {
139   VIXL_ASSERT(code < kNumberOfFPRegisters);
140   return dreg_names[code];
141 }
142 
143 
144 const char* Simulator::VRegNameForCode(unsigned code) {
145   VIXL_ASSERT(code < kNumberOfVRegisters);
146   return vreg_names[code];
147 }
148 
149 
150 #define COLOUR(colour_code)       "\033[0;" colour_code "m"
151 #define COLOUR_BOLD(colour_code)  "\033[1;" colour_code "m"
152 #define NORMAL  ""
153 #define GREY    "30"
154 #define RED     "31"
155 #define GREEN   "32"
156 #define YELLOW  "33"
157 #define BLUE    "34"
158 #define MAGENTA "35"
159 #define CYAN    "36"
160 #define WHITE   "37"
161 void Simulator::set_coloured_trace(bool value) {
162   coloured_trace_ = value;
163 
164   clr_normal          = value ? COLOUR(NORMAL)        : "";
165   clr_flag_name       = value ? COLOUR_BOLD(WHITE)    : "";
166   clr_flag_value      = value ? COLOUR(NORMAL)        : "";
167   clr_reg_name        = value ? COLOUR_BOLD(CYAN)     : "";
168   clr_reg_value       = value ? COLOUR(CYAN)          : "";
169   clr_vreg_name       = value ? COLOUR_BOLD(MAGENTA)  : "";
170   clr_vreg_value      = value ? COLOUR(MAGENTA)       : "";
171   clr_memory_address  = value ? COLOUR_BOLD(BLUE)     : "";
172   clr_warning         = value ? COLOUR_BOLD(YELLOW)   : "";
173   clr_warning_message = value ? COLOUR(YELLOW)        : "";
174   clr_printf          = value ? COLOUR(GREEN)         : "";
175 }
176 #undef COLOUR
177 #undef COLOUR_BOLD
178 #undef NORMAL
179 #undef GREY
180 #undef RED
181 #undef GREEN
182 #undef YELLOW
183 #undef BLUE
184 #undef MAGENTA
185 #undef CYAN
186 #undef WHITE
187 
188 
189 void Simulator::set_trace_parameters(int parameters) {
190   bool disasm_before = trace_parameters_ & LOG_DISASM;
191   trace_parameters_ = parameters;
192   bool disasm_after = trace_parameters_ & LOG_DISASM;
193 
194   if (disasm_before != disasm_after) {
195     if (disasm_after) {
196       decoder_->InsertVisitorBefore(print_disasm_, this);
197     } else {
198       decoder_->RemoveVisitor(print_disasm_);
199     }
200   }
201 }
202 
203 
204 void Simulator::set_instruction_stats(bool value) {
205   if (value != instruction_stats_) {
206     if (value) {
207       decoder_->AppendVisitor(instrumentation_);
208     } else {
209       decoder_->RemoveVisitor(instrumentation_);
210     }
211     instruction_stats_ = value;
212   }
213 }
214 
215 // Helpers ---------------------------------------------------------------------
216 uint64_t Simulator::AddWithCarry(unsigned reg_size,
217                                  bool set_flags,
218                                  uint64_t left,
219                                  uint64_t right,
220                                  int carry_in) {
221   VIXL_ASSERT((carry_in == 0) || (carry_in == 1));
222   VIXL_ASSERT((reg_size == kXRegSize) || (reg_size == kWRegSize));
223 
224   uint64_t max_uint = (reg_size == kWRegSize) ? kWMaxUInt : kXMaxUInt;
225   uint64_t reg_mask = (reg_size == kWRegSize) ? kWRegMask : kXRegMask;
226   uint64_t sign_mask = (reg_size == kWRegSize) ? kWSignMask : kXSignMask;
227 
228   left &= reg_mask;
229   right &= reg_mask;
230   uint64_t result = (left + right + carry_in) & reg_mask;
231 
232   if (set_flags) {
233     nzcv().SetN(CalcNFlag(result, reg_size));
234     nzcv().SetZ(CalcZFlag(result));
235 
236     // Compute the C flag by comparing the result to the max unsigned integer.
237     uint64_t max_uint_2op = max_uint - carry_in;
238     bool C = (left > max_uint_2op) || ((max_uint_2op - left) < right);
239     nzcv().SetC(C ? 1 : 0);
240 
241     // Overflow iff the sign bit is the same for the two inputs and different
242     // for the result.
243     uint64_t left_sign = left & sign_mask;
244     uint64_t right_sign = right & sign_mask;
245     uint64_t result_sign = result & sign_mask;
246     bool V = (left_sign == right_sign) && (left_sign != result_sign);
247     nzcv().SetV(V ? 1 : 0);
248 
249     LogSystemRegister(NZCV);
250   }
251   return result;
252 }
253 
254 
255 int64_t Simulator::ShiftOperand(unsigned reg_size,
256                                 int64_t value,
257                                 Shift shift_type,
258                                 unsigned amount) {
259   if (amount == 0) {
260     return value;
261   }
262   int64_t mask = reg_size == kXRegSize ? kXRegMask : kWRegMask;
263   switch (shift_type) {
264     case LSL:
265       return (value << amount) & mask;
266     case LSR:
267       return static_cast<uint64_t>(value) >> amount;
268     case ASR: {
269       // Shift used to restore the sign.
270       unsigned s_shift = kXRegSize - reg_size;
271       // Value with its sign restored.
272       int64_t s_value = (value << s_shift) >> s_shift;
273       return (s_value >> amount) & mask;
274     }
275     case ROR: {
276       if (reg_size == kWRegSize) {
277         value &= kWRegMask;
278       }
279       return (static_cast<uint64_t>(value) >> amount) |
280              ((value & ((INT64_C(1) << amount) - 1)) <<
281               (reg_size - amount));
282     }
283     default:
284       VIXL_UNIMPLEMENTED();
285       return 0;
286   }
287 }
288 
289 
290 int64_t Simulator::ExtendValue(unsigned reg_size,
291                                int64_t value,
292                                Extend extend_type,
293                                unsigned left_shift) {
294   switch (extend_type) {
295     case UXTB:
296       value &= kByteMask;
297       break;
298     case UXTH:
299       value &= kHalfWordMask;
300       break;
301     case UXTW:
302       value &= kWordMask;
303       break;
304     case SXTB:
305       value = (value << 56) >> 56;
306       break;
307     case SXTH:
308       value = (value << 48) >> 48;
309       break;
310     case SXTW:
311       value = (value << 32) >> 32;
312       break;
313     case UXTX:
314     case SXTX:
315       break;
316     default:
317       VIXL_UNREACHABLE();
318   }
319   int64_t mask = (reg_size == kXRegSize) ? kXRegMask : kWRegMask;
320   return (value << left_shift) & mask;
321 }
322 
323 
324 void Simulator::FPCompare(double val0, double val1, FPTrapFlags trap) {
325   AssertSupportedFPCR();
326 
327   // TODO: This assumes that the C++ implementation handles comparisons in the
328   // way that we expect (as per AssertSupportedFPCR()).
329   bool process_exception = false;
330   if ((std::isnan(val0) != 0) || (std::isnan(val1) != 0)) {
331     nzcv().SetRawValue(FPUnorderedFlag);
332     if (IsSignallingNaN(val0) || IsSignallingNaN(val1) ||
333         (trap == EnableTrap)) {
334       process_exception = true;
335     }
336   } else if (val0 < val1) {
337     nzcv().SetRawValue(FPLessThanFlag);
338   } else if (val0 > val1) {
339     nzcv().SetRawValue(FPGreaterThanFlag);
340   } else if (val0 == val1) {
341     nzcv().SetRawValue(FPEqualFlag);
342   } else {
343     VIXL_UNREACHABLE();
344   }
345   LogSystemRegister(NZCV);
346   if (process_exception) FPProcessException();
347 }
348 
349 
350 Simulator::PrintRegisterFormat Simulator::GetPrintRegisterFormatForSize(
351     unsigned reg_size, unsigned lane_size) {
352   VIXL_ASSERT(reg_size >= lane_size);
353 
354   uint32_t format = 0;
355   if (reg_size != lane_size) {
356     switch (reg_size) {
357       default: VIXL_UNREACHABLE(); break;
358       case kQRegSizeInBytes: format = kPrintRegAsQVector; break;
359       case kDRegSizeInBytes: format = kPrintRegAsDVector; break;
360     }
361   }
362 
363   switch (lane_size) {
364     default: VIXL_UNREACHABLE(); break;
365     case kQRegSizeInBytes: format |= kPrintReg1Q; break;
366     case kDRegSizeInBytes: format |= kPrintReg1D; break;
367     case kSRegSizeInBytes: format |= kPrintReg1S; break;
368     case kHRegSizeInBytes: format |= kPrintReg1H; break;
369     case kBRegSizeInBytes: format |= kPrintReg1B; break;
370   }
371   // These sizes would be duplicate case labels.
372   VIXL_STATIC_ASSERT(kXRegSizeInBytes == kDRegSizeInBytes);
373   VIXL_STATIC_ASSERT(kWRegSizeInBytes == kSRegSizeInBytes);
374   VIXL_STATIC_ASSERT(kPrintXReg == kPrintReg1D);
375   VIXL_STATIC_ASSERT(kPrintWReg == kPrintReg1S);
376 
377   return static_cast<PrintRegisterFormat>(format);
378 }
379 
380 
381 Simulator::PrintRegisterFormat Simulator::GetPrintRegisterFormat(
382     VectorFormat vform) {
383   switch (vform) {
384     default: VIXL_UNREACHABLE(); return kPrintReg16B;
385     case kFormat16B: return kPrintReg16B;
386     case kFormat8B: return kPrintReg8B;
387     case kFormat8H: return kPrintReg8H;
388     case kFormat4H: return kPrintReg4H;
389     case kFormat4S: return kPrintReg4S;
390     case kFormat2S: return kPrintReg2S;
391     case kFormat2D: return kPrintReg2D;
392     case kFormat1D: return kPrintReg1D;
393   }
394 }
395 
396 
397 void Simulator::PrintWrittenRegisters() {
398   for (unsigned i = 0; i < kNumberOfRegisters; i++) {
399     if (registers_[i].WrittenSinceLastLog()) PrintRegister(i);
400   }
401 }
402 
403 
404 void Simulator::PrintWrittenVRegisters() {
405   for (unsigned i = 0; i < kNumberOfVRegisters; i++) {
406     // At this point there is no type information, so print as a raw 1Q.
407     if (vregisters_[i].WrittenSinceLastLog()) PrintVRegister(i, kPrintReg1Q);
408   }
409 }
410 
411 
412 void Simulator::PrintSystemRegisters() {
413   PrintSystemRegister(NZCV);
414   PrintSystemRegister(FPCR);
415 }
416 
417 
418 void Simulator::PrintRegisters() {
419   for (unsigned i = 0; i < kNumberOfRegisters; i++) {
420     PrintRegister(i);
421   }
422 }
423 
424 
425 void Simulator::PrintVRegisters() {
426   for (unsigned i = 0; i < kNumberOfVRegisters; i++) {
427     // At this point there is no type information, so print as a raw 1Q.
428     PrintVRegister(i, kPrintReg1Q);
429   }
430 }
431 
432 
433 // Print a register's name and raw value.
434 //
435 // Only the least-significant `size_in_bytes` bytes of the register are printed,
436 // but the value is aligned as if the whole register had been printed.
437 //
438 // For typical register updates, size_in_bytes should be set to kXRegSizeInBytes
439 // -- the default -- so that the whole register is printed. Other values of
440 // size_in_bytes are intended for use when the register hasn't actually been
441 // updated (such as in PrintWrite).
442 //
443 // No newline is printed. This allows the caller to print more details (such as
444 // a memory access annotation).
445 void Simulator::PrintRegisterRawHelper(unsigned code, Reg31Mode r31mode,
446                                        int size_in_bytes) {
447   // The template for all supported sizes.
448   //   "# x{code}: 0xffeeddccbbaa9988"
449   //   "# w{code}:         0xbbaa9988"
450   //   "# w{code}<15:0>:       0x9988"
451   //   "# w{code}<7:0>:          0x88"
452   unsigned padding_chars = (kXRegSizeInBytes - size_in_bytes) * 2;
453 
454   const char * name = "";
455   const char * suffix = "";
456   switch (size_in_bytes) {
457     case kXRegSizeInBytes: name = XRegNameForCode(code, r31mode); break;
458     case kWRegSizeInBytes: name = WRegNameForCode(code, r31mode); break;
459     case 2:
460       name = WRegNameForCode(code, r31mode);
461       suffix = "<15:0>";
462       padding_chars -= strlen(suffix);
463       break;
464     case 1:
465       name = WRegNameForCode(code, r31mode);
466       suffix = "<7:0>";
467       padding_chars -= strlen(suffix);
468       break;
469     default:
470       VIXL_UNREACHABLE();
471   }
472   fprintf(stream_, "# %s%5s%s: ", clr_reg_name, name, suffix);
473 
474   // Print leading padding spaces.
475   VIXL_ASSERT(padding_chars < (kXRegSizeInBytes * 2));
476   for (unsigned i = 0; i < padding_chars; i++) {
477     putc(' ', stream_);
478   }
479 
480   // Print the specified bits in hexadecimal format.
481   uint64_t bits = reg<uint64_t>(code, r31mode);
482   bits &= kXRegMask >> ((kXRegSizeInBytes - size_in_bytes) * 8);
483   VIXL_STATIC_ASSERT(sizeof(bits) == kXRegSizeInBytes);
484 
485   int chars = size_in_bytes * 2;
486   fprintf(stream_, "%s0x%0*" PRIx64 "%s",
487           clr_reg_value, chars, bits, clr_normal);
488 }
489 
490 
491 void Simulator::PrintRegister(unsigned code, Reg31Mode r31mode) {
492   registers_[code].NotifyRegisterLogged();
493 
494   // Don't print writes into xzr.
495   if ((code == kZeroRegCode) && (r31mode == Reg31IsZeroRegister)) {
496     return;
497   }
498 
499   // The template for all x and w registers:
500   //   "# x{code}: 0x{value}"
501   //   "# w{code}: 0x{value}"
502 
503   PrintRegisterRawHelper(code, r31mode);
504   fprintf(stream_, "\n");
505 }
506 
507 
508 // Print a register's name and raw value.
509 //
510 // The `bytes` and `lsb` arguments can be used to limit the bytes that are
511 // printed. These arguments are intended for use in cases where register hasn't
512 // actually been updated (such as in PrintVWrite).
513 //
514 // No newline is printed. This allows the caller to print more details (such as
515 // a floating-point interpretation or a memory access annotation).
516 void Simulator::PrintVRegisterRawHelper(unsigned code, int bytes, int lsb) {
517   // The template for vector types:
518   //   "# v{code}: 0xffeeddccbbaa99887766554433221100".
519   // An example with bytes=4 and lsb=8:
520   //   "# v{code}:         0xbbaa9988                ".
521   fprintf(stream_, "# %s%5s: %s",
522           clr_vreg_name, VRegNameForCode(code), clr_vreg_value);
523 
524   int msb = lsb + bytes - 1;
525   int byte = kQRegSizeInBytes - 1;
526 
527   // Print leading padding spaces. (Two spaces per byte.)
528   while (byte > msb) {
529     fprintf(stream_, "  ");
530     byte--;
531   }
532 
533   // Print the specified part of the value, byte by byte.
534   qreg_t rawbits = qreg(code);
535   fprintf(stream_, "0x");
536   while (byte >= lsb) {
537     fprintf(stream_, "%02x", rawbits.val[byte]);
538     byte--;
539   }
540 
541   // Print trailing padding spaces.
542   while (byte >= 0) {
543     fprintf(stream_, "  ");
544     byte--;
545   }
546   fprintf(stream_, "%s", clr_normal);
547 }
548 
549 
550 // Print each of the specified lanes of a register as a float or double value.
551 //
552 // The `lane_count` and `lslane` arguments can be used to limit the lanes that
553 // are printed. These arguments are intended for use in cases where register
554 // hasn't actually been updated (such as in PrintVWrite).
555 //
556 // No newline is printed. This allows the caller to print more details (such as
557 // a memory access annotation).
558 void Simulator::PrintVRegisterFPHelper(unsigned code,
559                                        unsigned lane_size_in_bytes,
560                                        int lane_count,
561                                        int rightmost_lane) {
562   VIXL_ASSERT((lane_size_in_bytes == kSRegSizeInBytes) ||
563               (lane_size_in_bytes == kDRegSizeInBytes));
564 
565   unsigned msb = ((lane_count + rightmost_lane) * lane_size_in_bytes);
566   VIXL_ASSERT(msb <= kQRegSizeInBytes);
567 
568   // For scalar types ((lane_count == 1) && (rightmost_lane == 0)), a register
569   // name is used:
570   //   " (s{code}: {value})"
571   //   " (d{code}: {value})"
572   // For vector types, "..." is used to represent one or more omitted lanes.
573   //   " (..., {value}, {value}, ...)"
574   if ((lane_count == 1) && (rightmost_lane == 0)) {
575     const char * name =
576         (lane_size_in_bytes == kSRegSizeInBytes) ? SRegNameForCode(code)
577                                                  : DRegNameForCode(code);
578     fprintf(stream_, " (%s%s: ", clr_vreg_name, name);
579   } else {
580     if (msb < (kQRegSizeInBytes - 1)) {
581       fprintf(stream_, " (..., ");
582     } else {
583       fprintf(stream_, " (");
584     }
585   }
586 
587   // Print the list of values.
588   const char * separator = "";
589   int leftmost_lane = rightmost_lane + lane_count - 1;
590   for (int lane = leftmost_lane; lane >= rightmost_lane; lane--) {
591     double value =
592         (lane_size_in_bytes == kSRegSizeInBytes) ? vreg(code).Get<float>(lane)
593                                                  : vreg(code).Get<double>(lane);
594     fprintf(stream_, "%s%s%#g%s", separator, clr_vreg_value, value, clr_normal);
595     separator = ", ";
596   }
597 
598   if (rightmost_lane > 0) {
599     fprintf(stream_, ", ...");
600   }
601   fprintf(stream_, ")");
602 }
603 
604 
605 void Simulator::PrintVRegister(unsigned code, PrintRegisterFormat format) {
606   vregisters_[code].NotifyRegisterLogged();
607 
608   int lane_size_log2 = format & kPrintRegLaneSizeMask;
609 
610   int reg_size_log2;
611   if (format & kPrintRegAsQVector) {
612     reg_size_log2 = kQRegSizeInBytesLog2;
613   } else if (format & kPrintRegAsDVector) {
614     reg_size_log2 = kDRegSizeInBytesLog2;
615   } else {
616     // Scalar types.
617     reg_size_log2 = lane_size_log2;
618   }
619 
620   int lane_count = 1 << (reg_size_log2 - lane_size_log2);
621   int lane_size = 1 << lane_size_log2;
622 
623   // The template for vector types:
624   //   "# v{code}: 0x{rawbits} (..., {value}, ...)".
625   // The template for scalar types:
626   //   "# v{code}: 0x{rawbits} ({reg}:{value})".
627   // The values in parentheses after the bit representations are floating-point
628   // interpretations. They are displayed only if the kPrintVRegAsFP bit is set.
629 
630   PrintVRegisterRawHelper(code);
631   if (format & kPrintRegAsFP) {
632     PrintVRegisterFPHelper(code, lane_size, lane_count);
633   }
634 
635   fprintf(stream_, "\n");
636 }
637 
638 
639 void Simulator::PrintSystemRegister(SystemRegister id) {
640   switch (id) {
641     case NZCV:
642       fprintf(stream_, "# %sNZCV: %sN:%d Z:%d C:%d V:%d%s\n",
643               clr_flag_name, clr_flag_value,
644               nzcv().N(), nzcv().Z(), nzcv().C(), nzcv().V(),
645               clr_normal);
646       break;
647     case FPCR: {
648       static const char * rmode[] = {
649         "0b00 (Round to Nearest)",
650         "0b01 (Round towards Plus Infinity)",
651         "0b10 (Round towards Minus Infinity)",
652         "0b11 (Round towards Zero)"
653       };
654       VIXL_ASSERT(fpcr().RMode() < (sizeof(rmode) / sizeof(rmode[0])));
655       fprintf(stream_,
656               "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n",
657               clr_flag_name, clr_flag_value,
658               fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()],
659               clr_normal);
660       break;
661     }
662     default:
663       VIXL_UNREACHABLE();
664   }
665 }
666 
667 
668 void Simulator::PrintRead(uintptr_t address,
669                           unsigned reg_code,
670                           PrintRegisterFormat format) {
671   registers_[reg_code].NotifyRegisterLogged();
672 
673   USE(format);
674 
675   // The template is "# {reg}: 0x{value} <- {address}".
676   PrintRegisterRawHelper(reg_code, Reg31IsZeroRegister);
677   fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n",
678           clr_memory_address, address, clr_normal);
679 }
680 
681 
682 void Simulator::PrintVRead(uintptr_t address,
683                            unsigned reg_code,
684                            PrintRegisterFormat format,
685                            unsigned lane) {
686   vregisters_[reg_code].NotifyRegisterLogged();
687 
688   // The template is "# v{code}: 0x{rawbits} <- address".
689   PrintVRegisterRawHelper(reg_code);
690   if (format & kPrintRegAsFP) {
691     PrintVRegisterFPHelper(reg_code, GetPrintRegLaneSizeInBytes(format),
692                            GetPrintRegLaneCount(format), lane);
693   }
694   fprintf(stream_, " <- %s0x%016" PRIxPTR "%s\n",
695           clr_memory_address, address, clr_normal);
696 }
697 
698 
699 void Simulator::PrintWrite(uintptr_t address,
700                            unsigned reg_code,
701                            PrintRegisterFormat format) {
702   VIXL_ASSERT(GetPrintRegLaneCount(format) == 1);
703 
704   // The template is "# v{code}: 0x{value} -> {address}". To keep the trace tidy
705   // and readable, the value is aligned with the values in the register trace.
706   PrintRegisterRawHelper(reg_code, Reg31IsZeroRegister,
707                          GetPrintRegSizeInBytes(format));
708   fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n",
709           clr_memory_address, address, clr_normal);
710 }
711 
712 
713 void Simulator::PrintVWrite(uintptr_t address,
714                             unsigned reg_code,
715                             PrintRegisterFormat format,
716                             unsigned lane) {
717   // The templates:
718   //   "# v{code}: 0x{rawbits} -> {address}"
719   //   "# v{code}: 0x{rawbits} (..., {value}, ...) -> {address}".
720   //   "# v{code}: 0x{rawbits} ({reg}:{value}) -> {address}"
721   // Because this trace doesn't represent a change to the source register's
722   // value, only the relevant part of the value is printed. To keep the trace
723   // tidy and readable, the raw value is aligned with the other values in the
724   // register trace.
725   int lane_count = GetPrintRegLaneCount(format);
726   int lane_size = GetPrintRegLaneSizeInBytes(format);
727   int reg_size = GetPrintRegSizeInBytes(format);
728   PrintVRegisterRawHelper(reg_code, reg_size, lane_size * lane);
729   if (format & kPrintRegAsFP) {
730     PrintVRegisterFPHelper(reg_code, lane_size, lane_count, lane);
731   }
732   fprintf(stream_, " -> %s0x%016" PRIxPTR "%s\n",
733           clr_memory_address, address, clr_normal);
734 }
735 
736 
737 // Visitors---------------------------------------------------------------------
738 
739 void Simulator::VisitUnimplemented(const Instruction* instr) {
740   printf("Unimplemented instruction at %p: 0x%08" PRIx32 "\n",
741          reinterpret_cast<const void*>(instr), instr->InstructionBits());
742   VIXL_UNIMPLEMENTED();
743 }
744 
745 
746 void Simulator::VisitUnallocated(const Instruction* instr) {
747   printf("Unallocated instruction at %p: 0x%08" PRIx32 "\n",
748          reinterpret_cast<const void*>(instr), instr->InstructionBits());
749   VIXL_UNIMPLEMENTED();
750 }
751 
752 
753 void Simulator::VisitPCRelAddressing(const Instruction* instr) {
754   VIXL_ASSERT((instr->Mask(PCRelAddressingMask) == ADR) ||
755               (instr->Mask(PCRelAddressingMask) == ADRP));
756 
757   set_reg(instr->Rd(), instr->ImmPCOffsetTarget());
758 }
759 
760 
761 void Simulator::VisitUnconditionalBranch(const Instruction* instr) {
762   switch (instr->Mask(UnconditionalBranchMask)) {
763     case BL:
764       set_lr(instr->NextInstruction());
765       VIXL_FALLTHROUGH();
766     case B:
767       set_pc(instr->ImmPCOffsetTarget());
768       break;
769     default: VIXL_UNREACHABLE();
770   }
771 }
772 
773 
774 void Simulator::VisitConditionalBranch(const Instruction* instr) {
775   VIXL_ASSERT(instr->Mask(ConditionalBranchMask) == B_cond);
776   if (ConditionPassed(instr->ConditionBranch())) {
777     set_pc(instr->ImmPCOffsetTarget());
778   }
779 }
780 
781 
782 void Simulator::VisitUnconditionalBranchToRegister(const Instruction* instr) {
783   const Instruction* target = Instruction::Cast(xreg(instr->Rn()));
784 
785   switch (instr->Mask(UnconditionalBranchToRegisterMask)) {
786     case BLR:
787       set_lr(instr->NextInstruction());
788       VIXL_FALLTHROUGH();
789     case BR:
790     case RET: set_pc(target); break;
791     default: VIXL_UNREACHABLE();
792   }
793 }
794 
795 
796 void Simulator::VisitTestBranch(const Instruction* instr) {
797   unsigned bit_pos = (instr->ImmTestBranchBit5() << 5) |
798                      instr->ImmTestBranchBit40();
799   bool bit_zero = ((xreg(instr->Rt()) >> bit_pos) & 1) == 0;
800   bool take_branch = false;
801   switch (instr->Mask(TestBranchMask)) {
802     case TBZ: take_branch = bit_zero; break;
803     case TBNZ: take_branch = !bit_zero; break;
804     default: VIXL_UNIMPLEMENTED();
805   }
806   if (take_branch) {
807     set_pc(instr->ImmPCOffsetTarget());
808   }
809 }
810 
811 
812 void Simulator::VisitCompareBranch(const Instruction* instr) {
813   unsigned rt = instr->Rt();
814   bool take_branch = false;
815   switch (instr->Mask(CompareBranchMask)) {
816     case CBZ_w: take_branch = (wreg(rt) == 0); break;
817     case CBZ_x: take_branch = (xreg(rt) == 0); break;
818     case CBNZ_w: take_branch = (wreg(rt) != 0); break;
819     case CBNZ_x: take_branch = (xreg(rt) != 0); break;
820     default: VIXL_UNIMPLEMENTED();
821   }
822   if (take_branch) {
823     set_pc(instr->ImmPCOffsetTarget());
824   }
825 }
826 
827 
828 void Simulator::AddSubHelper(const Instruction* instr, int64_t op2) {
829   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
830   bool set_flags = instr->FlagsUpdate();
831   int64_t new_val = 0;
832   Instr operation = instr->Mask(AddSubOpMask);
833 
834   switch (operation) {
835     case ADD:
836     case ADDS: {
837       new_val = AddWithCarry(reg_size,
838                              set_flags,
839                              reg(reg_size, instr->Rn(), instr->RnMode()),
840                              op2);
841       break;
842     }
843     case SUB:
844     case SUBS: {
845       new_val = AddWithCarry(reg_size,
846                              set_flags,
847                              reg(reg_size, instr->Rn(), instr->RnMode()),
848                              ~op2,
849                              1);
850       break;
851     }
852     default: VIXL_UNREACHABLE();
853   }
854 
855   set_reg(reg_size, instr->Rd(), new_val, LogRegWrites, instr->RdMode());
856 }
857 
858 
859 void Simulator::VisitAddSubShifted(const Instruction* instr) {
860   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
861   int64_t op2 = ShiftOperand(reg_size,
862                              reg(reg_size, instr->Rm()),
863                              static_cast<Shift>(instr->ShiftDP()),
864                              instr->ImmDPShift());
865   AddSubHelper(instr, op2);
866 }
867 
868 
869 void Simulator::VisitAddSubImmediate(const Instruction* instr) {
870   int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0);
871   AddSubHelper(instr, op2);
872 }
873 
874 
875 void Simulator::VisitAddSubExtended(const Instruction* instr) {
876   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
877   int64_t op2 = ExtendValue(reg_size,
878                             reg(reg_size, instr->Rm()),
879                             static_cast<Extend>(instr->ExtendMode()),
880                             instr->ImmExtendShift());
881   AddSubHelper(instr, op2);
882 }
883 
884 
885 void Simulator::VisitAddSubWithCarry(const Instruction* instr) {
886   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
887   int64_t op2 = reg(reg_size, instr->Rm());
888   int64_t new_val;
889 
890   if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) {
891     op2 = ~op2;
892   }
893 
894   new_val = AddWithCarry(reg_size,
895                          instr->FlagsUpdate(),
896                          reg(reg_size, instr->Rn()),
897                          op2,
898                          C());
899 
900   set_reg(reg_size, instr->Rd(), new_val);
901 }
902 
903 
904 void Simulator::VisitLogicalShifted(const Instruction* instr) {
905   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
906   Shift shift_type = static_cast<Shift>(instr->ShiftDP());
907   unsigned shift_amount = instr->ImmDPShift();
908   int64_t op2 = ShiftOperand(reg_size, reg(reg_size, instr->Rm()), shift_type,
909                              shift_amount);
910   if (instr->Mask(NOT) == NOT) {
911     op2 = ~op2;
912   }
913   LogicalHelper(instr, op2);
914 }
915 
916 
917 void Simulator::VisitLogicalImmediate(const Instruction* instr) {
918   LogicalHelper(instr, instr->ImmLogical());
919 }
920 
921 
922 void Simulator::LogicalHelper(const Instruction* instr, int64_t op2) {
923   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
924   int64_t op1 = reg(reg_size, instr->Rn());
925   int64_t result = 0;
926   bool update_flags = false;
927 
928   // Switch on the logical operation, stripping out the NOT bit, as it has a
929   // different meaning for logical immediate instructions.
930   switch (instr->Mask(LogicalOpMask & ~NOT)) {
931     case ANDS: update_flags = true; VIXL_FALLTHROUGH();
932     case AND: result = op1 & op2; break;
933     case ORR: result = op1 | op2; break;
934     case EOR: result = op1 ^ op2; break;
935     default:
936       VIXL_UNIMPLEMENTED();
937   }
938 
939   if (update_flags) {
940     nzcv().SetN(CalcNFlag(result, reg_size));
941     nzcv().SetZ(CalcZFlag(result));
942     nzcv().SetC(0);
943     nzcv().SetV(0);
944     LogSystemRegister(NZCV);
945   }
946 
947   set_reg(reg_size, instr->Rd(), result, LogRegWrites, instr->RdMode());
948 }
949 
950 
951 void Simulator::VisitConditionalCompareRegister(const Instruction* instr) {
952   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
953   ConditionalCompareHelper(instr, reg(reg_size, instr->Rm()));
954 }
955 
956 
957 void Simulator::VisitConditionalCompareImmediate(const Instruction* instr) {
958   ConditionalCompareHelper(instr, instr->ImmCondCmp());
959 }
960 
961 
962 void Simulator::ConditionalCompareHelper(const Instruction* instr,
963                                          int64_t op2) {
964   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
965   int64_t op1 = reg(reg_size, instr->Rn());
966 
967   if (ConditionPassed(instr->Condition())) {
968     // If the condition passes, set the status flags to the result of comparing
969     // the operands.
970     if (instr->Mask(ConditionalCompareMask) == CCMP) {
971       AddWithCarry(reg_size, true, op1, ~op2, 1);
972     } else {
973       VIXL_ASSERT(instr->Mask(ConditionalCompareMask) == CCMN);
974       AddWithCarry(reg_size, true, op1, op2, 0);
975     }
976   } else {
977     // If the condition fails, set the status flags to the nzcv immediate.
978     nzcv().SetFlags(instr->Nzcv());
979     LogSystemRegister(NZCV);
980   }
981 }
982 
983 
984 void Simulator::VisitLoadStoreUnsignedOffset(const Instruction* instr) {
985   int offset = instr->ImmLSUnsigned() << instr->SizeLS();
986   LoadStoreHelper(instr, offset, Offset);
987 }
988 
989 
990 void Simulator::VisitLoadStoreUnscaledOffset(const Instruction* instr) {
991   LoadStoreHelper(instr, instr->ImmLS(), Offset);
992 }
993 
994 
995 void Simulator::VisitLoadStorePreIndex(const Instruction* instr) {
996   LoadStoreHelper(instr, instr->ImmLS(), PreIndex);
997 }
998 
999 
1000 void Simulator::VisitLoadStorePostIndex(const Instruction* instr) {
1001   LoadStoreHelper(instr, instr->ImmLS(), PostIndex);
1002 }
1003 
1004 
1005 void Simulator::VisitLoadStoreRegisterOffset(const Instruction* instr) {
1006   Extend ext = static_cast<Extend>(instr->ExtendMode());
1007   VIXL_ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX));
1008   unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS();
1009 
1010   int64_t offset = ExtendValue(kXRegSize, xreg(instr->Rm()), ext,
1011                                shift_amount);
1012   LoadStoreHelper(instr, offset, Offset);
1013 }
1014 
1015 
1016 
1017 void Simulator::LoadStoreHelper(const Instruction* instr,
1018                                 int64_t offset,
1019                                 AddrMode addrmode) {
1020   unsigned srcdst = instr->Rt();
1021   uintptr_t address = AddressModeHelper(instr->Rn(), offset, addrmode);
1022 
1023   LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreMask));
1024   switch (op) {
1025     case LDRB_w:
1026       set_wreg(srcdst, Memory::Read<uint8_t>(address), NoRegLog); break;
1027     case LDRH_w:
1028       set_wreg(srcdst, Memory::Read<uint16_t>(address), NoRegLog); break;
1029     case LDR_w:
1030       set_wreg(srcdst, Memory::Read<uint32_t>(address), NoRegLog); break;
1031     case LDR_x:
1032       set_xreg(srcdst, Memory::Read<uint64_t>(address), NoRegLog); break;
1033     case LDRSB_w:
1034       set_wreg(srcdst, Memory::Read<int8_t>(address), NoRegLog); break;
1035     case LDRSH_w:
1036       set_wreg(srcdst, Memory::Read<int16_t>(address), NoRegLog); break;
1037     case LDRSB_x:
1038       set_xreg(srcdst, Memory::Read<int8_t>(address), NoRegLog); break;
1039     case LDRSH_x:
1040       set_xreg(srcdst, Memory::Read<int16_t>(address), NoRegLog); break;
1041     case LDRSW_x:
1042       set_xreg(srcdst, Memory::Read<int32_t>(address), NoRegLog); break;
1043     case LDR_b:
1044       set_breg(srcdst, Memory::Read<uint8_t>(address), NoRegLog); break;
1045     case LDR_h:
1046       set_hreg(srcdst, Memory::Read<uint16_t>(address), NoRegLog); break;
1047     case LDR_s:
1048       set_sreg(srcdst, Memory::Read<float>(address), NoRegLog); break;
1049     case LDR_d:
1050       set_dreg(srcdst, Memory::Read<double>(address), NoRegLog); break;
1051     case LDR_q:
1052       set_qreg(srcdst, Memory::Read<qreg_t>(address), NoRegLog); break;
1053 
1054     case STRB_w:  Memory::Write<uint8_t>(address, wreg(srcdst)); break;
1055     case STRH_w:  Memory::Write<uint16_t>(address, wreg(srcdst)); break;
1056     case STR_w:   Memory::Write<uint32_t>(address, wreg(srcdst)); break;
1057     case STR_x:   Memory::Write<uint64_t>(address, xreg(srcdst)); break;
1058     case STR_b:   Memory::Write<uint8_t>(address, breg(srcdst)); break;
1059     case STR_h:   Memory::Write<uint16_t>(address, hreg(srcdst)); break;
1060     case STR_s:   Memory::Write<float>(address, sreg(srcdst)); break;
1061     case STR_d:   Memory::Write<double>(address, dreg(srcdst)); break;
1062     case STR_q:   Memory::Write<qreg_t>(address, qreg(srcdst)); break;
1063 
1064     // Ignore prfm hint instructions.
1065     case PRFM: break;
1066 
1067     default: VIXL_UNIMPLEMENTED();
1068   }
1069 
1070   unsigned access_size = 1 << instr->SizeLS();
1071   if (instr->IsLoad()) {
1072     if ((op == LDR_s) || (op == LDR_d)) {
1073       LogVRead(address, srcdst, GetPrintRegisterFormatForSizeFP(access_size));
1074     } else if ((op == LDR_b) || (op == LDR_h) || (op == LDR_q)) {
1075       LogVRead(address, srcdst, GetPrintRegisterFormatForSize(access_size));
1076     } else {
1077       LogRead(address, srcdst, GetPrintRegisterFormatForSize(access_size));
1078     }
1079   } else {
1080     if ((op == STR_s) || (op == STR_d)) {
1081       LogVWrite(address, srcdst, GetPrintRegisterFormatForSizeFP(access_size));
1082     } else if ((op == STR_b) || (op == STR_h) || (op == STR_q)) {
1083       LogVWrite(address, srcdst, GetPrintRegisterFormatForSize(access_size));
1084     } else {
1085       LogWrite(address, srcdst, GetPrintRegisterFormatForSize(access_size));
1086     }
1087   }
1088 
1089   local_monitor_.MaybeClear();
1090 }
1091 
1092 
1093 void Simulator::VisitLoadStorePairOffset(const Instruction* instr) {
1094   LoadStorePairHelper(instr, Offset);
1095 }
1096 
1097 
1098 void Simulator::VisitLoadStorePairPreIndex(const Instruction* instr) {
1099   LoadStorePairHelper(instr, PreIndex);
1100 }
1101 
1102 
1103 void Simulator::VisitLoadStorePairPostIndex(const Instruction* instr) {
1104   LoadStorePairHelper(instr, PostIndex);
1105 }
1106 
1107 
1108 void Simulator::VisitLoadStorePairNonTemporal(const Instruction* instr) {
1109   LoadStorePairHelper(instr, Offset);
1110 }
1111 
1112 
1113 void Simulator::LoadStorePairHelper(const Instruction* instr,
1114                                     AddrMode addrmode) {
1115   unsigned rt = instr->Rt();
1116   unsigned rt2 = instr->Rt2();
1117   int element_size = 1 << instr->SizeLSPair();
1118   int64_t offset = instr->ImmLSPair() * element_size;
1119   uintptr_t address = AddressModeHelper(instr->Rn(), offset, addrmode);
1120   uintptr_t address2 = address + element_size;
1121 
1122   LoadStorePairOp op =
1123     static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask));
1124 
1125   // 'rt' and 'rt2' can only be aliased for stores.
1126   VIXL_ASSERT(((op & LoadStorePairLBit) == 0) || (rt != rt2));
1127 
1128   switch (op) {
1129     // Use NoRegLog to suppress the register trace (LOG_REGS, LOG_FP_REGS). We
1130     // will print a more detailed log.
1131     case LDP_w: {
1132       set_wreg(rt, Memory::Read<uint32_t>(address), NoRegLog);
1133       set_wreg(rt2, Memory::Read<uint32_t>(address2), NoRegLog);
1134       break;
1135     }
1136     case LDP_s: {
1137       set_sreg(rt, Memory::Read<float>(address), NoRegLog);
1138       set_sreg(rt2, Memory::Read<float>(address2), NoRegLog);
1139       break;
1140     }
1141     case LDP_x: {
1142       set_xreg(rt, Memory::Read<uint64_t>(address), NoRegLog);
1143       set_xreg(rt2, Memory::Read<uint64_t>(address2), NoRegLog);
1144       break;
1145     }
1146     case LDP_d: {
1147       set_dreg(rt, Memory::Read<double>(address), NoRegLog);
1148       set_dreg(rt2, Memory::Read<double>(address2), NoRegLog);
1149       break;
1150     }
1151     case LDP_q: {
1152       set_qreg(rt, Memory::Read<qreg_t>(address), NoRegLog);
1153       set_qreg(rt2, Memory::Read<qreg_t>(address2), NoRegLog);
1154       break;
1155     }
1156     case LDPSW_x: {
1157       set_xreg(rt, Memory::Read<int32_t>(address), NoRegLog);
1158       set_xreg(rt2, Memory::Read<int32_t>(address2), NoRegLog);
1159       break;
1160     }
1161     case STP_w: {
1162       Memory::Write<uint32_t>(address, wreg(rt));
1163       Memory::Write<uint32_t>(address2, wreg(rt2));
1164       break;
1165     }
1166     case STP_s: {
1167       Memory::Write<float>(address, sreg(rt));
1168       Memory::Write<float>(address2, sreg(rt2));
1169       break;
1170     }
1171     case STP_x: {
1172       Memory::Write<uint64_t>(address, xreg(rt));
1173       Memory::Write<uint64_t>(address2, xreg(rt2));
1174       break;
1175     }
1176     case STP_d: {
1177       Memory::Write<double>(address, dreg(rt));
1178       Memory::Write<double>(address2, dreg(rt2));
1179       break;
1180     }
1181     case STP_q: {
1182       Memory::Write<qreg_t>(address, qreg(rt));
1183       Memory::Write<qreg_t>(address2, qreg(rt2));
1184       break;
1185     }
1186     default: VIXL_UNREACHABLE();
1187   }
1188 
1189   // Print a detailed trace (including the memory address) instead of the basic
1190   // register:value trace generated by set_*reg().
1191   if (instr->IsLoad()) {
1192     if ((op == LDP_s) || (op == LDP_d)) {
1193       LogVRead(address, rt, GetPrintRegisterFormatForSizeFP(element_size));
1194       LogVRead(address2, rt2, GetPrintRegisterFormatForSizeFP(element_size));
1195     } else if (op == LDP_q) {
1196       LogVRead(address, rt, GetPrintRegisterFormatForSize(element_size));
1197       LogVRead(address2, rt2, GetPrintRegisterFormatForSize(element_size));
1198     } else {
1199       LogRead(address, rt, GetPrintRegisterFormatForSize(element_size));
1200       LogRead(address2, rt2, GetPrintRegisterFormatForSize(element_size));
1201     }
1202   } else {
1203     if ((op == STP_s) || (op == STP_d)) {
1204       LogVWrite(address, rt, GetPrintRegisterFormatForSizeFP(element_size));
1205       LogVWrite(address2, rt2, GetPrintRegisterFormatForSizeFP(element_size));
1206     } else if (op == STP_q) {
1207       LogVWrite(address, rt, GetPrintRegisterFormatForSize(element_size));
1208       LogVWrite(address2, rt2, GetPrintRegisterFormatForSize(element_size));
1209     } else {
1210       LogWrite(address, rt, GetPrintRegisterFormatForSize(element_size));
1211       LogWrite(address2, rt2, GetPrintRegisterFormatForSize(element_size));
1212     }
1213   }
1214 
1215   local_monitor_.MaybeClear();
1216 }
1217 
1218 
1219 void Simulator::PrintExclusiveAccessWarning() {
1220   if (print_exclusive_access_warning_) {
1221     fprintf(
1222         stderr,
1223         "%sWARNING:%s VIXL simulator support for load-/store-/clear-exclusive "
1224         "instructions is limited. Refer to the README for details.%s\n",
1225         clr_warning, clr_warning_message, clr_normal);
1226     print_exclusive_access_warning_ = false;
1227   }
1228 }
1229 
1230 
1231 void Simulator::VisitLoadStoreExclusive(const Instruction* instr) {
1232   PrintExclusiveAccessWarning();
1233 
1234   unsigned rs = instr->Rs();
1235   unsigned rt = instr->Rt();
1236   unsigned rt2 = instr->Rt2();
1237   unsigned rn = instr->Rn();
1238 
1239   LoadStoreExclusive op =
1240       static_cast<LoadStoreExclusive>(instr->Mask(LoadStoreExclusiveMask));
1241 
1242   bool is_acquire_release = instr->LdStXAcquireRelease();
1243   bool is_exclusive = !instr->LdStXNotExclusive();
1244   bool is_load = instr->LdStXLoad();
1245   bool is_pair = instr->LdStXPair();
1246 
1247   unsigned element_size = 1 << instr->LdStXSizeLog2();
1248   unsigned access_size = is_pair ? element_size * 2 : element_size;
1249   uint64_t address = reg<uint64_t>(rn, Reg31IsStackPointer);
1250 
1251   // Verify that the address is available to the host.
1252   VIXL_ASSERT(address == static_cast<uintptr_t>(address));
1253 
1254   // Check the alignment of `address`.
1255   if (AlignDown(address, access_size) != address) {
1256     VIXL_ALIGNMENT_EXCEPTION();
1257   }
1258 
1259   // The sp must be aligned to 16 bytes when it is accessed.
1260   if ((rn == 31) && (AlignDown(address, 16) != address)) {
1261     VIXL_ALIGNMENT_EXCEPTION();
1262   }
1263 
1264   if (is_load) {
1265     if (is_exclusive) {
1266       local_monitor_.MarkExclusive(address, access_size);
1267     } else {
1268       // Any non-exclusive load can clear the local monitor as a side effect. We
1269       // don't need to do this, but it is useful to stress the simulated code.
1270       local_monitor_.Clear();
1271     }
1272 
1273     // Use NoRegLog to suppress the register trace (LOG_REGS, LOG_FP_REGS). We
1274     // will print a more detailed log.
1275     switch (op) {
1276       case LDXRB_w:
1277       case LDAXRB_w:
1278       case LDARB_w:
1279         set_wreg(rt, Memory::Read<uint8_t>(address), NoRegLog);
1280         break;
1281       case LDXRH_w:
1282       case LDAXRH_w:
1283       case LDARH_w:
1284         set_wreg(rt, Memory::Read<uint16_t>(address), NoRegLog);
1285         break;
1286       case LDXR_w:
1287       case LDAXR_w:
1288       case LDAR_w:
1289         set_wreg(rt, Memory::Read<uint32_t>(address), NoRegLog);
1290         break;
1291       case LDXR_x:
1292       case LDAXR_x:
1293       case LDAR_x:
1294         set_xreg(rt, Memory::Read<uint64_t>(address), NoRegLog);
1295         break;
1296       case LDXP_w:
1297       case LDAXP_w:
1298         set_wreg(rt, Memory::Read<uint32_t>(address), NoRegLog);
1299         set_wreg(rt2, Memory::Read<uint32_t>(address + element_size), NoRegLog);
1300         break;
1301       case LDXP_x:
1302       case LDAXP_x:
1303         set_xreg(rt, Memory::Read<uint64_t>(address), NoRegLog);
1304         set_xreg(rt2, Memory::Read<uint64_t>(address + element_size), NoRegLog);
1305         break;
1306       default:
1307         VIXL_UNREACHABLE();
1308     }
1309 
1310     if (is_acquire_release) {
1311       // Approximate load-acquire by issuing a full barrier after the load.
1312       __sync_synchronize();
1313     }
1314 
1315     LogRead(address, rt, GetPrintRegisterFormatForSize(element_size));
1316     if (is_pair) {
1317       LogRead(address + element_size, rt2,
1318               GetPrintRegisterFormatForSize(element_size));
1319     }
1320   } else {
1321     if (is_acquire_release) {
1322       // Approximate store-release by issuing a full barrier before the store.
1323       __sync_synchronize();
1324     }
1325 
1326     bool do_store = true;
1327     if (is_exclusive) {
1328       do_store = local_monitor_.IsExclusive(address, access_size) &&
1329                  global_monitor_.IsExclusive(address, access_size);
1330       set_wreg(rs, do_store ? 0 : 1);
1331 
1332       //  - All exclusive stores explicitly clear the local monitor.
1333       local_monitor_.Clear();
1334     } else {
1335       //  - Any other store can clear the local monitor as a side effect.
1336       local_monitor_.MaybeClear();
1337     }
1338 
1339     if (do_store) {
1340       switch (op) {
1341         case STXRB_w:
1342         case STLXRB_w:
1343         case STLRB_w:
1344           Memory::Write<uint8_t>(address, wreg(rt));
1345           break;
1346         case STXRH_w:
1347         case STLXRH_w:
1348         case STLRH_w:
1349           Memory::Write<uint16_t>(address, wreg(rt));
1350           break;
1351         case STXR_w:
1352         case STLXR_w:
1353         case STLR_w:
1354           Memory::Write<uint32_t>(address, wreg(rt));
1355           break;
1356         case STXR_x:
1357         case STLXR_x:
1358         case STLR_x:
1359           Memory::Write<uint64_t>(address, xreg(rt));
1360           break;
1361         case STXP_w:
1362         case STLXP_w:
1363           Memory::Write<uint32_t>(address, wreg(rt));
1364           Memory::Write<uint32_t>(address + element_size, wreg(rt2));
1365           break;
1366         case STXP_x:
1367         case STLXP_x:
1368           Memory::Write<uint64_t>(address, xreg(rt));
1369           Memory::Write<uint64_t>(address + element_size, xreg(rt2));
1370           break;
1371         default:
1372           VIXL_UNREACHABLE();
1373       }
1374 
1375       LogWrite(address, rt, GetPrintRegisterFormatForSize(element_size));
1376       if (is_pair) {
1377         LogWrite(address + element_size, rt2,
1378                  GetPrintRegisterFormatForSize(element_size));
1379       }
1380     }
1381   }
1382 }
1383 
1384 
1385 void Simulator::VisitLoadLiteral(const Instruction* instr) {
1386   unsigned rt = instr->Rt();
1387   uint64_t address = instr->LiteralAddress<uint64_t>();
1388 
1389   // Verify that the calculated address is available to the host.
1390   VIXL_ASSERT(address == static_cast<uintptr_t>(address));
1391 
1392   switch (instr->Mask(LoadLiteralMask)) {
1393     // Use NoRegLog to suppress the register trace (LOG_REGS, LOG_VREGS), then
1394     // print a more detailed log.
1395     case LDR_w_lit:
1396       set_wreg(rt, Memory::Read<uint32_t>(address), NoRegLog);
1397       LogRead(address, rt, kPrintWReg);
1398       break;
1399     case LDR_x_lit:
1400       set_xreg(rt, Memory::Read<uint64_t>(address), NoRegLog);
1401       LogRead(address, rt, kPrintXReg);
1402       break;
1403     case LDR_s_lit:
1404       set_sreg(rt, Memory::Read<float>(address), NoRegLog);
1405       LogVRead(address, rt, kPrintSReg);
1406       break;
1407     case LDR_d_lit:
1408       set_dreg(rt, Memory::Read<double>(address), NoRegLog);
1409       LogVRead(address, rt, kPrintDReg);
1410       break;
1411     case LDR_q_lit:
1412       set_qreg(rt, Memory::Read<qreg_t>(address), NoRegLog);
1413       LogVRead(address, rt, kPrintReg1Q);
1414       break;
1415     case LDRSW_x_lit:
1416       set_xreg(rt, Memory::Read<int32_t>(address), NoRegLog);
1417       LogRead(address, rt, kPrintWReg);
1418       break;
1419 
1420     // Ignore prfm hint instructions.
1421     case PRFM_lit: break;
1422 
1423     default: VIXL_UNREACHABLE();
1424   }
1425 
1426   local_monitor_.MaybeClear();
1427 }
1428 
1429 
1430 uintptr_t Simulator::AddressModeHelper(unsigned addr_reg,
1431                                        int64_t offset,
1432                                        AddrMode addrmode) {
1433   uint64_t address = xreg(addr_reg, Reg31IsStackPointer);
1434 
1435   if ((addr_reg == 31) && ((address % 16) != 0)) {
1436     // When the base register is SP the stack pointer is required to be
1437     // quadword aligned prior to the address calculation and write-backs.
1438     // Misalignment will cause a stack alignment fault.
1439     VIXL_ALIGNMENT_EXCEPTION();
1440   }
1441 
1442   if ((addrmode == PreIndex) || (addrmode == PostIndex)) {
1443     VIXL_ASSERT(offset != 0);
1444     // Only preindex should log the register update here. For Postindex, the
1445     // update will be printed automatically by LogWrittenRegisters _after_ the
1446     // memory access itself is logged.
1447     RegLogMode log_mode = (addrmode == PreIndex) ? LogRegWrites : NoRegLog;
1448     set_xreg(addr_reg, address + offset, log_mode, Reg31IsStackPointer);
1449   }
1450 
1451   if ((addrmode == Offset) || (addrmode == PreIndex)) {
1452     address += offset;
1453   }
1454 
1455   // Verify that the calculated address is available to the host.
1456   VIXL_ASSERT(address == static_cast<uintptr_t>(address));
1457 
1458   return static_cast<uintptr_t>(address);
1459 }
1460 
1461 
1462 void Simulator::VisitMoveWideImmediate(const Instruction* instr) {
1463   MoveWideImmediateOp mov_op =
1464     static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask));
1465   int64_t new_xn_val = 0;
1466 
1467   bool is_64_bits = instr->SixtyFourBits() == 1;
1468   // Shift is limited for W operations.
1469   VIXL_ASSERT(is_64_bits || (instr->ShiftMoveWide() < 2));
1470 
1471   // Get the shifted immediate.
1472   int64_t shift = instr->ShiftMoveWide() * 16;
1473   int64_t shifted_imm16 = static_cast<int64_t>(instr->ImmMoveWide()) << shift;
1474 
1475   // Compute the new value.
1476   switch (mov_op) {
1477     case MOVN_w:
1478     case MOVN_x: {
1479         new_xn_val = ~shifted_imm16;
1480         if (!is_64_bits) new_xn_val &= kWRegMask;
1481       break;
1482     }
1483     case MOVK_w:
1484     case MOVK_x: {
1485         unsigned reg_code = instr->Rd();
1486         int64_t prev_xn_val = is_64_bits ? xreg(reg_code)
1487                                          : wreg(reg_code);
1488         new_xn_val =
1489             (prev_xn_val & ~(INT64_C(0xffff) << shift)) | shifted_imm16;
1490       break;
1491     }
1492     case MOVZ_w:
1493     case MOVZ_x: {
1494         new_xn_val = shifted_imm16;
1495       break;
1496     }
1497     default:
1498       VIXL_UNREACHABLE();
1499   }
1500 
1501   // Update the destination register.
1502   set_xreg(instr->Rd(), new_xn_val);
1503 }
1504 
1505 
1506 void Simulator::VisitConditionalSelect(const Instruction* instr) {
1507   uint64_t new_val = xreg(instr->Rn());
1508 
1509   if (ConditionFailed(static_cast<Condition>(instr->Condition()))) {
1510     new_val = xreg(instr->Rm());
1511     switch (instr->Mask(ConditionalSelectMask)) {
1512       case CSEL_w:
1513       case CSEL_x: break;
1514       case CSINC_w:
1515       case CSINC_x: new_val++; break;
1516       case CSINV_w:
1517       case CSINV_x: new_val = ~new_val; break;
1518       case CSNEG_w:
1519       case CSNEG_x: new_val = -new_val; break;
1520       default: VIXL_UNIMPLEMENTED();
1521     }
1522   }
1523   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
1524   set_reg(reg_size, instr->Rd(), new_val);
1525 }
1526 
1527 
1528 void Simulator::VisitDataProcessing1Source(const Instruction* instr) {
1529   unsigned dst = instr->Rd();
1530   unsigned src = instr->Rn();
1531 
1532   switch (instr->Mask(DataProcessing1SourceMask)) {
1533     case RBIT_w: set_wreg(dst, ReverseBits(wreg(src))); break;
1534     case RBIT_x: set_xreg(dst, ReverseBits(xreg(src))); break;
1535     case REV16_w: set_wreg(dst, ReverseBytes(wreg(src), 1)); break;
1536     case REV16_x: set_xreg(dst, ReverseBytes(xreg(src), 1)); break;
1537     case REV_w: set_wreg(dst, ReverseBytes(wreg(src), 2)); break;
1538     case REV32_x: set_xreg(dst, ReverseBytes(xreg(src), 2)); break;
1539     case REV_x: set_xreg(dst, ReverseBytes(xreg(src), 3)); break;
1540     case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src))); break;
1541     case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src))); break;
1542     case CLS_w: {
1543       set_wreg(dst, CountLeadingSignBits(wreg(src)));
1544       break;
1545     }
1546     case CLS_x: {
1547       set_xreg(dst, CountLeadingSignBits(xreg(src)));
1548       break;
1549     }
1550     default: VIXL_UNIMPLEMENTED();
1551   }
1552 }
1553 
1554 
1555 uint32_t Simulator::Poly32Mod2(unsigned n, uint64_t data, uint32_t poly) {
1556   VIXL_ASSERT((n > 32) && (n <= 64));
1557   for (unsigned i = (n - 1); i >= 32; i--) {
1558     if (((data >> i) & 1) != 0) {
1559       uint64_t polysh32 = (uint64_t)poly << (i - 32);
1560       uint64_t mask = (UINT64_C(1) << i) - 1;
1561       data = ((data & mask) ^ polysh32);
1562     }
1563   }
1564   return data & 0xffffffff;
1565 }
1566 
1567 
1568 template <typename T>
1569 uint32_t Simulator::Crc32Checksum(uint32_t acc, T val, uint32_t poly) {
1570   unsigned size = sizeof(val) * 8;  // Number of bits in type T.
1571   VIXL_ASSERT((size == 8) || (size == 16) || (size == 32));
1572   uint64_t tempacc = static_cast<uint64_t>(ReverseBits(acc)) << size;
1573   uint64_t tempval = static_cast<uint64_t>(ReverseBits(val)) << 32;
1574   return ReverseBits(Poly32Mod2(32 + size, tempacc ^ tempval, poly));
1575 }
1576 
1577 
1578 uint32_t Simulator::Crc32Checksum(uint32_t acc, uint64_t val, uint32_t poly) {
1579   // Poly32Mod2 cannot handle inputs with more than 32 bits, so compute
1580   // the CRC of each 32-bit word sequentially.
1581   acc = Crc32Checksum(acc, (uint32_t)(val & 0xffffffff), poly);
1582   return Crc32Checksum(acc, (uint32_t)(val >> 32), poly);
1583 }
1584 
1585 
1586 void Simulator::VisitDataProcessing2Source(const Instruction* instr) {
1587   Shift shift_op = NO_SHIFT;
1588   int64_t result = 0;
1589   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
1590 
1591   switch (instr->Mask(DataProcessing2SourceMask)) {
1592     case SDIV_w: {
1593       int32_t rn = wreg(instr->Rn());
1594       int32_t rm = wreg(instr->Rm());
1595       if ((rn == kWMinInt) && (rm == -1)) {
1596         result = kWMinInt;
1597       } else if (rm == 0) {
1598         // Division by zero can be trapped, but not on A-class processors.
1599         result = 0;
1600       } else {
1601         result = rn / rm;
1602       }
1603       break;
1604     }
1605     case SDIV_x: {
1606       int64_t rn = xreg(instr->Rn());
1607       int64_t rm = xreg(instr->Rm());
1608       if ((rn == kXMinInt) && (rm == -1)) {
1609         result = kXMinInt;
1610       } else if (rm == 0) {
1611         // Division by zero can be trapped, but not on A-class processors.
1612         result = 0;
1613       } else {
1614         result = rn / rm;
1615       }
1616       break;
1617     }
1618     case UDIV_w: {
1619       uint32_t rn = static_cast<uint32_t>(wreg(instr->Rn()));
1620       uint32_t rm = static_cast<uint32_t>(wreg(instr->Rm()));
1621       if (rm == 0) {
1622         // Division by zero can be trapped, but not on A-class processors.
1623         result = 0;
1624       } else {
1625         result = rn / rm;
1626       }
1627       break;
1628     }
1629     case UDIV_x: {
1630       uint64_t rn = static_cast<uint64_t>(xreg(instr->Rn()));
1631       uint64_t rm = static_cast<uint64_t>(xreg(instr->Rm()));
1632       if (rm == 0) {
1633         // Division by zero can be trapped, but not on A-class processors.
1634         result = 0;
1635       } else {
1636         result = rn / rm;
1637       }
1638       break;
1639     }
1640     case LSLV_w:
1641     case LSLV_x: shift_op = LSL; break;
1642     case LSRV_w:
1643     case LSRV_x: shift_op = LSR; break;
1644     case ASRV_w:
1645     case ASRV_x: shift_op = ASR; break;
1646     case RORV_w:
1647     case RORV_x: shift_op = ROR; break;
1648     case CRC32B: {
1649       uint32_t acc = reg<uint32_t>(instr->Rn());
1650       uint8_t  val = reg<uint8_t>(instr->Rm());
1651       result = Crc32Checksum(acc, val, CRC32_POLY);
1652       break;
1653     }
1654     case CRC32H: {
1655       uint32_t acc = reg<uint32_t>(instr->Rn());
1656       uint16_t val = reg<uint16_t>(instr->Rm());
1657       result = Crc32Checksum(acc, val, CRC32_POLY);
1658       break;
1659     }
1660     case CRC32W: {
1661       uint32_t acc = reg<uint32_t>(instr->Rn());
1662       uint32_t val = reg<uint32_t>(instr->Rm());
1663       result = Crc32Checksum(acc, val, CRC32_POLY);
1664       break;
1665     }
1666     case CRC32X: {
1667       uint32_t acc = reg<uint32_t>(instr->Rn());
1668       uint64_t val = reg<uint64_t>(instr->Rm());
1669       result = Crc32Checksum(acc, val, CRC32_POLY);
1670       reg_size = kWRegSize;
1671       break;
1672     }
1673     case CRC32CB: {
1674       uint32_t acc = reg<uint32_t>(instr->Rn());
1675       uint8_t  val = reg<uint8_t>(instr->Rm());
1676       result = Crc32Checksum(acc, val, CRC32C_POLY);
1677       break;
1678     }
1679     case CRC32CH: {
1680       uint32_t acc = reg<uint32_t>(instr->Rn());
1681       uint16_t val = reg<uint16_t>(instr->Rm());
1682       result = Crc32Checksum(acc, val, CRC32C_POLY);
1683       break;
1684     }
1685     case CRC32CW: {
1686       uint32_t acc = reg<uint32_t>(instr->Rn());
1687       uint32_t val = reg<uint32_t>(instr->Rm());
1688       result = Crc32Checksum(acc, val, CRC32C_POLY);
1689       break;
1690     }
1691     case CRC32CX: {
1692       uint32_t acc = reg<uint32_t>(instr->Rn());
1693       uint64_t val = reg<uint64_t>(instr->Rm());
1694       result = Crc32Checksum(acc, val, CRC32C_POLY);
1695       reg_size = kWRegSize;
1696       break;
1697     }
1698     default: VIXL_UNIMPLEMENTED();
1699   }
1700 
1701   if (shift_op != NO_SHIFT) {
1702     // Shift distance encoded in the least-significant five/six bits of the
1703     // register.
1704     int mask = (instr->SixtyFourBits() == 1) ? 0x3f : 0x1f;
1705     unsigned shift = wreg(instr->Rm()) & mask;
1706     result = ShiftOperand(reg_size, reg(reg_size, instr->Rn()), shift_op,
1707                           shift);
1708   }
1709   set_reg(reg_size, instr->Rd(), result);
1710 }
1711 
1712 
1713 // The algorithm used is adapted from the one described in section 8.2 of
1714 //   Hacker's Delight, by Henry S. Warren, Jr.
1715 // It assumes that a right shift on a signed integer is an arithmetic shift.
1716 // Type T must be either uint64_t or int64_t.
1717 template <typename T>
1718 static T MultiplyHigh(T u, T v) {
1719   uint64_t u0, v0, w0;
1720   T u1, v1, w1, w2, t;
1721 
1722   VIXL_ASSERT(sizeof(u) == sizeof(u0));
1723 
1724   u0 = u & 0xffffffff;
1725   u1 = u >> 32;
1726   v0 = v & 0xffffffff;
1727   v1 = v >> 32;
1728 
1729   w0 = u0 * v0;
1730   t = u1 * v0 + (w0 >> 32);
1731   w1 = t & 0xffffffff;
1732   w2 = t >> 32;
1733   w1 = u0 * v1 + w1;
1734 
1735   return u1 * v1 + w2 + (w1 >> 32);
1736 }
1737 
1738 
1739 void Simulator::VisitDataProcessing3Source(const Instruction* instr) {
1740   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
1741 
1742   int64_t result = 0;
1743   // Extract and sign- or zero-extend 32-bit arguments for widening operations.
1744   uint64_t rn_u32 = reg<uint32_t>(instr->Rn());
1745   uint64_t rm_u32 = reg<uint32_t>(instr->Rm());
1746   int64_t rn_s32 = reg<int32_t>(instr->Rn());
1747   int64_t rm_s32 = reg<int32_t>(instr->Rm());
1748   switch (instr->Mask(DataProcessing3SourceMask)) {
1749     case MADD_w:
1750     case MADD_x:
1751       result = xreg(instr->Ra()) + (xreg(instr->Rn()) * xreg(instr->Rm()));
1752       break;
1753     case MSUB_w:
1754     case MSUB_x:
1755       result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm()));
1756       break;
1757     case SMADDL_x: result = xreg(instr->Ra()) + (rn_s32 * rm_s32); break;
1758     case SMSUBL_x: result = xreg(instr->Ra()) - (rn_s32 * rm_s32); break;
1759     case UMADDL_x: result = xreg(instr->Ra()) + (rn_u32 * rm_u32); break;
1760     case UMSUBL_x: result = xreg(instr->Ra()) - (rn_u32 * rm_u32); break;
1761     case UMULH_x:
1762       result = MultiplyHigh(reg<uint64_t>(instr->Rn()),
1763                             reg<uint64_t>(instr->Rm()));
1764       break;
1765     case SMULH_x:
1766       result = MultiplyHigh(xreg(instr->Rn()), xreg(instr->Rm()));
1767       break;
1768     default: VIXL_UNIMPLEMENTED();
1769   }
1770   set_reg(reg_size, instr->Rd(), result);
1771 }
1772 
1773 
1774 void Simulator::VisitBitfield(const Instruction* instr) {
1775   unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize;
1776   int64_t reg_mask = instr->SixtyFourBits() ? kXRegMask : kWRegMask;
1777   int64_t R = instr->ImmR();
1778   int64_t S = instr->ImmS();
1779   int64_t diff = S - R;
1780   int64_t mask;
1781   if (diff >= 0) {
1782     mask = (diff < (reg_size - 1)) ? (INT64_C(1) << (diff + 1)) - 1
1783                                    : reg_mask;
1784   } else {
1785     mask = (INT64_C(1) << (S + 1)) - 1;
1786     mask = (static_cast<uint64_t>(mask) >> R) | (mask << (reg_size - R));
1787     diff += reg_size;
1788   }
1789 
1790   // inzero indicates if the extracted bitfield is inserted into the
1791   // destination register value or in zero.
1792   // If extend is true, extend the sign of the extracted bitfield.
1793   bool inzero = false;
1794   bool extend = false;
1795   switch (instr->Mask(BitfieldMask)) {
1796     case BFM_x:
1797     case BFM_w:
1798       break;
1799     case SBFM_x:
1800     case SBFM_w:
1801       inzero = true;
1802       extend = true;
1803       break;
1804     case UBFM_x:
1805     case UBFM_w:
1806       inzero = true;
1807       break;
1808     default:
1809       VIXL_UNIMPLEMENTED();
1810   }
1811 
1812   int64_t dst = inzero ? 0 : reg(reg_size, instr->Rd());
1813   int64_t src = reg(reg_size, instr->Rn());
1814   // Rotate source bitfield into place.
1815   int64_t result = (static_cast<uint64_t>(src) >> R) | (src << (reg_size - R));
1816   // Determine the sign extension.
1817   int64_t topbits = ((INT64_C(1) << (reg_size - diff - 1)) - 1) << (diff + 1);
1818   int64_t signbits = extend && ((src >> S) & 1) ? topbits : 0;
1819 
1820   // Merge sign extension, dest/zero and bitfield.
1821   result = signbits | (result & mask) | (dst & ~mask);
1822 
1823   set_reg(reg_size, instr->Rd(), result);
1824 }
1825 
1826 
1827 void Simulator::VisitExtract(const Instruction* instr) {
1828   unsigned lsb = instr->ImmS();
1829   unsigned reg_size = (instr->SixtyFourBits() == 1) ? kXRegSize
1830                                                     : kWRegSize;
1831   uint64_t low_res = static_cast<uint64_t>(reg(reg_size, instr->Rm())) >> lsb;
1832   uint64_t high_res =
1833       (lsb == 0) ? 0 : reg(reg_size, instr->Rn()) << (reg_size - lsb);
1834   set_reg(reg_size, instr->Rd(), low_res | high_res);
1835 }
1836 
1837 
1838 void Simulator::VisitFPImmediate(const Instruction* instr) {
1839   AssertSupportedFPCR();
1840 
1841   unsigned dest = instr->Rd();
1842   switch (instr->Mask(FPImmediateMask)) {
1843     case FMOV_s_imm: set_sreg(dest, instr->ImmFP32()); break;
1844     case FMOV_d_imm: set_dreg(dest, instr->ImmFP64()); break;
1845     default: VIXL_UNREACHABLE();
1846   }
1847 }
1848 
1849 
1850 void Simulator::VisitFPIntegerConvert(const Instruction* instr) {
1851   AssertSupportedFPCR();
1852 
1853   unsigned dst = instr->Rd();
1854   unsigned src = instr->Rn();
1855 
1856   FPRounding round = RMode();
1857 
1858   switch (instr->Mask(FPIntegerConvertMask)) {
1859     case FCVTAS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieAway)); break;
1860     case FCVTAS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieAway)); break;
1861     case FCVTAS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieAway)); break;
1862     case FCVTAS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieAway)); break;
1863     case FCVTAU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieAway)); break;
1864     case FCVTAU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieAway)); break;
1865     case FCVTAU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieAway)); break;
1866     case FCVTAU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieAway)); break;
1867     case FCVTMS_ws:
1868       set_wreg(dst, FPToInt32(sreg(src), FPNegativeInfinity));
1869       break;
1870     case FCVTMS_xs:
1871       set_xreg(dst, FPToInt64(sreg(src), FPNegativeInfinity));
1872       break;
1873     case FCVTMS_wd:
1874       set_wreg(dst, FPToInt32(dreg(src), FPNegativeInfinity));
1875       break;
1876     case FCVTMS_xd:
1877       set_xreg(dst, FPToInt64(dreg(src), FPNegativeInfinity));
1878       break;
1879     case FCVTMU_ws:
1880       set_wreg(dst, FPToUInt32(sreg(src), FPNegativeInfinity));
1881       break;
1882     case FCVTMU_xs:
1883       set_xreg(dst, FPToUInt64(sreg(src), FPNegativeInfinity));
1884       break;
1885     case FCVTMU_wd:
1886       set_wreg(dst, FPToUInt32(dreg(src), FPNegativeInfinity));
1887       break;
1888     case FCVTMU_xd:
1889       set_xreg(dst, FPToUInt64(dreg(src), FPNegativeInfinity));
1890       break;
1891     case FCVTPS_ws:
1892       set_wreg(dst, FPToInt32(sreg(src), FPPositiveInfinity));
1893       break;
1894     case FCVTPS_xs:
1895       set_xreg(dst, FPToInt64(sreg(src), FPPositiveInfinity));
1896       break;
1897     case FCVTPS_wd:
1898       set_wreg(dst, FPToInt32(dreg(src), FPPositiveInfinity));
1899       break;
1900     case FCVTPS_xd:
1901       set_xreg(dst, FPToInt64(dreg(src), FPPositiveInfinity));
1902       break;
1903     case FCVTPU_ws:
1904       set_wreg(dst, FPToUInt32(sreg(src), FPPositiveInfinity));
1905       break;
1906     case FCVTPU_xs:
1907       set_xreg(dst, FPToUInt64(sreg(src), FPPositiveInfinity));
1908       break;
1909     case FCVTPU_wd:
1910       set_wreg(dst, FPToUInt32(dreg(src), FPPositiveInfinity));
1911       break;
1912     case FCVTPU_xd:
1913       set_xreg(dst, FPToUInt64(dreg(src), FPPositiveInfinity));
1914       break;
1915     case FCVTNS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieEven)); break;
1916     case FCVTNS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieEven)); break;
1917     case FCVTNS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieEven)); break;
1918     case FCVTNS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieEven)); break;
1919     case FCVTNU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieEven)); break;
1920     case FCVTNU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieEven)); break;
1921     case FCVTNU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieEven)); break;
1922     case FCVTNU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieEven)); break;
1923     case FCVTZS_ws: set_wreg(dst, FPToInt32(sreg(src), FPZero)); break;
1924     case FCVTZS_xs: set_xreg(dst, FPToInt64(sreg(src), FPZero)); break;
1925     case FCVTZS_wd: set_wreg(dst, FPToInt32(dreg(src), FPZero)); break;
1926     case FCVTZS_xd: set_xreg(dst, FPToInt64(dreg(src), FPZero)); break;
1927     case FCVTZU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPZero)); break;
1928     case FCVTZU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPZero)); break;
1929     case FCVTZU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPZero)); break;
1930     case FCVTZU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPZero)); break;
1931     case FMOV_ws: set_wreg(dst, sreg_bits(src)); break;
1932     case FMOV_xd: set_xreg(dst, dreg_bits(src)); break;
1933     case FMOV_sw: set_sreg_bits(dst, wreg(src)); break;
1934     case FMOV_dx: set_dreg_bits(dst, xreg(src)); break;
1935     case FMOV_d1_x:
1936       LogicVRegister(vreg(dst)).SetUint(kFormatD, 1, xreg(src));
1937       break;
1938     case FMOV_x_d1:
1939       set_xreg(dst, LogicVRegister(vreg(src)).Uint(kFormatD, 1));
1940       break;
1941 
1942     // A 32-bit input can be handled in the same way as a 64-bit input, since
1943     // the sign- or zero-extension will not affect the conversion.
1944     case SCVTF_dx: set_dreg(dst, FixedToDouble(xreg(src), 0, round)); break;
1945     case SCVTF_dw: set_dreg(dst, FixedToDouble(wreg(src), 0, round)); break;
1946     case UCVTF_dx: set_dreg(dst, UFixedToDouble(xreg(src), 0, round)); break;
1947     case UCVTF_dw: {
1948       set_dreg(dst, UFixedToDouble(static_cast<uint32_t>(wreg(src)), 0, round));
1949       break;
1950     }
1951     case SCVTF_sx: set_sreg(dst, FixedToFloat(xreg(src), 0, round)); break;
1952     case SCVTF_sw: set_sreg(dst, FixedToFloat(wreg(src), 0, round)); break;
1953     case UCVTF_sx: set_sreg(dst, UFixedToFloat(xreg(src), 0, round)); break;
1954     case UCVTF_sw: {
1955       set_sreg(dst, UFixedToFloat(static_cast<uint32_t>(wreg(src)), 0, round));
1956       break;
1957     }
1958 
1959     default: VIXL_UNREACHABLE();
1960   }
1961 }
1962 
1963 
1964 void Simulator::VisitFPFixedPointConvert(const Instruction* instr) {
1965   AssertSupportedFPCR();
1966 
1967   unsigned dst = instr->Rd();
1968   unsigned src = instr->Rn();
1969   int fbits = 64 - instr->FPScale();
1970 
1971   FPRounding round = RMode();
1972 
1973   switch (instr->Mask(FPFixedPointConvertMask)) {
1974     // A 32-bit input can be handled in the same way as a 64-bit input, since
1975     // the sign- or zero-extension will not affect the conversion.
1976     case SCVTF_dx_fixed:
1977       set_dreg(dst, FixedToDouble(xreg(src), fbits, round));
1978       break;
1979     case SCVTF_dw_fixed:
1980       set_dreg(dst, FixedToDouble(wreg(src), fbits, round));
1981       break;
1982     case UCVTF_dx_fixed:
1983       set_dreg(dst, UFixedToDouble(xreg(src), fbits, round));
1984       break;
1985     case UCVTF_dw_fixed: {
1986       set_dreg(dst,
1987                UFixedToDouble(static_cast<uint32_t>(wreg(src)), fbits, round));
1988       break;
1989     }
1990     case SCVTF_sx_fixed:
1991       set_sreg(dst, FixedToFloat(xreg(src), fbits, round));
1992       break;
1993     case SCVTF_sw_fixed:
1994       set_sreg(dst, FixedToFloat(wreg(src), fbits, round));
1995       break;
1996     case UCVTF_sx_fixed:
1997       set_sreg(dst, UFixedToFloat(xreg(src), fbits, round));
1998       break;
1999     case UCVTF_sw_fixed: {
2000       set_sreg(dst,
2001                UFixedToFloat(static_cast<uint32_t>(wreg(src)), fbits, round));
2002       break;
2003     }
2004     case FCVTZS_xd_fixed:
2005       set_xreg(dst, FPToInt64(dreg(src) * std::pow(2.0, fbits), FPZero));
2006       break;
2007     case FCVTZS_wd_fixed:
2008       set_wreg(dst, FPToInt32(dreg(src) * std::pow(2.0, fbits), FPZero));
2009       break;
2010     case FCVTZU_xd_fixed:
2011       set_xreg(dst, FPToUInt64(dreg(src) * std::pow(2.0, fbits), FPZero));
2012       break;
2013     case FCVTZU_wd_fixed:
2014       set_wreg(dst, FPToUInt32(dreg(src) * std::pow(2.0, fbits), FPZero));
2015       break;
2016     case FCVTZS_xs_fixed:
2017       set_xreg(dst, FPToInt64(sreg(src) * std::pow(2.0f, fbits), FPZero));
2018       break;
2019     case FCVTZS_ws_fixed:
2020       set_wreg(dst, FPToInt32(sreg(src) * std::pow(2.0f, fbits), FPZero));
2021       break;
2022     case FCVTZU_xs_fixed:
2023       set_xreg(dst, FPToUInt64(sreg(src) * std::pow(2.0f, fbits), FPZero));
2024       break;
2025     case FCVTZU_ws_fixed:
2026       set_wreg(dst, FPToUInt32(sreg(src) * std::pow(2.0f, fbits), FPZero));
2027       break;
2028     default: VIXL_UNREACHABLE();
2029   }
2030 }
2031 
2032 
2033 void Simulator::VisitFPCompare(const Instruction* instr) {
2034   AssertSupportedFPCR();
2035 
2036   FPTrapFlags trap = DisableTrap;
2037   switch (instr->Mask(FPCompareMask)) {
2038     case FCMPE_s: trap = EnableTrap; VIXL_FALLTHROUGH();
2039     case FCMP_s: FPCompare(sreg(instr->Rn()), sreg(instr->Rm()), trap); break;
2040     case FCMPE_d: trap = EnableTrap; VIXL_FALLTHROUGH();
2041     case FCMP_d: FPCompare(dreg(instr->Rn()), dreg(instr->Rm()), trap); break;
2042     case FCMPE_s_zero: trap = EnableTrap; VIXL_FALLTHROUGH();
2043     case FCMP_s_zero: FPCompare(sreg(instr->Rn()), 0.0f, trap); break;
2044     case FCMPE_d_zero: trap = EnableTrap; VIXL_FALLTHROUGH();
2045     case FCMP_d_zero: FPCompare(dreg(instr->Rn()), 0.0, trap); break;
2046     default: VIXL_UNIMPLEMENTED();
2047   }
2048 }
2049 
2050 
2051 void Simulator::VisitFPConditionalCompare(const Instruction* instr) {
2052   AssertSupportedFPCR();
2053 
2054   FPTrapFlags trap = DisableTrap;
2055   switch (instr->Mask(FPConditionalCompareMask)) {
2056     case FCCMPE_s: trap = EnableTrap;
2057       VIXL_FALLTHROUGH();
2058     case FCCMP_s:
2059       if (ConditionPassed(instr->Condition())) {
2060         FPCompare(sreg(instr->Rn()), sreg(instr->Rm()), trap);
2061       } else {
2062         nzcv().SetFlags(instr->Nzcv());
2063         LogSystemRegister(NZCV);
2064       }
2065       break;
2066     case FCCMPE_d: trap = EnableTrap;
2067       VIXL_FALLTHROUGH();
2068     case FCCMP_d:
2069       if (ConditionPassed(instr->Condition())) {
2070         FPCompare(dreg(instr->Rn()), dreg(instr->Rm()), trap);
2071       } else {
2072         nzcv().SetFlags(instr->Nzcv());
2073         LogSystemRegister(NZCV);
2074       }
2075       break;
2076     default: VIXL_UNIMPLEMENTED();
2077   }
2078 }
2079 
2080 
2081 void Simulator::VisitFPConditionalSelect(const Instruction* instr) {
2082   AssertSupportedFPCR();
2083 
2084   Instr selected;
2085   if (ConditionPassed(instr->Condition())) {
2086     selected = instr->Rn();
2087   } else {
2088     selected = instr->Rm();
2089   }
2090 
2091   switch (instr->Mask(FPConditionalSelectMask)) {
2092     case FCSEL_s: set_sreg(instr->Rd(), sreg(selected)); break;
2093     case FCSEL_d: set_dreg(instr->Rd(), dreg(selected)); break;
2094     default: VIXL_UNIMPLEMENTED();
2095   }
2096 }
2097 
2098 
2099 void Simulator::VisitFPDataProcessing1Source(const Instruction* instr) {
2100   AssertSupportedFPCR();
2101 
2102   FPRounding fpcr_rounding = static_cast<FPRounding>(fpcr().RMode());
2103   VectorFormat vform = (instr->Mask(FP64) == FP64) ? kFormatD : kFormatS;
2104   SimVRegister& rd = vreg(instr->Rd());
2105   SimVRegister& rn = vreg(instr->Rn());
2106   bool inexact_exception = false;
2107 
2108   unsigned fd = instr->Rd();
2109   unsigned fn = instr->Rn();
2110 
2111   switch (instr->Mask(FPDataProcessing1SourceMask)) {
2112     case FMOV_s: set_sreg(fd, sreg(fn)); return;
2113     case FMOV_d: set_dreg(fd, dreg(fn)); return;
2114     case FABS_s: fabs_(kFormatS, vreg(fd), vreg(fn)); return;
2115     case FABS_d: fabs_(kFormatD, vreg(fd), vreg(fn)); return;
2116     case FNEG_s: fneg(kFormatS, vreg(fd), vreg(fn)); return;
2117     case FNEG_d: fneg(kFormatD, vreg(fd), vreg(fn)); return;
2118     case FCVT_ds: set_dreg(fd, FPToDouble(sreg(fn))); return;
2119     case FCVT_sd: set_sreg(fd, FPToFloat(dreg(fn), FPTieEven)); return;
2120     case FCVT_hs: set_hreg(fd, FPToFloat16(sreg(fn), FPTieEven)); return;
2121     case FCVT_sh: set_sreg(fd, FPToFloat(hreg(fn))); return;
2122     case FCVT_dh: set_dreg(fd, FPToDouble(FPToFloat(hreg(fn)))); return;
2123     case FCVT_hd: set_hreg(fd, FPToFloat16(dreg(fn), FPTieEven)); return;
2124     case FSQRT_s:
2125     case FSQRT_d: fsqrt(vform, rd, rn); return;
2126     case FRINTI_s:
2127     case FRINTI_d: break;  // Use FPCR rounding mode.
2128     case FRINTX_s:
2129     case FRINTX_d: inexact_exception = true; break;
2130     case FRINTA_s:
2131     case FRINTA_d: fpcr_rounding = FPTieAway; break;
2132     case FRINTM_s:
2133     case FRINTM_d: fpcr_rounding = FPNegativeInfinity; break;
2134     case FRINTN_s:
2135     case FRINTN_d: fpcr_rounding = FPTieEven; break;
2136     case FRINTP_s:
2137     case FRINTP_d: fpcr_rounding = FPPositiveInfinity; break;
2138     case FRINTZ_s:
2139     case FRINTZ_d: fpcr_rounding = FPZero; break;
2140     default: VIXL_UNIMPLEMENTED();
2141   }
2142 
2143   // Only FRINT* instructions fall through the switch above.
2144   frint(vform, rd, rn, fpcr_rounding, inexact_exception);
2145 }
2146 
2147 
2148 void Simulator::VisitFPDataProcessing2Source(const Instruction* instr) {
2149   AssertSupportedFPCR();
2150 
2151   VectorFormat vform = (instr->Mask(FP64) == FP64) ? kFormatD : kFormatS;
2152   SimVRegister& rd = vreg(instr->Rd());
2153   SimVRegister& rn = vreg(instr->Rn());
2154   SimVRegister& rm = vreg(instr->Rm());
2155 
2156   switch (instr->Mask(FPDataProcessing2SourceMask)) {
2157     case FADD_s:
2158     case FADD_d: fadd(vform, rd, rn, rm); break;
2159     case FSUB_s:
2160     case FSUB_d: fsub(vform, rd, rn, rm); break;
2161     case FMUL_s:
2162     case FMUL_d: fmul(vform, rd, rn, rm); break;
2163     case FNMUL_s:
2164     case FNMUL_d: fnmul(vform, rd, rn, rm); break;
2165     case FDIV_s:
2166     case FDIV_d: fdiv(vform, rd, rn, rm); break;
2167     case FMAX_s:
2168     case FMAX_d: fmax(vform, rd, rn, rm); break;
2169     case FMIN_s:
2170     case FMIN_d: fmin(vform, rd, rn, rm); break;
2171     case FMAXNM_s:
2172     case FMAXNM_d: fmaxnm(vform, rd, rn, rm); break;
2173     case FMINNM_s:
2174     case FMINNM_d: fminnm(vform, rd, rn, rm); break;
2175     default:
2176       VIXL_UNREACHABLE();
2177   }
2178 }
2179 
2180 
2181 void Simulator::VisitFPDataProcessing3Source(const Instruction* instr) {
2182   AssertSupportedFPCR();
2183 
2184   unsigned fd = instr->Rd();
2185   unsigned fn = instr->Rn();
2186   unsigned fm = instr->Rm();
2187   unsigned fa = instr->Ra();
2188 
2189   switch (instr->Mask(FPDataProcessing3SourceMask)) {
2190     // fd = fa +/- (fn * fm)
2191     case FMADD_s: set_sreg(fd, FPMulAdd(sreg(fa), sreg(fn), sreg(fm))); break;
2192     case FMSUB_s: set_sreg(fd, FPMulAdd(sreg(fa), -sreg(fn), sreg(fm))); break;
2193     case FMADD_d: set_dreg(fd, FPMulAdd(dreg(fa), dreg(fn), dreg(fm))); break;
2194     case FMSUB_d: set_dreg(fd, FPMulAdd(dreg(fa), -dreg(fn), dreg(fm))); break;
2195     // Negated variants of the above.
2196     case FNMADD_s:
2197       set_sreg(fd, FPMulAdd(-sreg(fa), -sreg(fn), sreg(fm)));
2198       break;
2199     case FNMSUB_s:
2200       set_sreg(fd, FPMulAdd(-sreg(fa), sreg(fn), sreg(fm)));
2201       break;
2202     case FNMADD_d:
2203       set_dreg(fd, FPMulAdd(-dreg(fa), -dreg(fn), dreg(fm)));
2204       break;
2205     case FNMSUB_d:
2206       set_dreg(fd, FPMulAdd(-dreg(fa), dreg(fn), dreg(fm)));
2207       break;
2208     default: VIXL_UNIMPLEMENTED();
2209   }
2210 }
2211 
2212 
2213 bool Simulator::FPProcessNaNs(const Instruction* instr) {
2214   unsigned fd = instr->Rd();
2215   unsigned fn = instr->Rn();
2216   unsigned fm = instr->Rm();
2217   bool done = false;
2218 
2219   if (instr->Mask(FP64) == FP64) {
2220     double result = FPProcessNaNs(dreg(fn), dreg(fm));
2221     if (std::isnan(result)) {
2222       set_dreg(fd, result);
2223       done = true;
2224     }
2225   } else {
2226     float result = FPProcessNaNs(sreg(fn), sreg(fm));
2227     if (std::isnan(result)) {
2228       set_sreg(fd, result);
2229       done = true;
2230     }
2231   }
2232 
2233   return done;
2234 }
2235 
2236 
2237 void Simulator::SysOp_W(int op, int64_t val) {
2238   switch (op) {
2239     case IVAU:
2240     case CVAC:
2241     case CVAU:
2242     case CIVAC: {
2243       // Perform a dummy memory access to ensure that we have read access
2244       // to the specified address.
2245       volatile uint8_t y = Memory::Read<uint8_t>(val);
2246       USE(y);
2247       // TODO: Implement "case ZVA:".
2248       break;
2249     }
2250     default:
2251       VIXL_UNIMPLEMENTED();
2252   }
2253 }
2254 
2255 
2256 void Simulator::VisitSystem(const Instruction* instr) {
2257   // Some system instructions hijack their Op and Cp fields to represent a
2258   // range of immediates instead of indicating a different instruction. This
2259   // makes the decoding tricky.
2260   if (instr->Mask(SystemExclusiveMonitorFMask) == SystemExclusiveMonitorFixed) {
2261     VIXL_ASSERT(instr->Mask(SystemExclusiveMonitorMask) == CLREX);
2262     switch (instr->Mask(SystemExclusiveMonitorMask)) {
2263       case CLREX: {
2264         PrintExclusiveAccessWarning();
2265         ClearLocalMonitor();
2266         break;
2267       }
2268     }
2269   } else if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) {
2270     switch (instr->Mask(SystemSysRegMask)) {
2271       case MRS: {
2272         switch (instr->ImmSystemRegister()) {
2273           case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break;
2274           case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break;
2275           default: VIXL_UNIMPLEMENTED();
2276         }
2277         break;
2278       }
2279       case MSR: {
2280         switch (instr->ImmSystemRegister()) {
2281           case NZCV:
2282             nzcv().SetRawValue(wreg(instr->Rt()));
2283             LogSystemRegister(NZCV);
2284             break;
2285           case FPCR:
2286             fpcr().SetRawValue(wreg(instr->Rt()));
2287             LogSystemRegister(FPCR);
2288             break;
2289           default: VIXL_UNIMPLEMENTED();
2290         }
2291         break;
2292       }
2293     }
2294   } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
2295     VIXL_ASSERT(instr->Mask(SystemHintMask) == HINT);
2296     switch (instr->ImmHint()) {
2297       case NOP: break;
2298       default: VIXL_UNIMPLEMENTED();
2299     }
2300   } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) {
2301     __sync_synchronize();
2302   } else if ((instr->Mask(SystemSysFMask) == SystemSysFixed)) {
2303     switch (instr->Mask(SystemSysMask)) {
2304       case SYS: SysOp_W(instr->SysOp(), xreg(instr->Rt())); break;
2305       default: VIXL_UNIMPLEMENTED();
2306     }
2307   } else {
2308     VIXL_UNIMPLEMENTED();
2309   }
2310 }
2311 
2312 
2313 void Simulator::VisitCrypto2RegSHA(const Instruction* instr) {
2314   VisitUnimplemented(instr);
2315 }
2316 
2317 
2318 void Simulator::VisitCrypto3RegSHA(const Instruction* instr) {
2319   VisitUnimplemented(instr);
2320 }
2321 
2322 
2323 void Simulator::VisitCryptoAES(const Instruction* instr) {
2324   VisitUnimplemented(instr);
2325 }
2326 
2327 
2328 void Simulator::VisitNEON2RegMisc(const Instruction* instr) {
2329   NEONFormatDecoder nfd(instr);
2330   VectorFormat vf = nfd.GetVectorFormat();
2331 
2332   static const NEONFormatMap map_lp = {
2333     {23, 22, 30}, {NF_4H, NF_8H, NF_2S, NF_4S, NF_1D, NF_2D}
2334   };
2335   VectorFormat vf_lp = nfd.GetVectorFormat(&map_lp);
2336 
2337   static const NEONFormatMap map_fcvtl = {
2338     {22}, {NF_4S, NF_2D}
2339   };
2340   VectorFormat vf_fcvtl = nfd.GetVectorFormat(&map_fcvtl);
2341 
2342   static const NEONFormatMap map_fcvtn = {
2343     {22, 30}, {NF_4H, NF_8H, NF_2S, NF_4S}
2344   };
2345   VectorFormat vf_fcvtn = nfd.GetVectorFormat(&map_fcvtn);
2346 
2347   SimVRegister& rd = vreg(instr->Rd());
2348   SimVRegister& rn = vreg(instr->Rn());
2349 
2350   if (instr->Mask(NEON2RegMiscOpcode) <= NEON_NEG_opcode) {
2351     // These instructions all use a two bit size field, except NOT and RBIT,
2352     // which use the field to encode the operation.
2353     switch (instr->Mask(NEON2RegMiscMask)) {
2354       case NEON_REV64:     rev64(vf, rd, rn); break;
2355       case NEON_REV32:     rev32(vf, rd, rn); break;
2356       case NEON_REV16:     rev16(vf, rd, rn); break;
2357       case NEON_SUQADD:    suqadd(vf, rd, rn); break;
2358       case NEON_USQADD:    usqadd(vf, rd, rn); break;
2359       case NEON_CLS:       cls(vf, rd, rn); break;
2360       case NEON_CLZ:       clz(vf, rd, rn); break;
2361       case NEON_CNT:       cnt(vf, rd, rn); break;
2362       case NEON_SQABS:     abs(vf, rd, rn).SignedSaturate(vf); break;
2363       case NEON_SQNEG:     neg(vf, rd, rn).SignedSaturate(vf); break;
2364       case NEON_CMGT_zero: cmp(vf, rd, rn, 0, gt); break;
2365       case NEON_CMGE_zero: cmp(vf, rd, rn, 0, ge); break;
2366       case NEON_CMEQ_zero: cmp(vf, rd, rn, 0, eq); break;
2367       case NEON_CMLE_zero: cmp(vf, rd, rn, 0, le); break;
2368       case NEON_CMLT_zero: cmp(vf, rd, rn, 0, lt); break;
2369       case NEON_ABS:       abs(vf, rd, rn); break;
2370       case NEON_NEG:       neg(vf, rd, rn); break;
2371       case NEON_SADDLP:    saddlp(vf_lp, rd, rn); break;
2372       case NEON_UADDLP:    uaddlp(vf_lp, rd, rn); break;
2373       case NEON_SADALP:    sadalp(vf_lp, rd, rn); break;
2374       case NEON_UADALP:    uadalp(vf_lp, rd, rn); break;
2375       case NEON_RBIT_NOT:
2376         vf = nfd.GetVectorFormat(nfd.LogicalFormatMap());
2377         switch (instr->FPType()) {
2378           case 0: not_(vf, rd, rn); break;
2379           case 1: rbit(vf, rd, rn);; break;
2380           default:
2381             VIXL_UNIMPLEMENTED();
2382         }
2383         break;
2384     }
2385   } else {
2386     VectorFormat fpf = nfd.GetVectorFormat(nfd.FPFormatMap());
2387     FPRounding fpcr_rounding = static_cast<FPRounding>(fpcr().RMode());
2388     bool inexact_exception = false;
2389 
2390     // These instructions all use a one bit size field, except XTN, SQXTUN,
2391     // SHLL, SQXTN and UQXTN, which use a two bit size field.
2392     switch (instr->Mask(NEON2RegMiscFPMask)) {
2393       case NEON_FABS:   fabs_(fpf, rd, rn); return;
2394       case NEON_FNEG:   fneg(fpf, rd, rn); return;
2395       case NEON_FSQRT:  fsqrt(fpf, rd, rn); return;
2396       case NEON_FCVTL:
2397         if (instr->Mask(NEON_Q)) {
2398           fcvtl2(vf_fcvtl, rd, rn);
2399         } else {
2400           fcvtl(vf_fcvtl, rd, rn);
2401         }
2402         return;
2403       case NEON_FCVTN:
2404         if (instr->Mask(NEON_Q)) {
2405           fcvtn2(vf_fcvtn, rd, rn);
2406         } else {
2407           fcvtn(vf_fcvtn, rd, rn);
2408         }
2409         return;
2410       case NEON_FCVTXN:
2411         if (instr->Mask(NEON_Q)) {
2412           fcvtxn2(vf_fcvtn, rd, rn);
2413         } else {
2414           fcvtxn(vf_fcvtn, rd, rn);
2415         }
2416         return;
2417 
2418       // The following instructions break from the switch statement, rather
2419       // than return.
2420       case NEON_FRINTI:     break;  // Use FPCR rounding mode.
2421       case NEON_FRINTX:     inexact_exception = true; break;
2422       case NEON_FRINTA:     fpcr_rounding = FPTieAway; break;
2423       case NEON_FRINTM:     fpcr_rounding = FPNegativeInfinity; break;
2424       case NEON_FRINTN:     fpcr_rounding = FPTieEven; break;
2425       case NEON_FRINTP:     fpcr_rounding = FPPositiveInfinity; break;
2426       case NEON_FRINTZ:     fpcr_rounding = FPZero; break;
2427 
2428       case NEON_FCVTNS:     fcvts(fpf, rd, rn, FPTieEven); return;
2429       case NEON_FCVTNU:     fcvtu(fpf, rd, rn, FPTieEven); return;
2430       case NEON_FCVTPS:     fcvts(fpf, rd, rn, FPPositiveInfinity); return;
2431       case NEON_FCVTPU:     fcvtu(fpf, rd, rn, FPPositiveInfinity); return;
2432       case NEON_FCVTMS:     fcvts(fpf, rd, rn, FPNegativeInfinity); return;
2433       case NEON_FCVTMU:     fcvtu(fpf, rd, rn, FPNegativeInfinity); return;
2434       case NEON_FCVTZS:     fcvts(fpf, rd, rn, FPZero); return;
2435       case NEON_FCVTZU:     fcvtu(fpf, rd, rn, FPZero); return;
2436       case NEON_FCVTAS:     fcvts(fpf, rd, rn, FPTieAway); return;
2437       case NEON_FCVTAU:     fcvtu(fpf, rd, rn, FPTieAway); return;
2438       case NEON_SCVTF:      scvtf(fpf, rd, rn, 0, fpcr_rounding); return;
2439       case NEON_UCVTF:      ucvtf(fpf, rd, rn, 0, fpcr_rounding); return;
2440       case NEON_URSQRTE:    ursqrte(fpf, rd, rn); return;
2441       case NEON_URECPE:     urecpe(fpf, rd, rn); return;
2442       case NEON_FRSQRTE:    frsqrte(fpf, rd, rn); return;
2443       case NEON_FRECPE:     frecpe(fpf, rd, rn, fpcr_rounding); return;
2444       case NEON_FCMGT_zero: fcmp_zero(fpf, rd, rn, gt); return;
2445       case NEON_FCMGE_zero: fcmp_zero(fpf, rd, rn, ge); return;
2446       case NEON_FCMEQ_zero: fcmp_zero(fpf, rd, rn, eq); return;
2447       case NEON_FCMLE_zero: fcmp_zero(fpf, rd, rn, le); return;
2448       case NEON_FCMLT_zero: fcmp_zero(fpf, rd, rn, lt); return;
2449       default:
2450         if ((NEON_XTN_opcode <= instr->Mask(NEON2RegMiscOpcode)) &&
2451             (instr->Mask(NEON2RegMiscOpcode) <= NEON_UQXTN_opcode)) {
2452           switch (instr->Mask(NEON2RegMiscMask)) {
2453             case NEON_XTN: xtn(vf, rd, rn); return;
2454             case NEON_SQXTN: sqxtn(vf, rd, rn); return;
2455             case NEON_UQXTN: uqxtn(vf, rd, rn); return;
2456             case NEON_SQXTUN: sqxtun(vf, rd, rn); return;
2457             case NEON_SHLL:
2458               vf = nfd.GetVectorFormat(nfd.LongIntegerFormatMap());
2459               if (instr->Mask(NEON_Q)) {
2460                 shll2(vf, rd, rn);
2461               } else {
2462                 shll(vf, rd, rn);
2463               }
2464               return;
2465             default:
2466               VIXL_UNIMPLEMENTED();
2467           }
2468         } else {
2469           VIXL_UNIMPLEMENTED();
2470         }
2471     }
2472 
2473     // Only FRINT* instructions fall through the switch above.
2474     frint(fpf, rd, rn, fpcr_rounding, inexact_exception);
2475   }
2476 }
2477 
2478 
2479 void Simulator::VisitNEON3Same(const Instruction* instr) {
2480   NEONFormatDecoder nfd(instr);
2481   SimVRegister& rd = vreg(instr->Rd());
2482   SimVRegister& rn = vreg(instr->Rn());
2483   SimVRegister& rm = vreg(instr->Rm());
2484 
2485   if (instr->Mask(NEON3SameLogicalFMask) == NEON3SameLogicalFixed) {
2486     VectorFormat vf = nfd.GetVectorFormat(nfd.LogicalFormatMap());
2487     switch (instr->Mask(NEON3SameLogicalMask)) {
2488       case NEON_AND: and_(vf, rd, rn, rm); break;
2489       case NEON_ORR: orr(vf, rd, rn, rm); break;
2490       case NEON_ORN: orn(vf, rd, rn, rm); break;
2491       case NEON_EOR: eor(vf, rd, rn, rm); break;
2492       case NEON_BIC: bic(vf, rd, rn, rm); break;
2493       case NEON_BIF: bif(vf, rd, rn, rm); break;
2494       case NEON_BIT: bit(vf, rd, rn, rm); break;
2495       case NEON_BSL: bsl(vf, rd, rn, rm); break;
2496       default:
2497         VIXL_UNIMPLEMENTED();
2498     }
2499   } else if (instr->Mask(NEON3SameFPFMask) == NEON3SameFPFixed) {
2500     VectorFormat vf = nfd.GetVectorFormat(nfd.FPFormatMap());
2501     switch (instr->Mask(NEON3SameFPMask)) {
2502       case NEON_FADD:    fadd(vf, rd, rn, rm); break;
2503       case NEON_FSUB:    fsub(vf, rd, rn, rm); break;
2504       case NEON_FMUL:    fmul(vf, rd, rn, rm); break;
2505       case NEON_FDIV:    fdiv(vf, rd, rn, rm); break;
2506       case NEON_FMAX:    fmax(vf, rd, rn, rm); break;
2507       case NEON_FMIN:    fmin(vf, rd, rn, rm); break;
2508       case NEON_FMAXNM:  fmaxnm(vf, rd, rn, rm); break;
2509       case NEON_FMINNM:  fminnm(vf, rd, rn, rm); break;
2510       case NEON_FMLA:    fmla(vf, rd, rn, rm); break;
2511       case NEON_FMLS:    fmls(vf, rd, rn, rm); break;
2512       case NEON_FMULX:   fmulx(vf, rd, rn, rm); break;
2513       case NEON_FACGE:   fabscmp(vf, rd, rn, rm, ge); break;
2514       case NEON_FACGT:   fabscmp(vf, rd, rn, rm, gt); break;
2515       case NEON_FCMEQ:   fcmp(vf, rd, rn, rm, eq); break;
2516       case NEON_FCMGE:   fcmp(vf, rd, rn, rm, ge); break;
2517       case NEON_FCMGT:   fcmp(vf, rd, rn, rm, gt); break;
2518       case NEON_FRECPS:  frecps(vf, rd, rn, rm); break;
2519       case NEON_FRSQRTS: frsqrts(vf, rd, rn, rm); break;
2520       case NEON_FABD:    fabd(vf, rd, rn, rm); break;
2521       case NEON_FADDP:   faddp(vf, rd, rn, rm); break;
2522       case NEON_FMAXP:   fmaxp(vf, rd, rn, rm); break;
2523       case NEON_FMAXNMP: fmaxnmp(vf, rd, rn, rm); break;
2524       case NEON_FMINP:   fminp(vf, rd, rn, rm); break;
2525       case NEON_FMINNMP: fminnmp(vf, rd, rn, rm); break;
2526       default:
2527         VIXL_UNIMPLEMENTED();
2528     }
2529   } else {
2530     VectorFormat vf = nfd.GetVectorFormat();
2531     switch (instr->Mask(NEON3SameMask)) {
2532       case NEON_ADD:   add(vf, rd, rn, rm);  break;
2533       case NEON_ADDP:  addp(vf, rd, rn, rm); break;
2534       case NEON_CMEQ:  cmp(vf, rd, rn, rm, eq); break;
2535       case NEON_CMGE:  cmp(vf, rd, rn, rm, ge); break;
2536       case NEON_CMGT:  cmp(vf, rd, rn, rm, gt); break;
2537       case NEON_CMHI:  cmp(vf, rd, rn, rm, hi); break;
2538       case NEON_CMHS:  cmp(vf, rd, rn, rm, hs); break;
2539       case NEON_CMTST: cmptst(vf, rd, rn, rm); break;
2540       case NEON_MLS:   mls(vf, rd, rn, rm); break;
2541       case NEON_MLA:   mla(vf, rd, rn, rm); break;
2542       case NEON_MUL:   mul(vf, rd, rn, rm); break;
2543       case NEON_PMUL:  pmul(vf, rd, rn, rm); break;
2544       case NEON_SMAX:  smax(vf, rd, rn, rm); break;
2545       case NEON_SMAXP: smaxp(vf, rd, rn, rm); break;
2546       case NEON_SMIN:  smin(vf, rd, rn, rm); break;
2547       case NEON_SMINP: sminp(vf, rd, rn, rm); break;
2548       case NEON_SUB:   sub(vf, rd, rn, rm);  break;
2549       case NEON_UMAX:  umax(vf, rd, rn, rm); break;
2550       case NEON_UMAXP: umaxp(vf, rd, rn, rm); break;
2551       case NEON_UMIN:  umin(vf, rd, rn, rm); break;
2552       case NEON_UMINP: uminp(vf, rd, rn, rm); break;
2553       case NEON_SSHL:  sshl(vf, rd, rn, rm); break;
2554       case NEON_USHL:  ushl(vf, rd, rn, rm); break;
2555       case NEON_SABD:  absdiff(vf, rd, rn, rm, true); break;
2556       case NEON_UABD:  absdiff(vf, rd, rn, rm, false); break;
2557       case NEON_SABA:  saba(vf, rd, rn, rm); break;
2558       case NEON_UABA:  uaba(vf, rd, rn, rm); break;
2559       case NEON_UQADD: add(vf, rd, rn, rm).UnsignedSaturate(vf); break;
2560       case NEON_SQADD: add(vf, rd, rn, rm).SignedSaturate(vf); break;
2561       case NEON_UQSUB: sub(vf, rd, rn, rm).UnsignedSaturate(vf); break;
2562       case NEON_SQSUB: sub(vf, rd, rn, rm).SignedSaturate(vf); break;
2563       case NEON_SQDMULH:  sqdmulh(vf, rd, rn, rm); break;
2564       case NEON_SQRDMULH: sqrdmulh(vf, rd, rn, rm); break;
2565       case NEON_UQSHL: ushl(vf, rd, rn, rm).UnsignedSaturate(vf); break;
2566       case NEON_SQSHL: sshl(vf, rd, rn, rm).SignedSaturate(vf); break;
2567       case NEON_URSHL: ushl(vf, rd, rn, rm).Round(vf); break;
2568       case NEON_SRSHL: sshl(vf, rd, rn, rm).Round(vf); break;
2569       case NEON_UQRSHL:
2570         ushl(vf, rd, rn, rm).Round(vf).UnsignedSaturate(vf);
2571         break;
2572       case NEON_SQRSHL:
2573         sshl(vf, rd, rn, rm).Round(vf).SignedSaturate(vf);
2574         break;
2575       case NEON_UHADD:
2576         add(vf, rd, rn, rm).Uhalve(vf);
2577         break;
2578       case NEON_URHADD:
2579         add(vf, rd, rn, rm).Uhalve(vf).Round(vf);
2580         break;
2581       case NEON_SHADD:
2582         add(vf, rd, rn, rm).Halve(vf);
2583         break;
2584       case NEON_SRHADD:
2585         add(vf, rd, rn, rm).Halve(vf).Round(vf);
2586         break;
2587       case NEON_UHSUB:
2588         sub(vf, rd, rn, rm).Uhalve(vf);
2589         break;
2590       case NEON_SHSUB:
2591         sub(vf, rd, rn, rm).Halve(vf);
2592         break;
2593       default:
2594         VIXL_UNIMPLEMENTED();
2595     }
2596   }
2597 }
2598 
2599 
2600 void Simulator::VisitNEON3Different(const Instruction* instr) {
2601   NEONFormatDecoder nfd(instr);
2602   VectorFormat vf = nfd.GetVectorFormat();
2603   VectorFormat vf_l = nfd.GetVectorFormat(nfd.LongIntegerFormatMap());
2604 
2605   SimVRegister& rd = vreg(instr->Rd());
2606   SimVRegister& rn = vreg(instr->Rn());
2607   SimVRegister& rm = vreg(instr->Rm());
2608 
2609   switch (instr->Mask(NEON3DifferentMask)) {
2610     case NEON_PMULL:    pmull(vf_l, rd, rn, rm); break;
2611     case NEON_PMULL2:   pmull2(vf_l, rd, rn, rm); break;
2612     case NEON_UADDL:    uaddl(vf_l, rd, rn, rm); break;
2613     case NEON_UADDL2:   uaddl2(vf_l, rd, rn, rm); break;
2614     case NEON_SADDL:    saddl(vf_l, rd, rn, rm); break;
2615     case NEON_SADDL2:   saddl2(vf_l, rd, rn, rm); break;
2616     case NEON_USUBL:    usubl(vf_l, rd, rn, rm); break;
2617     case NEON_USUBL2:   usubl2(vf_l, rd, rn, rm); break;
2618     case NEON_SSUBL:    ssubl(vf_l, rd, rn, rm); break;
2619     case NEON_SSUBL2:   ssubl2(vf_l, rd, rn, rm); break;
2620     case NEON_SABAL:    sabal(vf_l, rd, rn, rm); break;
2621     case NEON_SABAL2:   sabal2(vf_l, rd, rn, rm); break;
2622     case NEON_UABAL:    uabal(vf_l, rd, rn, rm); break;
2623     case NEON_UABAL2:   uabal2(vf_l, rd, rn, rm); break;
2624     case NEON_SABDL:    sabdl(vf_l, rd, rn, rm); break;
2625     case NEON_SABDL2:   sabdl2(vf_l, rd, rn, rm); break;
2626     case NEON_UABDL:    uabdl(vf_l, rd, rn, rm); break;
2627     case NEON_UABDL2:   uabdl2(vf_l, rd, rn, rm); break;
2628     case NEON_SMLAL:    smlal(vf_l, rd, rn, rm); break;
2629     case NEON_SMLAL2:   smlal2(vf_l, rd, rn, rm); break;
2630     case NEON_UMLAL:    umlal(vf_l, rd, rn, rm); break;
2631     case NEON_UMLAL2:   umlal2(vf_l, rd, rn, rm); break;
2632     case NEON_SMLSL:    smlsl(vf_l, rd, rn, rm); break;
2633     case NEON_SMLSL2:   smlsl2(vf_l, rd, rn, rm); break;
2634     case NEON_UMLSL:    umlsl(vf_l, rd, rn, rm); break;
2635     case NEON_UMLSL2:   umlsl2(vf_l, rd, rn, rm); break;
2636     case NEON_SMULL:    smull(vf_l, rd, rn, rm); break;
2637     case NEON_SMULL2:   smull2(vf_l, rd, rn, rm); break;
2638     case NEON_UMULL:    umull(vf_l, rd, rn, rm); break;
2639     case NEON_UMULL2:   umull2(vf_l, rd, rn, rm); break;
2640     case NEON_SQDMLAL:  sqdmlal(vf_l, rd, rn, rm); break;
2641     case NEON_SQDMLAL2: sqdmlal2(vf_l, rd, rn, rm); break;
2642     case NEON_SQDMLSL:  sqdmlsl(vf_l, rd, rn, rm); break;
2643     case NEON_SQDMLSL2: sqdmlsl2(vf_l, rd, rn, rm); break;
2644     case NEON_SQDMULL:  sqdmull(vf_l, rd, rn, rm); break;
2645     case NEON_SQDMULL2: sqdmull2(vf_l, rd, rn, rm); break;
2646     case NEON_UADDW:    uaddw(vf_l, rd, rn, rm); break;
2647     case NEON_UADDW2:   uaddw2(vf_l, rd, rn, rm); break;
2648     case NEON_SADDW:    saddw(vf_l, rd, rn, rm); break;
2649     case NEON_SADDW2:   saddw2(vf_l, rd, rn, rm); break;
2650     case NEON_USUBW:    usubw(vf_l, rd, rn, rm); break;
2651     case NEON_USUBW2:   usubw2(vf_l, rd, rn, rm); break;
2652     case NEON_SSUBW:    ssubw(vf_l, rd, rn, rm); break;
2653     case NEON_SSUBW2:   ssubw2(vf_l, rd, rn, rm); break;
2654     case NEON_ADDHN:    addhn(vf, rd, rn, rm); break;
2655     case NEON_ADDHN2:   addhn2(vf, rd, rn, rm); break;
2656     case NEON_RADDHN:   raddhn(vf, rd, rn, rm); break;
2657     case NEON_RADDHN2:  raddhn2(vf, rd, rn, rm); break;
2658     case NEON_SUBHN:    subhn(vf, rd, rn, rm); break;
2659     case NEON_SUBHN2:   subhn2(vf, rd, rn, rm); break;
2660     case NEON_RSUBHN:   rsubhn(vf, rd, rn, rm); break;
2661     case NEON_RSUBHN2:  rsubhn2(vf, rd, rn, rm); break;
2662     default:
2663       VIXL_UNIMPLEMENTED();
2664   }
2665 }
2666 
2667 
2668 void Simulator::VisitNEONAcrossLanes(const Instruction* instr) {
2669   NEONFormatDecoder nfd(instr);
2670 
2671   SimVRegister& rd = vreg(instr->Rd());
2672   SimVRegister& rn = vreg(instr->Rn());
2673 
2674   // The input operand's VectorFormat is passed for these instructions.
2675   if (instr->Mask(NEONAcrossLanesFPFMask) == NEONAcrossLanesFPFixed) {
2676     VectorFormat vf = nfd.GetVectorFormat(nfd.FPFormatMap());
2677 
2678     switch (instr->Mask(NEONAcrossLanesFPMask)) {
2679       case NEON_FMAXV: fmaxv(vf, rd, rn); break;
2680       case NEON_FMINV: fminv(vf, rd, rn); break;
2681       case NEON_FMAXNMV: fmaxnmv(vf, rd, rn); break;
2682       case NEON_FMINNMV: fminnmv(vf, rd, rn); break;
2683       default:
2684         VIXL_UNIMPLEMENTED();
2685     }
2686   } else {
2687     VectorFormat vf = nfd.GetVectorFormat();
2688 
2689     switch (instr->Mask(NEONAcrossLanesMask)) {
2690       case NEON_ADDV:   addv(vf, rd, rn); break;
2691       case NEON_SMAXV:  smaxv(vf, rd, rn); break;
2692       case NEON_SMINV:  sminv(vf, rd, rn); break;
2693       case NEON_UMAXV:  umaxv(vf, rd, rn); break;
2694       case NEON_UMINV:  uminv(vf, rd, rn); break;
2695       case NEON_SADDLV: saddlv(vf, rd, rn); break;
2696       case NEON_UADDLV: uaddlv(vf, rd, rn); break;
2697       default:
2698         VIXL_UNIMPLEMENTED();
2699     }
2700   }
2701 }
2702 
2703 
2704 void Simulator::VisitNEONByIndexedElement(const Instruction* instr) {
2705   NEONFormatDecoder nfd(instr);
2706   VectorFormat vf_r = nfd.GetVectorFormat();
2707   VectorFormat vf = nfd.GetVectorFormat(nfd.LongIntegerFormatMap());
2708 
2709   SimVRegister& rd = vreg(instr->Rd());
2710   SimVRegister& rn = vreg(instr->Rn());
2711 
2712   ByElementOp Op = NULL;
2713 
2714   int rm_reg = instr->Rm();
2715   int index = (instr->NEONH() << 1) | instr->NEONL();
2716   if (instr->NEONSize() == 1) {
2717     rm_reg &= 0xf;
2718     index = (index << 1) | instr->NEONM();
2719   }
2720 
2721   switch (instr->Mask(NEONByIndexedElementMask)) {
2722     case NEON_MUL_byelement: Op = &Simulator::mul; vf = vf_r; break;
2723     case NEON_MLA_byelement: Op = &Simulator::mla; vf = vf_r; break;
2724     case NEON_MLS_byelement: Op = &Simulator::mls; vf = vf_r; break;
2725     case NEON_SQDMULH_byelement: Op = &Simulator::sqdmulh; vf = vf_r; break;
2726     case NEON_SQRDMULH_byelement: Op = &Simulator::sqrdmulh; vf = vf_r; break;
2727     case NEON_SMULL_byelement:
2728       if (instr->Mask(NEON_Q)) {
2729         Op = &Simulator::smull2;
2730       } else {
2731         Op = &Simulator::smull;
2732       }
2733       break;
2734     case NEON_UMULL_byelement:
2735       if (instr->Mask(NEON_Q)) {
2736         Op = &Simulator::umull2;
2737       } else {
2738         Op = &Simulator::umull;
2739       }
2740       break;
2741     case NEON_SMLAL_byelement:
2742       if (instr->Mask(NEON_Q)) {
2743         Op = &Simulator::smlal2;
2744       } else {
2745         Op = &Simulator::smlal;
2746       }
2747       break;
2748     case NEON_UMLAL_byelement:
2749       if (instr->Mask(NEON_Q)) {
2750         Op = &Simulator::umlal2;
2751       } else {
2752         Op = &Simulator::umlal;
2753       }
2754       break;
2755     case NEON_SMLSL_byelement:
2756       if (instr->Mask(NEON_Q)) {
2757         Op = &Simulator::smlsl2;
2758       } else {
2759         Op = &Simulator::smlsl;
2760       }
2761       break;
2762     case NEON_UMLSL_byelement:
2763       if (instr->Mask(NEON_Q)) {
2764         Op = &Simulator::umlsl2;
2765       } else {
2766         Op = &Simulator::umlsl;
2767       }
2768       break;
2769     case NEON_SQDMULL_byelement:
2770       if (instr->Mask(NEON_Q)) {
2771         Op = &Simulator::sqdmull2;
2772       } else {
2773         Op = &Simulator::sqdmull;
2774       }
2775       break;
2776     case NEON_SQDMLAL_byelement:
2777       if (instr->Mask(NEON_Q)) {
2778         Op = &Simulator::sqdmlal2;
2779       } else {
2780         Op = &Simulator::sqdmlal;
2781       }
2782       break;
2783     case NEON_SQDMLSL_byelement:
2784       if (instr->Mask(NEON_Q)) {
2785         Op = &Simulator::sqdmlsl2;
2786       } else {
2787         Op = &Simulator::sqdmlsl;
2788       }
2789       break;
2790     default:
2791       index = instr->NEONH();
2792       if ((instr->FPType() & 1) == 0) {
2793         index = (index << 1) | instr->NEONL();
2794       }
2795 
2796       vf = nfd.GetVectorFormat(nfd.FPFormatMap());
2797 
2798       switch (instr->Mask(NEONByIndexedElementFPMask)) {
2799         case NEON_FMUL_byelement: Op = &Simulator::fmul; break;
2800         case NEON_FMLA_byelement: Op = &Simulator::fmla; break;
2801         case NEON_FMLS_byelement: Op = &Simulator::fmls; break;
2802         case NEON_FMULX_byelement: Op = &Simulator::fmulx; break;
2803         default: VIXL_UNIMPLEMENTED();
2804       }
2805   }
2806 
2807   (this->*Op)(vf, rd, rn, vreg(rm_reg), index);
2808 }
2809 
2810 
2811 void Simulator::VisitNEONCopy(const Instruction* instr) {
2812   NEONFormatDecoder nfd(instr, NEONFormatDecoder::TriangularFormatMap());
2813   VectorFormat vf = nfd.GetVectorFormat();
2814 
2815   SimVRegister& rd = vreg(instr->Rd());
2816   SimVRegister& rn = vreg(instr->Rn());
2817   int imm5 = instr->ImmNEON5();
2818   int tz = CountTrailingZeros(imm5, 32);
2819   int reg_index = imm5 >> (tz + 1);
2820 
2821   if (instr->Mask(NEONCopyInsElementMask) == NEON_INS_ELEMENT) {
2822     int imm4 = instr->ImmNEON4();
2823     int rn_index = imm4 >> tz;
2824     ins_element(vf, rd, reg_index, rn, rn_index);
2825   } else if (instr->Mask(NEONCopyInsGeneralMask) == NEON_INS_GENERAL) {
2826     ins_immediate(vf, rd, reg_index, xreg(instr->Rn()));
2827   } else if (instr->Mask(NEONCopyUmovMask) == NEON_UMOV) {
2828     uint64_t value = LogicVRegister(rn).Uint(vf, reg_index);
2829     value &= MaxUintFromFormat(vf);
2830     set_xreg(instr->Rd(), value);
2831   } else if (instr->Mask(NEONCopyUmovMask) == NEON_SMOV) {
2832     int64_t value = LogicVRegister(rn).Int(vf, reg_index);
2833     if (instr->NEONQ()) {
2834       set_xreg(instr->Rd(), value);
2835     } else {
2836       set_wreg(instr->Rd(), (int32_t)value);
2837     }
2838   } else if (instr->Mask(NEONCopyDupElementMask) == NEON_DUP_ELEMENT) {
2839     dup_element(vf, rd, rn, reg_index);
2840   } else if (instr->Mask(NEONCopyDupGeneralMask) == NEON_DUP_GENERAL) {
2841     dup_immediate(vf, rd, xreg(instr->Rn()));
2842   } else {
2843     VIXL_UNIMPLEMENTED();
2844   }
2845 }
2846 
2847 
2848 void Simulator::VisitNEONExtract(const Instruction* instr) {
2849   NEONFormatDecoder nfd(instr, NEONFormatDecoder::LogicalFormatMap());
2850   VectorFormat vf = nfd.GetVectorFormat();
2851   SimVRegister& rd = vreg(instr->Rd());
2852   SimVRegister& rn = vreg(instr->Rn());
2853   SimVRegister& rm = vreg(instr->Rm());
2854   if (instr->Mask(NEONExtractMask) == NEON_EXT) {
2855     int index = instr->ImmNEONExt();
2856     ext(vf, rd, rn, rm, index);
2857   } else {
2858     VIXL_UNIMPLEMENTED();
2859   }
2860 }
2861 
2862 
2863 void Simulator::NEONLoadStoreMultiStructHelper(const Instruction* instr,
2864                                                AddrMode addr_mode) {
2865   NEONFormatDecoder nfd(instr, NEONFormatDecoder::LoadStoreFormatMap());
2866   VectorFormat vf = nfd.GetVectorFormat();
2867 
2868   uint64_t addr_base = xreg(instr->Rn(), Reg31IsStackPointer);
2869   int reg_size = RegisterSizeInBytesFromFormat(vf);
2870 
2871   int reg[4];
2872   uint64_t addr[4];
2873   for (int i = 0; i < 4; i++) {
2874     reg[i] = (instr->Rt() + i) % kNumberOfVRegisters;
2875     addr[i] = addr_base + (i * reg_size);
2876   }
2877   int count = 1;
2878   bool log_read = true;
2879 
2880   Instr itype = instr->Mask(NEONLoadStoreMultiStructMask);
2881   if (((itype == NEON_LD1_1v) || (itype == NEON_LD1_2v) ||
2882        (itype == NEON_LD1_3v) || (itype == NEON_LD1_4v) ||
2883        (itype == NEON_ST1_1v) || (itype == NEON_ST1_2v) ||
2884        (itype == NEON_ST1_3v) || (itype == NEON_ST1_4v)) &&
2885       (instr->Bits(20, 16) != 0)) {
2886     VIXL_UNREACHABLE();
2887   }
2888 
2889   // We use the PostIndex mask here, as it works in this case for both Offset
2890   // and PostIndex addressing.
2891   switch (instr->Mask(NEONLoadStoreMultiStructPostIndexMask)) {
2892     case NEON_LD1_4v:
2893     case NEON_LD1_4v_post: ld1(vf, vreg(reg[3]), addr[3]); count++;
2894       VIXL_FALLTHROUGH();
2895     case NEON_LD1_3v:
2896     case NEON_LD1_3v_post: ld1(vf, vreg(reg[2]), addr[2]); count++;
2897       VIXL_FALLTHROUGH();
2898     case NEON_LD1_2v:
2899     case NEON_LD1_2v_post: ld1(vf, vreg(reg[1]), addr[1]); count++;
2900       VIXL_FALLTHROUGH();
2901     case NEON_LD1_1v:
2902     case NEON_LD1_1v_post:
2903       ld1(vf, vreg(reg[0]), addr[0]);
2904       log_read = true;
2905       break;
2906     case NEON_ST1_4v:
2907     case NEON_ST1_4v_post: st1(vf, vreg(reg[3]), addr[3]); count++;
2908       VIXL_FALLTHROUGH();
2909     case NEON_ST1_3v:
2910     case NEON_ST1_3v_post: st1(vf, vreg(reg[2]), addr[2]); count++;
2911       VIXL_FALLTHROUGH();
2912     case NEON_ST1_2v:
2913     case NEON_ST1_2v_post: st1(vf, vreg(reg[1]), addr[1]); count++;
2914       VIXL_FALLTHROUGH();
2915     case NEON_ST1_1v:
2916     case NEON_ST1_1v_post:
2917       st1(vf, vreg(reg[0]), addr[0]);
2918       log_read = false;
2919       break;
2920     case NEON_LD2_post:
2921     case NEON_LD2:
2922       ld2(vf, vreg(reg[0]), vreg(reg[1]), addr[0]);
2923       count = 2;
2924       break;
2925     case NEON_ST2:
2926     case NEON_ST2_post:
2927       st2(vf, vreg(reg[0]), vreg(reg[1]), addr[0]);
2928       count = 2;
2929       break;
2930     case NEON_LD3_post:
2931     case NEON_LD3:
2932       ld3(vf, vreg(reg[0]), vreg(reg[1]), vreg(reg[2]), addr[0]);
2933       count = 3;
2934       break;
2935     case NEON_ST3:
2936     case NEON_ST3_post:
2937       st3(vf, vreg(reg[0]), vreg(reg[1]), vreg(reg[2]), addr[0]);
2938       count = 3;
2939       break;
2940     case NEON_ST4:
2941     case NEON_ST4_post:
2942       st4(vf, vreg(reg[0]), vreg(reg[1]), vreg(reg[2]), vreg(reg[3]),
2943           addr[0]);
2944       count = 4;
2945       break;
2946     case NEON_LD4_post:
2947     case NEON_LD4:
2948       ld4(vf, vreg(reg[0]), vreg(reg[1]), vreg(reg[2]), vreg(reg[3]),
2949           addr[0]);
2950       count = 4;
2951       break;
2952     default: VIXL_UNIMPLEMENTED();
2953   }
2954 
2955   // Explicitly log the register update whilst we have type information.
2956   for (int i = 0; i < count; i++) {
2957     // For de-interleaving loads, only print the base address.
2958     int lane_size = LaneSizeInBytesFromFormat(vf);
2959     PrintRegisterFormat format = GetPrintRegisterFormatTryFP(
2960         GetPrintRegisterFormatForSize(reg_size, lane_size));
2961     if (log_read) {
2962       LogVRead(addr_base, reg[i], format);
2963     } else {
2964       LogVWrite(addr_base, reg[i], format);
2965     }
2966   }
2967 
2968   if (addr_mode == PostIndex) {
2969     int rm = instr->Rm();
2970     // The immediate post index addressing mode is indicated by rm = 31.
2971     // The immediate is implied by the number of vector registers used.
2972     addr_base += (rm == 31) ? RegisterSizeInBytesFromFormat(vf) * count
2973                             : xreg(rm);
2974     set_xreg(instr->Rn(), addr_base);
2975   } else {
2976     VIXL_ASSERT(addr_mode == Offset);
2977   }
2978 }
2979 
2980 
2981 void Simulator::VisitNEONLoadStoreMultiStruct(const Instruction* instr) {
2982   NEONLoadStoreMultiStructHelper(instr, Offset);
2983 }
2984 
2985 
2986 void Simulator::VisitNEONLoadStoreMultiStructPostIndex(
2987     const Instruction* instr) {
2988   NEONLoadStoreMultiStructHelper(instr, PostIndex);
2989 }
2990 
2991 
2992 void Simulator::NEONLoadStoreSingleStructHelper(const Instruction* instr,
2993                                                 AddrMode addr_mode) {
2994   uint64_t addr = xreg(instr->Rn(), Reg31IsStackPointer);
2995   int rt = instr->Rt();
2996 
2997   Instr itype = instr->Mask(NEONLoadStoreSingleStructMask);
2998   if (((itype == NEON_LD1_b) || (itype == NEON_LD1_h) ||
2999        (itype == NEON_LD1_s) || (itype == NEON_LD1_d)) &&
3000       (instr->Bits(20, 16) != 0)) {
3001     VIXL_UNREACHABLE();
3002   }
3003 
3004   // We use the PostIndex mask here, as it works in this case for both Offset
3005   // and PostIndex addressing.
3006   bool do_load = false;
3007 
3008   NEONFormatDecoder nfd(instr, NEONFormatDecoder::LoadStoreFormatMap());
3009   VectorFormat vf_t = nfd.GetVectorFormat();
3010 
3011   VectorFormat vf = kFormat16B;
3012   switch (instr->Mask(NEONLoadStoreSingleStructPostIndexMask)) {
3013     case NEON_LD1_b:
3014     case NEON_LD1_b_post:
3015     case NEON_LD2_b:
3016     case NEON_LD2_b_post:
3017     case NEON_LD3_b:
3018     case NEON_LD3_b_post:
3019     case NEON_LD4_b:
3020     case NEON_LD4_b_post: do_load = true;
3021       VIXL_FALLTHROUGH();
3022     case NEON_ST1_b:
3023     case NEON_ST1_b_post:
3024     case NEON_ST2_b:
3025     case NEON_ST2_b_post:
3026     case NEON_ST3_b:
3027     case NEON_ST3_b_post:
3028     case NEON_ST4_b:
3029     case NEON_ST4_b_post: break;
3030 
3031     case NEON_LD1_h:
3032     case NEON_LD1_h_post:
3033     case NEON_LD2_h:
3034     case NEON_LD2_h_post:
3035     case NEON_LD3_h:
3036     case NEON_LD3_h_post:
3037     case NEON_LD4_h:
3038     case NEON_LD4_h_post: do_load = true;
3039       VIXL_FALLTHROUGH();
3040     case NEON_ST1_h:
3041     case NEON_ST1_h_post:
3042     case NEON_ST2_h:
3043     case NEON_ST2_h_post:
3044     case NEON_ST3_h:
3045     case NEON_ST3_h_post:
3046     case NEON_ST4_h:
3047     case NEON_ST4_h_post: vf = kFormat8H; break;
3048     case NEON_LD1_s:
3049     case NEON_LD1_s_post:
3050     case NEON_LD2_s:
3051     case NEON_LD2_s_post:
3052     case NEON_LD3_s:
3053     case NEON_LD3_s_post:
3054     case NEON_LD4_s:
3055     case NEON_LD4_s_post: do_load = true;
3056       VIXL_FALLTHROUGH();
3057     case NEON_ST1_s:
3058     case NEON_ST1_s_post:
3059     case NEON_ST2_s:
3060     case NEON_ST2_s_post:
3061     case NEON_ST3_s:
3062     case NEON_ST3_s_post:
3063     case NEON_ST4_s:
3064     case NEON_ST4_s_post: {
3065       VIXL_STATIC_ASSERT((NEON_LD1_s | (1 << NEONLSSize_offset)) == NEON_LD1_d);
3066       VIXL_STATIC_ASSERT(
3067           (NEON_LD1_s_post | (1 << NEONLSSize_offset)) == NEON_LD1_d_post);
3068       VIXL_STATIC_ASSERT((NEON_ST1_s | (1 << NEONLSSize_offset)) == NEON_ST1_d);
3069       VIXL_STATIC_ASSERT(
3070           (NEON_ST1_s_post | (1 << NEONLSSize_offset)) == NEON_ST1_d_post);
3071       vf = ((instr->NEONLSSize() & 1) == 0) ? kFormat4S : kFormat2D;
3072       break;
3073     }
3074 
3075     case NEON_LD1R:
3076     case NEON_LD1R_post: {
3077       vf = vf_t;
3078       ld1r(vf, vreg(rt), addr);
3079       do_load = true;
3080       break;
3081     }
3082 
3083     case NEON_LD2R:
3084     case NEON_LD2R_post: {
3085       vf = vf_t;
3086       int rt2 = (rt + 1) % kNumberOfVRegisters;
3087       ld2r(vf, vreg(rt), vreg(rt2), addr);
3088       do_load = true;
3089       break;
3090     }
3091 
3092     case NEON_LD3R:
3093     case NEON_LD3R_post: {
3094       vf = vf_t;
3095       int rt2 = (rt + 1) % kNumberOfVRegisters;
3096       int rt3 = (rt2 + 1) % kNumberOfVRegisters;
3097       ld3r(vf, vreg(rt), vreg(rt2), vreg(rt3), addr);
3098       do_load = true;
3099       break;
3100     }
3101 
3102     case NEON_LD4R:
3103     case NEON_LD4R_post: {
3104       vf = vf_t;
3105       int rt2 = (rt + 1) % kNumberOfVRegisters;
3106       int rt3 = (rt2 + 1) % kNumberOfVRegisters;
3107       int rt4 = (rt3 + 1) % kNumberOfVRegisters;
3108       ld4r(vf, vreg(rt), vreg(rt2), vreg(rt3), vreg(rt4), addr);
3109       do_load = true;
3110       break;
3111     }
3112     default: VIXL_UNIMPLEMENTED();
3113   }
3114 
3115   PrintRegisterFormat print_format =
3116       GetPrintRegisterFormatTryFP(GetPrintRegisterFormat(vf));
3117   // Make sure that the print_format only includes a single lane.
3118   print_format =
3119       static_cast<PrintRegisterFormat>(print_format & ~kPrintRegAsVectorMask);
3120 
3121   int esize = LaneSizeInBytesFromFormat(vf);
3122   int index_shift = LaneSizeInBytesLog2FromFormat(vf);
3123   int lane = instr->NEONLSIndex(index_shift);
3124   int scale = 0;
3125   int rt2 = (rt + 1) % kNumberOfVRegisters;
3126   int rt3 = (rt2 + 1) % kNumberOfVRegisters;
3127   int rt4 = (rt3 + 1) % kNumberOfVRegisters;
3128   switch (instr->Mask(NEONLoadStoreSingleLenMask)) {
3129     case NEONLoadStoreSingle1:
3130       scale = 1;
3131       if (do_load) {
3132         ld1(vf, vreg(rt), lane, addr);
3133         LogVRead(addr, rt, print_format, lane);
3134       } else {
3135         st1(vf, vreg(rt), lane, addr);
3136         LogVWrite(addr, rt, print_format, lane);
3137       }
3138       break;
3139     case NEONLoadStoreSingle2:
3140       scale = 2;
3141       if (do_load) {
3142         ld2(vf, vreg(rt), vreg(rt2), lane, addr);
3143         LogVRead(addr, rt, print_format, lane);
3144         LogVRead(addr + esize, rt2, print_format, lane);
3145       } else {
3146         st2(vf, vreg(rt), vreg(rt2), lane, addr);
3147         LogVWrite(addr, rt, print_format, lane);
3148         LogVWrite(addr + esize, rt2, print_format, lane);
3149       }
3150       break;
3151     case NEONLoadStoreSingle3:
3152       scale = 3;
3153       if (do_load) {
3154         ld3(vf, vreg(rt), vreg(rt2), vreg(rt3), lane, addr);
3155         LogVRead(addr, rt, print_format, lane);
3156         LogVRead(addr + esize, rt2, print_format, lane);
3157         LogVRead(addr + (2 * esize), rt3, print_format, lane);
3158       } else {
3159         st3(vf, vreg(rt), vreg(rt2), vreg(rt3), lane, addr);
3160         LogVWrite(addr, rt, print_format, lane);
3161         LogVWrite(addr + esize, rt2, print_format, lane);
3162         LogVWrite(addr + (2 * esize), rt3, print_format, lane);
3163       }
3164       break;
3165     case NEONLoadStoreSingle4:
3166       scale = 4;
3167       if (do_load) {
3168         ld4(vf, vreg(rt), vreg(rt2), vreg(rt3), vreg(rt4), lane, addr);
3169         LogVRead(addr, rt, print_format, lane);
3170         LogVRead(addr + esize, rt2, print_format, lane);
3171         LogVRead(addr + (2 * esize), rt3, print_format, lane);
3172         LogVRead(addr + (3 * esize), rt4, print_format, lane);
3173       } else {
3174         st4(vf, vreg(rt), vreg(rt2), vreg(rt3), vreg(rt4), lane, addr);
3175         LogVWrite(addr, rt, print_format, lane);
3176         LogVWrite(addr + esize, rt2, print_format, lane);
3177         LogVWrite(addr + (2 * esize), rt3, print_format, lane);
3178         LogVWrite(addr + (3 * esize), rt4, print_format, lane);
3179       }
3180       break;
3181     default: VIXL_UNIMPLEMENTED();
3182   }
3183 
3184   if (addr_mode == PostIndex) {
3185     int rm = instr->Rm();
3186     int lane_size = LaneSizeInBytesFromFormat(vf);
3187     set_xreg(instr->Rn(), addr + ((rm == 31) ? (scale * lane_size) : xreg(rm)));
3188   }
3189 }
3190 
3191 
3192 void Simulator::VisitNEONLoadStoreSingleStruct(const Instruction* instr) {
3193   NEONLoadStoreSingleStructHelper(instr, Offset);
3194 }
3195 
3196 
3197 void Simulator::VisitNEONLoadStoreSingleStructPostIndex(
3198     const Instruction* instr) {
3199   NEONLoadStoreSingleStructHelper(instr, PostIndex);
3200 }
3201 
3202 
3203 void Simulator::VisitNEONModifiedImmediate(const Instruction* instr) {
3204   SimVRegister& rd = vreg(instr->Rd());
3205   int cmode = instr->NEONCmode();
3206   int cmode_3_1 = (cmode >> 1) & 7;
3207   int cmode_3 = (cmode >> 3) & 1;
3208   int cmode_2 = (cmode >> 2) & 1;
3209   int cmode_1 = (cmode >> 1) & 1;
3210   int cmode_0 = cmode & 1;
3211   int q = instr->NEONQ();
3212   int op_bit = instr->NEONModImmOp();
3213   uint64_t imm8  = instr->ImmNEONabcdefgh();
3214 
3215   // Find the format and immediate value
3216   uint64_t imm = 0;
3217   VectorFormat vform = kFormatUndefined;
3218   switch (cmode_3_1) {
3219     case 0x0:
3220     case 0x1:
3221     case 0x2:
3222     case 0x3:
3223       vform = (q == 1) ? kFormat4S : kFormat2S;
3224       imm = imm8 << (8 * cmode_3_1);
3225       break;
3226     case 0x4:
3227     case 0x5:
3228       vform = (q == 1) ? kFormat8H : kFormat4H;
3229       imm = imm8 << (8 * cmode_1);
3230       break;
3231     case 0x6:
3232       vform = (q == 1) ? kFormat4S : kFormat2S;
3233       if (cmode_0 == 0) {
3234         imm = imm8 << 8  | 0x000000ff;
3235       } else {
3236         imm = imm8 << 16 | 0x0000ffff;
3237       }
3238       break;
3239     case 0x7:
3240       if (cmode_0 == 0 && op_bit == 0) {
3241         vform = q ? kFormat16B : kFormat8B;
3242         imm = imm8;
3243       } else if (cmode_0 == 0 && op_bit == 1) {
3244         vform = q ? kFormat2D : kFormat1D;
3245         imm = 0;
3246         for (int i = 0; i < 8; ++i) {
3247           if (imm8 & (1 << i)) {
3248             imm |= (UINT64_C(0xff) << (8 * i));
3249           }
3250         }
3251       } else {  // cmode_0 == 1, cmode == 0xf.
3252         if (op_bit == 0) {
3253           vform = q ? kFormat4S : kFormat2S;
3254           imm = float_to_rawbits(instr->ImmNEONFP32());
3255         } else if (q == 1) {
3256           vform = kFormat2D;
3257           imm = double_to_rawbits(instr->ImmNEONFP64());
3258         } else {
3259           VIXL_ASSERT((q == 0) && (op_bit == 1) && (cmode == 0xf));
3260           VisitUnallocated(instr);
3261         }
3262       }
3263       break;
3264     default: VIXL_UNREACHABLE(); break;
3265   }
3266 
3267   // Find the operation
3268   NEONModifiedImmediateOp op;
3269   if (cmode_3 == 0) {
3270     if (cmode_0 == 0) {
3271       op = op_bit ? NEONModifiedImmediate_MVNI : NEONModifiedImmediate_MOVI;
3272     } else {  // cmode<0> == '1'
3273       op = op_bit ? NEONModifiedImmediate_BIC : NEONModifiedImmediate_ORR;
3274     }
3275   } else {  // cmode<3> == '1'
3276     if (cmode_2 == 0) {
3277       if (cmode_0 == 0) {
3278         op = op_bit ? NEONModifiedImmediate_MVNI : NEONModifiedImmediate_MOVI;
3279       } else {  // cmode<0> == '1'
3280         op = op_bit ? NEONModifiedImmediate_BIC : NEONModifiedImmediate_ORR;
3281       }
3282     } else {  // cmode<2> == '1'
3283        if (cmode_1 == 0) {
3284          op = op_bit ? NEONModifiedImmediate_MVNI : NEONModifiedImmediate_MOVI;
3285        } else {  // cmode<1> == '1'
3286          if (cmode_0 == 0) {
3287            op = NEONModifiedImmediate_MOVI;
3288          } else {  // cmode<0> == '1'
3289            op = NEONModifiedImmediate_MOVI;
3290          }
3291        }
3292     }
3293   }
3294 
3295   // Call the logic function
3296   if (op == NEONModifiedImmediate_ORR) {
3297     orr(vform, rd, rd, imm);
3298   } else if (op == NEONModifiedImmediate_BIC) {
3299     bic(vform, rd, rd, imm);
3300   } else  if (op == NEONModifiedImmediate_MOVI) {
3301     movi(vform, rd, imm);
3302   } else if (op == NEONModifiedImmediate_MVNI) {
3303     mvni(vform, rd, imm);
3304   } else {
3305     VisitUnimplemented(instr);
3306   }
3307 }
3308 
3309 
3310 void Simulator::VisitNEONScalar2RegMisc(const Instruction* instr) {
3311   NEONFormatDecoder nfd(instr, NEONFormatDecoder::ScalarFormatMap());
3312   VectorFormat vf = nfd.GetVectorFormat();
3313 
3314   SimVRegister& rd = vreg(instr->Rd());
3315   SimVRegister& rn = vreg(instr->Rn());
3316 
3317   if (instr->Mask(NEON2RegMiscOpcode) <= NEON_NEG_scalar_opcode) {
3318     // These instructions all use a two bit size field, except NOT and RBIT,
3319     // which use the field to encode the operation.
3320     switch (instr->Mask(NEONScalar2RegMiscMask)) {
3321       case NEON_CMEQ_zero_scalar: cmp(vf, rd, rn, 0, eq); break;
3322       case NEON_CMGE_zero_scalar: cmp(vf, rd, rn, 0, ge); break;
3323       case NEON_CMGT_zero_scalar: cmp(vf, rd, rn, 0, gt); break;
3324       case NEON_CMLT_zero_scalar: cmp(vf, rd, rn, 0, lt); break;
3325       case NEON_CMLE_zero_scalar: cmp(vf, rd, rn, 0, le); break;
3326       case NEON_ABS_scalar:       abs(vf, rd, rn); break;
3327       case NEON_SQABS_scalar:     abs(vf, rd, rn).SignedSaturate(vf); break;
3328       case NEON_NEG_scalar:       neg(vf, rd, rn); break;
3329       case NEON_SQNEG_scalar:     neg(vf, rd, rn).SignedSaturate(vf); break;
3330       case NEON_SUQADD_scalar:    suqadd(vf, rd, rn); break;
3331       case NEON_USQADD_scalar:    usqadd(vf, rd, rn); break;
3332       default: VIXL_UNIMPLEMENTED(); break;
3333     }
3334   } else {
3335     VectorFormat fpf = nfd.GetVectorFormat(nfd.FPScalarFormatMap());
3336     FPRounding fpcr_rounding = static_cast<FPRounding>(fpcr().RMode());
3337 
3338     // These instructions all use a one bit size field, except SQXTUN, SQXTN
3339     // and UQXTN, which use a two bit size field.
3340     switch (instr->Mask(NEONScalar2RegMiscFPMask)) {
3341       case NEON_FRECPE_scalar:     frecpe(fpf, rd, rn, fpcr_rounding); break;
3342       case NEON_FRECPX_scalar:     frecpx(fpf, rd, rn); break;
3343       case NEON_FRSQRTE_scalar:    frsqrte(fpf, rd, rn); break;
3344       case NEON_FCMGT_zero_scalar: fcmp_zero(fpf, rd, rn, gt); break;
3345       case NEON_FCMGE_zero_scalar: fcmp_zero(fpf, rd, rn, ge); break;
3346       case NEON_FCMEQ_zero_scalar: fcmp_zero(fpf, rd, rn, eq); break;
3347       case NEON_FCMLE_zero_scalar: fcmp_zero(fpf, rd, rn, le); break;
3348       case NEON_FCMLT_zero_scalar: fcmp_zero(fpf, rd, rn, lt); break;
3349       case NEON_SCVTF_scalar:      scvtf(fpf, rd, rn, 0, fpcr_rounding); break;
3350       case NEON_UCVTF_scalar:      ucvtf(fpf, rd, rn, 0, fpcr_rounding); break;
3351       case NEON_FCVTNS_scalar: fcvts(fpf, rd, rn, FPTieEven); break;
3352       case NEON_FCVTNU_scalar: fcvtu(fpf, rd, rn, FPTieEven); break;
3353       case NEON_FCVTPS_scalar: fcvts(fpf, rd, rn, FPPositiveInfinity); break;
3354       case NEON_FCVTPU_scalar: fcvtu(fpf, rd, rn, FPPositiveInfinity); break;
3355       case NEON_FCVTMS_scalar: fcvts(fpf, rd, rn, FPNegativeInfinity); break;
3356       case NEON_FCVTMU_scalar: fcvtu(fpf, rd, rn, FPNegativeInfinity); break;
3357       case NEON_FCVTZS_scalar: fcvts(fpf, rd, rn, FPZero); break;
3358       case NEON_FCVTZU_scalar: fcvtu(fpf, rd, rn, FPZero); break;
3359       case NEON_FCVTAS_scalar: fcvts(fpf, rd, rn, FPTieAway); break;
3360       case NEON_FCVTAU_scalar: fcvtu(fpf, rd, rn, FPTieAway); break;
3361       case NEON_FCVTXN_scalar:
3362         // Unlike all of the other FP instructions above, fcvtxn encodes dest
3363         // size S as size<0>=1. There's only one case, so we ignore the form.
3364         VIXL_ASSERT(instr->Bit(22) == 1);
3365         fcvtxn(kFormatS, rd, rn);
3366         break;
3367       default:
3368         switch (instr->Mask(NEONScalar2RegMiscMask)) {
3369           case NEON_SQXTN_scalar:  sqxtn(vf, rd, rn); break;
3370           case NEON_UQXTN_scalar:  uqxtn(vf, rd, rn); break;
3371           case NEON_SQXTUN_scalar: sqxtun(vf, rd, rn); break;
3372           default:
3373             VIXL_UNIMPLEMENTED();
3374         }
3375     }
3376   }
3377 }
3378 
3379 
3380 void Simulator::VisitNEONScalar3Diff(const Instruction* instr) {
3381   NEONFormatDecoder nfd(instr, NEONFormatDecoder::LongScalarFormatMap());
3382   VectorFormat vf = nfd.GetVectorFormat();
3383 
3384   SimVRegister& rd = vreg(instr->Rd());
3385   SimVRegister& rn = vreg(instr->Rn());
3386   SimVRegister& rm = vreg(instr->Rm());
3387   switch (instr->Mask(NEONScalar3DiffMask)) {
3388     case NEON_SQDMLAL_scalar: sqdmlal(vf, rd, rn, rm); break;
3389     case NEON_SQDMLSL_scalar: sqdmlsl(vf, rd, rn, rm); break;
3390     case NEON_SQDMULL_scalar: sqdmull(vf, rd, rn, rm); break;
3391     default:
3392       VIXL_UNIMPLEMENTED();
3393   }
3394 }
3395 
3396 
3397 void Simulator::VisitNEONScalar3Same(const Instruction* instr) {
3398   NEONFormatDecoder nfd(instr, NEONFormatDecoder::ScalarFormatMap());
3399   VectorFormat vf = nfd.GetVectorFormat();
3400 
3401   SimVRegister& rd = vreg(instr->Rd());
3402   SimVRegister& rn = vreg(instr->Rn());
3403   SimVRegister& rm = vreg(instr->Rm());
3404 
3405   if (instr->Mask(NEONScalar3SameFPFMask) == NEONScalar3SameFPFixed) {
3406     vf = nfd.GetVectorFormat(nfd.FPScalarFormatMap());
3407     switch (instr->Mask(NEONScalar3SameFPMask)) {
3408       case NEON_FMULX_scalar:   fmulx(vf, rd, rn, rm); break;
3409       case NEON_FACGE_scalar:   fabscmp(vf, rd, rn, rm, ge); break;
3410       case NEON_FACGT_scalar:   fabscmp(vf, rd, rn, rm, gt); break;
3411       case NEON_FCMEQ_scalar:   fcmp(vf, rd, rn, rm, eq); break;
3412       case NEON_FCMGE_scalar:   fcmp(vf, rd, rn, rm, ge); break;
3413       case NEON_FCMGT_scalar:   fcmp(vf, rd, rn, rm, gt); break;
3414       case NEON_FRECPS_scalar:  frecps(vf, rd, rn, rm); break;
3415       case NEON_FRSQRTS_scalar: frsqrts(vf, rd, rn, rm); break;
3416       case NEON_FABD_scalar:    fabd(vf, rd, rn, rm); break;
3417       default:
3418         VIXL_UNIMPLEMENTED();
3419     }
3420   } else {
3421     switch (instr->Mask(NEONScalar3SameMask)) {
3422       case NEON_ADD_scalar:      add(vf, rd, rn, rm); break;
3423       case NEON_SUB_scalar:      sub(vf, rd, rn, rm); break;
3424       case NEON_CMEQ_scalar:     cmp(vf, rd, rn, rm, eq); break;
3425       case NEON_CMGE_scalar:     cmp(vf, rd, rn, rm, ge); break;
3426       case NEON_CMGT_scalar:     cmp(vf, rd, rn, rm, gt); break;
3427       case NEON_CMHI_scalar:     cmp(vf, rd, rn, rm, hi); break;
3428       case NEON_CMHS_scalar:     cmp(vf, rd, rn, rm, hs); break;
3429       case NEON_CMTST_scalar:    cmptst(vf, rd, rn, rm); break;
3430       case NEON_USHL_scalar:     ushl(vf, rd, rn, rm); break;
3431       case NEON_SSHL_scalar:     sshl(vf, rd, rn, rm); break;
3432       case NEON_SQDMULH_scalar:  sqdmulh(vf, rd, rn, rm); break;
3433       case NEON_SQRDMULH_scalar: sqrdmulh(vf, rd, rn, rm); break;
3434       case NEON_UQADD_scalar:
3435         add(vf, rd, rn, rm).UnsignedSaturate(vf);
3436         break;
3437       case NEON_SQADD_scalar:
3438         add(vf, rd, rn, rm).SignedSaturate(vf);
3439         break;
3440       case NEON_UQSUB_scalar:
3441         sub(vf, rd, rn, rm).UnsignedSaturate(vf);
3442         break;
3443       case NEON_SQSUB_scalar:
3444         sub(vf, rd, rn, rm).SignedSaturate(vf);
3445         break;
3446       case NEON_UQSHL_scalar:
3447         ushl(vf, rd, rn, rm).UnsignedSaturate(vf);
3448         break;
3449       case NEON_SQSHL_scalar:
3450         sshl(vf, rd, rn, rm).SignedSaturate(vf);
3451         break;
3452       case NEON_URSHL_scalar:
3453         ushl(vf, rd, rn, rm).Round(vf);
3454         break;
3455       case NEON_SRSHL_scalar:
3456         sshl(vf, rd, rn, rm).Round(vf);
3457         break;
3458       case NEON_UQRSHL_scalar:
3459         ushl(vf, rd, rn, rm).Round(vf).UnsignedSaturate(vf);
3460         break;
3461       case NEON_SQRSHL_scalar:
3462         sshl(vf, rd, rn, rm).Round(vf).SignedSaturate(vf);
3463         break;
3464       default:
3465         VIXL_UNIMPLEMENTED();
3466     }
3467   }
3468 }
3469 
3470 
3471 void Simulator::VisitNEONScalarByIndexedElement(const Instruction* instr) {
3472   NEONFormatDecoder nfd(instr, NEONFormatDecoder::LongScalarFormatMap());
3473   VectorFormat vf = nfd.GetVectorFormat();
3474   VectorFormat vf_r = nfd.GetVectorFormat(nfd.ScalarFormatMap());
3475 
3476   SimVRegister& rd = vreg(instr->Rd());
3477   SimVRegister& rn = vreg(instr->Rn());
3478   ByElementOp Op = NULL;
3479 
3480   int rm_reg = instr->Rm();
3481   int index = (instr->NEONH() << 1) | instr->NEONL();
3482   if (instr->NEONSize() == 1) {
3483     rm_reg &= 0xf;
3484     index = (index << 1) | instr->NEONM();
3485   }
3486 
3487   switch (instr->Mask(NEONScalarByIndexedElementMask)) {
3488     case NEON_SQDMULL_byelement_scalar: Op = &Simulator::sqdmull; break;
3489     case NEON_SQDMLAL_byelement_scalar: Op = &Simulator::sqdmlal; break;
3490     case NEON_SQDMLSL_byelement_scalar: Op = &Simulator::sqdmlsl; break;
3491     case NEON_SQDMULH_byelement_scalar:
3492       Op = &Simulator::sqdmulh;
3493       vf = vf_r;
3494       break;
3495     case NEON_SQRDMULH_byelement_scalar:
3496       Op = &Simulator::sqrdmulh;
3497       vf = vf_r;
3498       break;
3499     default:
3500       vf = nfd.GetVectorFormat(nfd.FPScalarFormatMap());
3501       index = instr->NEONH();
3502       if ((instr->FPType() & 1) == 0) {
3503         index = (index << 1) | instr->NEONL();
3504       }
3505       switch (instr->Mask(NEONScalarByIndexedElementFPMask)) {
3506         case NEON_FMUL_byelement_scalar: Op = &Simulator::fmul; break;
3507         case NEON_FMLA_byelement_scalar: Op = &Simulator::fmla; break;
3508         case NEON_FMLS_byelement_scalar: Op = &Simulator::fmls; break;
3509         case NEON_FMULX_byelement_scalar: Op = &Simulator::fmulx; break;
3510         default: VIXL_UNIMPLEMENTED();
3511       }
3512   }
3513 
3514   (this->*Op)(vf, rd, rn, vreg(rm_reg), index);
3515 }
3516 
3517 
3518 void Simulator::VisitNEONScalarCopy(const Instruction* instr) {
3519   NEONFormatDecoder nfd(instr, NEONFormatDecoder::TriangularScalarFormatMap());
3520   VectorFormat vf = nfd.GetVectorFormat();
3521 
3522   SimVRegister& rd = vreg(instr->Rd());
3523   SimVRegister& rn = vreg(instr->Rn());
3524 
3525   if (instr->Mask(NEONScalarCopyMask) == NEON_DUP_ELEMENT_scalar) {
3526     int imm5 = instr->ImmNEON5();
3527     int tz = CountTrailingZeros(imm5, 32);
3528     int rn_index = imm5 >> (tz + 1);
3529     dup_element(vf, rd, rn, rn_index);
3530   } else {
3531     VIXL_UNIMPLEMENTED();
3532   }
3533 }
3534 
3535 
3536 void Simulator::VisitNEONScalarPairwise(const Instruction* instr) {
3537   NEONFormatDecoder nfd(instr, NEONFormatDecoder::FPScalarFormatMap());
3538   VectorFormat vf = nfd.GetVectorFormat();
3539 
3540   SimVRegister& rd = vreg(instr->Rd());
3541   SimVRegister& rn = vreg(instr->Rn());
3542   switch (instr->Mask(NEONScalarPairwiseMask)) {
3543     case NEON_ADDP_scalar:    addp(vf, rd, rn); break;
3544     case NEON_FADDP_scalar:   faddp(vf, rd, rn); break;
3545     case NEON_FMAXP_scalar:   fmaxp(vf, rd, rn); break;
3546     case NEON_FMAXNMP_scalar: fmaxnmp(vf, rd, rn); break;
3547     case NEON_FMINP_scalar:   fminp(vf, rd, rn); break;
3548     case NEON_FMINNMP_scalar: fminnmp(vf, rd, rn); break;
3549     default:
3550       VIXL_UNIMPLEMENTED();
3551   }
3552 }
3553 
3554 
3555 void Simulator::VisitNEONScalarShiftImmediate(const Instruction* instr) {
3556   SimVRegister& rd = vreg(instr->Rd());
3557   SimVRegister& rn = vreg(instr->Rn());
3558   FPRounding fpcr_rounding = static_cast<FPRounding>(fpcr().RMode());
3559 
3560   static const NEONFormatMap map = {
3561     {22, 21, 20, 19},
3562     {NF_UNDEF, NF_B, NF_H, NF_H, NF_S, NF_S, NF_S, NF_S,
3563      NF_D,     NF_D, NF_D, NF_D, NF_D, NF_D, NF_D, NF_D}
3564   };
3565   NEONFormatDecoder nfd(instr, &map);
3566   VectorFormat vf = nfd.GetVectorFormat();
3567 
3568   int highestSetBit = HighestSetBitPosition(instr->ImmNEONImmh());
3569   int immhimmb = instr->ImmNEONImmhImmb();
3570   int right_shift = (16 << highestSetBit) - immhimmb;
3571   int left_shift = immhimmb - (8 << highestSetBit);
3572   switch (instr->Mask(NEONScalarShiftImmediateMask)) {
3573     case NEON_SHL_scalar:       shl(vf, rd, rn, left_shift); break;
3574     case NEON_SLI_scalar:       sli(vf, rd, rn, left_shift); break;
3575     case NEON_SQSHL_imm_scalar: sqshl(vf, rd, rn, left_shift); break;
3576     case NEON_UQSHL_imm_scalar: uqshl(vf, rd, rn, left_shift); break;
3577     case NEON_SQSHLU_scalar:    sqshlu(vf, rd, rn, left_shift); break;
3578     case NEON_SRI_scalar:       sri(vf, rd, rn, right_shift); break;
3579     case NEON_SSHR_scalar:      sshr(vf, rd, rn, right_shift); break;
3580     case NEON_USHR_scalar:      ushr(vf, rd, rn, right_shift); break;
3581     case NEON_SRSHR_scalar:     sshr(vf, rd, rn, right_shift).Round(vf); break;
3582     case NEON_URSHR_scalar:     ushr(vf, rd, rn, right_shift).Round(vf); break;
3583     case NEON_SSRA_scalar:      ssra(vf, rd, rn, right_shift); break;
3584     case NEON_USRA_scalar:      usra(vf, rd, rn, right_shift); break;
3585     case NEON_SRSRA_scalar:     srsra(vf, rd, rn, right_shift); break;
3586     case NEON_URSRA_scalar:     ursra(vf, rd, rn, right_shift); break;
3587     case NEON_UQSHRN_scalar:    uqshrn(vf, rd, rn, right_shift); break;
3588     case NEON_UQRSHRN_scalar:   uqrshrn(vf, rd, rn, right_shift); break;
3589     case NEON_SQSHRN_scalar:    sqshrn(vf, rd, rn, right_shift); break;
3590     case NEON_SQRSHRN_scalar:   sqrshrn(vf, rd, rn, right_shift); break;
3591     case NEON_SQSHRUN_scalar:   sqshrun(vf, rd, rn, right_shift); break;
3592     case NEON_SQRSHRUN_scalar:  sqrshrun(vf, rd, rn, right_shift); break;
3593     case NEON_FCVTZS_imm_scalar: fcvts(vf, rd, rn, FPZero, right_shift); break;
3594     case NEON_FCVTZU_imm_scalar: fcvtu(vf, rd, rn, FPZero, right_shift); break;
3595     case NEON_SCVTF_imm_scalar:
3596       scvtf(vf, rd, rn, right_shift, fpcr_rounding);
3597       break;
3598     case NEON_UCVTF_imm_scalar:
3599       ucvtf(vf, rd, rn, right_shift, fpcr_rounding);
3600       break;
3601     default:
3602       VIXL_UNIMPLEMENTED();
3603   }
3604 }
3605 
3606 
3607 void Simulator::VisitNEONShiftImmediate(const Instruction* instr) {
3608   SimVRegister& rd = vreg(instr->Rd());
3609   SimVRegister& rn = vreg(instr->Rn());
3610   FPRounding fpcr_rounding = static_cast<FPRounding>(fpcr().RMode());
3611 
3612   // 00010->8B, 00011->16B, 001x0->4H, 001x1->8H,
3613   // 01xx0->2S, 01xx1->4S, 1xxx1->2D, all others undefined.
3614   static const NEONFormatMap map = {
3615     {22, 21, 20, 19, 30},
3616     {NF_UNDEF, NF_UNDEF, NF_8B,    NF_16B, NF_4H,    NF_8H, NF_4H,    NF_8H,
3617      NF_2S,    NF_4S,    NF_2S,    NF_4S,  NF_2S,    NF_4S, NF_2S,    NF_4S,
3618      NF_UNDEF, NF_2D,    NF_UNDEF, NF_2D,  NF_UNDEF, NF_2D, NF_UNDEF, NF_2D,
3619      NF_UNDEF, NF_2D,    NF_UNDEF, NF_2D,  NF_UNDEF, NF_2D, NF_UNDEF, NF_2D}
3620   };
3621   NEONFormatDecoder nfd(instr, &map);
3622   VectorFormat vf = nfd.GetVectorFormat();
3623 
3624   // 0001->8H, 001x->4S, 01xx->2D, all others undefined.
3625   static const NEONFormatMap map_l = {
3626     {22, 21, 20, 19},
3627     {NF_UNDEF, NF_8H, NF_4S, NF_4S, NF_2D, NF_2D, NF_2D, NF_2D}
3628   };
3629   VectorFormat vf_l = nfd.GetVectorFormat(&map_l);
3630 
3631   int highestSetBit = HighestSetBitPosition(instr->ImmNEONImmh());
3632   int immhimmb = instr->ImmNEONImmhImmb();
3633   int right_shift = (16 << highestSetBit) - immhimmb;
3634   int left_shift = immhimmb - (8 << highestSetBit);
3635 
3636   switch (instr->Mask(NEONShiftImmediateMask)) {
3637     case NEON_SHL:    shl(vf, rd, rn, left_shift); break;
3638     case NEON_SLI:    sli(vf, rd, rn, left_shift); break;
3639     case NEON_SQSHLU: sqshlu(vf, rd, rn, left_shift); break;
3640     case NEON_SRI:    sri(vf, rd, rn, right_shift); break;
3641     case NEON_SSHR:   sshr(vf, rd, rn, right_shift); break;
3642     case NEON_USHR:   ushr(vf, rd, rn, right_shift); break;
3643     case NEON_SRSHR:  sshr(vf, rd, rn, right_shift).Round(vf); break;
3644     case NEON_URSHR:  ushr(vf, rd, rn, right_shift).Round(vf); break;
3645     case NEON_SSRA:   ssra(vf, rd, rn, right_shift); break;
3646     case NEON_USRA:   usra(vf, rd, rn, right_shift); break;
3647     case NEON_SRSRA:  srsra(vf, rd, rn, right_shift); break;
3648     case NEON_URSRA:  ursra(vf, rd, rn, right_shift); break;
3649     case NEON_SQSHL_imm: sqshl(vf, rd, rn, left_shift); break;
3650     case NEON_UQSHL_imm: uqshl(vf, rd, rn, left_shift); break;
3651     case NEON_SCVTF_imm: scvtf(vf, rd, rn, right_shift, fpcr_rounding); break;
3652     case NEON_UCVTF_imm: ucvtf(vf, rd, rn, right_shift, fpcr_rounding); break;
3653     case NEON_FCVTZS_imm: fcvts(vf, rd, rn, FPZero, right_shift); break;
3654     case NEON_FCVTZU_imm: fcvtu(vf, rd, rn, FPZero, right_shift); break;
3655     case NEON_SSHLL:
3656       vf = vf_l;
3657       if (instr->Mask(NEON_Q)) {
3658         sshll2(vf, rd, rn, left_shift);
3659       } else {
3660         sshll(vf, rd, rn, left_shift);
3661       }
3662       break;
3663     case NEON_USHLL:
3664       vf = vf_l;
3665       if (instr->Mask(NEON_Q)) {
3666         ushll2(vf, rd, rn, left_shift);
3667       } else {
3668         ushll(vf, rd, rn, left_shift);
3669       }
3670       break;
3671     case NEON_SHRN:
3672       if (instr->Mask(NEON_Q)) {
3673         shrn2(vf, rd, rn, right_shift);
3674       } else {
3675         shrn(vf, rd, rn, right_shift);
3676       }
3677       break;
3678     case NEON_RSHRN:
3679       if (instr->Mask(NEON_Q)) {
3680         rshrn2(vf, rd, rn, right_shift);
3681       } else {
3682         rshrn(vf, rd, rn, right_shift);
3683       }
3684       break;
3685     case NEON_UQSHRN:
3686       if (instr->Mask(NEON_Q)) {
3687         uqshrn2(vf, rd, rn, right_shift);
3688       } else {
3689         uqshrn(vf, rd, rn, right_shift);
3690       }
3691       break;
3692     case NEON_UQRSHRN:
3693       if (instr->Mask(NEON_Q)) {
3694         uqrshrn2(vf, rd, rn, right_shift);
3695       } else {
3696         uqrshrn(vf, rd, rn, right_shift);
3697       }
3698       break;
3699     case NEON_SQSHRN:
3700       if (instr->Mask(NEON_Q)) {
3701         sqshrn2(vf, rd, rn, right_shift);
3702       } else {
3703         sqshrn(vf, rd, rn, right_shift);
3704       }
3705       break;
3706     case NEON_SQRSHRN:
3707       if (instr->Mask(NEON_Q)) {
3708         sqrshrn2(vf, rd, rn, right_shift);
3709       } else {
3710         sqrshrn(vf, rd, rn, right_shift);
3711       }
3712       break;
3713     case NEON_SQSHRUN:
3714       if (instr->Mask(NEON_Q)) {
3715         sqshrun2(vf, rd, rn, right_shift);
3716       } else {
3717         sqshrun(vf, rd, rn, right_shift);
3718       }
3719       break;
3720     case NEON_SQRSHRUN:
3721       if (instr->Mask(NEON_Q)) {
3722         sqrshrun2(vf, rd, rn, right_shift);
3723       } else {
3724         sqrshrun(vf, rd, rn, right_shift);
3725       }
3726       break;
3727     default:
3728       VIXL_UNIMPLEMENTED();
3729   }
3730 }
3731 
3732 
3733 void Simulator::VisitNEONTable(const Instruction* instr) {
3734   NEONFormatDecoder nfd(instr, NEONFormatDecoder::LogicalFormatMap());
3735   VectorFormat vf = nfd.GetVectorFormat();
3736 
3737   SimVRegister& rd = vreg(instr->Rd());
3738   SimVRegister& rn = vreg(instr->Rn());
3739   SimVRegister& rn2 = vreg((instr->Rn() + 1) % kNumberOfVRegisters);
3740   SimVRegister& rn3 = vreg((instr->Rn() + 2) % kNumberOfVRegisters);
3741   SimVRegister& rn4 = vreg((instr->Rn() + 3) % kNumberOfVRegisters);
3742   SimVRegister& rm = vreg(instr->Rm());
3743 
3744   switch (instr->Mask(NEONTableMask)) {
3745     case NEON_TBL_1v: tbl(vf, rd, rn, rm); break;
3746     case NEON_TBL_2v: tbl(vf, rd, rn, rn2, rm); break;
3747     case NEON_TBL_3v: tbl(vf, rd, rn, rn2, rn3, rm); break;
3748     case NEON_TBL_4v: tbl(vf, rd, rn, rn2, rn3, rn4, rm); break;
3749     case NEON_TBX_1v: tbx(vf, rd, rn, rm); break;
3750     case NEON_TBX_2v: tbx(vf, rd, rn, rn2, rm); break;
3751     case NEON_TBX_3v: tbx(vf, rd, rn, rn2, rn3, rm); break;
3752     case NEON_TBX_4v: tbx(vf, rd, rn, rn2, rn3, rn4, rm); break;
3753     default:
3754       VIXL_UNIMPLEMENTED();
3755   }
3756 }
3757 
3758 
3759 void Simulator::VisitNEONPerm(const Instruction* instr) {
3760   NEONFormatDecoder nfd(instr);
3761   VectorFormat vf = nfd.GetVectorFormat();
3762 
3763   SimVRegister& rd = vreg(instr->Rd());
3764   SimVRegister& rn = vreg(instr->Rn());
3765   SimVRegister& rm = vreg(instr->Rm());
3766 
3767   switch (instr->Mask(NEONPermMask)) {
3768     case NEON_TRN1: trn1(vf, rd, rn, rm); break;
3769     case NEON_TRN2: trn2(vf, rd, rn, rm); break;
3770     case NEON_UZP1: uzp1(vf, rd, rn, rm); break;
3771     case NEON_UZP2: uzp2(vf, rd, rn, rm); break;
3772     case NEON_ZIP1: zip1(vf, rd, rn, rm); break;
3773     case NEON_ZIP2: zip2(vf, rd, rn, rm); break;
3774     default:
3775       VIXL_UNIMPLEMENTED();
3776   }
3777 }
3778 
3779 
3780 void Simulator::DoUnreachable(const Instruction* instr) {
3781   VIXL_ASSERT((instr->Mask(ExceptionMask) == HLT) &&
3782               (instr->ImmException() == kUnreachableOpcode));
3783 
3784   fprintf(stream_, "Hit UNREACHABLE marker at pc=%p.\n",
3785           reinterpret_cast<const void*>(instr));
3786   abort();
3787 }
3788 
3789 
3790 void Simulator::DoTrace(const Instruction* instr) {
3791   VIXL_ASSERT((instr->Mask(ExceptionMask) == HLT) &&
3792               (instr->ImmException() == kTraceOpcode));
3793 
3794   // Read the arguments encoded inline in the instruction stream.
3795   uint32_t parameters;
3796   uint32_t command;
3797 
3798   VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
3799   memcpy(&parameters, instr + kTraceParamsOffset, sizeof(parameters));
3800   memcpy(&command, instr + kTraceCommandOffset, sizeof(command));
3801 
3802   switch (command) {
3803     case TRACE_ENABLE:
3804       set_trace_parameters(trace_parameters() | parameters);
3805       break;
3806     case TRACE_DISABLE:
3807       set_trace_parameters(trace_parameters() & ~parameters);
3808       break;
3809     default:
3810       VIXL_UNREACHABLE();
3811   }
3812 
3813   set_pc(instr->InstructionAtOffset(kTraceLength));
3814 }
3815 
3816 
3817 void Simulator::DoLog(const Instruction* instr) {
3818   VIXL_ASSERT((instr->Mask(ExceptionMask) == HLT) &&
3819               (instr->ImmException() == kLogOpcode));
3820 
3821   // Read the arguments encoded inline in the instruction stream.
3822   uint32_t parameters;
3823 
3824   VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
3825   memcpy(&parameters, instr + kTraceParamsOffset, sizeof(parameters));
3826 
3827   // We don't support a one-shot LOG_DISASM.
3828   VIXL_ASSERT((parameters & LOG_DISASM) == 0);
3829   // Print the requested information.
3830   if (parameters & LOG_SYSREGS) PrintSystemRegisters();
3831   if (parameters & LOG_REGS) PrintRegisters();
3832   if (parameters & LOG_VREGS) PrintVRegisters();
3833 
3834   set_pc(instr->InstructionAtOffset(kLogLength));
3835 }
3836 
3837 
3838 void Simulator::DoPrintf(const Instruction* instr) {
3839   VIXL_ASSERT((instr->Mask(ExceptionMask) == HLT) &&
3840               (instr->ImmException() == kPrintfOpcode));
3841 
3842   // Read the arguments encoded inline in the instruction stream.
3843   uint32_t arg_count;
3844   uint32_t arg_pattern_list;
3845   VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
3846   memcpy(&arg_count,
3847          instr + kPrintfArgCountOffset,
3848          sizeof(arg_count));
3849   memcpy(&arg_pattern_list,
3850          instr + kPrintfArgPatternListOffset,
3851          sizeof(arg_pattern_list));
3852 
3853   VIXL_ASSERT(arg_count <= kPrintfMaxArgCount);
3854   VIXL_ASSERT((arg_pattern_list >> (kPrintfArgPatternBits * arg_count)) == 0);
3855 
3856   // We need to call the host printf function with a set of arguments defined by
3857   // arg_pattern_list. Because we don't know the types and sizes of the
3858   // arguments, this is very difficult to do in a robust and portable way. To
3859   // work around the problem, we pick apart the format string, and print one
3860   // format placeholder at a time.
3861 
3862   // Allocate space for the format string. We take a copy, so we can modify it.
3863   // Leave enough space for one extra character per expected argument (plus the
3864   // '\0' termination).
3865   const char * format_base = reg<const char *>(0);
3866   VIXL_ASSERT(format_base != NULL);
3867   size_t length = strlen(format_base) + 1;
3868   char * const format = (char *)js_calloc(length + arg_count);
3869 
3870   // A list of chunks, each with exactly one format placeholder.
3871   const char * chunks[kPrintfMaxArgCount];
3872 
3873   // Copy the format string and search for format placeholders.
3874   uint32_t placeholder_count = 0;
3875   char * format_scratch = format;
3876   for (size_t i = 0; i < length; i++) {
3877     if (format_base[i] != '%') {
3878       *format_scratch++ = format_base[i];
3879     } else {
3880       if (format_base[i + 1] == '%') {
3881         // Ignore explicit "%%" sequences.
3882         *format_scratch++ = format_base[i];
3883         i++;
3884         // Chunks after the first are passed as format strings to printf, so we
3885         // need to escape '%' characters in those chunks.
3886         if (placeholder_count > 0) *format_scratch++ = format_base[i];
3887       } else {
3888         VIXL_CHECK(placeholder_count < arg_count);
3889         // Insert '\0' before placeholders, and store their locations.
3890         *format_scratch++ = '\0';
3891         chunks[placeholder_count++] = format_scratch;
3892         *format_scratch++ = format_base[i];
3893       }
3894     }
3895   }
3896   VIXL_CHECK(placeholder_count == arg_count);
3897 
3898   // Finally, call printf with each chunk, passing the appropriate register
3899   // argument. Normally, printf returns the number of bytes transmitted, so we
3900   // can emulate a single printf call by adding the result from each chunk. If
3901   // any call returns a negative (error) value, though, just return that value.
3902 
3903   printf("%s", clr_printf);
3904 
3905   // Because '\0' is inserted before each placeholder, the first string in
3906   // 'format' contains no format placeholders and should be printed literally.
3907   int result = printf("%s", format);
3908   int pcs_r = 1;      // Start at x1. x0 holds the format string.
3909   int pcs_f = 0;      // Start at d0.
3910   if (result >= 0) {
3911     for (uint32_t i = 0; i < placeholder_count; i++) {
3912       int part_result = -1;
3913 
3914       uint32_t arg_pattern = arg_pattern_list >> (i * kPrintfArgPatternBits);
3915       arg_pattern &= (1 << kPrintfArgPatternBits) - 1;
3916       switch (arg_pattern) {
3917         case kPrintfArgW: part_result = printf(chunks[i], wreg(pcs_r++)); break;
3918         case kPrintfArgX: part_result = printf(chunks[i], xreg(pcs_r++)); break;
3919         case kPrintfArgD: part_result = printf(chunks[i], dreg(pcs_f++)); break;
3920         default: VIXL_UNREACHABLE();
3921       }
3922 
3923       if (part_result < 0) {
3924         // Handle error values.
3925         result = part_result;
3926         break;
3927       }
3928 
3929       result += part_result;
3930     }
3931   }
3932 
3933   printf("%s", clr_normal);
3934 
3935   // Printf returns its result in x0 (just like the C library's printf).
3936   set_xreg(0, result);
3937 
3938   // The printf parameters are inlined in the code, so skip them.
3939   set_pc(instr->InstructionAtOffset(kPrintfLength));
3940 
3941   // Set LR as if we'd just called a native printf function.
3942   set_lr(pc());
3943 
3944   js_free(format);
3945 }
3946 
3947 }  // namespace vixl
3948 
3949 #endif  // JS_SIMULATOR_ARM64
3950