| 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 |
| 216 if (instr->Bit(24) == 0) { | 221 if (instr->Bit(24) == 0) { |
| 217 if (instr->Bit(28) == 0) { | 222 if (instr->Bit(28) == 0) { |
| 218 if (instr->Bit(29) == 0) { | 223 if (instr->Bit(29) == 0) { |
| 219 if (instr->Bit(26) == 0) { | 224 if (instr->Bit(26) == 0) { |
| 220 if (instr->Mask(0xA08000) == 0x800000 || | 225 if (instr->Mask(0xA08000) == 0x800000 || |
| 221 instr->Mask(0xA00000) == 0xA00000) { | 226 instr->Mask(0xA00000) == 0xA00000) { |
| 222 V::VisitUnallocated(instr); | 227 V::VisitUnallocated(instr); |
| 223 } else if (instr->Mask(0x808000) == 0) { | 228 } else if (instr->Mask(0x808000) == 0) { |
| 224 // Load/Store exclusive without acquire/release are unimplemented. | 229 // Load/Store exclusive without acquire/release are unimplemented. |
| 225 V::VisitUnimplemented(instr); | 230 V::VisitUnimplemented(instr); |
| 226 } else { | 231 } else { |
| 227 V::VisitLoadStoreAcquireRelease(instr); | 232 V::VisitLoadStoreAcquireRelease(instr); |
| 228 } | 233 } |
| 229 } else { | |
| 230 DecodeAdvSIMDLoadStore(instr); | |
| 231 } | 234 } |
| 232 } else { | 235 } else { |
| 233 if ((instr->Bits(31, 30) == 0x3) || | 236 if ((instr->Bits(31, 30) == 0x3) || |
| 234 (instr->Mask(0xC4400000) == 0x40000000)) { | 237 (instr->Mask(0xC4400000) == 0x40000000)) { |
| 235 V::VisitUnallocated(instr); | 238 V::VisitUnallocated(instr); |
| 236 } else { | 239 } else { |
| 237 if (instr->Bit(23) == 0) { | 240 if (instr->Bit(23) == 0) { |
| 238 if (instr->Mask(0xC4400000) == 0xC0400000) { | 241 if (instr->Mask(0xC4400000) == 0xC0400000) { |
| 239 V::VisitUnallocated(instr); | 242 V::VisitUnallocated(instr); |
| 240 } else { | 243 } else { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 } | 509 } |
| 507 } | 510 } |
| 508 | 511 |
| 509 | 512 |
| 510 template<typename V> | 513 template<typename V> |
| 511 void Decoder<V>::DecodeFP(Instruction* instr) { | 514 void Decoder<V>::DecodeFP(Instruction* instr) { |
| 512 DCHECK((instr->Bits(27, 24) == 0xE) || | 515 DCHECK((instr->Bits(27, 24) == 0xE) || |
| 513 (instr->Bits(27, 24) == 0xF) ); | 516 (instr->Bits(27, 24) == 0xF) ); |
| 514 | 517 |
| 515 if (instr->Bit(28) == 0) { | 518 if (instr->Bit(28) == 0) { |
| 516 DecodeAdvSIMDDataProcessing(instr); | 519 DecodeNEONVectorDataProcessing(instr); |
| 517 } else { | 520 } else { |
| 518 if (instr->Bit(29) == 1) { | 521 if (instr->Bits(31, 30) == 0x3) { |
| 519 V::VisitUnallocated(instr); | 522 V::VisitUnallocated(instr); |
| 523 } else if (instr->Bits(31, 30) == 0x1) { |
| 524 DecodeNEONScalarDataProcessing(instr); |
| 520 } else { | 525 } else { |
| 521 if (instr->Bits(31, 30) == 0x3) { | 526 if (instr->Bit(29) == 0) { |
| 522 V::VisitUnallocated(instr); | |
| 523 } else if (instr->Bits(31, 30) == 0x1) { | |
| 524 DecodeAdvSIMDDataProcessing(instr); | |
| 525 } else { | |
| 526 if (instr->Bit(24) == 0) { | 527 if (instr->Bit(24) == 0) { |
| 527 if (instr->Bit(21) == 0) { | 528 if (instr->Bit(21) == 0) { |
| 528 if ((instr->Bit(23) == 1) || | 529 if ((instr->Bit(23) == 1) || |
| 529 (instr->Bit(18) == 1) || | 530 (instr->Bit(18) == 1) || |
| 530 (instr->Mask(0x80008000) == 0x00000000) || | 531 (instr->Mask(0x80008000) == 0x00000000) || |
| 531 (instr->Mask(0x000E0000) == 0x00000000) || | 532 (instr->Mask(0x000E0000) == 0x00000000) || |
| 532 (instr->Mask(0x000E0000) == 0x000A0000) || | 533 (instr->Mask(0x000E0000) == 0x000A0000) || |
| 533 (instr->Mask(0x00160000) == 0x00000000) || | 534 (instr->Mask(0x00160000) == 0x00000000) || |
| 534 (instr->Mask(0x00160000) == 0x00120000)) { | 535 (instr->Mask(0x00160000) == 0x00120000)) { |
| 535 V::VisitUnallocated(instr); | 536 V::VisitUnallocated(instr); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 } | 623 } |
| 623 } else { | 624 } else { |
| 624 // Bit 30 == 1 has been handled earlier. | 625 // Bit 30 == 1 has been handled earlier. |
| 625 DCHECK(instr->Bit(30) == 0); | 626 DCHECK(instr->Bit(30) == 0); |
| 626 if (instr->Mask(0xA0800000) != 0) { | 627 if (instr->Mask(0xA0800000) != 0) { |
| 627 V::VisitUnallocated(instr); | 628 V::VisitUnallocated(instr); |
| 628 } else { | 629 } else { |
| 629 V::VisitFPDataProcessing3Source(instr); | 630 V::VisitFPDataProcessing3Source(instr); |
| 630 } | 631 } |
| 631 } | 632 } |
| 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); |
| 632 } | 814 } |
| 633 } | 815 } |
| 634 } | 816 } |
| 635 } | 817 } |
| 636 | 818 |
| 637 | 819 |
| 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 | |
| 654 } // namespace internal | 820 } // namespace internal |
| 655 } // namespace v8 | 821 } // namespace v8 |
| 656 | 822 |
| 657 #endif // V8_ARM64_DECODER_ARM64_INL_H_ | 823 #endif // V8_ARM64_DECODER_ARM64_INL_H_ |
| OLD | NEW |