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 #include "src/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
6 #include "src/compiler/code-generator.h" | 6 #include "src/compiler/code-generator.h" |
7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 break; | 728 break; |
729 case kMips64Xor: | 729 case kMips64Xor: |
730 __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); | 730 __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); |
731 break; | 731 break; |
732 case kMips64Clz: | 732 case kMips64Clz: |
733 __ Clz(i.OutputRegister(), i.InputRegister(0)); | 733 __ Clz(i.OutputRegister(), i.InputRegister(0)); |
734 break; | 734 break; |
735 case kMips64Dclz: | 735 case kMips64Dclz: |
736 __ dclz(i.OutputRegister(), i.InputRegister(0)); | 736 __ dclz(i.OutputRegister(), i.InputRegister(0)); |
737 break; | 737 break; |
| 738 case kMips64Ctz: { |
| 739 Register reg1 = kScratchReg; |
| 740 Register reg2 = kScratchReg2; |
| 741 Label skip_for_zero; |
| 742 Label end; |
| 743 // Branch if the operand is zero |
| 744 __ Branch(&skip_for_zero, eq, i.InputRegister(0), Operand(zero_reg)); |
| 745 // Find the number of bits before the last bit set to 1. |
| 746 __ Subu(reg2, zero_reg, i.InputRegister(0)); |
| 747 __ And(reg2, reg2, i.InputRegister(0)); |
| 748 __ clz(reg2, reg2); |
| 749 // Get the number of bits after the last bit set to 1. |
| 750 __ li(reg1, 0x1F); |
| 751 __ Subu(i.OutputRegister(), reg1, reg2); |
| 752 __ Branch(&end); |
| 753 __ bind(&skip_for_zero); |
| 754 // If the operand is zero, return word length as the result. |
| 755 __ li(i.OutputRegister(), 0x20); |
| 756 __ bind(&end); |
| 757 } break; |
| 758 case kMips64Dctz: { |
| 759 Register reg1 = kScratchReg; |
| 760 Register reg2 = kScratchReg2; |
| 761 Label skip_for_zero; |
| 762 Label end; |
| 763 // Branch if the operand is zero |
| 764 __ Branch(&skip_for_zero, eq, i.InputRegister(0), Operand(zero_reg)); |
| 765 // Find the number of bits before the last bit set to 1. |
| 766 __ Dsubu(reg2, zero_reg, i.InputRegister(0)); |
| 767 __ And(reg2, reg2, i.InputRegister(0)); |
| 768 __ dclz(reg2, reg2); |
| 769 // Get the number of bits after the last bit set to 1. |
| 770 __ li(reg1, 0x3F); |
| 771 __ Subu(i.OutputRegister(), reg1, reg2); |
| 772 __ Branch(&end); |
| 773 __ bind(&skip_for_zero); |
| 774 // If the operand is zero, return word length as the result. |
| 775 __ li(i.OutputRegister(), 0x40); |
| 776 __ bind(&end); |
| 777 } break; |
| 778 case kMips64Popcnt: { |
| 779 Register reg1 = kScratchReg; |
| 780 Register reg2 = kScratchReg2; |
| 781 uint32_t m1 = 0x55555555; |
| 782 uint32_t m2 = 0x33333333; |
| 783 uint32_t m4 = 0x0f0f0f0f; |
| 784 uint32_t m8 = 0x00ff00ff; |
| 785 uint32_t m16 = 0x0000ffff; |
| 786 |
| 787 // Put count of ones in every 2 bits into those 2 bits. |
| 788 __ li(at, m1); |
| 789 __ dsrl(reg1, i.InputRegister(0), 1); |
| 790 __ And(reg2, i.InputRegister(0), at); |
| 791 __ And(reg1, reg1, at); |
| 792 __ Daddu(reg1, reg1, reg2); |
| 793 |
| 794 // Put count of ones in every 4 bits into those 4 bits. |
| 795 __ li(at, m2); |
| 796 __ dsrl(reg2, reg1, 2); |
| 797 __ And(reg2, reg2, at); |
| 798 __ And(reg1, reg1, at); |
| 799 __ Daddu(reg1, reg1, reg2); |
| 800 |
| 801 // Put count of ones in every 8 bits into those 8 bits. |
| 802 __ li(at, m4); |
| 803 __ dsrl(reg2, reg1, 4); |
| 804 __ And(reg2, reg2, at); |
| 805 __ And(reg1, reg1, at); |
| 806 __ Daddu(reg1, reg1, reg2); |
| 807 |
| 808 // Put count of ones in every 16 bits into those 16 bits. |
| 809 __ li(at, m8); |
| 810 __ dsrl(reg2, reg1, 8); |
| 811 __ And(reg2, reg2, at); |
| 812 __ And(reg1, reg1, at); |
| 813 __ Daddu(reg1, reg1, reg2); |
| 814 |
| 815 // Calculate total number of ones. |
| 816 __ li(at, m16); |
| 817 __ dsrl(reg2, reg1, 16); |
| 818 __ And(reg2, reg2, at); |
| 819 __ And(reg1, reg1, at); |
| 820 __ Daddu(i.OutputRegister(), reg1, reg2); |
| 821 } break; |
| 822 case kMips64Dpopcnt: { |
| 823 Register reg1 = kScratchReg; |
| 824 Register reg2 = kScratchReg2; |
| 825 uint64_t m1 = 0x5555555555555555; |
| 826 uint64_t m2 = 0x3333333333333333; |
| 827 uint64_t m4 = 0x0f0f0f0f0f0f0f0f; |
| 828 uint64_t m8 = 0x00ff00ff00ff00ff; |
| 829 uint64_t m16 = 0x0000ffff0000ffff; |
| 830 uint64_t m32 = 0x00000000ffffffff; |
| 831 |
| 832 // Put count of ones in every 2 bits into those 2 bits. |
| 833 __ li(at, m1); |
| 834 __ dsrl(reg1, i.InputRegister(0), 1); |
| 835 __ and_(reg2, i.InputRegister(0), at); |
| 836 __ and_(reg1, reg1, at); |
| 837 __ Daddu(reg1, reg1, reg2); |
| 838 |
| 839 // Put count of ones in every 4 bits into those 4 bits. |
| 840 __ li(at, m2); |
| 841 __ dsrl(reg2, reg1, 2); |
| 842 __ and_(reg2, reg2, at); |
| 843 __ and_(reg1, reg1, at); |
| 844 __ Daddu(reg1, reg1, reg2); |
| 845 |
| 846 // Put count of ones in every 8 bits into those 8 bits. |
| 847 __ li(at, m4); |
| 848 __ dsrl(reg2, reg1, 4); |
| 849 __ and_(reg2, reg2, at); |
| 850 __ and_(reg1, reg1, at); |
| 851 __ Daddu(reg1, reg1, reg2); |
| 852 |
| 853 // Put count of ones in every 16 bits into those 16 bits. |
| 854 __ li(at, m8); |
| 855 __ dsrl(reg2, reg1, 8); |
| 856 __ and_(reg2, reg2, at); |
| 857 __ and_(reg1, reg1, at); |
| 858 __ Daddu(reg1, reg1, reg2); |
| 859 |
| 860 // Put count of ones in every 32 bits into those 32 bits. |
| 861 __ li(at, m16); |
| 862 __ dsrl(reg2, reg1, 16); |
| 863 __ and_(reg2, reg2, at); |
| 864 __ and_(reg1, reg1, at); |
| 865 __ Daddu(reg1, reg1, reg2); |
| 866 |
| 867 // Calculate total number of ones. |
| 868 __ li(at, m32); |
| 869 __ dsrl32(reg2, reg1, 0); |
| 870 __ and_(reg2, reg2, at); |
| 871 __ and_(reg1, reg1, at); |
| 872 __ Daddu(i.OutputRegister(), reg1, reg2); |
| 873 } break; |
738 case kMips64Shl: | 874 case kMips64Shl: |
739 if (instr->InputAt(1)->IsRegister()) { | 875 if (instr->InputAt(1)->IsRegister()) { |
740 __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 876 __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); |
741 } else { | 877 } else { |
742 int64_t imm = i.InputOperand(1).immediate(); | 878 int64_t imm = i.InputOperand(1).immediate(); |
743 __ sll(i.OutputRegister(), i.InputRegister(0), | 879 __ sll(i.OutputRegister(), i.InputRegister(0), |
744 static_cast<uint16_t>(imm)); | 880 static_cast<uint16_t>(imm)); |
745 } | 881 } |
746 break; | 882 break; |
747 case kMips64Shr: | 883 case kMips64Shr: |
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 padding_size -= v8::internal::Assembler::kInstrSize; | 2117 padding_size -= v8::internal::Assembler::kInstrSize; |
1982 } | 2118 } |
1983 } | 2119 } |
1984 } | 2120 } |
1985 | 2121 |
1986 #undef __ | 2122 #undef __ |
1987 | 2123 |
1988 } // namespace compiler | 2124 } // namespace compiler |
1989 } // namespace internal | 2125 } // namespace internal |
1990 } // namespace v8 | 2126 } // namespace v8 |
OLD | NEW |