| 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) { |
| 520 set_fpreg(code, value); | 522 set_fpreg(code, value); |
| 521 } | 523 } |
| 522 | 524 |
| 523 void set_dreg(unsigned code, double value) { | 525 void set_dreg(unsigned code, double value) { |
| 524 set_fpreg(code, value); | 526 set_fpreg(code, value); |
| 525 } | 527 } |
| 526 | 528 |
| 527 void set_dreg_bits(unsigned code, uint64_t value) { | 529 void set_dreg_bits(unsigned code, uint64_t value) { |
| 528 set_fpreg(code, value); | 530 set_fpreg(code, value); |
| 529 } | 531 } |
| 530 | 532 |
| 531 bool N() { return nzcv_.N() != 0; } | 533 bool N() { return nzcv_.N() != 0; } |
| 532 bool Z() { return nzcv_.Z() != 0; } | 534 bool Z() { return nzcv_.Z() != 0; } |
| 533 bool C() { return nzcv_.C() != 0; } | 535 bool C() { return nzcv_.C() != 0; } |
| 534 bool V() { return nzcv_.V() != 0; } | 536 bool V() { return nzcv_.V() != 0; } |
| 535 SimSystemRegister& nzcv() { return nzcv_; } | 537 SimSystemRegister& nzcv() { return nzcv_; } |
| 536 | 538 |
| 537 // TODO(jbramley): Find a way to make the fpcr_ members return the proper | 539 // TODO(jbramley): Find a way to make the fpcr_ members return the proper |
| 538 // types, so this accessor is not necessary. | 540 // types, so these accessors are not necessary. |
| 539 FPRounding RMode() { return static_cast<FPRounding>(fpcr_.RMode()); } | 541 FPRounding RMode() { return static_cast<FPRounding>(fpcr_.RMode()); } |
| 542 bool DN() { return fpcr_.DN() != 0; } |
| 540 SimSystemRegister& fpcr() { return fpcr_; } | 543 SimSystemRegister& fpcr() { return fpcr_; } |
| 541 | 544 |
| 542 // Debug helpers | 545 // Debug helpers |
| 543 | 546 |
| 544 // Simulator breakpoints. | 547 // Simulator breakpoints. |
| 545 struct Breakpoint { | 548 struct Breakpoint { |
| 546 Instruction* location; | 549 Instruction* location; |
| 547 bool enabled; | 550 bool enabled; |
| 548 }; | 551 }; |
| 549 std::vector<Breakpoint> breakpoints_; | 552 std::vector<Breakpoint> breakpoints_; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 Shift shift_type, | 701 Shift shift_type, |
| 699 unsigned amount); | 702 unsigned amount); |
| 700 int64_t ExtendValue(unsigned reg_width, | 703 int64_t ExtendValue(unsigned reg_width, |
| 701 int64_t value, | 704 int64_t value, |
| 702 Extend extend_type, | 705 Extend extend_type, |
| 703 unsigned left_shift = 0); | 706 unsigned left_shift = 0); |
| 704 | 707 |
| 705 uint64_t ReverseBits(uint64_t value, unsigned num_bits); | 708 uint64_t ReverseBits(uint64_t value, unsigned num_bits); |
| 706 uint64_t ReverseBytes(uint64_t value, ReverseByteMode mode); | 709 uint64_t ReverseBytes(uint64_t value, ReverseByteMode mode); |
| 707 | 710 |
| 711 template <typename T> |
| 712 T FPDefaultNaN() const; |
| 713 |
| 708 void FPCompare(double val0, double val1); | 714 void FPCompare(double val0, double val1); |
| 709 double FPRoundInt(double value, FPRounding round_mode); | 715 double FPRoundInt(double value, FPRounding round_mode); |
| 710 double FPToDouble(float value); | 716 double FPToDouble(float value); |
| 711 float FPToFloat(double value, FPRounding round_mode); | 717 float FPToFloat(double value, FPRounding round_mode); |
| 712 double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); | 718 double FixedToDouble(int64_t src, int fbits, FPRounding round_mode); |
| 713 double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); | 719 double UFixedToDouble(uint64_t src, int fbits, FPRounding round_mode); |
| 714 float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); | 720 float FixedToFloat(int64_t src, int fbits, FPRounding round_mode); |
| 715 float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); | 721 float UFixedToFloat(uint64_t src, int fbits, FPRounding round_mode); |
| 716 int32_t FPToInt32(double value, FPRounding rmode); | 722 int32_t FPToInt32(double value, FPRounding rmode); |
| 717 int64_t FPToInt64(double value, FPRounding rmode); | 723 int64_t FPToInt64(double value, FPRounding rmode); |
| 718 uint32_t FPToUInt32(double value, FPRounding rmode); | 724 uint32_t FPToUInt32(double value, FPRounding rmode); |
| 719 uint64_t FPToUInt64(double value, FPRounding rmode); | 725 uint64_t FPToUInt64(double value, FPRounding rmode); |
| 720 | 726 |
| 721 template <typename T> | 727 template <typename T> |
| 728 T FPAdd(T op1, T op2); |
| 729 |
| 730 template <typename T> |
| 731 T FPDiv(T op1, T op2); |
| 732 |
| 733 template <typename T> |
| 722 T FPMax(T a, T b); | 734 T FPMax(T a, T b); |
| 723 | 735 |
| 724 template <typename T> | 736 template <typename T> |
| 725 T FPMin(T a, T b); | 737 T FPMaxNM(T a, T b); |
| 726 | 738 |
| 727 template <typename T> | 739 template <typename T> |
| 728 T FPMaxNM(T a, T b); | 740 T FPMin(T a, T b); |
| 729 | 741 |
| 730 template <typename T> | 742 template <typename T> |
| 731 T FPMinNM(T a, T b); | 743 T FPMinNM(T a, T b); |
| 732 | 744 |
| 745 template <typename T> |
| 746 T FPMul(T op1, T op2); |
| 747 |
| 748 template <typename T> |
| 749 T FPMulAdd(T a, T op1, T op2); |
| 750 |
| 751 template <typename T> |
| 752 T FPSqrt(T op); |
| 753 |
| 754 template <typename T> |
| 755 T FPSub(T op1, T op2); |
| 756 |
| 757 // Standard NaN processing. |
| 758 template <typename T> |
| 759 T FPProcessNaN(T op); |
| 760 |
| 761 bool FPProcessNaNs(Instruction* instr); |
| 762 |
| 763 template <typename T> |
| 764 T FPProcessNaNs(T op1, T op2); |
| 765 |
| 766 template <typename T> |
| 767 T FPProcessNaNs3(T op1, T op2, T op3); |
| 768 |
| 733 void CheckStackAlignment(); | 769 void CheckStackAlignment(); |
| 734 | 770 |
| 735 inline void CheckPCSComplianceAndRun(); | 771 inline void CheckPCSComplianceAndRun(); |
| 736 | 772 |
| 737 #ifdef DEBUG | 773 #ifdef DEBUG |
| 738 // Corruption values should have their least significant byte cleared to | 774 // Corruption values should have their least significant byte cleared to |
| 739 // allow the code of the register being corrupted to be inserted. | 775 // allow the code of the register being corrupted to be inserted. |
| 740 static const uint64_t kCallerSavedRegisterCorruptionValue = | 776 static const uint64_t kCallerSavedRegisterCorruptionValue = |
| 741 0xca11edc0de000000UL; | 777 0xca11edc0de000000UL; |
| 742 // This value is a NaN in both 32-bit and 64-bit FP. | 778 // This value is a NaN in both 32-bit and 64-bit FP. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 SimSystemRegister fpcr_; | 811 SimSystemRegister fpcr_; |
| 776 | 812 |
| 777 // Only a subset of FPCR features are supported by the simulator. This helper | 813 // Only a subset of FPCR features are supported by the simulator. This helper |
| 778 // checks that the FPCR settings are supported. | 814 // checks that the FPCR settings are supported. |
| 779 // | 815 // |
| 780 // This is checked when floating-point instructions are executed, not when | 816 // This is checked when floating-point instructions are executed, not when |
| 781 // FPCR is set. This allows generated code to modify FPCR for external | 817 // FPCR is set. This allows generated code to modify FPCR for external |
| 782 // functions, or to save and restore it when entering and leaving generated | 818 // functions, or to save and restore it when entering and leaving generated |
| 783 // code. | 819 // code. |
| 784 void AssertSupportedFPCR() { | 820 void AssertSupportedFPCR() { |
| 785 ASSERT(fpcr().DN() == 0); // No default-NaN support. | |
| 786 ASSERT(fpcr().FZ() == 0); // No flush-to-zero support. | 821 ASSERT(fpcr().FZ() == 0); // No flush-to-zero support. |
| 787 ASSERT(fpcr().RMode() == FPTieEven); // Ties-to-even rounding only. | 822 ASSERT(fpcr().RMode() == FPTieEven); // Ties-to-even rounding only. |
| 788 | 823 |
| 789 // The simulator does not support half-precision operations so fpcr().AHP() | 824 // The simulator does not support half-precision operations so fpcr().AHP() |
| 790 // is irrelevant, and is not checked here. | 825 // is irrelevant, and is not checked here. |
| 791 } | 826 } |
| 792 | 827 |
| 793 static int CalcNFlag(uint64_t result, unsigned reg_size) { | 828 static int CalcNFlag(uint64_t result, unsigned reg_size) { |
| 794 return (result >> (reg_size - 1)) & 1; | 829 return (result >> (reg_size - 1)) & 1; |
| 795 } | 830 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 static void UnregisterCTryCatch() { | 907 static void UnregisterCTryCatch() { |
| 873 Simulator::current(Isolate::Current())->PopAddress(); | 908 Simulator::current(Isolate::Current())->PopAddress(); |
| 874 } | 909 } |
| 875 }; | 910 }; |
| 876 | 911 |
| 877 #endif // !defined(USE_SIMULATOR) | 912 #endif // !defined(USE_SIMULATOR) |
| 878 | 913 |
| 879 } } // namespace v8::internal | 914 } } // namespace v8::internal |
| 880 | 915 |
| 881 #endif // V8_A64_SIMULATOR_A64_H_ | 916 #endif // V8_A64_SIMULATOR_A64_H_ |
| OLD | NEW |