| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_DECODER_ARM64_INL_H_ | 5 #ifndef V8_ARM64_DECODER_ARM64_INL_H_ |
| 6 #define V8_ARM64_DECODER_ARM64_INL_H_ | 6 #define V8_ARM64_DECODER_ARM64_INL_H_ |
| 7 | 7 |
| 8 #include "src/arm64/decoder-arm64.h" | 8 #include "src/arm64/decoder-arm64.h" |
| 9 #include "src/globals.h" | 9 #include "src/globals.h" |
| 10 #include "src/utils.h" | 10 #include "src/utils.h" |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 } | 206 } |
| 207 | 207 |
| 208 | 208 |
| 209 template<typename V> | 209 template<typename V> |
| 210 void Decoder<V>::DecodeLoadStore(Instruction* instr) { | 210 void Decoder<V>::DecodeLoadStore(Instruction* instr) { |
| 211 DCHECK((instr->Bits(27, 24) == 0x8) || | 211 DCHECK((instr->Bits(27, 24) == 0x8) || |
| 212 (instr->Bits(27, 24) == 0x9) || | 212 (instr->Bits(27, 24) == 0x9) || |
| 213 (instr->Bits(27, 24) == 0xC) || | 213 (instr->Bits(27, 24) == 0xC) || |
| 214 (instr->Bits(27, 24) == 0xD) ); | 214 (instr->Bits(27, 24) == 0xD) ); |
| 215 | 215 |
| 216 if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) { | |
| 217 DecodeNEONLoadStore(instr); | |
| 218 return; | |
| 219 } | |
| 220 | |
| 221 if (instr->Bit(24) == 0) { | 216 if (instr->Bit(24) == 0) { |
| 222 if (instr->Bit(28) == 0) { | 217 if (instr->Bit(28) == 0) { |
| 223 if (instr->Bit(29) == 0) { | 218 if (instr->Bit(29) == 0) { |
| 224 if (instr->Bit(26) == 0) { | 219 if (instr->Bit(26) == 0) { |
| 225 if (instr->Mask(0xA08000) == 0x800000 || | 220 if (instr->Mask(0xA08000) == 0x800000 || |
| 226 instr->Mask(0xA00000) == 0xA00000) { | 221 instr->Mask(0xA00000) == 0xA00000) { |
| 227 V::VisitUnallocated(instr); | 222 V::VisitUnallocated(instr); |
| 228 } else if (instr->Mask(0x808000) == 0) { | 223 } else if (instr->Mask(0x808000) == 0) { |
| 229 // Load/Store exclusive without acquire/release are unimplemented. | 224 // Load/Store exclusive without acquire/release are unimplemented. |
| 230 V::VisitUnimplemented(instr); | 225 V::VisitUnimplemented(instr); |
| 231 } else { | 226 } else { |
| 232 V::VisitLoadStoreAcquireRelease(instr); | 227 V::VisitLoadStoreAcquireRelease(instr); |
| 233 } | 228 } |
| 229 } else { |
| 230 DecodeAdvSIMDLoadStore(instr); |
| 234 } | 231 } |
| 235 } else { | 232 } else { |
| 236 if ((instr->Bits(31, 30) == 0x3) || | 233 if ((instr->Bits(31, 30) == 0x3) || |
| 237 (instr->Mask(0xC4400000) == 0x40000000)) { | 234 (instr->Mask(0xC4400000) == 0x40000000)) { |
| 238 V::VisitUnallocated(instr); | 235 V::VisitUnallocated(instr); |
| 239 } else { | 236 } else { |
| 240 if (instr->Bit(23) == 0) { | 237 if (instr->Bit(23) == 0) { |
| 241 if (instr->Mask(0xC4400000) == 0xC0400000) { | 238 if (instr->Mask(0xC4400000) == 0xC0400000) { |
| 242 V::VisitUnallocated(instr); | 239 V::VisitUnallocated(instr); |
| 243 } else { | 240 } else { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 } | 506 } |
| 510 } | 507 } |
| 511 | 508 |
| 512 | 509 |
| 513 template<typename V> | 510 template<typename V> |
| 514 void Decoder<V>::DecodeFP(Instruction* instr) { | 511 void Decoder<V>::DecodeFP(Instruction* instr) { |
| 515 DCHECK((instr->Bits(27, 24) == 0xE) || | 512 DCHECK((instr->Bits(27, 24) == 0xE) || |
| 516 (instr->Bits(27, 24) == 0xF) ); | 513 (instr->Bits(27, 24) == 0xF) ); |
| 517 | 514 |
| 518 if (instr->Bit(28) == 0) { | 515 if (instr->Bit(28) == 0) { |
| 519 DecodeNEONVectorDataProcessing(instr); | 516 DecodeAdvSIMDDataProcessing(instr); |
| 520 } else { | 517 } else { |
| 521 if (instr->Bits(31, 30) == 0x3) { | 518 if (instr->Bit(29) == 1) { |
| 522 V::VisitUnallocated(instr); | 519 V::VisitUnallocated(instr); |
| 523 } else if (instr->Bits(31, 30) == 0x1) { | |
| 524 DecodeNEONScalarDataProcessing(instr); | |
| 525 } else { | 520 } else { |
| 526 if (instr->Bit(29) == 0) { | 521 if (instr->Bits(31, 30) == 0x3) { |
| 522 V::VisitUnallocated(instr); |
| 523 } else if (instr->Bits(31, 30) == 0x1) { |
| 524 DecodeAdvSIMDDataProcessing(instr); |
| 525 } else { |
| 527 if (instr->Bit(24) == 0) { | 526 if (instr->Bit(24) == 0) { |
| 528 if (instr->Bit(21) == 0) { | 527 if (instr->Bit(21) == 0) { |
| 529 if ((instr->Bit(23) == 1) || | 528 if ((instr->Bit(23) == 1) || |
| 530 (instr->Bit(18) == 1) || | 529 (instr->Bit(18) == 1) || |
| 531 (instr->Mask(0x80008000) == 0x00000000) || | 530 (instr->Mask(0x80008000) == 0x00000000) || |
| 532 (instr->Mask(0x000E0000) == 0x00000000) || | 531 (instr->Mask(0x000E0000) == 0x00000000) || |
| 533 (instr->Mask(0x000E0000) == 0x000A0000) || | 532 (instr->Mask(0x000E0000) == 0x000A0000) || |
| 534 (instr->Mask(0x00160000) == 0x00000000) || | 533 (instr->Mask(0x00160000) == 0x00000000) || |
| 535 (instr->Mask(0x00160000) == 0x00120000)) { | 534 (instr->Mask(0x00160000) == 0x00120000)) { |
| 536 V::VisitUnallocated(instr); | 535 V::VisitUnallocated(instr); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 } | 622 } |
| 624 } else { | 623 } else { |
| 625 // Bit 30 == 1 has been handled earlier. | 624 // Bit 30 == 1 has been handled earlier. |
| 626 DCHECK(instr->Bit(30) == 0); | 625 DCHECK(instr->Bit(30) == 0); |
| 627 if (instr->Mask(0xA0800000) != 0) { | 626 if (instr->Mask(0xA0800000) != 0) { |
| 628 V::VisitUnallocated(instr); | 627 V::VisitUnallocated(instr); |
| 629 } else { | 628 } else { |
| 630 V::VisitFPDataProcessing3Source(instr); | 629 V::VisitFPDataProcessing3Source(instr); |
| 631 } | 630 } |
| 632 } | 631 } |
| 633 } else { | |
| 634 V::VisitUnallocated(instr); | |
| 635 } | |
| 636 } | |
| 637 } | |
| 638 } | |
| 639 | |
| 640 template <typename V> | |
| 641 void Decoder<V>::DecodeNEONLoadStore(Instruction* instr) { | |
| 642 DCHECK(instr->Bits(29, 25) == 0x6); | |
| 643 if (instr->Bit(31) == 0) { | |
| 644 if ((instr->Bit(24) == 0) && (instr->Bit(21) == 1)) { | |
| 645 V::VisitUnallocated(instr); | |
| 646 return; | |
| 647 } | |
| 648 | |
| 649 if (instr->Bit(23) == 0) { | |
| 650 if (instr->Bits(20, 16) == 0) { | |
| 651 if (instr->Bit(24) == 0) { | |
| 652 V::VisitNEONLoadStoreMultiStruct(instr); | |
| 653 } else { | |
| 654 V::VisitNEONLoadStoreSingleStruct(instr); | |
| 655 } | |
| 656 } else { | |
| 657 V::VisitUnallocated(instr); | |
| 658 } | |
| 659 } else { | |
| 660 if (instr->Bit(24) == 0) { | |
| 661 V::VisitNEONLoadStoreMultiStructPostIndex(instr); | |
| 662 } else { | |
| 663 V::VisitNEONLoadStoreSingleStructPostIndex(instr); | |
| 664 } | |
| 665 } | |
| 666 } else { | |
| 667 V::VisitUnallocated(instr); | |
| 668 } | |
| 669 } | |
| 670 | |
| 671 template <typename V> | |
| 672 void Decoder<V>::DecodeNEONVectorDataProcessing(Instruction* instr) { | |
| 673 DCHECK(instr->Bits(28, 25) == 0x7); | |
| 674 if (instr->Bit(31) == 0) { | |
| 675 if (instr->Bit(24) == 0) { | |
| 676 if (instr->Bit(21) == 0) { | |
| 677 if (instr->Bit(15) == 0) { | |
| 678 if (instr->Bit(10) == 0) { | |
| 679 if (instr->Bit(29) == 0) { | |
| 680 if (instr->Bit(11) == 0) { | |
| 681 V::VisitNEONTable(instr); | |
| 682 } else { | |
| 683 V::VisitNEONPerm(instr); | |
| 684 } | |
| 685 } else { | |
| 686 V::VisitNEONExtract(instr); | |
| 687 } | |
| 688 } else { | |
| 689 if (instr->Bits(23, 22) == 0) { | |
| 690 V::VisitNEONCopy(instr); | |
| 691 } else { | |
| 692 V::VisitUnallocated(instr); | |
| 693 } | |
| 694 } | |
| 695 } else { | |
| 696 V::VisitUnallocated(instr); | |
| 697 } | |
| 698 } else { | |
| 699 if (instr->Bit(10) == 0) { | |
| 700 if (instr->Bit(11) == 0) { | |
| 701 V::VisitNEON3Different(instr); | |
| 702 } else { | |
| 703 if (instr->Bits(18, 17) == 0) { | |
| 704 if (instr->Bit(20) == 0) { | |
| 705 if (instr->Bit(19) == 0) { | |
| 706 V::VisitNEON2RegMisc(instr); | |
| 707 } else { | |
| 708 if (instr->Bits(30, 29) == 0x2) { | |
| 709 V::VisitUnallocated(instr); | |
| 710 } else { | |
| 711 V::VisitUnallocated(instr); | |
| 712 } | |
| 713 } | |
| 714 } else { | |
| 715 if (instr->Bit(19) == 0) { | |
| 716 V::VisitNEONAcrossLanes(instr); | |
| 717 } else { | |
| 718 V::VisitUnallocated(instr); | |
| 719 } | |
| 720 } | |
| 721 } else { | |
| 722 V::VisitUnallocated(instr); | |
| 723 } | |
| 724 } | |
| 725 } else { | |
| 726 V::VisitNEON3Same(instr); | |
| 727 } | |
| 728 } | |
| 729 } else { | |
| 730 if (instr->Bit(10) == 0) { | |
| 731 V::VisitNEONByIndexedElement(instr); | |
| 732 } else { | |
| 733 if (instr->Bit(23) == 0) { | |
| 734 if (instr->Bits(22, 19) == 0) { | |
| 735 V::VisitNEONModifiedImmediate(instr); | |
| 736 } else { | |
| 737 V::VisitNEONShiftImmediate(instr); | |
| 738 } | |
| 739 } else { | |
| 740 V::VisitUnallocated(instr); | |
| 741 } | |
| 742 } | |
| 743 } | |
| 744 } else { | |
| 745 V::VisitUnallocated(instr); | |
| 746 } | |
| 747 } | |
| 748 | |
| 749 template <typename V> | |
| 750 void Decoder<V>::DecodeNEONScalarDataProcessing(Instruction* instr) { | |
| 751 DCHECK(instr->Bits(28, 25) == 0xF); | |
| 752 if (instr->Bit(24) == 0) { | |
| 753 if (instr->Bit(21) == 0) { | |
| 754 if (instr->Bit(15) == 0) { | |
| 755 if (instr->Bit(10) == 0) { | |
| 756 if (instr->Bit(29) == 0) { | |
| 757 if (instr->Bit(11) == 0) { | |
| 758 V::VisitUnallocated(instr); | |
| 759 } else { | |
| 760 V::VisitUnallocated(instr); | |
| 761 } | |
| 762 } else { | |
| 763 V::VisitUnallocated(instr); | |
| 764 } | |
| 765 } else { | |
| 766 if (instr->Bits(23, 22) == 0) { | |
| 767 V::VisitNEONScalarCopy(instr); | |
| 768 } else { | |
| 769 V::VisitUnallocated(instr); | |
| 770 } | |
| 771 } | |
| 772 } else { | |
| 773 V::VisitUnallocated(instr); | |
| 774 } | |
| 775 } else { | |
| 776 if (instr->Bit(10) == 0) { | |
| 777 if (instr->Bit(11) == 0) { | |
| 778 V::VisitNEONScalar3Diff(instr); | |
| 779 } else { | |
| 780 if (instr->Bits(18, 17) == 0) { | |
| 781 if (instr->Bit(20) == 0) { | |
| 782 if (instr->Bit(19) == 0) { | |
| 783 V::VisitNEONScalar2RegMisc(instr); | |
| 784 } else { | |
| 785 if (instr->Bit(29) == 0) { | |
| 786 V::VisitUnallocated(instr); | |
| 787 } else { | |
| 788 V::VisitUnallocated(instr); | |
| 789 } | |
| 790 } | |
| 791 } else { | |
| 792 if (instr->Bit(19) == 0) { | |
| 793 V::VisitNEONScalarPairwise(instr); | |
| 794 } else { | |
| 795 V::VisitUnallocated(instr); | |
| 796 } | |
| 797 } | |
| 798 } else { | |
| 799 V::VisitUnallocated(instr); | |
| 800 } | |
| 801 } | |
| 802 } else { | |
| 803 V::VisitNEONScalar3Same(instr); | |
| 804 } | |
| 805 } | |
| 806 } else { | |
| 807 if (instr->Bit(10) == 0) { | |
| 808 V::VisitNEONScalarByIndexedElement(instr); | |
| 809 } else { | |
| 810 if (instr->Bit(23) == 0) { | |
| 811 V::VisitNEONScalarShiftImmediate(instr); | |
| 812 } else { | |
| 813 V::VisitUnallocated(instr); | |
| 814 } | 632 } |
| 815 } | 633 } |
| 816 } | 634 } |
| 817 } | 635 } |
| 818 | 636 |
| 819 | 637 |
| 638 template<typename V> |
| 639 void Decoder<V>::DecodeAdvSIMDLoadStore(Instruction* instr) { |
| 640 // TODO(all): Implement Advanced SIMD load/store instruction decode. |
| 641 DCHECK(instr->Bits(29, 25) == 0x6); |
| 642 V::VisitUnimplemented(instr); |
| 643 } |
| 644 |
| 645 |
| 646 template<typename V> |
| 647 void Decoder<V>::DecodeAdvSIMDDataProcessing(Instruction* instr) { |
| 648 // TODO(all): Implement Advanced SIMD data processing instruction decode. |
| 649 DCHECK(instr->Bits(27, 25) == 0x7); |
| 650 V::VisitUnimplemented(instr); |
| 651 } |
| 652 |
| 653 |
| 820 } // namespace internal | 654 } // namespace internal |
| 821 } // namespace v8 | 655 } // namespace v8 |
| 822 | 656 |
| 823 #endif // V8_ARM64_DECODER_ARM64_INL_H_ | 657 #endif // V8_ARM64_DECODER_ARM64_INL_H_ |
| OLD | NEW |