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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2359713003: [Subzero][MIPS32] Implements 64-bit shl, lshr, ashr for MIPS (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Added lowering of shifts operations with constant shift amount Created 4 years, 2 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 // 1 //
2 // The Subzero Code Generator 2 // The Subzero Code Generator
3 // 3 //
4 // This file is distributed under the University of Illinois Open Source 4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details. 5 // License. See LICENSE.TXT for details.
6 // 6 //
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 /// 8 ///
9 /// \file 9 /// \file
10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost
(...skipping 1770 matching lines...) Expand 10 before | Expand all | Expand 10 after
1781 _mov(Dest, T); 1781 _mov(Dest, T);
1782 } else { 1782 } else {
1783 _mov(Dest, SP); 1783 _mov(Dest, SP);
1784 } 1784 }
1785 } 1785 }
1786 1786
1787 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr, 1787 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
1788 Variable *Dest, Operand *Src0, 1788 Variable *Dest, Operand *Src0,
1789 Operand *Src1) { 1789 Operand *Src1) {
1790 InstArithmetic::OpKind Op = Instr->getOp(); 1790 InstArithmetic::OpKind Op = Instr->getOp();
1791 switch (Op) {
1792 case InstArithmetic::Add:
1793 case InstArithmetic::And:
1794 case InstArithmetic::Or:
1795 case InstArithmetic::Sub:
1796 case InstArithmetic::Xor:
1797 case InstArithmetic::Mul:
1798 break;
1799 default:
1800 UnimplementedLoweringError(this, Instr);
1801 return;
1802 }
1803 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1791 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
1804 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1792 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1805 Variable *Src0LoR = legalizeToReg(loOperand(Src0)); 1793 Variable *Src0LoR = nullptr;
1806 Variable *Src1LoR = legalizeToReg(loOperand(Src1)); 1794 Variable *Src1LoR = nullptr;
1807 Variable *Src0HiR = legalizeToReg(hiOperand(Src0)); 1795 Variable *Src0HiR = nullptr;
1808 Variable *Src1HiR = legalizeToReg(hiOperand(Src1)); 1796 Variable *Src1HiR = nullptr;
1809 1797
1810 switch (Op) { 1798 switch (Op) {
1811 case InstArithmetic::_num: 1799 case InstArithmetic::_num:
1812 llvm::report_fatal_error("Unknown arithmetic operator"); 1800 llvm::report_fatal_error("Unknown arithmetic operator");
1813 return; 1801 return;
1814 case InstArithmetic::Add: { 1802 case InstArithmetic::Add: {
1803 Src0LoR = legalizeToReg(loOperand(Src0));
1804 Src1LoR = legalizeToReg(loOperand(Src1));
1805 Src0HiR = legalizeToReg(hiOperand(Src0));
1806 Src1HiR = legalizeToReg(hiOperand(Src1));
1815 auto *T_Carry = I32Reg(), *T_Lo = I32Reg(), *T_Hi = I32Reg(), 1807 auto *T_Carry = I32Reg(), *T_Lo = I32Reg(), *T_Hi = I32Reg(),
1816 *T_Hi2 = I32Reg(); 1808 *T_Hi2 = I32Reg();
1817 _addu(T_Lo, Src0LoR, Src1LoR); 1809 _addu(T_Lo, Src0LoR, Src1LoR);
1818 _mov(DestLo, T_Lo); 1810 _mov(DestLo, T_Lo);
1819 _sltu(T_Carry, T_Lo, Src0LoR); 1811 _sltu(T_Carry, T_Lo, Src0LoR);
1820 _addu(T_Hi, T_Carry, Src0HiR); 1812 _addu(T_Hi, T_Carry, Src0HiR);
1821 _addu(T_Hi2, Src1HiR, T_Hi); 1813 _addu(T_Hi2, Src1HiR, T_Hi);
1822 _mov(DestHi, T_Hi2); 1814 _mov(DestHi, T_Hi2);
1823 return; 1815 return;
1824 } 1816 }
1825 case InstArithmetic::And: { 1817 case InstArithmetic::And: {
1818 Src0LoR = legalizeToReg(loOperand(Src0));
1819 Src1LoR = legalizeToReg(loOperand(Src1));
1820 Src0HiR = legalizeToReg(hiOperand(Src0));
1821 Src1HiR = legalizeToReg(hiOperand(Src1));
1826 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); 1822 auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
1827 _and(T_Lo, Src0LoR, Src1LoR); 1823 _and(T_Lo, Src0LoR, Src1LoR);
1828 _mov(DestLo, T_Lo); 1824 _mov(DestLo, T_Lo);
1829 _and(T_Hi, Src0HiR, Src1HiR); 1825 _and(T_Hi, Src0HiR, Src1HiR);
1830 _mov(DestHi, T_Hi); 1826 _mov(DestHi, T_Hi);
1831 return; 1827 return;
1832 } 1828 }
1833 case InstArithmetic::Sub: { 1829 case InstArithmetic::Sub: {
1830 Src0LoR = legalizeToReg(loOperand(Src0));
1831 Src1LoR = legalizeToReg(loOperand(Src1));
1832 Src0HiR = legalizeToReg(hiOperand(Src0));
1833 Src1HiR = legalizeToReg(hiOperand(Src1));
1834 auto *T_Borrow = I32Reg(), *T_Lo = I32Reg(), *T_Hi = I32Reg(), 1834 auto *T_Borrow = I32Reg(), *T_Lo = I32Reg(), *T_Hi = I32Reg(),
1835 *T_Hi2 = I32Reg(); 1835 *T_Hi2 = I32Reg();
1836 _subu(T_Lo, Src0LoR, Src1LoR); 1836 _subu(T_Lo, Src0LoR, Src1LoR);
1837 _mov(DestLo, T_Lo); 1837 _mov(DestLo, T_Lo);
1838 _sltu(T_Borrow, Src0LoR, Src1LoR); 1838 _sltu(T_Borrow, Src0LoR, Src1LoR);
1839 _addu(T_Hi, T_Borrow, Src1HiR); 1839 _addu(T_Hi, T_Borrow, Src1HiR);
1840 _subu(T_Hi2, Src0HiR, T_Hi); 1840 _subu(T_Hi2, Src0HiR, T_Hi);
1841 _mov(DestHi, T_Hi2); 1841 _mov(DestHi, T_Hi2);
1842 return; 1842 return;
1843 } 1843 }
1844 case InstArithmetic::Or: { 1844 case InstArithmetic::Or: {
1845 Src0LoR = legalizeToReg(loOperand(Src0));
1846 Src1LoR = legalizeToReg(loOperand(Src1));
1847 Src0HiR = legalizeToReg(hiOperand(Src0));
1848 Src1HiR = legalizeToReg(hiOperand(Src1));
1845 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); 1849 auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
1846 _or(T_Lo, Src0LoR, Src1LoR); 1850 _or(T_Lo, Src0LoR, Src1LoR);
1847 _mov(DestLo, T_Lo); 1851 _mov(DestLo, T_Lo);
1848 _or(T_Hi, Src0HiR, Src1HiR); 1852 _or(T_Hi, Src0HiR, Src1HiR);
1849 _mov(DestHi, T_Hi); 1853 _mov(DestHi, T_Hi);
1850 return; 1854 return;
1851 } 1855 }
1852 case InstArithmetic::Xor: { 1856 case InstArithmetic::Xor: {
1857 Src0LoR = legalizeToReg(loOperand(Src0));
1858 Src1LoR = legalizeToReg(loOperand(Src1));
1859 Src0HiR = legalizeToReg(hiOperand(Src0));
1860 Src1HiR = legalizeToReg(hiOperand(Src1));
1853 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); 1861 auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
1854 _xor(T_Lo, Src0LoR, Src1LoR); 1862 _xor(T_Lo, Src0LoR, Src1LoR);
1855 _mov(DestLo, T_Lo); 1863 _mov(DestLo, T_Lo);
1856 _xor(T_Hi, Src0HiR, Src1HiR); 1864 _xor(T_Hi, Src0HiR, Src1HiR);
1857 _mov(DestHi, T_Hi); 1865 _mov(DestHi, T_Hi);
1858 return; 1866 return;
1859 } 1867 }
1860 case InstArithmetic::Mul: { 1868 case InstArithmetic::Mul: {
1861 // TODO(rkotler): Make sure that mul has the side effect of clobbering 1869 // TODO(rkotler): Make sure that mul has the side effect of clobbering
1862 // LO, HI. Check for any other LO, HI quirkiness in this section. 1870 // LO, HI. Check for any other LO, HI quirkiness in this section.
1871 Src0LoR = legalizeToReg(loOperand(Src0));
1872 Src1LoR = legalizeToReg(loOperand(Src1));
1873 Src0HiR = legalizeToReg(hiOperand(Src0));
1874 Src1HiR = legalizeToReg(hiOperand(Src1));
1863 auto *T_Lo = I32Reg(RegMIPS32::Reg_LO), *T_Hi = I32Reg(RegMIPS32::Reg_HI); 1875 auto *T_Lo = I32Reg(RegMIPS32::Reg_LO), *T_Hi = I32Reg(RegMIPS32::Reg_HI);
1864 auto *T1 = I32Reg(), *T2 = I32Reg(); 1876 auto *T1 = I32Reg(), *T2 = I32Reg();
1865 auto *TM1 = I32Reg(), *TM2 = I32Reg(), *TM3 = I32Reg(), *TM4 = I32Reg(); 1877 auto *TM1 = I32Reg(), *TM2 = I32Reg(), *TM3 = I32Reg(), *TM4 = I32Reg();
1866 _multu(T_Lo, Src0LoR, Src1LoR); 1878 _multu(T_Lo, Src0LoR, Src1LoR);
1867 Context.insert<InstFakeDef>(T_Hi, T_Lo); 1879 Context.insert<InstFakeDef>(T_Hi, T_Lo);
1868 _mflo(T1, T_Lo); 1880 _mflo(T1, T_Lo);
1869 _mfhi(T2, T_Hi); 1881 _mfhi(T2, T_Hi);
1870 _mov(DestLo, T1); 1882 _mov(DestLo, T1);
1871 _mul(TM1, Src0HiR, Src1LoR); 1883 _mul(TM1, Src0HiR, Src1LoR);
1872 _mul(TM2, Src0LoR, Src1HiR); 1884 _mul(TM2, Src0LoR, Src1HiR);
1873 _addu(TM3, TM1, T2); 1885 _addu(TM3, TM1, T2);
1874 _addu(TM4, TM3, TM2); 1886 _addu(TM4, TM3, TM2);
1875 _mov(DestHi, TM4); 1887 _mov(DestHi, TM4);
1876 return; 1888 return;
1877 } 1889 }
1890 case InstArithmetic::Shl: {
1891 auto *T_Lo = I32Reg();
1892 auto *T_Hi = I32Reg();
1893 auto *T1_Lo = I32Reg();
1894 auto *T1_Hi = I32Reg();
1895 auto *T1 = I32Reg();
1896 auto *T2 = I32Reg();
1897 auto *T3 = I32Reg();
1898 auto *T4 = I32Reg();
1899 auto *T5 = I32Reg();
1900
1901 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
1902 Src0LoR = legalizeToReg(loOperand(Src0));
1903 int64_t ShiftAmount = Const->getValue();
1904 if (ShiftAmount == 1) {
1905 Src0HiR = legalizeToReg(hiOperand(Src0));
1906 _addu(T_Lo, Src0LoR, Src0LoR);
1907 _sltu(T1, T_Lo, Src0LoR);
1908 _addu(T2, T1, Src0HiR);
1909 _addu(T_Hi, Src0HiR, T2);
1910 } else if (ShiftAmount < INT32_BITS) {
1911 Src0HiR = legalizeToReg(hiOperand(Src0));
1912 _srl(T1, Src0LoR, INT32_BITS - ShiftAmount);
1913 _sll(T2, Src0HiR, ShiftAmount);
1914 _or(T_Hi, T1, T2);
1915 _sll(T_Lo, Src0LoR, ShiftAmount);
1916 } else if (ShiftAmount == INT32_BITS) {
1917 _addiu(T_Lo, getZero(), 0);
1918 _mov(T_Hi, Src0LoR);
1919 } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
1920 _sll(T_Hi, Src0LoR, ShiftAmount - INT32_BITS);
1921 _addiu(T_Lo, getZero(), 0);
1922 }
1923 _mov(DestLo, T_Lo);
1924 _mov(DestHi, T_Hi);
1925 return;
1926 }
1927
1928 Src0LoR = legalizeToReg(loOperand(Src0));
1929 Src1LoR = legalizeToReg(loOperand(Src1));
1930 Src0HiR = legalizeToReg(hiOperand(Src0));
1931
1932 _sllv(T1, Src0HiR, Src1LoR);
1933 _not(T2, Src1LoR);
1934 _srl(T3, Src0LoR, 1);
1935 _srlv(T4, T3, T2);
1936 _or(T_Hi, T1, T4);
1937 _sllv(T_Lo, Src0LoR, Src1LoR);
1938
1939 _mov(T1_Hi, T_Hi);
1940 _mov(T1_Lo, T_Lo);
1941 _andi(T5, Src1LoR, INT32_BITS);
1942 _movn(T1_Hi, T_Lo, T5);
1943 _movn(T1_Lo, getZero(), T5);
1944 _mov(DestHi, T1_Hi);
1945 _mov(DestLo, T1_Lo);
1946 return;
1947 }
1948 case InstArithmetic::Lshr: {
1949
1950 auto *T_Lo = I32Reg();
1951 auto *T_Hi = I32Reg();
1952 auto *T1_Lo = I32Reg();
1953 auto *T1_Hi = I32Reg();
1954 auto *T1 = I32Reg();
1955 auto *T2 = I32Reg();
1956 auto *T3 = I32Reg();
1957 auto *T4 = I32Reg();
1958 auto *T5 = I32Reg();
1959
1960 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
1961 Src0HiR = legalizeToReg(hiOperand(Src0));
1962 int64_t ShiftAmount = Const->getValue();
1963 if (ShiftAmount < INT32_BITS) {
1964 Src0LoR = legalizeToReg(loOperand(Src0));
1965 _sll(T1, Src0HiR, INT32_BITS - ShiftAmount);
1966 _srl(T2, Src0LoR, ShiftAmount);
1967 _or(T_Lo, T1, T2);
1968 _srl(T_Hi, Src0HiR, ShiftAmount);
1969 } else if (ShiftAmount == INT32_BITS) {
1970 _mov(T_Lo, Src0HiR);
1971 _addiu(T_Hi, getZero(), 0);
1972 } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
1973 _srl(T_Lo, Src0HiR, ShiftAmount - INT32_BITS);
1974 _addiu(T_Hi, getZero(), 0);
1975 }
1976 _mov(DestLo, T_Lo);
1977 _mov(DestHi, T_Hi);
1978 return;
1979 }
1980
1981 Src0LoR = legalizeToReg(loOperand(Src0));
1982 Src1LoR = legalizeToReg(loOperand(Src1));
1983 Src0HiR = legalizeToReg(hiOperand(Src0));
1984
1985 _srlv(T1, Src0LoR, Src1LoR);
1986 _not(T2, Src1LoR);
1987 _sll(T3, Src0HiR, 1);
1988 _sllv(T4, T3, T2);
1989 _or(T_Lo, T1, T4);
1990 _srlv(T_Hi, Src0HiR, Src1LoR);
1991
1992 _mov(T1_Hi, T_Hi);
1993 _mov(T1_Lo, T_Lo);
1994 _andi(T5, Src1LoR, INT32_BITS);
1995 _movn(T1_Lo, T_Hi, T5);
1996 _movn(T1_Hi, getZero(), T5);
1997 _mov(DestHi, T1_Hi);
1998 _mov(DestLo, T1_Lo);
1999 return;
2000 }
2001 case InstArithmetic::Ashr: {
2002
2003 auto *T_Lo = I32Reg();
2004 auto *T_Hi = I32Reg();
2005 auto *T1_Lo = I32Reg();
2006 auto *T1_Hi = I32Reg();
2007 auto *T1 = I32Reg();
2008 auto *T2 = I32Reg();
2009 auto *T3 = I32Reg();
2010 auto *T4 = I32Reg();
2011 auto *T5 = I32Reg();
2012 auto *T6 = I32Reg();
2013
2014 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
2015 Src0HiR = legalizeToReg(hiOperand(Src0));
2016 int64_t ShiftAmount = Const->getValue();
2017 if (ShiftAmount < INT32_BITS) {
2018 Src0LoR = legalizeToReg(loOperand(Src0));
2019 _sll(T1, Src0HiR, INT32_BITS - ShiftAmount);
2020 _srl(T2, Src0LoR, ShiftAmount);
2021 _or(T_Lo, T1, T2);
2022 _sra(T_Hi, Src0HiR, ShiftAmount);
2023 } else if (ShiftAmount == INT32_BITS) {
2024 _sra(T_Hi, Src0HiR, INT32_BITS - 1);
2025 _mov(T_Lo, Src0HiR);
2026 } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
2027 _sra(T_Lo, Src0HiR, ShiftAmount - INT32_BITS);
2028 _sra(T_Hi, Src0HiR, INT32_BITS - 1);
2029 }
2030 _mov(DestLo, T_Lo);
2031 _mov(DestHi, T_Hi);
2032 return;
2033 }
2034
2035 Src0LoR = legalizeToReg(loOperand(Src0));
2036 Src1LoR = legalizeToReg(loOperand(Src1));
2037 Src0HiR = legalizeToReg(hiOperand(Src0));
2038
2039 _srlv(T1, Src0LoR, Src1LoR);
2040 _not(T2, Src1LoR);
2041 _sll(T3, Src0HiR, 1);
2042 _sllv(T4, T3, T2);
2043 _or(T_Lo, T1, T4);
2044 _srav(T_Hi, Src0HiR, Src1LoR);
2045
2046 _mov(T1_Hi, T_Hi);
2047 _mov(T1_Lo, T_Lo);
2048 _andi(T5, Src1LoR, INT32_BITS);
2049 _movn(T1_Lo, T_Hi, T5);
2050 _sra(T6, Src0HiR, INT32_BITS - 1);
2051 _movn(T1_Hi, T6, T5);
2052 _mov(DestHi, T1_Hi);
2053 _mov(DestLo, T1_Lo);
2054 return;
2055 }
1878 default: 2056 default:
1879 UnimplementedLoweringError(this, Instr); 2057 UnimplementedLoweringError(this, Instr);
1880 return; 2058 return;
1881 } 2059 }
1882 } 2060 }
1883 2061
1884 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { 2062 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
1885 Variable *Dest = Instr->getDest(); 2063 Variable *Dest = Instr->getDest();
1886 // We need to signal all the UnimplementedLoweringError errors before any 2064 // We need to signal all the UnimplementedLoweringError errors before any
1887 // legalization into new variables, otherwise Om1 register allocation may fail 2065 // legalization into new variables, otherwise Om1 register allocation may fail
(...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after
3366 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve 3544 // Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve
3367 // integrity of liveness analysis. Undef values are also turned into zeroes, 3545 // integrity of liveness analysis. Undef values are also turned into zeroes,
3368 // since loOperand() and hiOperand() don't expect Undef input. 3546 // since loOperand() and hiOperand() don't expect Undef input.
3369 void TargetMIPS32::prelowerPhis() { 3547 void TargetMIPS32::prelowerPhis() {
3370 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func); 3548 PhiLowering::prelowerPhis32Bit<TargetMIPS32>(this, Context.getNode(), Func);
3371 } 3549 }
3372 3550
3373 void TargetMIPS32::postLower() { 3551 void TargetMIPS32::postLower() {
3374 if (Func->getOptLevel() == Opt_m1) 3552 if (Func->getOptLevel() == Opt_m1)
3375 return; 3553 return;
3376 // TODO(rkotler): Find two-address non-SSA instructions where Dest==Src0, 3554 markRedefinitions();
3377 // and set the IsDestRedefined flag to keep liveness analysis consistent. 3555 Context.availabilityUpdate();
3378 UnimplementedError(getFlags());
3379 } 3556 }
3380 3557
3381 void TargetMIPS32::makeRandomRegisterPermutation( 3558 void TargetMIPS32::makeRandomRegisterPermutation(
3382 llvm::SmallVectorImpl<RegNumT> &Permutation, 3559 llvm::SmallVectorImpl<RegNumT> &Permutation,
3383 const SmallBitVector &ExcludeRegisters, uint64_t Salt) const { 3560 const SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
3384 (void)Permutation; 3561 (void)Permutation;
3385 (void)ExcludeRegisters; 3562 (void)ExcludeRegisters;
3386 (void)Salt; 3563 (void)Salt;
3387 UnimplementedError(getFlags()); 3564 UnimplementedError(getFlags());
3388 } 3565 }
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
3667 Str << "\t.set\t" 3844 Str << "\t.set\t"
3668 << "nomips16\n"; 3845 << "nomips16\n";
3669 } 3846 }
3670 3847
3671 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 3848 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
3672 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 3849 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
3673 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 3850 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
3674 3851
3675 } // end of namespace MIPS32 3852 } // end of namespace MIPS32
3676 } // end of namespace Ice 3853 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698