| OLD | NEW | 
|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #ifndef V8_ARM64_SIMULATOR_ARM64_H_ | 5 #ifndef V8_ARM64_SIMULATOR_ARM64_H_ | 
| 6 #define V8_ARM64_SIMULATOR_ARM64_H_ | 6 #define V8_ARM64_SIMULATOR_ARM64_H_ | 
| 7 | 7 | 
| 8 #include <stdarg.h> | 8 #include <stdarg.h> | 
| 9 #include <vector> | 9 #include <vector> | 
| 10 | 10 | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 63     return try_catch_address; | 63     return try_catch_address; | 
| 64   } | 64   } | 
| 65 | 65 | 
| 66   static void UnregisterCTryCatch(v8::internal::Isolate* isolate) { | 66   static void UnregisterCTryCatch(v8::internal::Isolate* isolate) { | 
| 67     USE(isolate); | 67     USE(isolate); | 
| 68   } | 68   } | 
| 69 }; | 69 }; | 
| 70 | 70 | 
| 71 #else  // !defined(USE_SIMULATOR) | 71 #else  // !defined(USE_SIMULATOR) | 
| 72 | 72 | 
|  | 73 // Assemble the specified IEEE-754 components into the target type and apply | 
|  | 74 // appropriate rounding. | 
|  | 75 //  sign:     0 = positive, 1 = negative | 
|  | 76 //  exponent: Unbiased IEEE-754 exponent. | 
|  | 77 //  mantissa: The mantissa of the input. The top bit (which is not encoded for | 
|  | 78 //            normal IEEE-754 values) must not be omitted. This bit has the | 
|  | 79 //            value 'pow(2, exponent)'. | 
|  | 80 // | 
|  | 81 // The input value is assumed to be a normalized value. That is, the input may | 
|  | 82 // not be infinity or NaN. If the source value is subnormal, it must be | 
|  | 83 // normalized before calling this function such that the highest set bit in the | 
|  | 84 // mantissa has the value 'pow(2, exponent)'. | 
|  | 85 // | 
|  | 86 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than | 
|  | 87 // calling a templated FPRound. | 
|  | 88 template <class T, int ebits, int mbits> | 
|  | 89 T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, | 
|  | 90           FPRounding round_mode) { | 
|  | 91   static_assert((sizeof(T) * 8) >= (1 + ebits + mbits), | 
|  | 92                 "destination type T not large enough"); | 
|  | 93   static_assert(sizeof(T) <= sizeof(uint64_t), | 
|  | 94                 "maximum size of destination type T is 64 bits"); | 
|  | 95   static_assert(std::is_unsigned<T>::value, | 
|  | 96                 "destination type T must be unsigned"); | 
|  | 97 | 
|  | 98   DCHECK((sign == 0) || (sign == 1)); | 
|  | 99 | 
|  | 100   // Only FPTieEven and FPRoundOdd rounding modes are implemented. | 
|  | 101   DCHECK((round_mode == FPTieEven) || (round_mode == FPRoundOdd)); | 
|  | 102 | 
|  | 103   // Rounding can promote subnormals to normals, and normals to infinities. For | 
|  | 104   // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be | 
|  | 105   // encodable as a float, but rounding based on the low-order mantissa bits | 
|  | 106   // could make it overflow. With ties-to-even rounding, this value would become | 
|  | 107   // an infinity. | 
|  | 108 | 
|  | 109   // ---- Rounding Method ---- | 
|  | 110   // | 
|  | 111   // The exponent is irrelevant in the rounding operation, so we treat the | 
|  | 112   // lowest-order bit that will fit into the result ('onebit') as having | 
|  | 113   // the value '1'. Similarly, the highest-order bit that won't fit into | 
|  | 114   // the result ('halfbit') has the value '0.5'. The 'point' sits between | 
|  | 115   // 'onebit' and 'halfbit': | 
|  | 116   // | 
|  | 117   //            These bits fit into the result. | 
|  | 118   //               |---------------------| | 
|  | 119   //  mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | 
|  | 120   //                                     || | 
|  | 121   //                                    / | | 
|  | 122   //                                   /  halfbit | 
|  | 123   //                               onebit | 
|  | 124   // | 
|  | 125   // For subnormal outputs, the range of representable bits is smaller and | 
|  | 126   // the position of onebit and halfbit depends on the exponent of the | 
|  | 127   // input, but the method is otherwise similar. | 
|  | 128   // | 
|  | 129   //   onebit(frac) | 
|  | 130   //     | | 
|  | 131   //     | halfbit(frac)          halfbit(adjusted) | 
|  | 132   //     | /                      / | 
|  | 133   //     | |                      | | 
|  | 134   //  0b00.0 (exact)      -> 0b00.0 (exact)                    -> 0b00 | 
|  | 135   //  0b00.0...           -> 0b00.0...                         -> 0b00 | 
|  | 136   //  0b00.1 (exact)      -> 0b00.0111..111                    -> 0b00 | 
|  | 137   //  0b00.1...           -> 0b00.1...                         -> 0b01 | 
|  | 138   //  0b01.0 (exact)      -> 0b01.0 (exact)                    -> 0b01 | 
|  | 139   //  0b01.0...           -> 0b01.0...                         -> 0b01 | 
|  | 140   //  0b01.1 (exact)      -> 0b01.1 (exact)                    -> 0b10 | 
|  | 141   //  0b01.1...           -> 0b01.1...                         -> 0b10 | 
|  | 142   //  0b10.0 (exact)      -> 0b10.0 (exact)                    -> 0b10 | 
|  | 143   //  0b10.0...           -> 0b10.0...                         -> 0b10 | 
|  | 144   //  0b10.1 (exact)      -> 0b10.0111..111                    -> 0b10 | 
|  | 145   //  0b10.1...           -> 0b10.1...                         -> 0b11 | 
|  | 146   //  0b11.0 (exact)      -> 0b11.0 (exact)                    -> 0b11 | 
|  | 147   //  ...                   /             |                      /   | | 
|  | 148   //                       /              |                     /    | | 
|  | 149   //                                                           /     | | 
|  | 150   // adjusted = frac - (halfbit(mantissa) & ~onebit(frac));   /      | | 
|  | 151   // | 
|  | 152   //                   mantissa = (mantissa >> shift) + halfbit(adjusted); | 
|  | 153 | 
|  | 154   const int mantissa_offset = 0; | 
|  | 155   const int exponent_offset = mantissa_offset + mbits; | 
|  | 156   const int sign_offset = exponent_offset + ebits; | 
|  | 157   DCHECK_EQ(sign_offset, static_cast<int>(sizeof(T) * 8 - 1)); | 
|  | 158 | 
|  | 159   // Bail out early for zero inputs. | 
|  | 160   if (mantissa == 0) { | 
|  | 161     return static_cast<T>(sign << sign_offset); | 
|  | 162   } | 
|  | 163 | 
|  | 164   // If all bits in the exponent are set, the value is infinite or NaN. | 
|  | 165   // This is true for all binary IEEE-754 formats. | 
|  | 166   const int infinite_exponent = (1 << ebits) - 1; | 
|  | 167   const int max_normal_exponent = infinite_exponent - 1; | 
|  | 168 | 
|  | 169   // Apply the exponent bias to encode it for the result. Doing this early makes | 
|  | 170   // it easy to detect values that will be infinite or subnormal. | 
|  | 171   exponent += max_normal_exponent >> 1; | 
|  | 172 | 
|  | 173   if (exponent > max_normal_exponent) { | 
|  | 174     // Overflow: the input is too large for the result type to represent. | 
|  | 175     if (round_mode == FPTieEven) { | 
|  | 176       // FPTieEven rounding mode handles overflows using infinities. | 
|  | 177       exponent = infinite_exponent; | 
|  | 178       mantissa = 0; | 
|  | 179     } else { | 
|  | 180       DCHECK_EQ(round_mode, FPRoundOdd); | 
|  | 181       // FPRoundOdd rounding mode handles overflows using the largest magnitude | 
|  | 182       // normal number. | 
|  | 183       exponent = max_normal_exponent; | 
|  | 184       mantissa = (UINT64_C(1) << exponent_offset) - 1; | 
|  | 185     } | 
|  | 186     return static_cast<T>((sign << sign_offset) | | 
|  | 187                           (exponent << exponent_offset) | | 
|  | 188                           (mantissa << mantissa_offset)); | 
|  | 189   } | 
|  | 190 | 
|  | 191   // Calculate the shift required to move the top mantissa bit to the proper | 
|  | 192   // place in the destination type. | 
|  | 193   const int highest_significant_bit = 63 - CountLeadingZeros(mantissa, 64); | 
|  | 194   int shift = highest_significant_bit - mbits; | 
|  | 195 | 
|  | 196   if (exponent <= 0) { | 
|  | 197     // The output will be subnormal (before rounding). | 
|  | 198     // For subnormal outputs, the shift must be adjusted by the exponent. The +1 | 
|  | 199     // is necessary because the exponent of a subnormal value (encoded as 0) is | 
|  | 200     // the same as the exponent of the smallest normal value (encoded as 1). | 
|  | 201     shift += -exponent + 1; | 
|  | 202 | 
|  | 203     // Handle inputs that would produce a zero output. | 
|  | 204     // | 
|  | 205     // Shifts higher than highest_significant_bit+1 will always produce a zero | 
|  | 206     // result. A shift of exactly highest_significant_bit+1 might produce a | 
|  | 207     // non-zero result after rounding. | 
|  | 208     if (shift > (highest_significant_bit + 1)) { | 
|  | 209       if (round_mode == FPTieEven) { | 
|  | 210         // The result will always be +/-0.0. | 
|  | 211         return static_cast<T>(sign << sign_offset); | 
|  | 212       } else { | 
|  | 213         DCHECK_EQ(round_mode, FPRoundOdd); | 
|  | 214         DCHECK_NE(mantissa, 0U); | 
|  | 215         // For FPRoundOdd, if the mantissa is too small to represent and | 
|  | 216         // non-zero return the next "odd" value. | 
|  | 217         return static_cast<T>((sign << sign_offset) | 1); | 
|  | 218       } | 
|  | 219     } | 
|  | 220 | 
|  | 221     // Properly encode the exponent for a subnormal output. | 
|  | 222     exponent = 0; | 
|  | 223   } else { | 
|  | 224     // Clear the topmost mantissa bit, since this is not encoded in IEEE-754 | 
|  | 225     // normal values. | 
|  | 226     mantissa &= ~(UINT64_C(1) << highest_significant_bit); | 
|  | 227   } | 
|  | 228 | 
|  | 229   if (shift > 0) { | 
|  | 230     if (round_mode == FPTieEven) { | 
|  | 231       // We have to shift the mantissa to the right. Some precision is lost, so | 
|  | 232       // we need to apply rounding. | 
|  | 233       uint64_t onebit_mantissa = (mantissa >> (shift)) & 1; | 
|  | 234       uint64_t halfbit_mantissa = (mantissa >> (shift - 1)) & 1; | 
|  | 235       uint64_t adjustment = (halfbit_mantissa & ~onebit_mantissa); | 
|  | 236       uint64_t adjusted = mantissa - adjustment; | 
|  | 237       T halfbit_adjusted = (adjusted >> (shift - 1)) & 1; | 
|  | 238 | 
|  | 239       T result = | 
|  | 240           static_cast<T>((sign << sign_offset) | (exponent << exponent_offset) | | 
|  | 241                          ((mantissa >> shift) << mantissa_offset)); | 
|  | 242 | 
|  | 243       // A very large mantissa can overflow during rounding. If this happens, | 
|  | 244       // the exponent should be incremented and the mantissa set to 1.0 | 
|  | 245       // (encoded as 0). Applying halfbit_adjusted after assembling the float | 
|  | 246       // has the nice side-effect that this case is handled for free. | 
|  | 247       // | 
|  | 248       // This also handles cases where a very large finite value overflows to | 
|  | 249       // infinity, or where a very large subnormal value overflows to become | 
|  | 250       // normal. | 
|  | 251       return result + halfbit_adjusted; | 
|  | 252     } else { | 
|  | 253       DCHECK_EQ(round_mode, FPRoundOdd); | 
|  | 254       // If any bits at position halfbit or below are set, onebit (ie. the | 
|  | 255       // bottom bit of the resulting mantissa) must be set. | 
|  | 256       uint64_t fractional_bits = mantissa & ((UINT64_C(1) << shift) - 1); | 
|  | 257       if (fractional_bits != 0) { | 
|  | 258         mantissa |= UINT64_C(1) << shift; | 
|  | 259       } | 
|  | 260 | 
|  | 261       return static_cast<T>((sign << sign_offset) | | 
|  | 262                             (exponent << exponent_offset) | | 
|  | 263                             ((mantissa >> shift) << mantissa_offset)); | 
|  | 264     } | 
|  | 265   } else { | 
|  | 266     // We have to shift the mantissa to the left (or not at all). The input | 
|  | 267     // mantissa is exactly representable in the output mantissa, so apply no | 
|  | 268     // rounding correction. | 
|  | 269     return static_cast<T>((sign << sign_offset) | | 
|  | 270                           (exponent << exponent_offset) | | 
|  | 271                           ((mantissa << -shift) << mantissa_offset)); | 
|  | 272   } | 
|  | 273 } | 
|  | 274 | 
|  | 275 // Representation of memory, with typed getters and setters for access. | 
|  | 276 class SimMemory { | 
|  | 277  public: | 
|  | 278   template <typename T> | 
|  | 279   static T AddressUntag(T address) { | 
|  | 280     // Cast the address using a C-style cast. A reinterpret_cast would be | 
|  | 281     // appropriate, but it can't cast one integral type to another. | 
|  | 282     uint64_t bits = (uint64_t)address; | 
|  | 283     return (T)(bits & ~kAddressTagMask); | 
|  | 284   } | 
|  | 285 | 
|  | 286   template <typename T, typename A> | 
|  | 287   static T Read(A address) { | 
|  | 288     T value; | 
|  | 289     address = AddressUntag(address); | 
|  | 290     DCHECK((sizeof(value) == 1) || (sizeof(value) == 2) || | 
|  | 291            (sizeof(value) == 4) || (sizeof(value) == 8) || | 
|  | 292            (sizeof(value) == 16)); | 
|  | 293     memcpy(&value, reinterpret_cast<const char*>(address), sizeof(value)); | 
|  | 294     return value; | 
|  | 295   } | 
|  | 296 | 
|  | 297   template <typename T, typename A> | 
|  | 298   static void Write(A address, T value) { | 
|  | 299     address = AddressUntag(address); | 
|  | 300     DCHECK((sizeof(value) == 1) || (sizeof(value) == 2) || | 
|  | 301            (sizeof(value) == 4) || (sizeof(value) == 8) || | 
|  | 302            (sizeof(value) == 16)); | 
|  | 303     memcpy(reinterpret_cast<char*>(address), &value, sizeof(value)); | 
|  | 304   } | 
|  | 305 }; | 
| 73 | 306 | 
| 74 // The proper way to initialize a simulated system register (such as NZCV) is as | 307 // The proper way to initialize a simulated system register (such as NZCV) is as | 
| 75 // follows: | 308 // follows: | 
| 76 //  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV); | 309 //  SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV); | 
| 77 class SimSystemRegister { | 310 class SimSystemRegister { | 
| 78  public: | 311  public: | 
| 79   // The default constructor represents a register which has no writable bits. | 312   // The default constructor represents a register which has no writable bits. | 
| 80   // It is not possible to set its value to anything other than 0. | 313   // It is not possible to set its value to anything other than 0. | 
| 81   SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) { } | 314   SimSystemRegister() : value_(0), write_ignore_mask_(0xffffffff) { } | 
| 82 | 315 | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 118   // describes the bits which are not modifiable. | 351   // describes the bits which are not modifiable. | 
| 119   SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) | 352   SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) | 
| 120       : value_(value), write_ignore_mask_(write_ignore_mask) { } | 353       : value_(value), write_ignore_mask_(write_ignore_mask) { } | 
| 121 | 354 | 
| 122   uint32_t value_; | 355   uint32_t value_; | 
| 123   uint32_t write_ignore_mask_; | 356   uint32_t write_ignore_mask_; | 
| 124 }; | 357 }; | 
| 125 | 358 | 
| 126 | 359 | 
| 127 // Represent a register (r0-r31, v0-v31). | 360 // Represent a register (r0-r31, v0-v31). | 
|  | 361 template <int kSizeInBytes> | 
| 128 class SimRegisterBase { | 362 class SimRegisterBase { | 
| 129  public: | 363  public: | 
| 130   template<typename T> | 364   template<typename T> | 
| 131   void Set(T new_value) { | 365   void Set(T new_value) { | 
| 132     value_ = 0; | 366     static_assert(sizeof(new_value) <= kSizeInBytes, | 
|  | 367                   "Size of new_value must be <= size of template type."); | 
|  | 368     if (sizeof(new_value) < kSizeInBytes) { | 
|  | 369       // All AArch64 registers are zero-extending. | 
|  | 370       memset(value_ + sizeof(new_value), 0, kSizeInBytes - sizeof(new_value)); | 
|  | 371     } | 
| 133     memcpy(&value_, &new_value, sizeof(T)); | 372     memcpy(&value_, &new_value, sizeof(T)); | 
| 134   } | 373     NotifyRegisterWrite(); | 
| 135 | 374   } | 
| 136   template<typename T> | 375 | 
| 137   T Get() const { | 376   // Insert a typed value into a register, leaving the rest of the register | 
|  | 377   // unchanged. The lane parameter indicates where in the register the value | 
|  | 378   // should be inserted, in the range [ 0, sizeof(value_) / sizeof(T) ), where | 
|  | 379   // 0 represents the least significant bits. | 
|  | 380   template <typename T> | 
|  | 381   void Insert(int lane, T new_value) { | 
|  | 382     DCHECK_GE(lane, 0); | 
|  | 383     DCHECK_LE(sizeof(new_value) + (lane * sizeof(new_value)), | 
|  | 384               static_cast<unsigned>(kSizeInBytes)); | 
|  | 385     memcpy(&value_[lane * sizeof(new_value)], &new_value, sizeof(new_value)); | 
|  | 386     NotifyRegisterWrite(); | 
|  | 387   } | 
|  | 388 | 
|  | 389   template <typename T> | 
|  | 390   T Get(int lane = 0) const { | 
| 138     T result; | 391     T result; | 
| 139     memcpy(&result, &value_, sizeof(T)); | 392     DCHECK_GE(lane, 0); | 
|  | 393     DCHECK_LE(sizeof(result) + (lane * sizeof(result)), | 
|  | 394               static_cast<unsigned>(kSizeInBytes)); | 
|  | 395     memcpy(&result, &value_[lane * sizeof(result)], sizeof(result)); | 
| 140     return result; | 396     return result; | 
| 141   } | 397   } | 
| 142 | 398 | 
|  | 399   // TODO(all): Make this return a map of updated bytes, so that we can | 
|  | 400   // highlight updated lanes for load-and-insert. (That never happens for scalar | 
|  | 401   // code, but NEON has some instructions that can update individual lanes.) | 
|  | 402   bool WrittenSinceLastLog() const { return written_since_last_log_; } | 
|  | 403 | 
|  | 404   void NotifyRegisterLogged() { written_since_last_log_ = false; } | 
|  | 405 | 
| 143  protected: | 406  protected: | 
| 144   int64_t value_; | 407   uint8_t value_[kSizeInBytes]; | 
|  | 408 | 
|  | 409   // Helpers to aid with register tracing. | 
|  | 410   bool written_since_last_log_; | 
|  | 411 | 
|  | 412   void NotifyRegisterWrite() { written_since_last_log_ = true; } | 
| 145 }; | 413 }; | 
| 146 | 414 typedef SimRegisterBase<kXRegSize> SimRegister;   // r0-r31 | 
| 147 | 415 typedef SimRegisterBase<kQRegSize> SimVRegister;  // v0-v31 | 
| 148 typedef SimRegisterBase SimRegister;      // r0-r31 | 416 | 
| 149 typedef SimRegisterBase SimFPRegister;    // v0-v31 | 417 // Representation of a vector register, with typed getters and setters for lanes | 
| 150 | 418 // and additional information to represent lane state. | 
|  | 419 class LogicVRegister { | 
|  | 420  public: | 
|  | 421   inline LogicVRegister(SimVRegister& other)  // NOLINT | 
|  | 422       : register_(other) { | 
|  | 423     for (unsigned i = 0; i < sizeof(saturated_) / sizeof(saturated_[0]); i++) { | 
|  | 424       saturated_[i] = kNotSaturated; | 
|  | 425     } | 
|  | 426     for (unsigned i = 0; i < sizeof(round_) / sizeof(round_[0]); i++) { | 
|  | 427       round_[i] = 0; | 
|  | 428     } | 
|  | 429   } | 
|  | 430 | 
|  | 431   int64_t Int(VectorFormat vform, int index) const { | 
|  | 432     int64_t element; | 
|  | 433     switch (LaneSizeInBitsFromFormat(vform)) { | 
|  | 434       case 8: | 
|  | 435         element = register_.Get<int8_t>(index); | 
|  | 436         break; | 
|  | 437       case 16: | 
|  | 438         element = register_.Get<int16_t>(index); | 
|  | 439         break; | 
|  | 440       case 32: | 
|  | 441         element = register_.Get<int32_t>(index); | 
|  | 442         break; | 
|  | 443       case 64: | 
|  | 444         element = register_.Get<int64_t>(index); | 
|  | 445         break; | 
|  | 446       default: | 
|  | 447         UNREACHABLE(); | 
|  | 448         return 0; | 
|  | 449     } | 
|  | 450     return element; | 
|  | 451   } | 
|  | 452 | 
|  | 453   uint64_t Uint(VectorFormat vform, int index) const { | 
|  | 454     uint64_t element; | 
|  | 455     switch (LaneSizeInBitsFromFormat(vform)) { | 
|  | 456       case 8: | 
|  | 457         element = register_.Get<uint8_t>(index); | 
|  | 458         break; | 
|  | 459       case 16: | 
|  | 460         element = register_.Get<uint16_t>(index); | 
|  | 461         break; | 
|  | 462       case 32: | 
|  | 463         element = register_.Get<uint32_t>(index); | 
|  | 464         break; | 
|  | 465       case 64: | 
|  | 466         element = register_.Get<uint64_t>(index); | 
|  | 467         break; | 
|  | 468       default: | 
|  | 469         UNREACHABLE(); | 
|  | 470         return 0; | 
|  | 471     } | 
|  | 472     return element; | 
|  | 473   } | 
|  | 474 | 
|  | 475   uint64_t UintLeftJustified(VectorFormat vform, int index) const { | 
|  | 476     return Uint(vform, index) << (64 - LaneSizeInBitsFromFormat(vform)); | 
|  | 477   } | 
|  | 478 | 
|  | 479   int64_t IntLeftJustified(VectorFormat vform, int index) const { | 
|  | 480     uint64_t value = UintLeftJustified(vform, index); | 
|  | 481     int64_t result; | 
|  | 482     memcpy(&result, &value, sizeof(result)); | 
|  | 483     return result; | 
|  | 484   } | 
|  | 485 | 
|  | 486   void SetInt(VectorFormat vform, int index, int64_t value) const { | 
|  | 487     switch (LaneSizeInBitsFromFormat(vform)) { | 
|  | 488       case 8: | 
|  | 489         register_.Insert(index, static_cast<int8_t>(value)); | 
|  | 490         break; | 
|  | 491       case 16: | 
|  | 492         register_.Insert(index, static_cast<int16_t>(value)); | 
|  | 493         break; | 
|  | 494       case 32: | 
|  | 495         register_.Insert(index, static_cast<int32_t>(value)); | 
|  | 496         break; | 
|  | 497       case 64: | 
|  | 498         register_.Insert(index, static_cast<int64_t>(value)); | 
|  | 499         break; | 
|  | 500       default: | 
|  | 501         UNREACHABLE(); | 
|  | 502         return; | 
|  | 503     } | 
|  | 504   } | 
|  | 505 | 
|  | 506   void SetIntArray(VectorFormat vform, const int64_t* src) const { | 
|  | 507     ClearForWrite(vform); | 
|  | 508     for (int i = 0; i < LaneCountFromFormat(vform); i++) { | 
|  | 509       SetInt(vform, i, src[i]); | 
|  | 510     } | 
|  | 511   } | 
|  | 512 | 
|  | 513   void SetUint(VectorFormat vform, int index, uint64_t value) const { | 
|  | 514     switch (LaneSizeInBitsFromFormat(vform)) { | 
|  | 515       case 8: | 
|  | 516         register_.Insert(index, static_cast<uint8_t>(value)); | 
|  | 517         break; | 
|  | 518       case 16: | 
|  | 519         register_.Insert(index, static_cast<uint16_t>(value)); | 
|  | 520         break; | 
|  | 521       case 32: | 
|  | 522         register_.Insert(index, static_cast<uint32_t>(value)); | 
|  | 523         break; | 
|  | 524       case 64: | 
|  | 525         register_.Insert(index, static_cast<uint64_t>(value)); | 
|  | 526         break; | 
|  | 527       default: | 
|  | 528         UNREACHABLE(); | 
|  | 529         return; | 
|  | 530     } | 
|  | 531   } | 
|  | 532 | 
|  | 533   void SetUintArray(VectorFormat vform, const uint64_t* src) const { | 
|  | 534     ClearForWrite(vform); | 
|  | 535     for (int i = 0; i < LaneCountFromFormat(vform); i++) { | 
|  | 536       SetUint(vform, i, src[i]); | 
|  | 537     } | 
|  | 538   } | 
|  | 539 | 
|  | 540   void ReadUintFromMem(VectorFormat vform, int index, uint64_t addr) const; | 
|  | 541 | 
|  | 542   void WriteUintToMem(VectorFormat vform, int index, uint64_t addr) const; | 
|  | 543 | 
|  | 544   template <typename T> | 
|  | 545   T Float(int index) const { | 
|  | 546     return register_.Get<T>(index); | 
|  | 547   } | 
|  | 548 | 
|  | 549   template <typename T> | 
|  | 550   void SetFloat(int index, T value) const { | 
|  | 551     register_.Insert(index, value); | 
|  | 552   } | 
|  | 553 | 
|  | 554   // When setting a result in a register of size less than Q, the top bits of | 
|  | 555   // the Q register must be cleared. | 
|  | 556   void ClearForWrite(VectorFormat vform) const { | 
|  | 557     unsigned size = RegisterSizeInBytesFromFormat(vform); | 
|  | 558     for (unsigned i = size; i < kQRegSize; i++) { | 
|  | 559       SetUint(kFormat16B, i, 0); | 
|  | 560     } | 
|  | 561   } | 
|  | 562 | 
|  | 563   // Saturation state for each lane of a vector. | 
|  | 564   enum Saturation { | 
|  | 565     kNotSaturated = 0, | 
|  | 566     kSignedSatPositive = 1 << 0, | 
|  | 567     kSignedSatNegative = 1 << 1, | 
|  | 568     kSignedSatMask = kSignedSatPositive | kSignedSatNegative, | 
|  | 569     kSignedSatUndefined = kSignedSatMask, | 
|  | 570     kUnsignedSatPositive = 1 << 2, | 
|  | 571     kUnsignedSatNegative = 1 << 3, | 
|  | 572     kUnsignedSatMask = kUnsignedSatPositive | kUnsignedSatNegative, | 
|  | 573     kUnsignedSatUndefined = kUnsignedSatMask | 
|  | 574   }; | 
|  | 575 | 
|  | 576   // Getters for saturation state. | 
|  | 577   Saturation GetSignedSaturation(int index) { | 
|  | 578     return static_cast<Saturation>(saturated_[index] & kSignedSatMask); | 
|  | 579   } | 
|  | 580 | 
|  | 581   Saturation GetUnsignedSaturation(int index) { | 
|  | 582     return static_cast<Saturation>(saturated_[index] & kUnsignedSatMask); | 
|  | 583   } | 
|  | 584 | 
|  | 585   // Setters for saturation state. | 
|  | 586   void ClearSat(int index) { saturated_[index] = kNotSaturated; } | 
|  | 587 | 
|  | 588   void SetSignedSat(int index, bool positive) { | 
|  | 589     SetSatFlag(index, positive ? kSignedSatPositive : kSignedSatNegative); | 
|  | 590   } | 
|  | 591 | 
|  | 592   void SetUnsignedSat(int index, bool positive) { | 
|  | 593     SetSatFlag(index, positive ? kUnsignedSatPositive : kUnsignedSatNegative); | 
|  | 594   } | 
|  | 595 | 
|  | 596   void SetSatFlag(int index, Saturation sat) { | 
|  | 597     saturated_[index] = static_cast<Saturation>(saturated_[index] | sat); | 
|  | 598     DCHECK_NE(sat & kUnsignedSatMask, kUnsignedSatUndefined); | 
|  | 599     DCHECK_NE(sat & kSignedSatMask, kSignedSatUndefined); | 
|  | 600   } | 
|  | 601 | 
|  | 602   // Saturate lanes of a vector based on saturation state. | 
|  | 603   LogicVRegister& SignedSaturate(VectorFormat vform) { | 
|  | 604     for (int i = 0; i < LaneCountFromFormat(vform); i++) { | 
|  | 605       Saturation sat = GetSignedSaturation(i); | 
|  | 606       if (sat == kSignedSatPositive) { | 
|  | 607         SetInt(vform, i, MaxIntFromFormat(vform)); | 
|  | 608       } else if (sat == kSignedSatNegative) { | 
|  | 609         SetInt(vform, i, MinIntFromFormat(vform)); | 
|  | 610       } | 
|  | 611     } | 
|  | 612     return *this; | 
|  | 613   } | 
|  | 614 | 
|  | 615   LogicVRegister& UnsignedSaturate(VectorFormat vform) { | 
|  | 616     for (int i = 0; i < LaneCountFromFormat(vform); i++) { | 
|  | 617       Saturation sat = GetUnsignedSaturation(i); | 
|  | 618       if (sat == kUnsignedSatPositive) { | 
|  | 619         SetUint(vform, i, MaxUintFromFormat(vform)); | 
|  | 620       } else if (sat == kUnsignedSatNegative) { | 
|  | 621         SetUint(vform, i, 0); | 
|  | 622       } | 
|  | 623     } | 
|  | 624     return *this; | 
|  | 625   } | 
|  | 626 | 
|  | 627   // Getter for rounding state. | 
|  | 628   bool GetRounding(int index) { return round_[index]; } | 
|  | 629 | 
|  | 630   // Setter for rounding state. | 
|  | 631   void SetRounding(int index, bool round) { round_[index] = round; } | 
|  | 632 | 
|  | 633   // Round lanes of a vector based on rounding state. | 
|  | 634   LogicVRegister& Round(VectorFormat vform) { | 
|  | 635     for (int i = 0; i < LaneCountFromFormat(vform); i++) { | 
|  | 636       SetUint(vform, i, Uint(vform, i) + (GetRounding(i) ? 1 : 0)); | 
|  | 637     } | 
|  | 638     return *this; | 
|  | 639   } | 
|  | 640 | 
|  | 641   // Unsigned halve lanes of a vector, and use the saturation state to set the | 
|  | 642   // top bit. | 
|  | 643   LogicVRegister& Uhalve(VectorFormat vform) { | 
|  | 644     for (int i = 0; i < LaneCountFromFormat(vform); i++) { | 
|  | 645       uint64_t val = Uint(vform, i); | 
|  | 646       SetRounding(i, (val & 1) == 1); | 
|  | 647       val >>= 1; | 
|  | 648       if (GetUnsignedSaturation(i) != kNotSaturated) { | 
|  | 649         // If the operation causes unsigned saturation, the bit shifted into the | 
|  | 650         // most significant bit must be set. | 
|  | 651         val |= (MaxUintFromFormat(vform) >> 1) + 1; | 
|  | 652       } | 
|  | 653       SetInt(vform, i, val); | 
|  | 654     } | 
|  | 655     return *this; | 
|  | 656   } | 
|  | 657 | 
|  | 658   // Signed halve lanes of a vector, and use the carry state to set the top bit. | 
|  | 659   LogicVRegister& Halve(VectorFormat vform) { | 
|  | 660     for (int i = 0; i < LaneCountFromFormat(vform); i++) { | 
|  | 661       int64_t val = Int(vform, i); | 
|  | 662       SetRounding(i, (val & 1) == 1); | 
|  | 663       val >>= 1; | 
|  | 664       if (GetSignedSaturation(i) != kNotSaturated) { | 
|  | 665         // If the operation causes signed saturation, the sign bit must be | 
|  | 666         // inverted. | 
|  | 667         val ^= (MaxUintFromFormat(vform) >> 1) + 1; | 
|  | 668       } | 
|  | 669       SetInt(vform, i, val); | 
|  | 670     } | 
|  | 671     return *this; | 
|  | 672   } | 
|  | 673 | 
|  | 674  private: | 
|  | 675   SimVRegister& register_; | 
|  | 676 | 
|  | 677   // Allocate one saturation state entry per lane; largest register is type Q, | 
|  | 678   // and lanes can be a minimum of one byte wide. | 
|  | 679   Saturation saturated_[kQRegSize]; | 
|  | 680 | 
|  | 681   // Allocate one rounding state entry per lane. | 
|  | 682   bool round_[kQRegSize]; | 
|  | 683 }; | 
| 151 | 684 | 
| 152 class Simulator : public DecoderVisitor { | 685 class Simulator : public DecoderVisitor { | 
| 153  public: | 686  public: | 
| 154   static void FlushICache(base::CustomMatcherHashMap* i_cache, void* start, | 687   static void FlushICache(base::CustomMatcherHashMap* i_cache, void* start, | 
| 155                           size_t size) { | 688                           size_t size) { | 
| 156     USE(i_cache); | 689     USE(i_cache); | 
| 157     USE(start); | 690     USE(start); | 
| 158     USE(size); | 691     USE(size); | 
| 159   } | 692   } | 
| 160 | 693 | 
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 308 | 841 | 
| 309   virtual void Decode(Instruction* instr) { | 842   virtual void Decode(Instruction* instr) { | 
| 310     decoder_->Decode(instr); | 843     decoder_->Decode(instr); | 
| 311   } | 844   } | 
| 312 | 845 | 
| 313   void ExecuteInstruction() { | 846   void ExecuteInstruction() { | 
| 314     DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize)); | 847     DCHECK(IsAligned(reinterpret_cast<uintptr_t>(pc_), kInstructionSize)); | 
| 315     CheckBreakNext(); | 848     CheckBreakNext(); | 
| 316     Decode(pc_); | 849     Decode(pc_); | 
| 317     increment_pc(); | 850     increment_pc(); | 
|  | 851     LogAllWrittenRegisters(); | 
| 318     CheckBreakpoints(); | 852     CheckBreakpoints(); | 
| 319   } | 853   } | 
| 320 | 854 | 
| 321   // Declare all Visitor functions. | 855   // Declare all Visitor functions. | 
| 322   #define DECLARE(A)  void Visit##A(Instruction* instr); | 856   #define DECLARE(A)  void Visit##A(Instruction* instr); | 
| 323   VISITOR_LIST(DECLARE) | 857   VISITOR_LIST(DECLARE) | 
| 324   #undef DECLARE | 858   #undef DECLARE | 
| 325 | 859 | 
| 326   bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const { | 860   bool IsZeroRegister(unsigned code, Reg31Mode r31mode) const { | 
| 327     return ((code == 31) && (r31mode == Reg31IsZeroRegister)); | 861     return ((code == 31) && (r31mode == Reg31IsZeroRegister)); | 
| 328   } | 862   } | 
| 329 | 863 | 
| 330   // Register accessors. | 864   // Register accessors. | 
| 331   // Return 'size' bits of the value of an integer register, as the specified | 865   // Return 'size' bits of the value of an integer register, as the specified | 
| 332   // type. The value is zero-extended to fill the result. | 866   // type. The value is zero-extended to fill the result. | 
| 333   // | 867   // | 
| 334   template<typename T> | 868   template<typename T> | 
| 335   T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { | 869   T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { | 
| 336     DCHECK(code < kNumberOfRegisters); | 870     DCHECK_LT(code, static_cast<unsigned>(kNumberOfRegisters)); | 
| 337     if (IsZeroRegister(code, r31mode)) { | 871     if (IsZeroRegister(code, r31mode)) { | 
| 338       return 0; | 872       return 0; | 
| 339     } | 873     } | 
| 340     return registers_[code].Get<T>(); | 874     return registers_[code].Get<T>(); | 
| 341   } | 875   } | 
| 342 | 876 | 
| 343   // Common specialized accessors for the reg() template. | 877   // Common specialized accessors for the reg() template. | 
| 344   int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { | 878   int32_t wreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { | 
| 345     return reg<int32_t>(code, r31mode); | 879     return reg<int32_t>(code, r31mode); | 
| 346   } | 880   } | 
| 347 | 881 | 
| 348   int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { | 882   int64_t xreg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { | 
| 349     return reg<int64_t>(code, r31mode); | 883     return reg<int64_t>(code, r31mode); | 
| 350   } | 884   } | 
| 351 | 885 | 
|  | 886   enum RegLogMode { LogRegWrites, NoRegLog }; | 
|  | 887 | 
| 352   // Write 'value' into an integer register. The value is zero-extended. This | 888   // Write 'value' into an integer register. The value is zero-extended. This | 
| 353   // behaviour matches AArch64 register writes. | 889   // behaviour matches AArch64 register writes. | 
| 354   template<typename T> | 890   template<typename T> | 
| 355   void set_reg(unsigned code, T value, | 891   void set_reg(unsigned code, T value, | 
| 356                Reg31Mode r31mode = Reg31IsZeroRegister) { | 892                Reg31Mode r31mode = Reg31IsZeroRegister) { | 
| 357     set_reg_no_log(code, value, r31mode); | 893     set_reg_no_log(code, value, r31mode); | 
| 358     LogRegister(code, r31mode); | 894     LogRegister(code, r31mode); | 
| 359   } | 895   } | 
| 360 | 896 | 
| 361   // Common specialized accessors for the set_reg() template. | 897   // Common specialized accessors for the set_reg() template. | 
| 362   void set_wreg(unsigned code, int32_t value, | 898   void set_wreg(unsigned code, int32_t value, | 
| 363                 Reg31Mode r31mode = Reg31IsZeroRegister) { | 899                 Reg31Mode r31mode = Reg31IsZeroRegister) { | 
| 364     set_reg(code, value, r31mode); | 900     set_reg(code, value, r31mode); | 
| 365   } | 901   } | 
| 366 | 902 | 
| 367   void set_xreg(unsigned code, int64_t value, | 903   void set_xreg(unsigned code, int64_t value, | 
| 368                 Reg31Mode r31mode = Reg31IsZeroRegister) { | 904                 Reg31Mode r31mode = Reg31IsZeroRegister) { | 
| 369     set_reg(code, value, r31mode); | 905     set_reg(code, value, r31mode); | 
| 370   } | 906   } | 
| 371 | 907 | 
| 372   // As above, but don't automatically log the register update. | 908   // As above, but don't automatically log the register update. | 
| 373   template <typename T> | 909   template <typename T> | 
| 374   void set_reg_no_log(unsigned code, T value, | 910   void set_reg_no_log(unsigned code, T value, | 
| 375                       Reg31Mode r31mode = Reg31IsZeroRegister) { | 911                       Reg31Mode r31mode = Reg31IsZeroRegister) { | 
| 376     DCHECK(code < kNumberOfRegisters); | 912     DCHECK_LT(code, static_cast<unsigned>(kNumberOfRegisters)); | 
| 377     if (!IsZeroRegister(code, r31mode)) { | 913     if (!IsZeroRegister(code, r31mode)) { | 
| 378       registers_[code].Set(value); | 914       registers_[code].Set(value); | 
| 379     } | 915     } | 
| 380   } | 916   } | 
| 381 | 917 | 
| 382   void set_wreg_no_log(unsigned code, int32_t value, | 918   void set_wreg_no_log(unsigned code, int32_t value, | 
| 383                        Reg31Mode r31mode = Reg31IsZeroRegister) { | 919                        Reg31Mode r31mode = Reg31IsZeroRegister) { | 
| 384     set_reg_no_log(code, value, r31mode); | 920     set_reg_no_log(code, value, r31mode); | 
| 385   } | 921   } | 
| 386 | 922 | 
| 387   void set_xreg_no_log(unsigned code, int64_t value, | 923   void set_xreg_no_log(unsigned code, int64_t value, | 
| 388                        Reg31Mode r31mode = Reg31IsZeroRegister) { | 924                        Reg31Mode r31mode = Reg31IsZeroRegister) { | 
| 389     set_reg_no_log(code, value, r31mode); | 925     set_reg_no_log(code, value, r31mode); | 
| 390   } | 926   } | 
| 391 | 927 | 
| 392   // Commonly-used special cases. | 928   // Commonly-used special cases. | 
| 393   template<typename T> | 929   template<typename T> | 
| 394   void set_lr(T value) { | 930   void set_lr(T value) { | 
| 395     DCHECK(sizeof(T) == kPointerSize); | 931     DCHECK_EQ(sizeof(T), static_cast<unsigned>(kPointerSize)); | 
| 396     set_reg(kLinkRegCode, value); | 932     set_reg(kLinkRegCode, value); | 
| 397   } | 933   } | 
| 398 | 934 | 
| 399   template<typename T> | 935   template<typename T> | 
| 400   void set_sp(T value) { | 936   void set_sp(T value) { | 
| 401     DCHECK(sizeof(T) == kPointerSize); | 937     DCHECK_EQ(sizeof(T), static_cast<unsigned>(kPointerSize)); | 
| 402     set_reg(31, value, Reg31IsStackPointer); | 938     set_reg(31, value, Reg31IsStackPointer); | 
| 403   } | 939   } | 
| 404 | 940 | 
|  | 941   // Vector register accessors. | 
|  | 942   // These are equivalent to the integer register accessors, but for vector | 
|  | 943   // registers. | 
|  | 944 | 
|  | 945   // A structure for representing a 128-bit Q register. | 
|  | 946   struct qreg_t { | 
|  | 947     uint8_t val[kQRegSize]; | 
|  | 948   }; | 
|  | 949 | 
|  | 950   // Basic accessor: read the register as the specified type. | 
|  | 951   template <typename T> | 
|  | 952   T vreg(unsigned code) const { | 
|  | 953     static_assert((sizeof(T) == kBRegSize) || (sizeof(T) == kHRegSize) || | 
|  | 954                       (sizeof(T) == kSRegSize) || (sizeof(T) == kDRegSize) || | 
|  | 955                       (sizeof(T) == kQRegSize), | 
|  | 956                   "Template type must match size of register."); | 
|  | 957     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters)); | 
|  | 958 | 
|  | 959     return vregisters_[code].Get<T>(); | 
|  | 960   } | 
|  | 961 | 
|  | 962   inline SimVRegister& vreg(unsigned code) { return vregisters_[code]; } | 
|  | 963 | 
| 405   int64_t sp() { return xreg(31, Reg31IsStackPointer); } | 964   int64_t sp() { return xreg(31, Reg31IsStackPointer); } | 
| 406   int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } | 965   int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } | 
| 407   int64_t fp() { | 966   int64_t fp() { | 
| 408       return xreg(kFramePointerRegCode, Reg31IsStackPointer); | 967       return xreg(kFramePointerRegCode, Reg31IsStackPointer); | 
| 409   } | 968   } | 
| 410   Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } | 969   Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } | 
| 411 | 970 | 
| 412   Address get_sp() const { return reg<Address>(31, Reg31IsStackPointer); } | 971   Address get_sp() const { return reg<Address>(31, Reg31IsStackPointer); } | 
| 413 | 972 | 
| 414   template<typename T> | 973   // Common specialized accessors for the vreg() template. | 
| 415   T fpreg(unsigned code) const { | 974   uint8_t breg(unsigned code) const { return vreg<uint8_t>(code); } | 
| 416     DCHECK(code < kNumberOfRegisters); |  | 
| 417     return fpregisters_[code].Get<T>(); |  | 
| 418   } |  | 
| 419 | 975 | 
| 420   // Common specialized accessors for the fpreg() template. | 976   float hreg(unsigned code) const { return vreg<uint16_t>(code); } | 
| 421   float sreg(unsigned code) const { |  | 
| 422     return fpreg<float>(code); |  | 
| 423   } |  | 
| 424 | 977 | 
| 425   uint32_t sreg_bits(unsigned code) const { | 978   float sreg(unsigned code) const { return vreg<float>(code); } | 
| 426     return fpreg<uint32_t>(code); |  | 
| 427   } |  | 
| 428 | 979 | 
| 429   double dreg(unsigned code) const { | 980   uint32_t sreg_bits(unsigned code) const { return vreg<uint32_t>(code); } | 
| 430     return fpreg<double>(code); |  | 
| 431   } |  | 
| 432 | 981 | 
| 433   uint64_t dreg_bits(unsigned code) const { | 982   double dreg(unsigned code) const { return vreg<double>(code); } | 
| 434     return fpreg<uint64_t>(code); |  | 
| 435   } |  | 
| 436 | 983 | 
| 437   double fpreg(unsigned size, unsigned code) const { | 984   uint64_t dreg_bits(unsigned code) const { return vreg<uint64_t>(code); } | 
|  | 985 | 
|  | 986   qreg_t qreg(unsigned code) const { return vreg<qreg_t>(code); } | 
|  | 987 | 
|  | 988   // As above, with parameterized size and return type. The value is | 
|  | 989   // either zero-extended or truncated to fit, as required. | 
|  | 990   template <typename T> | 
|  | 991   T vreg(unsigned size, unsigned code) const { | 
|  | 992     uint64_t raw = 0; | 
|  | 993     T result; | 
|  | 994 | 
| 438     switch (size) { | 995     switch (size) { | 
| 439       case kSRegSizeInBits: return sreg(code); | 996       case kSRegSize: | 
| 440       case kDRegSizeInBits: return dreg(code); | 997         raw = vreg<uint32_t>(code); | 
|  | 998         break; | 
|  | 999       case kDRegSize: | 
|  | 1000         raw = vreg<uint64_t>(code); | 
|  | 1001         break; | 
| 441       default: | 1002       default: | 
| 442         UNREACHABLE(); | 1003         UNREACHABLE(); | 
| 443         return 0.0; | 1004         break; | 
| 444     } | 1005     } | 
|  | 1006 | 
|  | 1007     static_assert(sizeof(result) <= sizeof(raw), | 
|  | 1008                   "Template type must be <= 64 bits."); | 
|  | 1009     // Copy the result and truncate to fit. This assumes a little-endian host. | 
|  | 1010     memcpy(&result, &raw, sizeof(result)); | 
|  | 1011     return result; | 
| 445   } | 1012   } | 
| 446 | 1013 | 
| 447   // Write 'value' into a floating-point register. The value is zero-extended. | 1014   // Write 'value' into a floating-point register. The value is zero-extended. | 
| 448   // This behaviour matches AArch64 register writes. | 1015   // This behaviour matches AArch64 register writes. | 
| 449   template<typename T> | 1016   template <typename T> | 
| 450   void set_fpreg(unsigned code, T value) { | 1017   void set_vreg(unsigned code, T value, RegLogMode log_mode = LogRegWrites) { | 
| 451     set_fpreg_no_log(code, value); | 1018     static_assert( | 
|  | 1019         (sizeof(value) == kBRegSize) || (sizeof(value) == kHRegSize) || | 
|  | 1020             (sizeof(value) == kSRegSize) || (sizeof(value) == kDRegSize) || | 
|  | 1021             (sizeof(value) == kQRegSize), | 
|  | 1022         "Template type must match size of register."); | 
|  | 1023     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters)); | 
|  | 1024     vregisters_[code].Set(value); | 
| 452 | 1025 | 
| 453     if (sizeof(value) <= kSRegSize) { | 1026     if (log_mode == LogRegWrites) { | 
| 454       LogFPRegister(code, kPrintSRegValue); | 1027       LogVRegister(code, GetPrintRegisterFormat(value)); | 
| 455     } else { |  | 
| 456       LogFPRegister(code, kPrintDRegValue); |  | 
| 457     } | 1028     } | 
| 458   } | 1029   } | 
| 459 | 1030 | 
| 460   // Common specialized accessors for the set_fpreg() template. | 1031   // Common specialized accessors for the set_vreg() template. | 
| 461   void set_sreg(unsigned code, float value) { | 1032   void set_breg(unsigned code, int8_t value, | 
| 462     set_fpreg(code, value); | 1033                 RegLogMode log_mode = LogRegWrites) { | 
|  | 1034     set_vreg(code, value, log_mode); | 
| 463   } | 1035   } | 
| 464 | 1036 | 
| 465   void set_sreg_bits(unsigned code, uint32_t value) { | 1037   void set_hreg(unsigned code, int16_t value, | 
| 466     set_fpreg(code, value); | 1038                 RegLogMode log_mode = LogRegWrites) { | 
|  | 1039     set_vreg(code, value, log_mode); | 
| 467   } | 1040   } | 
| 468 | 1041 | 
| 469   void set_dreg(unsigned code, double value) { | 1042   void set_sreg(unsigned code, float value, | 
| 470     set_fpreg(code, value); | 1043                 RegLogMode log_mode = LogRegWrites) { | 
|  | 1044     set_vreg(code, value, log_mode); | 
| 471   } | 1045   } | 
| 472 | 1046 | 
| 473   void set_dreg_bits(unsigned code, uint64_t value) { | 1047   void set_sreg_bits(unsigned code, uint32_t value, | 
| 474     set_fpreg(code, value); | 1048                      RegLogMode log_mode = LogRegWrites) { | 
|  | 1049     set_vreg(code, value, log_mode); | 
|  | 1050   } | 
|  | 1051 | 
|  | 1052   void set_dreg(unsigned code, double value, | 
|  | 1053                 RegLogMode log_mode = LogRegWrites) { | 
|  | 1054     set_vreg(code, value, log_mode); | 
|  | 1055   } | 
|  | 1056 | 
|  | 1057   void set_dreg_bits(unsigned code, uint64_t value, | 
|  | 1058                      RegLogMode log_mode = LogRegWrites) { | 
|  | 1059     set_vreg(code, value, log_mode); | 
|  | 1060   } | 
|  | 1061 | 
|  | 1062   void set_qreg(unsigned code, qreg_t value, | 
|  | 1063                 RegLogMode log_mode = LogRegWrites) { | 
|  | 1064     set_vreg(code, value, log_mode); | 
| 475   } | 1065   } | 
| 476 | 1066 | 
| 477   // As above, but don't automatically log the register update. | 1067   // As above, but don't automatically log the register update. | 
| 478   template <typename T> | 1068   template <typename T> | 
| 479   void set_fpreg_no_log(unsigned code, T value) { | 1069   void set_vreg_no_log(unsigned code, T value) { | 
| 480     DCHECK((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); | 1070     STATIC_ASSERT((sizeof(value) == kBRegSize) || | 
| 481     DCHECK(code < kNumberOfFPRegisters); | 1071                   (sizeof(value) == kHRegSize) || | 
| 482     fpregisters_[code].Set(value); | 1072                   (sizeof(value) == kSRegSize) || | 
|  | 1073                   (sizeof(value) == kDRegSize) || (sizeof(value) == kQRegSize)); | 
|  | 1074     DCHECK_LT(code, static_cast<unsigned>(kNumberOfVRegisters)); | 
|  | 1075     vregisters_[code].Set(value); | 
|  | 1076   } | 
|  | 1077 | 
|  | 1078   void set_breg_no_log(unsigned code, uint8_t value) { | 
|  | 1079     set_vreg_no_log(code, value); | 
|  | 1080   } | 
|  | 1081 | 
|  | 1082   void set_hreg_no_log(unsigned code, uint16_t value) { | 
|  | 1083     set_vreg_no_log(code, value); | 
| 483   } | 1084   } | 
| 484 | 1085 | 
| 485   void set_sreg_no_log(unsigned code, float value) { | 1086   void set_sreg_no_log(unsigned code, float value) { | 
| 486     set_fpreg_no_log(code, value); | 1087     set_vreg_no_log(code, value); | 
| 487   } | 1088   } | 
| 488 | 1089 | 
| 489   void set_dreg_no_log(unsigned code, double value) { | 1090   void set_dreg_no_log(unsigned code, double value) { | 
| 490     set_fpreg_no_log(code, value); | 1091     set_vreg_no_log(code, value); | 
|  | 1092   } | 
|  | 1093 | 
|  | 1094   void set_qreg_no_log(unsigned code, qreg_t value) { | 
|  | 1095     set_vreg_no_log(code, value); | 
| 491   } | 1096   } | 
| 492 | 1097 | 
| 493   SimSystemRegister& nzcv() { return nzcv_; } | 1098   SimSystemRegister& nzcv() { return nzcv_; } | 
| 494   SimSystemRegister& fpcr() { return fpcr_; } | 1099   SimSystemRegister& fpcr() { return fpcr_; } | 
|  | 1100   FPRounding RMode() { return static_cast<FPRounding>(fpcr_.RMode()); } | 
|  | 1101   bool DN() { return fpcr_.DN() != 0; } | 
| 495 | 1102 | 
| 496   // Debug helpers | 1103   // Debug helpers | 
| 497 | 1104 | 
| 498   // Simulator breakpoints. | 1105   // Simulator breakpoints. | 
| 499   struct Breakpoint { | 1106   struct Breakpoint { | 
| 500     Instruction* location; | 1107     Instruction* location; | 
| 501     bool enabled; | 1108     bool enabled; | 
| 502   }; | 1109   }; | 
| 503   std::vector<Breakpoint> breakpoints_; | 1110   std::vector<Breakpoint> breakpoints_; | 
| 504   void SetBreakpoint(Instruction* breakpoint); | 1111   void SetBreakpoint(Instruction* breakpoint); | 
| 505   void ListBreakpoints(); | 1112   void ListBreakpoints(); | 
| 506   void CheckBreakpoints(); | 1113   void CheckBreakpoints(); | 
| 507 | 1114 | 
| 508   // Helpers for the 'next' command. | 1115   // Helpers for the 'next' command. | 
| 509   // When this is set, the Simulator will insert a breakpoint after the next BL | 1116   // When this is set, the Simulator will insert a breakpoint after the next BL | 
| 510   // instruction it meets. | 1117   // instruction it meets. | 
| 511   bool break_on_next_; | 1118   bool break_on_next_; | 
| 512   // Check if the Simulator should insert a break after the current instruction | 1119   // Check if the Simulator should insert a break after the current instruction | 
| 513   // for the 'next' command. | 1120   // for the 'next' command. | 
| 514   void CheckBreakNext(); | 1121   void CheckBreakNext(); | 
| 515 | 1122 | 
| 516   // Disassemble instruction at the given address. | 1123   // Disassemble instruction at the given address. | 
| 517   void PrintInstructionsAt(Instruction* pc, uint64_t count); | 1124   void PrintInstructionsAt(Instruction* pc, uint64_t count); | 
| 518 | 1125 | 
| 519   // Print all registers of the specified types. | 1126   // Print all registers of the specified types. | 
| 520   void PrintRegisters(); | 1127   void PrintRegisters(); | 
| 521   void PrintFPRegisters(); | 1128   void PrintVRegisters(); | 
| 522   void PrintSystemRegisters(); | 1129   void PrintSystemRegisters(); | 
| 523 | 1130 | 
| 524   // Like Print* (above), but respect log_parameters(). | 1131   // As above, but only print the registers that have been updated. | 
| 525   void LogSystemRegisters() { | 1132   void PrintWrittenRegisters(); | 
| 526     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegisters(); | 1133   void PrintWrittenVRegisters(); | 
|  | 1134 | 
|  | 1135   // As above, but respect LOG_REG and LOG_VREG. | 
|  | 1136   void LogWrittenRegisters() { | 
|  | 1137     if (log_parameters() & LOG_REGS) PrintWrittenRegisters(); | 
| 527   } | 1138   } | 
| 528   void LogRegisters() { | 1139   void LogWrittenVRegisters() { | 
| 529     if (log_parameters() & LOG_REGS) PrintRegisters(); | 1140     if (log_parameters() & LOG_VREGS) PrintWrittenVRegisters(); | 
| 530   } | 1141   } | 
| 531   void LogFPRegisters() { | 1142   void LogAllWrittenRegisters() { | 
| 532     if (log_parameters() & LOG_FP_REGS) PrintFPRegisters(); | 1143     LogWrittenRegisters(); | 
|  | 1144     LogWrittenVRegisters(); | 
| 533   } | 1145   } | 
| 534 | 1146 | 
| 535   // Specify relevant register sizes, for PrintFPRegister. | 1147   // Specify relevant register formats for Print(V)Register and related helpers. | 
| 536   // | 1148   enum PrintRegisterFormat { | 
| 537   // These values are bit masks; they can be combined in case multiple views of | 1149     // The lane size. | 
| 538   // a machine register are interesting. | 1150     kPrintRegLaneSizeB = 0 << 0, | 
| 539   enum PrintFPRegisterSizes { | 1151     kPrintRegLaneSizeH = 1 << 0, | 
| 540     kPrintDRegValue = 1 << kDRegSize, | 1152     kPrintRegLaneSizeS = 2 << 0, | 
| 541     kPrintSRegValue = 1 << kSRegSize, | 1153     kPrintRegLaneSizeW = kPrintRegLaneSizeS, | 
| 542     kPrintAllFPRegValues = kPrintDRegValue | kPrintSRegValue | 1154     kPrintRegLaneSizeD = 3 << 0, | 
|  | 1155     kPrintRegLaneSizeX = kPrintRegLaneSizeD, | 
|  | 1156     kPrintRegLaneSizeQ = 4 << 0, | 
|  | 1157 | 
|  | 1158     kPrintRegLaneSizeOffset = 0, | 
|  | 1159     kPrintRegLaneSizeMask = 7 << 0, | 
|  | 1160 | 
|  | 1161     // The lane count. | 
|  | 1162     kPrintRegAsScalar = 0, | 
|  | 1163     kPrintRegAsDVector = 1 << 3, | 
|  | 1164     kPrintRegAsQVector = 2 << 3, | 
|  | 1165 | 
|  | 1166     kPrintRegAsVectorMask = 3 << 3, | 
|  | 1167 | 
|  | 1168     // Indicate floating-point format lanes. (This flag is only supported for S- | 
|  | 1169     // and D-sized lanes.) | 
|  | 1170     kPrintRegAsFP = 1 << 5, | 
|  | 1171 | 
|  | 1172     // Supported combinations. | 
|  | 1173 | 
|  | 1174     kPrintXReg = kPrintRegLaneSizeX | kPrintRegAsScalar, | 
|  | 1175     kPrintWReg = kPrintRegLaneSizeW | kPrintRegAsScalar, | 
|  | 1176     kPrintSReg = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP, | 
|  | 1177     kPrintDReg = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP, | 
|  | 1178 | 
|  | 1179     kPrintReg1B = kPrintRegLaneSizeB | kPrintRegAsScalar, | 
|  | 1180     kPrintReg8B = kPrintRegLaneSizeB | kPrintRegAsDVector, | 
|  | 1181     kPrintReg16B = kPrintRegLaneSizeB | kPrintRegAsQVector, | 
|  | 1182     kPrintReg1H = kPrintRegLaneSizeH | kPrintRegAsScalar, | 
|  | 1183     kPrintReg4H = kPrintRegLaneSizeH | kPrintRegAsDVector, | 
|  | 1184     kPrintReg8H = kPrintRegLaneSizeH | kPrintRegAsQVector, | 
|  | 1185     kPrintReg1S = kPrintRegLaneSizeS | kPrintRegAsScalar, | 
|  | 1186     kPrintReg2S = kPrintRegLaneSizeS | kPrintRegAsDVector, | 
|  | 1187     kPrintReg4S = kPrintRegLaneSizeS | kPrintRegAsQVector, | 
|  | 1188     kPrintReg1SFP = kPrintRegLaneSizeS | kPrintRegAsScalar | kPrintRegAsFP, | 
|  | 1189     kPrintReg2SFP = kPrintRegLaneSizeS | kPrintRegAsDVector | kPrintRegAsFP, | 
|  | 1190     kPrintReg4SFP = kPrintRegLaneSizeS | kPrintRegAsQVector | kPrintRegAsFP, | 
|  | 1191     kPrintReg1D = kPrintRegLaneSizeD | kPrintRegAsScalar, | 
|  | 1192     kPrintReg2D = kPrintRegLaneSizeD | kPrintRegAsQVector, | 
|  | 1193     kPrintReg1DFP = kPrintRegLaneSizeD | kPrintRegAsScalar | kPrintRegAsFP, | 
|  | 1194     kPrintReg2DFP = kPrintRegLaneSizeD | kPrintRegAsQVector | kPrintRegAsFP, | 
|  | 1195     kPrintReg1Q = kPrintRegLaneSizeQ | kPrintRegAsScalar | 
| 543   }; | 1196   }; | 
| 544 | 1197 | 
|  | 1198   unsigned GetPrintRegLaneSizeInBytesLog2(PrintRegisterFormat format) { | 
|  | 1199     return (format & kPrintRegLaneSizeMask) >> kPrintRegLaneSizeOffset; | 
|  | 1200   } | 
|  | 1201 | 
|  | 1202   unsigned GetPrintRegLaneSizeInBytes(PrintRegisterFormat format) { | 
|  | 1203     return 1 << GetPrintRegLaneSizeInBytesLog2(format); | 
|  | 1204   } | 
|  | 1205 | 
|  | 1206   unsigned GetPrintRegSizeInBytesLog2(PrintRegisterFormat format) { | 
|  | 1207     if (format & kPrintRegAsDVector) return kDRegSizeLog2; | 
|  | 1208     if (format & kPrintRegAsQVector) return kQRegSizeLog2; | 
|  | 1209 | 
|  | 1210     // Scalar types. | 
|  | 1211     return GetPrintRegLaneSizeInBytesLog2(format); | 
|  | 1212   } | 
|  | 1213 | 
|  | 1214   unsigned GetPrintRegSizeInBytes(PrintRegisterFormat format) { | 
|  | 1215     return 1 << GetPrintRegSizeInBytesLog2(format); | 
|  | 1216   } | 
|  | 1217 | 
|  | 1218   unsigned GetPrintRegLaneCount(PrintRegisterFormat format) { | 
|  | 1219     unsigned reg_size_log2 = GetPrintRegSizeInBytesLog2(format); | 
|  | 1220     unsigned lane_size_log2 = GetPrintRegLaneSizeInBytesLog2(format); | 
|  | 1221     DCHECK_GE(reg_size_log2, lane_size_log2); | 
|  | 1222     return 1 << (reg_size_log2 - lane_size_log2); | 
|  | 1223   } | 
|  | 1224 | 
|  | 1225   template <typename T> | 
|  | 1226   PrintRegisterFormat GetPrintRegisterFormat(T value) { | 
|  | 1227     return GetPrintRegisterFormatForSize(sizeof(value)); | 
|  | 1228   } | 
|  | 1229 | 
|  | 1230   PrintRegisterFormat GetPrintRegisterFormat(double value) { | 
|  | 1231     static_assert(sizeof(value) == kDRegSize, | 
|  | 1232                   "D register must be size of double."); | 
|  | 1233     return GetPrintRegisterFormatForSizeFP(sizeof(value)); | 
|  | 1234   } | 
|  | 1235 | 
|  | 1236   PrintRegisterFormat GetPrintRegisterFormat(float value) { | 
|  | 1237     static_assert(sizeof(value) == kSRegSize, | 
|  | 1238                   "S register must be size of float."); | 
|  | 1239     return GetPrintRegisterFormatForSizeFP(sizeof(value)); | 
|  | 1240   } | 
|  | 1241 | 
|  | 1242   PrintRegisterFormat GetPrintRegisterFormat(VectorFormat vform); | 
|  | 1243   PrintRegisterFormat GetPrintRegisterFormatFP(VectorFormat vform); | 
|  | 1244 | 
|  | 1245   PrintRegisterFormat GetPrintRegisterFormatForSize(size_t reg_size, | 
|  | 1246                                                     size_t lane_size); | 
|  | 1247 | 
|  | 1248   PrintRegisterFormat GetPrintRegisterFormatForSize(size_t size) { | 
|  | 1249     return GetPrintRegisterFormatForSize(size, size); | 
|  | 1250   } | 
|  | 1251 | 
|  | 1252   PrintRegisterFormat GetPrintRegisterFormatForSizeFP(size_t size) { | 
|  | 1253     switch (size) { | 
|  | 1254       default: | 
|  | 1255         UNREACHABLE(); | 
|  | 1256       case kDRegSize: | 
|  | 1257         return kPrintDReg; | 
|  | 1258       case kSRegSize: | 
|  | 1259         return kPrintSReg; | 
|  | 1260     } | 
|  | 1261   } | 
|  | 1262 | 
|  | 1263   PrintRegisterFormat GetPrintRegisterFormatTryFP(PrintRegisterFormat format) { | 
|  | 1264     if ((GetPrintRegLaneSizeInBytes(format) == kSRegSize) || | 
|  | 1265         (GetPrintRegLaneSizeInBytes(format) == kDRegSize)) { | 
|  | 1266       return static_cast<PrintRegisterFormat>(format | kPrintRegAsFP); | 
|  | 1267     } | 
|  | 1268     return format; | 
|  | 1269   } | 
|  | 1270 | 
| 545   // Print individual register values (after update). | 1271   // Print individual register values (after update). | 
| 546   void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer); | 1272   void PrintRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer); | 
| 547   void PrintFPRegister(unsigned code, | 1273   void PrintVRegister(unsigned code, PrintRegisterFormat sizes); | 
| 548                        PrintFPRegisterSizes sizes = kPrintAllFPRegValues); |  | 
| 549   void PrintSystemRegister(SystemRegister id); | 1274   void PrintSystemRegister(SystemRegister id); | 
| 550 | 1275 | 
| 551   // Like Print* (above), but respect log_parameters(). | 1276   // Like Print* (above), but respect log_parameters(). | 
| 552   void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) { | 1277   void LogRegister(unsigned code, Reg31Mode r31mode = Reg31IsStackPointer) { | 
| 553     if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode); | 1278     if (log_parameters() & LOG_REGS) PrintRegister(code, r31mode); | 
| 554   } | 1279   } | 
| 555   void LogFPRegister(unsigned code, | 1280   void LogVRegister(unsigned code, PrintRegisterFormat format) { | 
| 556                      PrintFPRegisterSizes sizes = kPrintAllFPRegValues) { | 1281     if (log_parameters() & LOG_VREGS) PrintVRegister(code, format); | 
| 557     if (log_parameters() & LOG_FP_REGS) PrintFPRegister(code, sizes); |  | 
| 558   } | 1282   } | 
| 559   void LogSystemRegister(SystemRegister id) { | 1283   void LogSystemRegister(SystemRegister id) { | 
| 560     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id); | 1284     if (log_parameters() & LOG_SYS_REGS) PrintSystemRegister(id); | 
| 561   } | 1285   } | 
| 562 | 1286 | 
| 563   // Print memory accesses. | 1287   // Print memory accesses. | 
| 564   void PrintRead(uintptr_t address, size_t size, unsigned reg_code); | 1288   void PrintRead(uintptr_t address, unsigned reg_code, | 
| 565   void PrintReadFP(uintptr_t address, size_t size, unsigned reg_code); | 1289                  PrintRegisterFormat format); | 
| 566   void PrintWrite(uintptr_t address, size_t size, unsigned reg_code); | 1290   void PrintWrite(uintptr_t address, unsigned reg_code, | 
| 567   void PrintWriteFP(uintptr_t address, size_t size, unsigned reg_code); | 1291                   PrintRegisterFormat format); | 
|  | 1292   void PrintVRead(uintptr_t address, unsigned reg_code, | 
|  | 1293                   PrintRegisterFormat format, unsigned lane); | 
|  | 1294   void PrintVWrite(uintptr_t address, unsigned reg_code, | 
|  | 1295                    PrintRegisterFormat format, unsigned lane); | 
| 568 | 1296 | 
| 569   // Like Print* (above), but respect log_parameters(). | 1297   // Like Print* (above), but respect log_parameters(). | 
| 570   void LogRead(uintptr_t address, size_t size, unsigned reg_code) { | 1298   void LogRead(uintptr_t address, unsigned reg_code, | 
| 571     if (log_parameters() & LOG_REGS) PrintRead(address, size, reg_code); | 1299                PrintRegisterFormat format) { | 
|  | 1300     if (log_parameters() & LOG_REGS) PrintRead(address, reg_code, format); | 
| 572   } | 1301   } | 
| 573   void LogReadFP(uintptr_t address, size_t size, unsigned reg_code) { | 1302   void LogWrite(uintptr_t address, unsigned reg_code, | 
| 574     if (log_parameters() & LOG_FP_REGS) PrintReadFP(address, size, reg_code); | 1303                 PrintRegisterFormat format) { | 
|  | 1304     if (log_parameters() & LOG_WRITE) PrintWrite(address, reg_code, format); | 
| 575   } | 1305   } | 
| 576   void LogWrite(uintptr_t address, size_t size, unsigned reg_code) { | 1306   void LogVRead(uintptr_t address, unsigned reg_code, | 
| 577     if (log_parameters() & LOG_WRITE) PrintWrite(address, size, reg_code); | 1307                 PrintRegisterFormat format, unsigned lane = 0) { | 
|  | 1308     if (log_parameters() & LOG_VREGS) { | 
|  | 1309       PrintVRead(address, reg_code, format, lane); | 
|  | 1310     } | 
| 578   } | 1311   } | 
| 579   void LogWriteFP(uintptr_t address, size_t size, unsigned reg_code) { | 1312   void LogVWrite(uintptr_t address, unsigned reg_code, | 
| 580     if (log_parameters() & LOG_WRITE) PrintWriteFP(address, size, reg_code); | 1313                  PrintRegisterFormat format, unsigned lane = 0) { | 
|  | 1314     if (log_parameters() & LOG_WRITE) { | 
|  | 1315       PrintVWrite(address, reg_code, format, lane); | 
|  | 1316     } | 
| 581   } | 1317   } | 
| 582 | 1318 | 
| 583   int log_parameters() { return log_parameters_; } | 1319   int log_parameters() { return log_parameters_; } | 
| 584   void set_log_parameters(int new_parameters) { | 1320   void set_log_parameters(int new_parameters) { | 
| 585     log_parameters_ = new_parameters; | 1321     log_parameters_ = new_parameters; | 
| 586     if (!decoder_) { | 1322     if (!decoder_) { | 
| 587       if (new_parameters & LOG_DISASM) { | 1323       if (new_parameters & LOG_DISASM) { | 
| 588         PrintF("Run --debug-sim to dynamically turn on disassembler\n"); | 1324         PrintF("Run --debug-sim to dynamically turn on disassembler\n"); | 
| 589       } | 1325       } | 
| 590       return; | 1326       return; | 
| 591     } | 1327     } | 
| 592     if (new_parameters & LOG_DISASM) { | 1328     if (new_parameters & LOG_DISASM) { | 
| 593       decoder_->InsertVisitorBefore(print_disasm_, this); | 1329       decoder_->InsertVisitorBefore(print_disasm_, this); | 
| 594     } else { | 1330     } else { | 
| 595       decoder_->RemoveVisitor(print_disasm_); | 1331       decoder_->RemoveVisitor(print_disasm_); | 
| 596     } | 1332     } | 
| 597   } | 1333   } | 
| 598 | 1334 | 
|  | 1335   // Helper functions for register tracing. | 
|  | 1336   void PrintRegisterRawHelper(unsigned code, Reg31Mode r31mode, | 
|  | 1337                               int size_in_bytes = kXRegSize); | 
|  | 1338   void PrintVRegisterRawHelper(unsigned code, int bytes = kQRegSize, | 
|  | 1339                                int lsb = 0); | 
|  | 1340   void PrintVRegisterFPHelper(unsigned code, unsigned lane_size_in_bytes, | 
|  | 1341                               int lane_count = 1, int rightmost_lane = 0); | 
|  | 1342 | 
| 599   static inline const char* WRegNameForCode(unsigned code, | 1343   static inline const char* WRegNameForCode(unsigned code, | 
| 600       Reg31Mode mode = Reg31IsZeroRegister); | 1344       Reg31Mode mode = Reg31IsZeroRegister); | 
| 601   static inline const char* XRegNameForCode(unsigned code, | 1345   static inline const char* XRegNameForCode(unsigned code, | 
| 602       Reg31Mode mode = Reg31IsZeroRegister); | 1346       Reg31Mode mode = Reg31IsZeroRegister); | 
| 603   static inline const char* SRegNameForCode(unsigned code); | 1347   static inline const char* SRegNameForCode(unsigned code); | 
| 604   static inline const char* DRegNameForCode(unsigned code); | 1348   static inline const char* DRegNameForCode(unsigned code); | 
| 605   static inline const char* VRegNameForCode(unsigned code); | 1349   static inline const char* VRegNameForCode(unsigned code); | 
| 606   static inline int CodeFromName(const char* name); | 1350   static inline int CodeFromName(const char* name); | 
| 607 | 1351 | 
| 608  protected: | 1352  protected: | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 663   void ConditionalCompareHelper(Instruction* instr, T op2); | 1407   void ConditionalCompareHelper(Instruction* instr, T op2); | 
| 664   void LoadStoreHelper(Instruction* instr, | 1408   void LoadStoreHelper(Instruction* instr, | 
| 665                        int64_t offset, | 1409                        int64_t offset, | 
| 666                        AddrMode addrmode); | 1410                        AddrMode addrmode); | 
| 667   void LoadStorePairHelper(Instruction* instr, AddrMode addrmode); | 1411   void LoadStorePairHelper(Instruction* instr, AddrMode addrmode); | 
| 668   uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset, | 1412   uintptr_t LoadStoreAddress(unsigned addr_reg, int64_t offset, | 
| 669                              AddrMode addrmode); | 1413                              AddrMode addrmode); | 
| 670   void LoadStoreWriteBack(unsigned addr_reg, | 1414   void LoadStoreWriteBack(unsigned addr_reg, | 
| 671                           int64_t offset, | 1415                           int64_t offset, | 
| 672                           AddrMode addrmode); | 1416                           AddrMode addrmode); | 
|  | 1417   void NEONLoadStoreMultiStructHelper(const Instruction* instr, | 
|  | 1418                                       AddrMode addr_mode); | 
|  | 1419   void NEONLoadStoreSingleStructHelper(const Instruction* instr, | 
|  | 1420                                        AddrMode addr_mode); | 
| 673   void CheckMemoryAccess(uintptr_t address, uintptr_t stack); | 1421   void CheckMemoryAccess(uintptr_t address, uintptr_t stack); | 
| 674 | 1422 | 
| 675   // Memory read helpers. | 1423   // Memory read helpers. | 
| 676   template <typename T, typename A> | 1424   template <typename T, typename A> | 
| 677   T MemoryRead(A address) { | 1425   T MemoryRead(A address) { | 
| 678     T value; | 1426     T value; | 
| 679     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || | 1427     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || | 
| 680                   (sizeof(value) == 4) || (sizeof(value) == 8)); | 1428                   (sizeof(value) == 4) || (sizeof(value) == 8) || | 
|  | 1429                   (sizeof(value) == 16)); | 
| 681     memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value)); | 1430     memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value)); | 
| 682     return value; | 1431     return value; | 
| 683   } | 1432   } | 
| 684 | 1433 | 
| 685   // Memory write helpers. | 1434   // Memory write helpers. | 
| 686   template <typename T, typename A> | 1435   template <typename T, typename A> | 
| 687   void MemoryWrite(A address, T value) { | 1436   void MemoryWrite(A address, T value) { | 
| 688     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || | 1437     STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) || | 
| 689                   (sizeof(value) == 4) || (sizeof(value) == 8)); | 1438                   (sizeof(value) == 4) || (sizeof(value) == 8) || | 
|  | 1439                   (sizeof(value) == 16)); | 
| 690     memcpy(reinterpret_cast<void*>(address), &value, sizeof(value)); | 1440     memcpy(reinterpret_cast<void*>(address), &value, sizeof(value)); | 
| 691   } | 1441   } | 
| 692 | 1442 | 
| 693   template <typename T> | 1443   template <typename T> | 
| 694   T ShiftOperand(T value, | 1444   T ShiftOperand(T value, | 
| 695                  Shift shift_type, | 1445                  Shift shift_type, | 
| 696                  unsigned amount); | 1446                  unsigned amount); | 
| 697   template <typename T> | 1447   template <typename T> | 
| 698   T ExtendValue(T value, | 1448   T ExtendValue(T value, | 
| 699                 Extend extend_type, | 1449                 Extend extend_type, | 
| 700                 unsigned left_shift = 0); | 1450                 unsigned left_shift = 0); | 
| 701   template <typename T> | 1451   template <typename T> | 
| 702   void Extract(Instruction* instr); | 1452   void Extract(Instruction* instr); | 
| 703   template <typename T> | 1453   template <typename T> | 
| 704   void DataProcessing2Source(Instruction* instr); | 1454   void DataProcessing2Source(Instruction* instr); | 
| 705   template <typename T> | 1455   template <typename T> | 
| 706   void BitfieldHelper(Instruction* instr); | 1456   void BitfieldHelper(Instruction* instr); | 
| 707 | 1457   uint16_t PolynomialMult(uint8_t op1, uint8_t op2); | 
| 708   template <typename T> | 1458 | 
| 709   T FPDefaultNaN() const; | 1459   void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr); | 
|  | 1460   void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr); | 
|  | 1461   void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr); | 
|  | 1462   void ld2(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1463            uint64_t addr); | 
|  | 1464   void ld2(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1465            int index, uint64_t addr); | 
|  | 1466   void ld2r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1467             uint64_t addr); | 
|  | 1468   void ld3(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1469            LogicVRegister dst3, uint64_t addr); | 
|  | 1470   void ld3(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1471            LogicVRegister dst3, int index, uint64_t addr); | 
|  | 1472   void ld3r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1473             LogicVRegister dst3, uint64_t addr); | 
|  | 1474   void ld4(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1475            LogicVRegister dst3, LogicVRegister dst4, uint64_t addr); | 
|  | 1476   void ld4(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1477            LogicVRegister dst3, LogicVRegister dst4, int index, uint64_t addr); | 
|  | 1478   void ld4r(VectorFormat vform, LogicVRegister dst1, LogicVRegister dst2, | 
|  | 1479             LogicVRegister dst3, LogicVRegister dst4, uint64_t addr); | 
|  | 1480   void st1(VectorFormat vform, LogicVRegister src, uint64_t addr); | 
|  | 1481   void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr); | 
|  | 1482   void st2(VectorFormat vform, LogicVRegister src, LogicVRegister src2, | 
|  | 1483            uint64_t addr); | 
|  | 1484   void st2(VectorFormat vform, LogicVRegister src, LogicVRegister src2, | 
|  | 1485            int index, uint64_t addr); | 
|  | 1486   void st3(VectorFormat vform, LogicVRegister src, LogicVRegister src2, | 
|  | 1487            LogicVRegister src3, uint64_t addr); | 
|  | 1488   void st3(VectorFormat vform, LogicVRegister src, LogicVRegister src2, | 
|  | 1489            LogicVRegister src3, int index, uint64_t addr); | 
|  | 1490   void st4(VectorFormat vform, LogicVRegister src, LogicVRegister src2, | 
|  | 1491            LogicVRegister src3, LogicVRegister src4, uint64_t addr); | 
|  | 1492   void st4(VectorFormat vform, LogicVRegister src, LogicVRegister src2, | 
|  | 1493            LogicVRegister src3, LogicVRegister src4, int index, uint64_t addr); | 
|  | 1494   LogicVRegister cmp(VectorFormat vform, LogicVRegister dst, | 
|  | 1495                      const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1496                      Condition cond); | 
|  | 1497   LogicVRegister cmp(VectorFormat vform, LogicVRegister dst, | 
|  | 1498                      const LogicVRegister& src1, int imm, Condition cond); | 
|  | 1499   LogicVRegister cmptst(VectorFormat vform, LogicVRegister dst, | 
|  | 1500                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1501   LogicVRegister add(VectorFormat vform, LogicVRegister dst, | 
|  | 1502                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1503   LogicVRegister addp(VectorFormat vform, LogicVRegister dst, | 
|  | 1504                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1505   LogicVRegister mla(VectorFormat vform, LogicVRegister dst, | 
|  | 1506                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1507   LogicVRegister mls(VectorFormat vform, LogicVRegister dst, | 
|  | 1508                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1509   LogicVRegister mul(VectorFormat vform, LogicVRegister dst, | 
|  | 1510                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1511   LogicVRegister mul(VectorFormat vform, LogicVRegister dst, | 
|  | 1512                      const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1513                      int index); | 
|  | 1514   LogicVRegister mla(VectorFormat vform, LogicVRegister dst, | 
|  | 1515                      const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1516                      int index); | 
|  | 1517   LogicVRegister mls(VectorFormat vform, LogicVRegister dst, | 
|  | 1518                      const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1519                      int index); | 
|  | 1520   LogicVRegister pmul(VectorFormat vform, LogicVRegister dst, | 
|  | 1521                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1522 | 
|  | 1523   typedef LogicVRegister (Simulator::*ByElementOp)(VectorFormat vform, | 
|  | 1524                                                    LogicVRegister dst, | 
|  | 1525                                                    const LogicVRegister& src1, | 
|  | 1526                                                    const LogicVRegister& src2, | 
|  | 1527                                                    int index); | 
|  | 1528   LogicVRegister fmul(VectorFormat vform, LogicVRegister dst, | 
|  | 1529                       const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1530                       int index); | 
|  | 1531   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst, | 
|  | 1532                       const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1533                       int index); | 
|  | 1534   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst, | 
|  | 1535                       const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1536                       int index); | 
|  | 1537   LogicVRegister fmulx(VectorFormat vform, LogicVRegister dst, | 
|  | 1538                        const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1539                        int index); | 
|  | 1540   LogicVRegister smull(VectorFormat vform, LogicVRegister dst, | 
|  | 1541                        const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1542                        int index); | 
|  | 1543   LogicVRegister smull2(VectorFormat vform, LogicVRegister dst, | 
|  | 1544                         const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1545                         int index); | 
|  | 1546   LogicVRegister umull(VectorFormat vform, LogicVRegister dst, | 
|  | 1547                        const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1548                        int index); | 
|  | 1549   LogicVRegister umull2(VectorFormat vform, LogicVRegister dst, | 
|  | 1550                         const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1551                         int index); | 
|  | 1552   LogicVRegister smlal(VectorFormat vform, LogicVRegister dst, | 
|  | 1553                        const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1554                        int index); | 
|  | 1555   LogicVRegister smlal2(VectorFormat vform, LogicVRegister dst, | 
|  | 1556                         const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1557                         int index); | 
|  | 1558   LogicVRegister umlal(VectorFormat vform, LogicVRegister dst, | 
|  | 1559                        const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1560                        int index); | 
|  | 1561   LogicVRegister umlal2(VectorFormat vform, LogicVRegister dst, | 
|  | 1562                         const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1563                         int index); | 
|  | 1564   LogicVRegister smlsl(VectorFormat vform, LogicVRegister dst, | 
|  | 1565                        const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1566                        int index); | 
|  | 1567   LogicVRegister smlsl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1568                         const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1569                         int index); | 
|  | 1570   LogicVRegister umlsl(VectorFormat vform, LogicVRegister dst, | 
|  | 1571                        const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1572                        int index); | 
|  | 1573   LogicVRegister umlsl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1574                         const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1575                         int index); | 
|  | 1576   LogicVRegister sqdmull(VectorFormat vform, LogicVRegister dst, | 
|  | 1577                          const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1578                          int index); | 
|  | 1579   LogicVRegister sqdmull2(VectorFormat vform, LogicVRegister dst, | 
|  | 1580                           const LogicVRegister& src1, | 
|  | 1581                           const LogicVRegister& src2, int index); | 
|  | 1582   LogicVRegister sqdmlal(VectorFormat vform, LogicVRegister dst, | 
|  | 1583                          const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1584                          int index); | 
|  | 1585   LogicVRegister sqdmlal2(VectorFormat vform, LogicVRegister dst, | 
|  | 1586                           const LogicVRegister& src1, | 
|  | 1587                           const LogicVRegister& src2, int index); | 
|  | 1588   LogicVRegister sqdmlsl(VectorFormat vform, LogicVRegister dst, | 
|  | 1589                          const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1590                          int index); | 
|  | 1591   LogicVRegister sqdmlsl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1592                           const LogicVRegister& src1, | 
|  | 1593                           const LogicVRegister& src2, int index); | 
|  | 1594   LogicVRegister sqdmulh(VectorFormat vform, LogicVRegister dst, | 
|  | 1595                          const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1596                          int index); | 
|  | 1597   LogicVRegister sqrdmulh(VectorFormat vform, LogicVRegister dst, | 
|  | 1598                           const LogicVRegister& src1, | 
|  | 1599                           const LogicVRegister& src2, int index); | 
|  | 1600   LogicVRegister sub(VectorFormat vform, LogicVRegister dst, | 
|  | 1601                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1602   LogicVRegister and_(VectorFormat vform, LogicVRegister dst, | 
|  | 1603                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1604   LogicVRegister orr(VectorFormat vform, LogicVRegister dst, | 
|  | 1605                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1606   LogicVRegister orn(VectorFormat vform, LogicVRegister dst, | 
|  | 1607                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1608   LogicVRegister eor(VectorFormat vform, LogicVRegister dst, | 
|  | 1609                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1610   LogicVRegister bic(VectorFormat vform, LogicVRegister dst, | 
|  | 1611                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1612   LogicVRegister bic(VectorFormat vform, LogicVRegister dst, | 
|  | 1613                      const LogicVRegister& src, uint64_t imm); | 
|  | 1614   LogicVRegister bif(VectorFormat vform, LogicVRegister dst, | 
|  | 1615                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1616   LogicVRegister bit(VectorFormat vform, LogicVRegister dst, | 
|  | 1617                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1618   LogicVRegister bsl(VectorFormat vform, LogicVRegister dst, | 
|  | 1619                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1620   LogicVRegister cls(VectorFormat vform, LogicVRegister dst, | 
|  | 1621                      const LogicVRegister& src); | 
|  | 1622   LogicVRegister clz(VectorFormat vform, LogicVRegister dst, | 
|  | 1623                      const LogicVRegister& src); | 
|  | 1624   LogicVRegister cnt(VectorFormat vform, LogicVRegister dst, | 
|  | 1625                      const LogicVRegister& src); | 
|  | 1626   LogicVRegister not_(VectorFormat vform, LogicVRegister dst, | 
|  | 1627                       const LogicVRegister& src); | 
|  | 1628   LogicVRegister rbit(VectorFormat vform, LogicVRegister dst, | 
|  | 1629                       const LogicVRegister& src); | 
|  | 1630   LogicVRegister rev(VectorFormat vform, LogicVRegister dst, | 
|  | 1631                      const LogicVRegister& src, int revSize); | 
|  | 1632   LogicVRegister rev16(VectorFormat vform, LogicVRegister dst, | 
|  | 1633                        const LogicVRegister& src); | 
|  | 1634   LogicVRegister rev32(VectorFormat vform, LogicVRegister dst, | 
|  | 1635                        const LogicVRegister& src); | 
|  | 1636   LogicVRegister rev64(VectorFormat vform, LogicVRegister dst, | 
|  | 1637                        const LogicVRegister& src); | 
|  | 1638   LogicVRegister addlp(VectorFormat vform, LogicVRegister dst, | 
|  | 1639                        const LogicVRegister& src, bool is_signed, | 
|  | 1640                        bool do_accumulate); | 
|  | 1641   LogicVRegister saddlp(VectorFormat vform, LogicVRegister dst, | 
|  | 1642                         const LogicVRegister& src); | 
|  | 1643   LogicVRegister uaddlp(VectorFormat vform, LogicVRegister dst, | 
|  | 1644                         const LogicVRegister& src); | 
|  | 1645   LogicVRegister sadalp(VectorFormat vform, LogicVRegister dst, | 
|  | 1646                         const LogicVRegister& src); | 
|  | 1647   LogicVRegister uadalp(VectorFormat vform, LogicVRegister dst, | 
|  | 1648                         const LogicVRegister& src); | 
|  | 1649   LogicVRegister ext(VectorFormat vform, LogicVRegister dst, | 
|  | 1650                      const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1651                      int index); | 
|  | 1652   LogicVRegister ins_element(VectorFormat vform, LogicVRegister dst, | 
|  | 1653                              int dst_index, const LogicVRegister& src, | 
|  | 1654                              int src_index); | 
|  | 1655   LogicVRegister ins_immediate(VectorFormat vform, LogicVRegister dst, | 
|  | 1656                                int dst_index, uint64_t imm); | 
|  | 1657   LogicVRegister dup_element(VectorFormat vform, LogicVRegister dst, | 
|  | 1658                              const LogicVRegister& src, int src_index); | 
|  | 1659   LogicVRegister dup_immediate(VectorFormat vform, LogicVRegister dst, | 
|  | 1660                                uint64_t imm); | 
|  | 1661   LogicVRegister movi(VectorFormat vform, LogicVRegister dst, uint64_t imm); | 
|  | 1662   LogicVRegister mvni(VectorFormat vform, LogicVRegister dst, uint64_t imm); | 
|  | 1663   LogicVRegister orr(VectorFormat vform, LogicVRegister dst, | 
|  | 1664                      const LogicVRegister& src, uint64_t imm); | 
|  | 1665   LogicVRegister sshl(VectorFormat vform, LogicVRegister dst, | 
|  | 1666                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1667   LogicVRegister ushl(VectorFormat vform, LogicVRegister dst, | 
|  | 1668                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1669   LogicVRegister SMinMax(VectorFormat vform, LogicVRegister dst, | 
|  | 1670                          const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1671                          bool max); | 
|  | 1672   LogicVRegister smax(VectorFormat vform, LogicVRegister dst, | 
|  | 1673                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1674   LogicVRegister smin(VectorFormat vform, LogicVRegister dst, | 
|  | 1675                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1676   LogicVRegister SMinMaxP(VectorFormat vform, LogicVRegister dst, | 
|  | 1677                           const LogicVRegister& src1, | 
|  | 1678                           const LogicVRegister& src2, bool max); | 
|  | 1679   LogicVRegister smaxp(VectorFormat vform, LogicVRegister dst, | 
|  | 1680                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1681   LogicVRegister sminp(VectorFormat vform, LogicVRegister dst, | 
|  | 1682                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1683   LogicVRegister addp(VectorFormat vform, LogicVRegister dst, | 
|  | 1684                       const LogicVRegister& src); | 
|  | 1685   LogicVRegister addv(VectorFormat vform, LogicVRegister dst, | 
|  | 1686                       const LogicVRegister& src); | 
|  | 1687   LogicVRegister uaddlv(VectorFormat vform, LogicVRegister dst, | 
|  | 1688                         const LogicVRegister& src); | 
|  | 1689   LogicVRegister saddlv(VectorFormat vform, LogicVRegister dst, | 
|  | 1690                         const LogicVRegister& src); | 
|  | 1691   LogicVRegister SMinMaxV(VectorFormat vform, LogicVRegister dst, | 
|  | 1692                           const LogicVRegister& src, bool max); | 
|  | 1693   LogicVRegister smaxv(VectorFormat vform, LogicVRegister dst, | 
|  | 1694                        const LogicVRegister& src); | 
|  | 1695   LogicVRegister sminv(VectorFormat vform, LogicVRegister dst, | 
|  | 1696                        const LogicVRegister& src); | 
|  | 1697   LogicVRegister uxtl(VectorFormat vform, LogicVRegister dst, | 
|  | 1698                       const LogicVRegister& src); | 
|  | 1699   LogicVRegister uxtl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1700                        const LogicVRegister& src); | 
|  | 1701   LogicVRegister sxtl(VectorFormat vform, LogicVRegister dst, | 
|  | 1702                       const LogicVRegister& src); | 
|  | 1703   LogicVRegister sxtl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1704                        const LogicVRegister& src); | 
|  | 1705   LogicVRegister Table(VectorFormat vform, LogicVRegister dst, | 
|  | 1706                        const LogicVRegister& ind, bool zero_out_of_bounds, | 
|  | 1707                        const LogicVRegister* tab1, | 
|  | 1708                        const LogicVRegister* tab2 = NULL, | 
|  | 1709                        const LogicVRegister* tab3 = NULL, | 
|  | 1710                        const LogicVRegister* tab4 = NULL); | 
|  | 1711   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst, | 
|  | 1712                      const LogicVRegister& tab, const LogicVRegister& ind); | 
|  | 1713   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst, | 
|  | 1714                      const LogicVRegister& tab, const LogicVRegister& tab2, | 
|  | 1715                      const LogicVRegister& ind); | 
|  | 1716   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst, | 
|  | 1717                      const LogicVRegister& tab, const LogicVRegister& tab2, | 
|  | 1718                      const LogicVRegister& tab3, const LogicVRegister& ind); | 
|  | 1719   LogicVRegister tbl(VectorFormat vform, LogicVRegister dst, | 
|  | 1720                      const LogicVRegister& tab, const LogicVRegister& tab2, | 
|  | 1721                      const LogicVRegister& tab3, const LogicVRegister& tab4, | 
|  | 1722                      const LogicVRegister& ind); | 
|  | 1723   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst, | 
|  | 1724                      const LogicVRegister& tab, const LogicVRegister& ind); | 
|  | 1725   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst, | 
|  | 1726                      const LogicVRegister& tab, const LogicVRegister& tab2, | 
|  | 1727                      const LogicVRegister& ind); | 
|  | 1728   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst, | 
|  | 1729                      const LogicVRegister& tab, const LogicVRegister& tab2, | 
|  | 1730                      const LogicVRegister& tab3, const LogicVRegister& ind); | 
|  | 1731   LogicVRegister tbx(VectorFormat vform, LogicVRegister dst, | 
|  | 1732                      const LogicVRegister& tab, const LogicVRegister& tab2, | 
|  | 1733                      const LogicVRegister& tab3, const LogicVRegister& tab4, | 
|  | 1734                      const LogicVRegister& ind); | 
|  | 1735   LogicVRegister uaddl(VectorFormat vform, LogicVRegister dst, | 
|  | 1736                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1737   LogicVRegister uaddl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1738                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1739   LogicVRegister uaddw(VectorFormat vform, LogicVRegister dst, | 
|  | 1740                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1741   LogicVRegister uaddw2(VectorFormat vform, LogicVRegister dst, | 
|  | 1742                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1743   LogicVRegister saddl(VectorFormat vform, LogicVRegister dst, | 
|  | 1744                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1745   LogicVRegister saddl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1746                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1747   LogicVRegister saddw(VectorFormat vform, LogicVRegister dst, | 
|  | 1748                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1749   LogicVRegister saddw2(VectorFormat vform, LogicVRegister dst, | 
|  | 1750                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1751   LogicVRegister usubl(VectorFormat vform, LogicVRegister dst, | 
|  | 1752                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1753   LogicVRegister usubl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1754                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1755   LogicVRegister usubw(VectorFormat vform, LogicVRegister dst, | 
|  | 1756                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1757   LogicVRegister usubw2(VectorFormat vform, LogicVRegister dst, | 
|  | 1758                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1759   LogicVRegister ssubl(VectorFormat vform, LogicVRegister dst, | 
|  | 1760                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1761   LogicVRegister ssubl2(VectorFormat vform, LogicVRegister dst, | 
|  | 1762                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1763   LogicVRegister ssubw(VectorFormat vform, LogicVRegister dst, | 
|  | 1764                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1765   LogicVRegister ssubw2(VectorFormat vform, LogicVRegister dst, | 
|  | 1766                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1767   LogicVRegister UMinMax(VectorFormat vform, LogicVRegister dst, | 
|  | 1768                          const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1769                          bool max); | 
|  | 1770   LogicVRegister umax(VectorFormat vform, LogicVRegister dst, | 
|  | 1771                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1772   LogicVRegister umin(VectorFormat vform, LogicVRegister dst, | 
|  | 1773                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1774   LogicVRegister UMinMaxP(VectorFormat vform, LogicVRegister dst, | 
|  | 1775                           const LogicVRegister& src1, | 
|  | 1776                           const LogicVRegister& src2, bool max); | 
|  | 1777   LogicVRegister umaxp(VectorFormat vform, LogicVRegister dst, | 
|  | 1778                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1779   LogicVRegister uminp(VectorFormat vform, LogicVRegister dst, | 
|  | 1780                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1781   LogicVRegister UMinMaxV(VectorFormat vform, LogicVRegister dst, | 
|  | 1782                           const LogicVRegister& src, bool max); | 
|  | 1783   LogicVRegister umaxv(VectorFormat vform, LogicVRegister dst, | 
|  | 1784                        const LogicVRegister& src); | 
|  | 1785   LogicVRegister uminv(VectorFormat vform, LogicVRegister dst, | 
|  | 1786                        const LogicVRegister& src); | 
|  | 1787   LogicVRegister trn1(VectorFormat vform, LogicVRegister dst, | 
|  | 1788                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1789   LogicVRegister trn2(VectorFormat vform, LogicVRegister dst, | 
|  | 1790                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1791   LogicVRegister zip1(VectorFormat vform, LogicVRegister dst, | 
|  | 1792                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1793   LogicVRegister zip2(VectorFormat vform, LogicVRegister dst, | 
|  | 1794                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1795   LogicVRegister uzp1(VectorFormat vform, LogicVRegister dst, | 
|  | 1796                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1797   LogicVRegister uzp2(VectorFormat vform, LogicVRegister dst, | 
|  | 1798                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1799   LogicVRegister shl(VectorFormat vform, LogicVRegister dst, | 
|  | 1800                      const LogicVRegister& src, int shift); | 
|  | 1801   LogicVRegister scvtf(VectorFormat vform, LogicVRegister dst, | 
|  | 1802                        const LogicVRegister& src, int fbits, | 
|  | 1803                        FPRounding rounding_mode); | 
|  | 1804   LogicVRegister ucvtf(VectorFormat vform, LogicVRegister dst, | 
|  | 1805                        const LogicVRegister& src, int fbits, | 
|  | 1806                        FPRounding rounding_mode); | 
|  | 1807   LogicVRegister sshll(VectorFormat vform, LogicVRegister dst, | 
|  | 1808                        const LogicVRegister& src, int shift); | 
|  | 1809   LogicVRegister sshll2(VectorFormat vform, LogicVRegister dst, | 
|  | 1810                         const LogicVRegister& src, int shift); | 
|  | 1811   LogicVRegister shll(VectorFormat vform, LogicVRegister dst, | 
|  | 1812                       const LogicVRegister& src); | 
|  | 1813   LogicVRegister shll2(VectorFormat vform, LogicVRegister dst, | 
|  | 1814                        const LogicVRegister& src); | 
|  | 1815   LogicVRegister ushll(VectorFormat vform, LogicVRegister dst, | 
|  | 1816                        const LogicVRegister& src, int shift); | 
|  | 1817   LogicVRegister ushll2(VectorFormat vform, LogicVRegister dst, | 
|  | 1818                         const LogicVRegister& src, int shift); | 
|  | 1819   LogicVRegister sli(VectorFormat vform, LogicVRegister dst, | 
|  | 1820                      const LogicVRegister& src, int shift); | 
|  | 1821   LogicVRegister sri(VectorFormat vform, LogicVRegister dst, | 
|  | 1822                      const LogicVRegister& src, int shift); | 
|  | 1823   LogicVRegister sshr(VectorFormat vform, LogicVRegister dst, | 
|  | 1824                       const LogicVRegister& src, int shift); | 
|  | 1825   LogicVRegister ushr(VectorFormat vform, LogicVRegister dst, | 
|  | 1826                       const LogicVRegister& src, int shift); | 
|  | 1827   LogicVRegister ssra(VectorFormat vform, LogicVRegister dst, | 
|  | 1828                       const LogicVRegister& src, int shift); | 
|  | 1829   LogicVRegister usra(VectorFormat vform, LogicVRegister dst, | 
|  | 1830                       const LogicVRegister& src, int shift); | 
|  | 1831   LogicVRegister srsra(VectorFormat vform, LogicVRegister dst, | 
|  | 1832                        const LogicVRegister& src, int shift); | 
|  | 1833   LogicVRegister ursra(VectorFormat vform, LogicVRegister dst, | 
|  | 1834                        const LogicVRegister& src, int shift); | 
|  | 1835   LogicVRegister suqadd(VectorFormat vform, LogicVRegister dst, | 
|  | 1836                         const LogicVRegister& src); | 
|  | 1837   LogicVRegister usqadd(VectorFormat vform, LogicVRegister dst, | 
|  | 1838                         const LogicVRegister& src); | 
|  | 1839   LogicVRegister sqshl(VectorFormat vform, LogicVRegister dst, | 
|  | 1840                        const LogicVRegister& src, int shift); | 
|  | 1841   LogicVRegister uqshl(VectorFormat vform, LogicVRegister dst, | 
|  | 1842                        const LogicVRegister& src, int shift); | 
|  | 1843   LogicVRegister sqshlu(VectorFormat vform, LogicVRegister dst, | 
|  | 1844                         const LogicVRegister& src, int shift); | 
|  | 1845   LogicVRegister abs(VectorFormat vform, LogicVRegister dst, | 
|  | 1846                      const LogicVRegister& src); | 
|  | 1847   LogicVRegister neg(VectorFormat vform, LogicVRegister dst, | 
|  | 1848                      const LogicVRegister& src); | 
|  | 1849   LogicVRegister ExtractNarrow(VectorFormat vform, LogicVRegister dst, | 
|  | 1850                                bool dstIsSigned, const LogicVRegister& src, | 
|  | 1851                                bool srcIsSigned); | 
|  | 1852   LogicVRegister xtn(VectorFormat vform, LogicVRegister dst, | 
|  | 1853                      const LogicVRegister& src); | 
|  | 1854   LogicVRegister sqxtn(VectorFormat vform, LogicVRegister dst, | 
|  | 1855                        const LogicVRegister& src); | 
|  | 1856   LogicVRegister uqxtn(VectorFormat vform, LogicVRegister dst, | 
|  | 1857                        const LogicVRegister& src); | 
|  | 1858   LogicVRegister sqxtun(VectorFormat vform, LogicVRegister dst, | 
|  | 1859                         const LogicVRegister& src); | 
|  | 1860   LogicVRegister AbsDiff(VectorFormat vform, LogicVRegister dst, | 
|  | 1861                          const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 1862                          bool issigned); | 
|  | 1863   LogicVRegister saba(VectorFormat vform, LogicVRegister dst, | 
|  | 1864                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1865   LogicVRegister uaba(VectorFormat vform, LogicVRegister dst, | 
|  | 1866                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1867   LogicVRegister shrn(VectorFormat vform, LogicVRegister dst, | 
|  | 1868                       const LogicVRegister& src, int shift); | 
|  | 1869   LogicVRegister shrn2(VectorFormat vform, LogicVRegister dst, | 
|  | 1870                        const LogicVRegister& src, int shift); | 
|  | 1871   LogicVRegister rshrn(VectorFormat vform, LogicVRegister dst, | 
|  | 1872                        const LogicVRegister& src, int shift); | 
|  | 1873   LogicVRegister rshrn2(VectorFormat vform, LogicVRegister dst, | 
|  | 1874                         const LogicVRegister& src, int shift); | 
|  | 1875   LogicVRegister uqshrn(VectorFormat vform, LogicVRegister dst, | 
|  | 1876                         const LogicVRegister& src, int shift); | 
|  | 1877   LogicVRegister uqshrn2(VectorFormat vform, LogicVRegister dst, | 
|  | 1878                          const LogicVRegister& src, int shift); | 
|  | 1879   LogicVRegister uqrshrn(VectorFormat vform, LogicVRegister dst, | 
|  | 1880                          const LogicVRegister& src, int shift); | 
|  | 1881   LogicVRegister uqrshrn2(VectorFormat vform, LogicVRegister dst, | 
|  | 1882                           const LogicVRegister& src, int shift); | 
|  | 1883   LogicVRegister sqshrn(VectorFormat vform, LogicVRegister dst, | 
|  | 1884                         const LogicVRegister& src, int shift); | 
|  | 1885   LogicVRegister sqshrn2(VectorFormat vform, LogicVRegister dst, | 
|  | 1886                          const LogicVRegister& src, int shift); | 
|  | 1887   LogicVRegister sqrshrn(VectorFormat vform, LogicVRegister dst, | 
|  | 1888                          const LogicVRegister& src, int shift); | 
|  | 1889   LogicVRegister sqrshrn2(VectorFormat vform, LogicVRegister dst, | 
|  | 1890                           const LogicVRegister& src, int shift); | 
|  | 1891   LogicVRegister sqshrun(VectorFormat vform, LogicVRegister dst, | 
|  | 1892                          const LogicVRegister& src, int shift); | 
|  | 1893   LogicVRegister sqshrun2(VectorFormat vform, LogicVRegister dst, | 
|  | 1894                           const LogicVRegister& src, int shift); | 
|  | 1895   LogicVRegister sqrshrun(VectorFormat vform, LogicVRegister dst, | 
|  | 1896                           const LogicVRegister& src, int shift); | 
|  | 1897   LogicVRegister sqrshrun2(VectorFormat vform, LogicVRegister dst, | 
|  | 1898                            const LogicVRegister& src, int shift); | 
|  | 1899   LogicVRegister sqrdmulh(VectorFormat vform, LogicVRegister dst, | 
|  | 1900                           const LogicVRegister& src1, | 
|  | 1901                           const LogicVRegister& src2, bool round = true); | 
|  | 1902   LogicVRegister sqdmulh(VectorFormat vform, LogicVRegister dst, | 
|  | 1903                          const LogicVRegister& src1, | 
|  | 1904                          const LogicVRegister& src2); | 
|  | 1905 #define NEON_3VREG_LOGIC_LIST(V) \ | 
|  | 1906   V(addhn)                       \ | 
|  | 1907   V(addhn2)                      \ | 
|  | 1908   V(raddhn)                      \ | 
|  | 1909   V(raddhn2)                     \ | 
|  | 1910   V(subhn)                       \ | 
|  | 1911   V(subhn2)                      \ | 
|  | 1912   V(rsubhn)                      \ | 
|  | 1913   V(rsubhn2)                     \ | 
|  | 1914   V(pmull)                       \ | 
|  | 1915   V(pmull2)                      \ | 
|  | 1916   V(sabal)                       \ | 
|  | 1917   V(sabal2)                      \ | 
|  | 1918   V(uabal)                       \ | 
|  | 1919   V(uabal2)                      \ | 
|  | 1920   V(sabdl)                       \ | 
|  | 1921   V(sabdl2)                      \ | 
|  | 1922   V(uabdl)                       \ | 
|  | 1923   V(uabdl2)                      \ | 
|  | 1924   V(smull)                       \ | 
|  | 1925   V(smull2)                      \ | 
|  | 1926   V(umull)                       \ | 
|  | 1927   V(umull2)                      \ | 
|  | 1928   V(smlal)                       \ | 
|  | 1929   V(smlal2)                      \ | 
|  | 1930   V(umlal)                       \ | 
|  | 1931   V(umlal2)                      \ | 
|  | 1932   V(smlsl)                       \ | 
|  | 1933   V(smlsl2)                      \ | 
|  | 1934   V(umlsl)                       \ | 
|  | 1935   V(umlsl2)                      \ | 
|  | 1936   V(sqdmlal)                     \ | 
|  | 1937   V(sqdmlal2)                    \ | 
|  | 1938   V(sqdmlsl)                     \ | 
|  | 1939   V(sqdmlsl2)                    \ | 
|  | 1940   V(sqdmull)                     \ | 
|  | 1941   V(sqdmull2) | 
|  | 1942 | 
|  | 1943 #define DEFINE_LOGIC_FUNC(FXN)                               \ | 
|  | 1944   LogicVRegister FXN(VectorFormat vform, LogicVRegister dst, \ | 
|  | 1945                      const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1946   NEON_3VREG_LOGIC_LIST(DEFINE_LOGIC_FUNC) | 
|  | 1947 #undef DEFINE_LOGIC_FUNC | 
|  | 1948 | 
|  | 1949 #define NEON_FP3SAME_LIST(V) \ | 
|  | 1950   V(fadd, FPAdd, false)      \ | 
|  | 1951   V(fsub, FPSub, true)       \ | 
|  | 1952   V(fmul, FPMul, true)       \ | 
|  | 1953   V(fmulx, FPMulx, true)     \ | 
|  | 1954   V(fdiv, FPDiv, true)       \ | 
|  | 1955   V(fmax, FPMax, false)      \ | 
|  | 1956   V(fmin, FPMin, false)      \ | 
|  | 1957   V(fmaxnm, FPMaxNM, false)  \ | 
|  | 1958   V(fminnm, FPMinNM, false) | 
|  | 1959 | 
|  | 1960 #define DECLARE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN)                           \ | 
|  | 1961   template <typename T>                                                      \ | 
|  | 1962   LogicVRegister FN(VectorFormat vform, LogicVRegister dst,                  \ | 
|  | 1963                     const LogicVRegister& src1, const LogicVRegister& src2); \ | 
|  | 1964   LogicVRegister FN(VectorFormat vform, LogicVRegister dst,                  \ | 
|  | 1965                     const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1966   NEON_FP3SAME_LIST(DECLARE_NEON_FP_VECTOR_OP) | 
|  | 1967 #undef DECLARE_NEON_FP_VECTOR_OP | 
|  | 1968 | 
|  | 1969 #define NEON_FPPAIRWISE_LIST(V) \ | 
|  | 1970   V(faddp, fadd, FPAdd)         \ | 
|  | 1971   V(fmaxp, fmax, FPMax)         \ | 
|  | 1972   V(fmaxnmp, fmaxnm, FPMaxNM)   \ | 
|  | 1973   V(fminp, fmin, FPMin)         \ | 
|  | 1974   V(fminnmp, fminnm, FPMinNM) | 
|  | 1975 | 
|  | 1976 #define DECLARE_NEON_FP_PAIR_OP(FNP, FN, OP)                                  \ | 
|  | 1977   LogicVRegister FNP(VectorFormat vform, LogicVRegister dst,                  \ | 
|  | 1978                      const LogicVRegister& src1, const LogicVRegister& src2); \ | 
|  | 1979   LogicVRegister FNP(VectorFormat vform, LogicVRegister dst,                  \ | 
|  | 1980                      const LogicVRegister& src); | 
|  | 1981   NEON_FPPAIRWISE_LIST(DECLARE_NEON_FP_PAIR_OP) | 
|  | 1982 #undef DECLARE_NEON_FP_PAIR_OP | 
|  | 1983 | 
|  | 1984   template <typename T> | 
|  | 1985   LogicVRegister frecps(VectorFormat vform, LogicVRegister dst, | 
|  | 1986                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1987   LogicVRegister frecps(VectorFormat vform, LogicVRegister dst, | 
|  | 1988                         const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1989   template <typename T> | 
|  | 1990   LogicVRegister frsqrts(VectorFormat vform, LogicVRegister dst, | 
|  | 1991                          const LogicVRegister& src1, | 
|  | 1992                          const LogicVRegister& src2); | 
|  | 1993   LogicVRegister frsqrts(VectorFormat vform, LogicVRegister dst, | 
|  | 1994                          const LogicVRegister& src1, | 
|  | 1995                          const LogicVRegister& src2); | 
|  | 1996   template <typename T> | 
|  | 1997   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst, | 
|  | 1998                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 1999   LogicVRegister fmla(VectorFormat vform, LogicVRegister dst, | 
|  | 2000                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 2001   template <typename T> | 
|  | 2002   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst, | 
|  | 2003                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 2004   LogicVRegister fmls(VectorFormat vform, LogicVRegister dst, | 
|  | 2005                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 2006   LogicVRegister fnmul(VectorFormat vform, LogicVRegister dst, | 
|  | 2007                        const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 2008 | 
|  | 2009   template <typename T> | 
|  | 2010   LogicVRegister fcmp(VectorFormat vform, LogicVRegister dst, | 
|  | 2011                       const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 2012                       Condition cond); | 
|  | 2013   LogicVRegister fcmp(VectorFormat vform, LogicVRegister dst, | 
|  | 2014                       const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 2015                       Condition cond); | 
|  | 2016   LogicVRegister fabscmp(VectorFormat vform, LogicVRegister dst, | 
|  | 2017                          const LogicVRegister& src1, const LogicVRegister& src2, | 
|  | 2018                          Condition cond); | 
|  | 2019   LogicVRegister fcmp_zero(VectorFormat vform, LogicVRegister dst, | 
|  | 2020                            const LogicVRegister& src, Condition cond); | 
|  | 2021 | 
|  | 2022   template <typename T> | 
|  | 2023   LogicVRegister fneg(VectorFormat vform, LogicVRegister dst, | 
|  | 2024                       const LogicVRegister& src); | 
|  | 2025   LogicVRegister fneg(VectorFormat vform, LogicVRegister dst, | 
|  | 2026                       const LogicVRegister& src); | 
|  | 2027   template <typename T> | 
|  | 2028   LogicVRegister frecpx(VectorFormat vform, LogicVRegister dst, | 
|  | 2029                         const LogicVRegister& src); | 
|  | 2030   LogicVRegister frecpx(VectorFormat vform, LogicVRegister dst, | 
|  | 2031                         const LogicVRegister& src); | 
|  | 2032   template <typename T> | 
|  | 2033   LogicVRegister fabs_(VectorFormat vform, LogicVRegister dst, | 
|  | 2034                        const LogicVRegister& src); | 
|  | 2035   LogicVRegister fabs_(VectorFormat vform, LogicVRegister dst, | 
|  | 2036                        const LogicVRegister& src); | 
|  | 2037   LogicVRegister fabd(VectorFormat vform, LogicVRegister dst, | 
|  | 2038                       const LogicVRegister& src1, const LogicVRegister& src2); | 
|  | 2039   LogicVRegister frint(VectorFormat vform, LogicVRegister dst, | 
|  | 2040                        const LogicVRegister& src, FPRounding rounding_mode, | 
|  | 2041                        bool inexact_exception = false); | 
|  | 2042   LogicVRegister fcvts(VectorFormat vform, LogicVRegister dst, | 
|  | 2043                        const LogicVRegister& src, FPRounding rounding_mode, | 
|  | 2044                        int fbits = 0); | 
|  | 2045   LogicVRegister fcvtu(VectorFormat vform, LogicVRegister dst, | 
|  | 2046                        const LogicVRegister& src, FPRounding rounding_mode, | 
|  | 2047                        int fbits = 0); | 
|  | 2048   LogicVRegister fcvtl(VectorFormat vform, LogicVRegister dst, | 
|  | 2049                        const LogicVRegister& src); | 
|  | 2050   LogicVRegister fcvtl2(VectorFormat vform, LogicVRegister dst, | 
|  | 2051                         const LogicVRegister& src); | 
|  | 2052   LogicVRegister fcvtn(VectorFormat vform, LogicVRegister dst, | 
|  | 2053                        const LogicVRegister& src); | 
|  | 2054   LogicVRegister fcvtn2(VectorFormat vform, LogicVRegister dst, | 
|  | 2055                         const LogicVRegister& src); | 
|  | 2056   LogicVRegister fcvtxn(VectorFormat vform, LogicVRegister dst, | 
|  | 2057                         const LogicVRegister& src); | 
|  | 2058   LogicVRegister fcvtxn2(VectorFormat vform, LogicVRegister dst, | 
|  | 2059                          const LogicVRegister& src); | 
|  | 2060   LogicVRegister fsqrt(VectorFormat vform, LogicVRegister dst, | 
|  | 2061                        const LogicVRegister& src); | 
|  | 2062   LogicVRegister frsqrte(VectorFormat vform, LogicVRegister dst, | 
|  | 2063                          const LogicVRegister& src); | 
|  | 2064   LogicVRegister frecpe(VectorFormat vform, LogicVRegister dst, | 
|  | 2065                         const LogicVRegister& src, FPRounding rounding); | 
|  | 2066   LogicVRegister ursqrte(VectorFormat vform, LogicVRegister dst, | 
|  | 2067                          const LogicVRegister& src); | 
|  | 2068   LogicVRegister urecpe(VectorFormat vform, LogicVRegister dst, | 
|  | 2069                         const LogicVRegister& src); | 
|  | 2070 | 
|  | 2071   typedef float (Simulator::*FPMinMaxOp)(float a, float b); | 
|  | 2072 | 
|  | 2073   LogicVRegister FMinMaxV(VectorFormat vform, LogicVRegister dst, | 
|  | 2074                           const LogicVRegister& src, FPMinMaxOp Op); | 
|  | 2075 | 
|  | 2076   LogicVRegister fminv(VectorFormat vform, LogicVRegister dst, | 
|  | 2077                        const LogicVRegister& src); | 
|  | 2078   LogicVRegister fmaxv(VectorFormat vform, LogicVRegister dst, | 
|  | 2079                        const LogicVRegister& src); | 
|  | 2080   LogicVRegister fminnmv(VectorFormat vform, LogicVRegister dst, | 
|  | 2081                          const LogicVRegister& src); | 
|  | 2082   LogicVRegister fmaxnmv(VectorFormat vform, LogicVRegister dst, | 
|  | 2083                          const LogicVRegister& src); | 
|  | 2084 | 
|  | 2085   template <typename T> | 
|  | 2086   T FPRecipSqrtEstimate(T op); | 
|  | 2087   template <typename T> | 
|  | 2088   T FPRecipEstimate(T op, FPRounding rounding); | 
|  | 2089   template <typename T, typename R> | 
|  | 2090   R FPToFixed(T op, int fbits, bool is_signed, FPRounding rounding); | 
| 710 | 2091 | 
| 711   void FPCompare(double val0, double val1); | 2092   void FPCompare(double val0, double val1); | 
| 712   double FPRoundInt(double value, FPRounding round_mode); | 2093   double FPRoundInt(double value, FPRounding round_mode); | 
| 713   double FPToDouble(float value); | 2094   double FPToDouble(float value); | 
| 714   float FPToFloat(double value, FPRounding round_mode); | 2095   float FPToFloat(double value, FPRounding round_mode); | 
|  | 2096   float FPToFloat(float16 value); | 
|  | 2097   float16 FPToFloat16(float value, FPRounding round_mode); | 
|  | 2098   float16 FPToFloat16(double value, FPRounding round_mode); | 
|  | 2099   double recip_sqrt_estimate(double a); | 
|  | 2100   double recip_estimate(double a); | 
|  | 2101   double FPRecipSqrtEstimate(double a); | 
|  | 2102   double FPRecipEstimate(double a); | 
| 715   double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); | 2103   double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); | 
| 716   double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); | 2104   double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); | 
| 717   float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); | 2105   float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); | 
| 718   float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); | 2106   float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); | 
| 719   int32_t FPToInt32(double value, FPRounding rmode); | 2107   int32_t FPToInt32(double value, FPRounding rmode); | 
| 720   int64_t FPToInt64(double value, FPRounding rmode); | 2108   int64_t FPToInt64(double value, FPRounding rmode); | 
| 721   uint32_t FPToUInt32(double value, FPRounding rmode); | 2109   uint32_t FPToUInt32(double value, FPRounding rmode); | 
| 722   uint64_t FPToUInt64(double value, FPRounding rmode); | 2110   uint64_t FPToUInt64(double value, FPRounding rmode); | 
| 723 | 2111 | 
| 724   template <typename T> | 2112   template <typename T> | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 736   template <typename T> | 2124   template <typename T> | 
| 737   T FPMin(T a, T b); | 2125   T FPMin(T a, T b); | 
| 738 | 2126 | 
| 739   template <typename T> | 2127   template <typename T> | 
| 740   T FPMinNM(T a, T b); | 2128   T FPMinNM(T a, T b); | 
| 741 | 2129 | 
| 742   template <typename T> | 2130   template <typename T> | 
| 743   T FPMul(T op1, T op2); | 2131   T FPMul(T op1, T op2); | 
| 744 | 2132 | 
| 745   template <typename T> | 2133   template <typename T> | 
|  | 2134   T FPMulx(T op1, T op2); | 
|  | 2135 | 
|  | 2136   template <typename T> | 
| 746   T FPMulAdd(T a, T op1, T op2); | 2137   T FPMulAdd(T a, T op1, T op2); | 
| 747 | 2138 | 
| 748   template <typename T> | 2139   template <typename T> | 
| 749   T FPSqrt(T op); | 2140   T FPSqrt(T op); | 
| 750 | 2141 | 
| 751   template <typename T> | 2142   template <typename T> | 
| 752   T FPSub(T op1, T op2); | 2143   T FPSub(T op1, T op2); | 
| 753 | 2144 | 
| 754   // Standard NaN processing. |  | 
| 755   template <typename T> | 2145   template <typename T> | 
| 756   T FPProcessNaN(T op); | 2146   T FPRecipStepFused(T op1, T op2); | 
| 757 |  | 
| 758   bool FPProcessNaNs(Instruction* instr); |  | 
| 759 | 2147 | 
| 760   template <typename T> | 2148   template <typename T> | 
| 761   T FPProcessNaNs(T op1, T op2); | 2149   T FPRSqrtStepFused(T op1, T op2); | 
| 762 | 2150 | 
| 763   template <typename T> | 2151   // This doesn't do anything at the moment. We'll need it if we want support | 
| 764   T FPProcessNaNs3(T op1, T op2, T op3); | 2152   // for cumulative exception bits or floating-point exceptions. | 
|  | 2153   void FPProcessException() {} | 
|  | 2154 | 
|  | 2155   // Standard NaN processing. | 
|  | 2156   bool FPProcessNaNs(Instruction* instr); | 
| 765 | 2157 | 
| 766   void CheckStackAlignment(); | 2158   void CheckStackAlignment(); | 
| 767 | 2159 | 
| 768   inline void CheckPCSComplianceAndRun(); | 2160   inline void CheckPCSComplianceAndRun(); | 
| 769 | 2161 | 
| 770 #ifdef DEBUG | 2162 #ifdef DEBUG | 
| 771   // Corruption values should have their least significant byte cleared to | 2163   // Corruption values should have their least significant byte cleared to | 
| 772   // allow the code of the register being corrupted to be inserted. | 2164   // allow the code of the register being corrupted to be inserted. | 
| 773   static const uint64_t kCallerSavedRegisterCorruptionValue = | 2165   static const uint64_t kCallerSavedRegisterCorruptionValue = | 
| 774       0xca11edc0de000000UL; | 2166       0xca11edc0de000000UL; | 
| 775   // This value is a NaN in both 32-bit and 64-bit FP. | 2167   // This value is a NaN in both 32-bit and 64-bit FP. | 
| 776   static const uint64_t kCallerSavedFPRegisterCorruptionValue = | 2168   static const uint64_t kCallerSavedVRegisterCorruptionValue = | 
| 777       0x7ff000007f801000UL; | 2169       0x7ff000007f801000UL; | 
| 778   // This value is a mix of 32/64-bits NaN and "verbose" immediate. | 2170   // This value is a mix of 32/64-bits NaN and "verbose" immediate. | 
| 779   static const uint64_t kDefaultCPURegisterCorruptionValue = | 2171   static const uint64_t kDefaultCPURegisterCorruptionValue = | 
| 780       0x7ffbad007f8bad00UL; | 2172       0x7ffbad007f8bad00UL; | 
| 781 | 2173 | 
| 782   void CorruptRegisters(CPURegList* list, | 2174   void CorruptRegisters(CPURegList* list, | 
| 783                         uint64_t value = kDefaultCPURegisterCorruptionValue); | 2175                         uint64_t value = kDefaultCPURegisterCorruptionValue); | 
| 784   void CorruptAllCallerSavedCPURegisters(); | 2176   void CorruptAllCallerSavedCPURegisters(); | 
| 785 #endif | 2177 #endif | 
| 786 | 2178 | 
| 787   // Pseudo Printf instruction | 2179   // Pseudo Printf instruction | 
| 788   void DoPrintf(Instruction* instr); | 2180   void DoPrintf(Instruction* instr); | 
| 789 | 2181 | 
| 790   // Processor state --------------------------------------- | 2182   // Processor state --------------------------------------- | 
| 791 | 2183 | 
| 792   // Output stream. | 2184   // Output stream. | 
| 793   FILE* stream_; | 2185   FILE* stream_; | 
| 794   PrintDisassembler* print_disasm_; | 2186   PrintDisassembler* print_disasm_; | 
| 795   void PRINTF_FORMAT(2, 3) TraceSim(const char* format, ...); | 2187   void PRINTF_FORMAT(2, 3) TraceSim(const char* format, ...); | 
| 796 | 2188 | 
| 797   // Instrumentation. | 2189   // Instrumentation. | 
| 798   Instrument* instrument_; | 2190   Instrument* instrument_; | 
| 799 | 2191 | 
| 800   // General purpose registers. Register 31 is the stack pointer. | 2192   // General purpose registers. Register 31 is the stack pointer. | 
| 801   SimRegister registers_[kNumberOfRegisters]; | 2193   SimRegister registers_[kNumberOfRegisters]; | 
| 802 | 2194 | 
| 803   // Floating point registers | 2195   // Floating point registers | 
| 804   SimFPRegister fpregisters_[kNumberOfFPRegisters]; | 2196   SimVRegister vregisters_[kNumberOfVRegisters]; | 
| 805 | 2197 | 
| 806   // Processor state | 2198   // Processor state | 
| 807   // bits[31, 27]: Condition flags N, Z, C, and V. | 2199   // bits[31, 27]: Condition flags N, Z, C, and V. | 
| 808   //               (Negative, Zero, Carry, Overflow) | 2200   //               (Negative, Zero, Carry, Overflow) | 
| 809   SimSystemRegister nzcv_; | 2201   SimSystemRegister nzcv_; | 
| 810 | 2202 | 
| 811   // Floating-Point Control Register | 2203   // Floating-Point Control Register | 
| 812   SimSystemRegister fpcr_; | 2204   SimSystemRegister fpcr_; | 
| 813 | 2205 | 
| 814   // Only a subset of FPCR features are supported by the simulator. This helper | 2206   // Only a subset of FPCR features are supported by the simulator. This helper | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 861   void set_last_debugger_input(char* input) { | 2253   void set_last_debugger_input(char* input) { | 
| 862     DeleteArray(last_debugger_input_); | 2254     DeleteArray(last_debugger_input_); | 
| 863     last_debugger_input_ = input; | 2255     last_debugger_input_ = input; | 
| 864   } | 2256   } | 
| 865   char* last_debugger_input() { return last_debugger_input_; } | 2257   char* last_debugger_input() { return last_debugger_input_; } | 
| 866   char* last_debugger_input_; | 2258   char* last_debugger_input_; | 
| 867 | 2259 | 
| 868  private: | 2260  private: | 
| 869   void Init(FILE* stream); | 2261   void Init(FILE* stream); | 
| 870 | 2262 | 
|  | 2263   template <typename T> | 
|  | 2264   static T FPDefaultNaN(); | 
|  | 2265 | 
|  | 2266   template <typename T> | 
|  | 2267   T FPProcessNaN(T op) { | 
|  | 2268     DCHECK(std::isnan(op)); | 
|  | 2269     return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op); | 
|  | 2270   } | 
|  | 2271 | 
|  | 2272   template <typename T> | 
|  | 2273   T FPProcessNaNs(T op1, T op2) { | 
|  | 2274     if (IsSignallingNaN(op1)) { | 
|  | 2275       return FPProcessNaN(op1); | 
|  | 2276     } else if (IsSignallingNaN(op2)) { | 
|  | 2277       return FPProcessNaN(op2); | 
|  | 2278     } else if (std::isnan(op1)) { | 
|  | 2279       DCHECK(IsQuietNaN(op1)); | 
|  | 2280       return FPProcessNaN(op1); | 
|  | 2281     } else if (std::isnan(op2)) { | 
|  | 2282       DCHECK(IsQuietNaN(op2)); | 
|  | 2283       return FPProcessNaN(op2); | 
|  | 2284     } else { | 
|  | 2285       return 0.0; | 
|  | 2286     } | 
|  | 2287   } | 
|  | 2288 | 
|  | 2289   template <typename T> | 
|  | 2290   T FPProcessNaNs3(T op1, T op2, T op3) { | 
|  | 2291     if (IsSignallingNaN(op1)) { | 
|  | 2292       return FPProcessNaN(op1); | 
|  | 2293     } else if (IsSignallingNaN(op2)) { | 
|  | 2294       return FPProcessNaN(op2); | 
|  | 2295     } else if (IsSignallingNaN(op3)) { | 
|  | 2296       return FPProcessNaN(op3); | 
|  | 2297     } else if (std::isnan(op1)) { | 
|  | 2298       DCHECK(IsQuietNaN(op1)); | 
|  | 2299       return FPProcessNaN(op1); | 
|  | 2300     } else if (std::isnan(op2)) { | 
|  | 2301       DCHECK(IsQuietNaN(op2)); | 
|  | 2302       return FPProcessNaN(op2); | 
|  | 2303     } else if (std::isnan(op3)) { | 
|  | 2304       DCHECK(IsQuietNaN(op3)); | 
|  | 2305       return FPProcessNaN(op3); | 
|  | 2306     } else { | 
|  | 2307       return 0.0; | 
|  | 2308     } | 
|  | 2309   } | 
|  | 2310 | 
| 871   int  log_parameters_; | 2311   int  log_parameters_; | 
| 872   Isolate* isolate_; | 2312   Isolate* isolate_; | 
| 873 }; | 2313 }; | 
| 874 | 2314 | 
| 875 | 2315 | 
| 876 // When running with the simulator transition into simulated execution at this | 2316 // When running with the simulator transition into simulated execution at this | 
| 877 // point. | 2317 // point. | 
| 878 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4)  \ | 2318 #define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4)  \ | 
| 879   reinterpret_cast<Object*>(Simulator::current(isolate)->CallJS( \ | 2319   reinterpret_cast<Object*>(Simulator::current(isolate)->CallJS( \ | 
| 880       FUNCTION_ADDR(entry), p0, p1, p2, p3, p4)) | 2320       FUNCTION_ADDR(entry), p0, p1, p2, p3, p4)) | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 906     Simulator::current(isolate)->PopAddress(); | 2346     Simulator::current(isolate)->PopAddress(); | 
| 907   } | 2347   } | 
| 908 }; | 2348 }; | 
| 909 | 2349 | 
| 910 #endif  // !defined(USE_SIMULATOR) | 2350 #endif  // !defined(USE_SIMULATOR) | 
| 911 | 2351 | 
| 912 }  // namespace internal | 2352 }  // namespace internal | 
| 913 }  // namespace v8 | 2353 }  // namespace v8 | 
| 914 | 2354 | 
| 915 #endif  // V8_ARM64_SIMULATOR_ARM64_H_ | 2355 #endif  // V8_ARM64_SIMULATOR_ARM64_H_ | 
| OLD | NEW | 
|---|