| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 ASSERT(size <= kSizeInBytes); | 179 ASSERT(size <= kSizeInBytes); |
| 180 T result; | 180 T result; |
| 181 memset(&result, 0, sizeof(result)); | 181 memset(&result, 0, sizeof(result)); |
| 182 memcpy(&result, value_, size); | 182 memcpy(&result, value_, size); |
| 183 return result; | 183 return result; |
| 184 } | 184 } |
| 185 | 185 |
| 186 protected: | 186 protected: |
| 187 uint8_t value_[kSizeInBytes]; | 187 uint8_t value_[kSizeInBytes]; |
| 188 }; | 188 }; |
| 189 typedef SimRegisterBase<kXRegSizeInBytes> SimRegister; // r0-r31 | 189 typedef SimRegisterBase<kXRegSize> SimRegister; // r0-r31 |
| 190 typedef SimRegisterBase<kDRegSizeInBytes> SimFPRegister; // v0-v31 | 190 typedef SimRegisterBase<kDRegSize> SimFPRegister; // v0-v31 |
| 191 | 191 |
| 192 | 192 |
| 193 class Simulator : public DecoderVisitor { | 193 class Simulator : public DecoderVisitor { |
| 194 public: | 194 public: |
| 195 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, | 195 explicit Simulator(Decoder<DispatchingDecoderVisitor>* decoder, |
| 196 Isolate* isolate = NULL, | 196 Isolate* isolate = NULL, |
| 197 FILE* stream = stderr); | 197 FILE* stream = stderr); |
| 198 Simulator(); | 198 Simulator(); |
| 199 ~Simulator(); | 199 ~Simulator(); |
| 200 | 200 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 // Declare all Visitor functions. | 351 // Declare all Visitor functions. |
| 352 #define DECLARE(A) void Visit##A(Instruction* instr); | 352 #define DECLARE(A) void Visit##A(Instruction* instr); |
| 353 VISITOR_LIST(DECLARE) | 353 VISITOR_LIST(DECLARE) |
| 354 #undef DECLARE | 354 #undef DECLARE |
| 355 | 355 |
| 356 // Register accessors. | 356 // Register accessors. |
| 357 | 357 |
| 358 // Return 'size' bits of the value of an integer register, as the specified | 358 // Return 'size' bits of the value of an integer register, as the specified |
| 359 // type. The value is zero-extended to fill the result. | 359 // type. The value is zero-extended to fill the result. |
| 360 // | 360 // |
| 361 // The only supported values of 'size' are kXRegSize and kWRegSize. | 361 // The only supported values of 'size' are kXRegSizeInBits and |
| 362 // kWRegSizeInBits. |
| 362 template<typename T> | 363 template<typename T> |
| 363 T reg(unsigned size, unsigned code, | 364 T reg(unsigned size, unsigned code, |
| 364 Reg31Mode r31mode = Reg31IsZeroRegister) const { | 365 Reg31Mode r31mode = Reg31IsZeroRegister) const { |
| 365 unsigned size_in_bytes = size / 8; | 366 unsigned size_in_bytes = size / 8; |
| 366 ASSERT(size_in_bytes <= sizeof(T)); | 367 ASSERT(size_in_bytes <= sizeof(T)); |
| 367 ASSERT((size == kXRegSize) || (size == kWRegSize)); | 368 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); |
| 368 ASSERT(code < kNumberOfRegisters); | 369 ASSERT(code < kNumberOfRegisters); |
| 369 | 370 |
| 370 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { | 371 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { |
| 371 T result; | 372 T result; |
| 372 memset(&result, 0, sizeof(result)); | 373 memset(&result, 0, sizeof(result)); |
| 373 return result; | 374 return result; |
| 374 } | 375 } |
| 375 return registers_[code].Get<T>(size_in_bytes); | 376 return registers_[code].Get<T>(size_in_bytes); |
| 376 } | 377 } |
| 377 | 378 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 393 } | 394 } |
| 394 | 395 |
| 395 int64_t reg(unsigned size, unsigned code, | 396 int64_t reg(unsigned size, unsigned code, |
| 396 Reg31Mode r31mode = Reg31IsZeroRegister) const { | 397 Reg31Mode r31mode = Reg31IsZeroRegister) const { |
| 397 return reg<int64_t>(size, code, r31mode); | 398 return reg<int64_t>(size, code, r31mode); |
| 398 } | 399 } |
| 399 | 400 |
| 400 // Write 'size' bits of 'value' into an integer register. The value is | 401 // Write 'size' bits of 'value' into an integer register. The value is |
| 401 // zero-extended. This behaviour matches AArch64 register writes. | 402 // zero-extended. This behaviour matches AArch64 register writes. |
| 402 // | 403 // |
| 403 // The only supported values of 'size' are kXRegSize and kWRegSize. | 404 // The only supported values of 'size' are kXRegSizeInBits and |
| 405 // kWRegSizeInBits. |
| 404 template<typename T> | 406 template<typename T> |
| 405 void set_reg(unsigned size, unsigned code, T value, | 407 void set_reg(unsigned size, unsigned code, T value, |
| 406 Reg31Mode r31mode = Reg31IsZeroRegister) { | 408 Reg31Mode r31mode = Reg31IsZeroRegister) { |
| 407 unsigned size_in_bytes = size / 8; | 409 unsigned size_in_bytes = size / 8; |
| 408 ASSERT(size_in_bytes <= sizeof(T)); | 410 ASSERT(size_in_bytes <= sizeof(T)); |
| 409 ASSERT((size == kXRegSize) || (size == kWRegSize)); | 411 ASSERT((size == kXRegSizeInBits) || (size == kWRegSizeInBits)); |
| 410 ASSERT(code < kNumberOfRegisters); | 412 ASSERT(code < kNumberOfRegisters); |
| 411 | 413 |
| 412 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { | 414 if ((code == 31) && (r31mode == Reg31IsZeroRegister)) { |
| 413 return; | 415 return; |
| 414 } | 416 } |
| 415 return registers_[code].Set(value, size_in_bytes); | 417 return registers_[code].Set(value, size_in_bytes); |
| 416 } | 418 } |
| 417 | 419 |
| 418 // Like set_reg(), but infer the access size from the template type. | 420 // Like set_reg(), but infer the access size from the template type. |
| 419 template<typename T> | 421 template<typename T> |
| 420 void set_reg(unsigned code, T value, | 422 void set_reg(unsigned code, T value, |
| 421 Reg31Mode r31mode = Reg31IsZeroRegister) { | 423 Reg31Mode r31mode = Reg31IsZeroRegister) { |
| 422 set_reg(sizeof(value) * 8, code, value, r31mode); | 424 set_reg(sizeof(value) * 8, code, value, r31mode); |
| 423 } | 425 } |
| 424 | 426 |
| 425 // Common specialized accessors for the set_reg() template. | 427 // Common specialized accessors for the set_reg() template. |
| 426 void set_wreg(unsigned code, int32_t value, | 428 void set_wreg(unsigned code, int32_t value, |
| 427 Reg31Mode r31mode = Reg31IsZeroRegister) { | 429 Reg31Mode r31mode = Reg31IsZeroRegister) { |
| 428 set_reg(kWRegSize, code, value, r31mode); | 430 set_reg(kWRegSizeInBits, code, value, r31mode); |
| 429 } | 431 } |
| 430 | 432 |
| 431 void set_xreg(unsigned code, int64_t value, | 433 void set_xreg(unsigned code, int64_t value, |
| 432 Reg31Mode r31mode = Reg31IsZeroRegister) { | 434 Reg31Mode r31mode = Reg31IsZeroRegister) { |
| 433 set_reg(kXRegSize, code, value, r31mode); | 435 set_reg(kXRegSizeInBits, code, value, r31mode); |
| 434 } | 436 } |
| 435 | 437 |
| 436 // Commonly-used special cases. | 438 // Commonly-used special cases. |
| 437 template<typename T> | 439 template<typename T> |
| 438 void set_lr(T value) { | 440 void set_lr(T value) { |
| 439 ASSERT(sizeof(T) == kPointerSize); | 441 ASSERT(sizeof(T) == kPointerSize); |
| 440 set_reg(kLinkRegCode, value); | 442 set_reg(kLinkRegCode, value); |
| 441 } | 443 } |
| 442 | 444 |
| 443 template<typename T> | 445 template<typename T> |
| 444 void set_sp(T value) { | 446 void set_sp(T value) { |
| 445 ASSERT(sizeof(T) == kPointerSize); | 447 ASSERT(sizeof(T) == kPointerSize); |
| 446 set_reg(31, value, Reg31IsStackPointer); | 448 set_reg(31, value, Reg31IsStackPointer); |
| 447 } | 449 } |
| 448 | 450 |
| 449 int64_t sp() { return xreg(31, Reg31IsStackPointer); } | 451 int64_t sp() { return xreg(31, Reg31IsStackPointer); } |
| 450 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } | 452 int64_t jssp() { return xreg(kJSSPCode, Reg31IsStackPointer); } |
| 451 int64_t fp() { | 453 int64_t fp() { |
| 452 return xreg(kFramePointerRegCode, Reg31IsStackPointer); | 454 return xreg(kFramePointerRegCode, Reg31IsStackPointer); |
| 453 } | 455 } |
| 454 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } | 456 Instruction* lr() { return reg<Instruction*>(kLinkRegCode); } |
| 455 | 457 |
| 456 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } | 458 Address get_sp() { return reg<Address>(31, Reg31IsStackPointer); } |
| 457 | 459 |
| 458 // Return 'size' bits of the value of a floating-point register, as the | 460 // Return 'size' bits of the value of a floating-point register, as the |
| 459 // specified type. The value is zero-extended to fill the result. | 461 // specified type. The value is zero-extended to fill the result. |
| 460 // | 462 // |
| 461 // The only supported values of 'size' are kDRegSize and kSRegSize. | 463 // The only supported values of 'size' are kDRegSizeInBits and |
| 464 // kSRegSizeInBits. |
| 462 template<typename T> | 465 template<typename T> |
| 463 T fpreg(unsigned size, unsigned code) const { | 466 T fpreg(unsigned size, unsigned code) const { |
| 464 unsigned size_in_bytes = size / 8; | 467 unsigned size_in_bytes = size / 8; |
| 465 ASSERT(size_in_bytes <= sizeof(T)); | 468 ASSERT(size_in_bytes <= sizeof(T)); |
| 466 ASSERT((size == kDRegSize) || (size == kSRegSize)); | 469 ASSERT((size == kDRegSizeInBits) || (size == kSRegSizeInBits)); |
| 467 ASSERT(code < kNumberOfFPRegisters); | 470 ASSERT(code < kNumberOfFPRegisters); |
| 468 return fpregisters_[code].Get<T>(size_in_bytes); | 471 return fpregisters_[code].Get<T>(size_in_bytes); |
| 469 } | 472 } |
| 470 | 473 |
| 471 // Like fpreg(), but infer the access size from the template type. | 474 // Like fpreg(), but infer the access size from the template type. |
| 472 template<typename T> | 475 template<typename T> |
| 473 T fpreg(unsigned code) const { | 476 T fpreg(unsigned code) const { |
| 474 return fpreg<T>(sizeof(T) * 8, code); | 477 return fpreg<T>(sizeof(T) * 8, code); |
| 475 } | 478 } |
| 476 | 479 |
| 477 // Common specialized accessors for the fpreg() template. | 480 // Common specialized accessors for the fpreg() template. |
| 478 float sreg(unsigned code) const { | 481 float sreg(unsigned code) const { |
| 479 return fpreg<float>(code); | 482 return fpreg<float>(code); |
| 480 } | 483 } |
| 481 | 484 |
| 482 uint32_t sreg_bits(unsigned code) const { | 485 uint32_t sreg_bits(unsigned code) const { |
| 483 return fpreg<uint32_t>(code); | 486 return fpreg<uint32_t>(code); |
| 484 } | 487 } |
| 485 | 488 |
| 486 double dreg(unsigned code) const { | 489 double dreg(unsigned code) const { |
| 487 return fpreg<double>(code); | 490 return fpreg<double>(code); |
| 488 } | 491 } |
| 489 | 492 |
| 490 uint64_t dreg_bits(unsigned code) const { | 493 uint64_t dreg_bits(unsigned code) const { |
| 491 return fpreg<uint64_t>(code); | 494 return fpreg<uint64_t>(code); |
| 492 } | 495 } |
| 493 | 496 |
| 494 double fpreg(unsigned size, unsigned code) const { | 497 double fpreg(unsigned size, unsigned code) const { |
| 495 switch (size) { | 498 switch (size) { |
| 496 case kSRegSize: return sreg(code); | 499 case kSRegSizeInBits: return sreg(code); |
| 497 case kDRegSize: return dreg(code); | 500 case kDRegSizeInBits: return dreg(code); |
| 498 default: | 501 default: |
| 499 UNREACHABLE(); | 502 UNREACHABLE(); |
| 500 return 0.0; | 503 return 0.0; |
| 501 } | 504 } |
| 502 } | 505 } |
| 503 | 506 |
| 504 // Write 'value' into a floating-point register. The value is zero-extended. | 507 // Write 'value' into a floating-point register. The value is zero-extended. |
| 505 // This behaviour matches AArch64 register writes. | 508 // This behaviour matches AArch64 register writes. |
| 506 template<typename T> | 509 template<typename T> |
| 507 void set_fpreg(unsigned code, T value) { | 510 void set_fpreg(unsigned code, T value) { |
| 508 ASSERT((sizeof(value) == kDRegSizeInBytes) || | 511 ASSERT((sizeof(value) == kDRegSize) || (sizeof(value) == kSRegSize)); |
| 509 (sizeof(value) == kSRegSizeInBytes)); | |
| 510 ASSERT(code < kNumberOfFPRegisters); | 512 ASSERT(code < kNumberOfFPRegisters); |
| 511 fpregisters_[code].Set(value, sizeof(value)); | 513 fpregisters_[code].Set(value, sizeof(value)); |
| 512 } | 514 } |
| 513 | 515 |
| 514 // Common specialized accessors for the set_fpreg() template. | 516 // Common specialized accessors for the set_fpreg() template. |
| 515 void set_sreg(unsigned code, float value) { | 517 void set_sreg(unsigned code, float value) { |
| 516 set_fpreg(code, value); | 518 set_fpreg(code, value); |
| 517 } | 519 } |
| 518 | 520 |
| 519 void set_sreg_bits(unsigned code, uint32_t value) { | 521 void set_sreg_bits(unsigned code, uint32_t value) { |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 static void UnregisterCTryCatch() { | 874 static void UnregisterCTryCatch() { |
| 873 Simulator::current(Isolate::Current())->PopAddress(); | 875 Simulator::current(Isolate::Current())->PopAddress(); |
| 874 } | 876 } |
| 875 }; | 877 }; |
| 876 | 878 |
| 877 #endif // !defined(USE_SIMULATOR) | 879 #endif // !defined(USE_SIMULATOR) |
| 878 | 880 |
| 879 } } // namespace v8::internal | 881 } } // namespace v8::internal |
| 880 | 882 |
| 881 #endif // V8_A64_SIMULATOR_A64_H_ | 883 #endif // V8_A64_SIMULATOR_A64_H_ |
| OLD | NEW |