Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1066)

Side by Side Diff: src/compiler/mips64/code-generator-mips64.cc

Issue 1588383002: MIPS: [turbofan] Implement Word32Ctz, Word64Ctz, Word32Popcnt and Word64Popcnt (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove unneccesary mov instructions Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/mips/instruction-selector-mips.cc ('k') | src/compiler/mips64/instruction-codes-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698