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