Chromium Code Reviews| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 | 68 |
| 69 static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { | 69 static uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) { |
| 70 return try_catch_address; | 70 return try_catch_address; |
| 71 } | 71 } |
| 72 | 72 |
| 73 static void UnregisterCTryCatch() { } | 73 static void UnregisterCTryCatch() { } |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 #else // !defined(USE_SIMULATOR) | 76 #else // !defined(USE_SIMULATOR) |
| 77 | 77 |
| 78 | |
| 79 template<typename T> | |
| 80 struct make_unsigned { | |
| 81 typedef T type; | |
| 82 }; | |
| 83 | |
| 84 | |
| 78 enum ReverseByteMode { | 85 enum ReverseByteMode { |
| 79 Reverse16 = 0, | 86 Reverse16 = 0, |
| 80 Reverse32 = 1, | 87 Reverse32 = 1, |
| 81 Reverse64 = 2 | 88 Reverse64 = 2 |
| 82 }; | 89 }; |
| 83 | 90 |
| 84 | 91 |
| 85 // The proper way to initialize a simulated system register (such as NZCV) is as | 92 // The proper way to initialize a simulated system register (such as NZCV) is as |
| 86 // follows: | 93 // follows: |
| 87 // SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV); | 94 // SimSystemRegister nzcv = SimSystemRegister::DefaultValueFor(NZCV); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 // describes the bits which are not modifiable. | 136 // describes the bits which are not modifiable. |
| 130 SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) | 137 SimSystemRegister(uint32_t value, uint32_t write_ignore_mask) |
| 131 : value_(value), write_ignore_mask_(write_ignore_mask) { } | 138 : value_(value), write_ignore_mask_(write_ignore_mask) { } |
| 132 | 139 |
| 133 uint32_t value_; | 140 uint32_t value_; |
| 134 uint32_t write_ignore_mask_; | 141 uint32_t write_ignore_mask_; |
| 135 }; | 142 }; |
| 136 | 143 |
| 137 | 144 |
| 138 // Represent a register (r0-r31, v0-v31). | 145 // Represent a register (r0-r31, v0-v31). |
| 139 template<int kSizeInBytes> | |
| 140 class SimRegisterBase { | 146 class SimRegisterBase { |
| 141 public: | 147 public: |
| 142 template<typename T> | 148 void Set(int64_t new_value, unsigned size) { |
| 143 void Set(T new_value, unsigned size = sizeof(T)) { | 149 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); |
| 144 ASSERT(size <= kSizeInBytes); | |
| 145 ASSERT(size <= sizeof(new_value)); | |
| 146 // All AArch64 registers are zero-extending; Writing a W register clears the | 150 // All AArch64 registers are zero-extending; Writing a W register clears the |
| 147 // top bits of the corresponding X register. | 151 // top bits of the corresponding X register. |
| 148 memset(value_, 0, kSizeInBytes); | 152 value_ = new_value; |
|
Sven Panne
2014/05/16 11:15:47
A ternary is a bit more readable here:
value_ =
jbramley
2014/05/16 14:05:50
You probably need to set the value just once, to a
| |
| 149 memcpy(value_, &new_value, size); | 153 STATIC_ASSERT(kWRegSizeInBits == kSRegSizeInBits); |
| 154 if (size == kWRegSizeInBits) { | |
| 155 value_ &= kWRegMask; | |
| 156 } | |
|
jbramley
2014/05/16 14:05:50
else {
ASSERT(size == (sizeof(value_) * kByteSiz
| |
| 157 } | |
| 158 | |
| 159 template<typename T> | |
| 160 void Set(T new_value) { | |
|
Sven Panne
2014/05/16 11:15:47
This method and the corresponding templatized Get
jbramley
2014/05/16 14:05:50
Indeed; I'd like to see what you're aiming for. I
Fritz
2014/05/16 18:11:46
My direction is to only use the templatized Get/Se
| |
| 161 value_ = 0; | |
| 162 memcpy(&value_, &new_value, sizeof(T)); | |
| 150 } | 163 } |
| 151 | 164 |
| 152 // Copy 'size' bytes of the register to the result, and zero-extend to fill | 165 // Copy 'size' bytes of the register to the result, and zero-extend to fill |
| 153 // the result. | 166 // the result. |
| 167 int64_t Get(unsigned size) const { | |
| 168 ASSERT(size/8 <= kXRegSize); | |
| 169 int64_t result = value_; | |
|
Sven Panne
2014/05/16 11:15:47
I think a ternary is more readable here, too:
| |
| 170 if (size == kSRegSizeInBits) { | |
|
jbramley
2014/05/16 14:05:50
Use of SRegSize is surprising here; use WRegSize i
| |
| 171 result &= kSRegMask; | |
| 172 } | |
| 173 return result; | |
| 174 } | |
| 175 | |
| 154 template<typename T> | 176 template<typename T> |
| 155 T Get(unsigned size = sizeof(T)) const { | 177 T Get() const { |
| 156 ASSERT(size <= kSizeInBytes); | |
| 157 T result; | 178 T result; |
| 158 memset(&result, 0, sizeof(result)); | 179 memcpy(&result, &value_, sizeof(T)); |
| 159 memcpy(&result, value_, size); | |
| 160 return result; | 180 return result; |
| 161 } | 181 } |
| 162 | 182 |
| 163 protected: | 183 protected: |
| 164 uint8_t value_[kSizeInBytes]; | 184 int64_t value_; |
|
jbramley
2014/05/16 14:05:50
Have you thought about how NEON Q registers might
Fritz
2014/05/16 18:11:46
I don't have a fully formed solution yet. I do re
| |
| 165 }; | 185 }; |
| 166 typedef SimRegisterBase<kXRegSize> SimRegister; // r0-r31 | 186 |
| 167 typedef SimRegisterBase<kDRegSize> SimFPRegister; // v0-v31 | 187 STATIC_ASSERT(kXRegSize == kDRegSize); |
|
jbramley
2014/05/16 14:05:50
It'd be better to put this next to the declaration
| |
| 188 typedef SimRegisterBase SimRegister; // r0-r31 | |
| 189 typedef SimRegisterBase SimFPRegister; // v0-v31 | |
| 168 | 190 |
| 169 | 191 |
| 170 class Simulator : public DecoderVisitor { | 192 class Simulator : public DecoderVisitor { |
| 171 public: | 193 public: |
| 172 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, | 194 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, |
| 173 Isolate* isolate = NULL, | 195 Isolate* isolate = NULL, |
| 174 FILE* stream = stderr); | 196 FILE* stream = stderr); |
| 175 Simulator(); | 197 Simulator(); |
| 176 ~Simulator(); | 198 ~Simulator(); |
| 177 | 199 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 LogProcessorState(); | 346 LogProcessorState(); |
| 325 increment_pc(); | 347 increment_pc(); |
| 326 CheckBreakpoints(); | 348 CheckBreakpoints(); |
| 327 } | 349 } |
| 328 | 350 |
| 329 // Declare all Visitor functions. | 351 // Declare all Visitor functions. |
| 330 #define DECLARE(A) void Visit##A(Instruction* instr); | 352 #define DECLARE(A) void Visit##A(Instruction* instr); |
| 331 VISITOR_LIST(DECLARE) | 353 VISITOR_LIST(DECLARE) |
| 332 #undef DECLARE | 354 #undef DECLARE |
| 333 | 355 |
| 356 bool Reg31ZeroMode(unsigned code, Reg31Mode r31mode) const { | |
|
jbramley
2014/05/16 14:05:50
`IsZeroRegister(...)` would be a better name.
Fritz
2014/05/16 18:11:46
Done.
| |
| 357 return ((code == 31) && (r31mode == Reg31IsZeroRegister)); | |
| 358 } | |
| 359 | |
| 334 // Register accessors. | 360 // Register accessors. |
| 335 | |
| 336 // Return 'size' bits of the value of an integer register, as the specified | 361 // Return 'size' bits of the value of an integer register, as the specified |
| 337 // type. The value is zero-extended to fill the result. | 362 // type. The value is zero-extended to fill the result. |
| 338 // | 363 // |
| 339 // The only supported values of 'size' are kXRegSizeInBits and | 364 // The only supported values of 'size' are kXRegSizeInBits and |
| 340 // kWRegSizeInBits. | 365 // kWRegSizeInBits. |
| 341 template<typename T> | 366 int64_t reg(unsigned size, unsigned code, |
| 342 T reg(unsigned size, unsigned code, | |
| 343 Reg31Mode r31mode = Reg31IsZeroRegister) const { | 367 Reg31Mode r31mode = Reg31IsZeroRegister) const { |
| 344 unsigned size_in_bytes = size / 8; | |
| 345 ASSERT(size_in_bytes <= sizeof(T)); | |
| 346 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); | 368 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); |
| 347 ASSERT(code < kNumberOfRegisters); | 369 ASSERT(code < kNumberOfRegisters); |
| 348 | 370 |
| 349 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { | 371 if (Reg31ZeroMode(code, r31mode)) { |
| 350 T result; | 372 return 0; |
| 351 memset(&result, 0, sizeof(result)); | |
| 352 return result; | |
| 353 } | 373 } |
| 354 return registers_[code].Get<T>(size_in_bytes); | 374 return registers_[code].Get(size); |
| 355 } | 375 } |
| 356 | 376 |
| 357 // Like reg(), but infer the access size from the template type. | 377 // Like reg(), but infer the access size from the template type. |
| 358 template<typename T> | 378 template<typename T> |
| 359 T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { | 379 T reg(unsigned code, Reg31Mode r31mode = Reg31IsZeroRegister) const { |
| 360 return reg<T>(sizeof(T) * 8, code, r31mode); | 380 ASSERT(code < kNumberOfRegisters); |
| 381 if (Reg31ZeroMode(code, r31mode)) { | |
| 382 return 0; | |
| 383 } | |
| 384 return registers_[code].Get<T>(); | |
| 361 } | 385 } |
| 362 | 386 |
| 363 // Common specialized accessors for the reg() template. | 387 // Common specialized accessors for the reg() template. |
| 364 int32_t wreg(unsigned code, | 388 int32_t wreg(unsigned code, |
| 365 Reg31Mode r31mode = Reg31IsZeroRegister) const { | 389 Reg31Mode r31mode = Reg31IsZeroRegister) const { |
| 366 return reg<int32_t>(code, r31mode); | 390 return reg<int32_t>(code, r31mode); |
| 367 } | 391 } |
| 368 | 392 |
| 369 int64_t xreg(unsigned code, | 393 int64_t xreg(unsigned code, |
| 370 Reg31Mode r31mode = Reg31IsZeroRegister) const { | 394 Reg31Mode r31mode = Reg31IsZeroRegister) const { |
| 371 return reg<int64_t>(code, r31mode); | 395 return reg<int64_t>(code, r31mode); |
| 372 } | 396 } |
| 373 | 397 |
| 374 int64_t reg(unsigned size, unsigned code, | |
| 375 Reg31Mode r31mode = Reg31IsZeroRegister) const { | |
| 376 return reg<int64_t>(size, code, r31mode); | |
| 377 } | |
| 378 | |
| 379 // Write 'size' bits of 'value' into an integer register. The value is | 398 // Write 'size' bits of 'value' into an integer register. The value is |
| 380 // zero-extended. This behaviour matches AArch64 register writes. | 399 // zero-extended. This behaviour matches AArch64 register writes. |
| 381 // | 400 // |
| 382 // The only supported values of 'size' are kXRegSizeInBits and | 401 // The only supported values of 'size' are kXRegSizeInBits and |
| 383 // kWRegSizeInBits. | 402 // kWRegSizeInBits. |
| 384 template<typename T> | 403 template<typename T> |
| 385 void set_reg(unsigned size, unsigned code, T value, | 404 void set_reg(unsigned size, unsigned code, T value, |
| 386 Reg31Mode r31mode = Reg31IsZeroRegister) { | 405 Reg31Mode r31mode = Reg31IsZeroRegister) { |
| 387 unsigned size_in_bytes = size / 8; | |
| 388 ASSERT(size_in_bytes <= sizeof(T)); | |
| 389 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); | 406 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); |
| 390 ASSERT(code < kNumberOfRegisters); | 407 ASSERT(code < kNumberOfRegisters); |
| 391 | 408 |
| 392 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { | 409 if (!Reg31ZeroMode(code, r31mode)) |
| 393 return; | 410 registers_[code].Set(value, size); |
| 394 } | |
| 395 return registers_[code].Set(value, size_in_bytes); | |
| 396 } | 411 } |
| 397 | 412 |
| 398 // Like set_reg(), but infer the access size from the template type. | 413 // Like set_reg(), but infer the access size from the template type. |
| 399 template<typename T> | 414 template<typename T> |
| 400 void set_reg(unsigned code, T value, | 415 void set_reg(unsigned code, T value, |
| 401 Reg31Mode r31mode = Reg31IsZeroRegister) { | 416 Reg31Mode r31mode = Reg31IsZeroRegister) { |
| 402 set_reg(sizeof(value) * 8, code, value, r31mode); | 417 ASSERT(code < kNumberOfRegisters); |
| 418 if (!Reg31ZeroMode(code, r31mode)) | |
| 419 registers_[code].Set(value); | |
| 403 } | 420 } |
| 404 | 421 |
| 405 // Common specialized accessors for the set_reg() template. | 422 // Common specialized accessors for the set_reg() template. |
| 406 void set_wreg(unsigned code, int32_t value, | 423 void set_wreg(unsigned code, int32_t value, |
| 407 Reg31Mode r31mode = Reg31IsZeroRegister) { | 424 Reg31Mode r31mode = Reg31IsZeroRegister) { |
| 408 set_reg(kWRegSizeInBits, code, value, r31mode); | 425 set_reg(code, value, r31mode); |
| 409 } | 426 } |
| 410 | 427 |
| 411 void set_xreg(unsigned code, int64_t value, | 428 void set_xreg(unsigned code, int64_t value, |
| 412 Reg31Mode r31mode = Reg31IsZeroRegister) { | 429 Reg31Mode r31mode = Reg31IsZeroRegister) { |
| 413 set_reg(kXRegSizeInBits, code, value, r31mode); | 430 set_reg(code, value, r31mode); |
| 414 } | 431 } |
| 415 | 432 |
| 416 // Commonly-used special cases. | 433 // Commonly-used special cases. |
| 417 template<typename T> | 434 template<typename T> |
| 418 void set_lr(T value) { | 435 void set_lr(T value) { |
| 419 ASSERT(sizeof(T) == kPointerSize); | 436 ASSERT(sizeof(T) == kPointerSize); |
| 420 set_reg(kLinkRegCode, value); | 437 set_reg(kLinkRegCode, value); |
| 421 } | 438 } |
| 422 | 439 |
| 423 template<typename T> | 440 template<typename T> |
| 424 void set_sp(T value) { | 441 void set_sp(T value) { |
| 425 ASSERT(sizeof(T) == kPointerSize); | 442 ASSERT(sizeof(T) == kPointerSize); |
| 426 set_reg(31, value, Reg31IsStackPointer); | 443 set_reg(31, value, Reg31IsStackPointer); |
| 427 } | 444 } |
| 428 | 445 |
| 429 int64_t sp() { return xreg(31, Reg31IsStackPointer); } | 446 int64_t sp() { return xreg(31, Reg31IsStackPointer); } |
| 430 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } | 447 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } |
| 431 int64_t fp() { | 448 int64_t fp() { |
| 432 return xreg(kFramePointerRegCode, Reg31IsStackPointer); | 449 return xreg(kFramePointerRegCode, Reg31IsStackPointer); |
| 433 } | 450 } |
| 434 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } | 451 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } |
| 435 | 452 |
| 436 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } | 453 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } |
| 437 | 454 |
| 438 // Return 'size' bits of the value of a floating-point register, as the | |
| 439 // specified type. The value is zero-extended to fill the result. | |
| 440 // | |
| 441 // The only supported values of 'size' are kDRegSizeInBits and | |
| 442 // kSRegSizeInBits. | |
| 443 template<typename T> | |
| 444 T fpreg(unsigned size, unsigned code) const { | |
| 445 unsigned size_in_bytes = size / 8; | |
| 446 ASSERT(size_in_bytes <= sizeof(T)); | |
| 447 ASSERT((size == kDRegSizeInBits) || (size == kSRegSizeInBits)); | |
| 448 ASSERT(code < kNumberOfFPRegisters); | |
| 449 return fpregisters_[code].Get<T>(size_in_bytes); | |
| 450 } | |
| 451 | |
| 452 // Like fpreg(), but infer the access size from the template type. | |
| 453 template<typename T> | 455 template<typename T> |
| 454 T fpreg(unsigned code) const { | 456 T fpreg(unsigned code) const { |
| 455 return fpreg<T>(sizeof(T) * 8, code); | 457 ASSERT(code < kNumberOfRegisters); |
| 458 return fpregisters_[code].Get<T>(); | |
| 456 } | 459 } |
| 457 | 460 |
| 458 // Common specialized accessors for the fpreg() template. | 461 // Common specialized accessors for the fpreg() template. |
| 459 float sreg(unsigned code) const { | 462 float sreg(unsigned code) const { |
| 460 return fpreg<float>(code); | 463 return fpreg<float>(code); |
| 461 } | 464 } |
| 462 | 465 |
| 463 uint32_t sreg_bits(unsigned code) const { | 466 uint32_t sreg_bits(unsigned code) const { |
| 464 return fpreg<uint32_t>(code); | 467 return fpreg<uint32_t>(code); |
| 465 } | 468 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 481 return 0.0; | 484 return 0.0; |
| 482 } | 485 } |
| 483 } | 486 } |
| 484 | 487 |
| 485 // Write 'value' into a floating-point register. The value is zero-extended. | 488 // Write 'value' into a floating-point register. The value is zero-extended. |
| 486 // This behaviour matches AArch64 register writes. | 489 // This behaviour matches AArch64 register writes. |
| 487 template<typename T> | 490 template<typename T> |
| 488 void set_fpreg(unsigned code, T value) { | 491 void set_fpreg(unsigned code, T value) { |
| 489 ASSERT((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); | 492 ASSERT((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); |
| 490 ASSERT(code < kNumberOfFPRegisters); | 493 ASSERT(code < kNumberOfFPRegisters); |
| 491 fpregisters_[code].Set(value, sizeof(value)); | 494 fpregisters_[code].Set(value); |
| 492 } | 495 } |
| 493 | 496 |
| 494 // Common specialized accessors for the set_fpreg() template. | 497 // Common specialized accessors for the set_fpreg() template. |
| 495 void set_sreg(unsigned code, float value) { | 498 void set_sreg(unsigned code, float value) { |
| 496 set_fpreg(code, value); | 499 set_fpreg(code, value); |
| 497 } | 500 } |
| 498 | 501 |
| 499 void set_sreg_bits(unsigned code, uint32_t value) { | 502 void set_sreg_bits(unsigned code, uint32_t value) { |
| 500 set_fpreg(code, value); | 503 set_fpreg(code, value); |
| 501 } | 504 } |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 655 float MemoryReadFP32(uint8_t* address); | 658 float MemoryReadFP32(uint8_t* address); |
| 656 uint64_t MemoryRead64(uint8_t* address); | 659 uint64_t MemoryRead64(uint8_t* address); |
| 657 double MemoryReadFP64(uint8_t* address); | 660 double MemoryReadFP64(uint8_t* address); |
| 658 | 661 |
| 659 void MemoryWrite(uint8_t* address, uint64_t value, unsigned num_bytes); | 662 void MemoryWrite(uint8_t* address, uint64_t value, unsigned num_bytes); |
| 660 void MemoryWrite32(uint8_t* address, uint32_t value); | 663 void MemoryWrite32(uint8_t* address, uint32_t value); |
| 661 void MemoryWriteFP32(uint8_t* address, float value); | 664 void MemoryWriteFP32(uint8_t* address, float value); |
| 662 void MemoryWrite64(uint8_t* address, uint64_t value); | 665 void MemoryWrite64(uint8_t* address, uint64_t value); |
| 663 void MemoryWriteFP64(uint8_t* address, double value); | 666 void MemoryWriteFP64(uint8_t* address, double value); |
| 664 | 667 |
| 665 int64_t ShiftOperand(unsigned reg_size, | 668 |
| 666 int64_t value, | 669 template <typename T> |
| 667 Shift shift_type, | 670 T ShiftOperand(T value, |
| 668 unsigned amount); | 671 Shift shift_type, |
| 672 unsigned amount); | |
| 673 | |
| 674 template <typename T> | |
| 675 void DataProcessing2Source(Instruction* instr); | |
| 676 | |
| 669 int64_t Rotate(unsigned reg_width, | 677 int64_t Rotate(unsigned reg_width, |
| 670 int64_t value, | 678 int64_t value, |
| 671 Shift shift_type, | 679 Shift shift_type, |
| 672 unsigned amount); | 680 unsigned amount); |
| 673 int64_t ExtendValue(unsigned reg_width, | 681 int64_t ExtendValue(unsigned reg_width, |
| 674 int64_t value, | 682 int64_t value, |
| 675 Extend extend_type, | 683 Extend extend_type, |
| 676 unsigned left_shift = 0); | 684 unsigned left_shift = 0); |
| 677 | 685 |
| 678 uint64_t ReverseBits(uint64_t value, unsigned num_bits); | 686 uint64_t ReverseBits(uint64_t value, unsigned num_bits); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 880 static void UnregisterCTryCatch() { | 888 static void UnregisterCTryCatch() { |
| 881 Simulator::current(Isolate::Current())->PopAddress(); | 889 Simulator::current(Isolate::Current())->PopAddress(); |
| 882 } | 890 } |
| 883 }; | 891 }; |
| 884 | 892 |
| 885 #endif // !defined(USE_SIMULATOR) | 893 #endif // !defined(USE_SIMULATOR) |
| 886 | 894 |
| 887 } } // namespace v8::internal | 895 } } // namespace v8::internal |
| 888 | 896 |
| 889 #endif // V8_ARM64_SIMULATOR_ARM64_H_ | 897 #endif // V8_ARM64_SIMULATOR_ARM64_H_ |
| OLD | NEW |