| OLD | NEW |
| 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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 | 270 |
| 271 Operand *TargetHelper = Ctx->getRuntimeHelperFunc(HelperID); | 271 Operand *TargetHelper = Ctx->getRuntimeHelperFunc(HelperID); |
| 272 constexpr SizeT MaxArgs = 2; | 272 constexpr SizeT MaxArgs = 2; |
| 273 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 273 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
| 274 NoTailCall, IsTargetHelperCall); | 274 NoTailCall, IsTargetHelperCall); |
| 275 Call->addArg(Instr->getSrc(0)); | 275 Call->addArg(Instr->getSrc(0)); |
| 276 Call->addArg(Instr->getSrc(1)); | 276 Call->addArg(Instr->getSrc(1)); |
| 277 Instr->setDeleted(); | 277 Instr->setDeleted(); |
| 278 return; | 278 return; |
| 279 } | 279 } |
| 280 case IceType_i32: | |
| 281 case IceType_i16: | |
| 282 case IceType_i8: { | |
| 283 InstCast::OpKind CastKind; | |
| 284 RuntimeHelper HelperID = RuntimeHelper::H_Num; | |
| 285 switch (Op) { | |
| 286 default: | |
| 287 return; | |
| 288 case InstArithmetic::Udiv: | |
| 289 HelperID = RuntimeHelper::H_udiv_i32; | |
| 290 CastKind = InstCast::Zext; | |
| 291 break; | |
| 292 case InstArithmetic::Sdiv: | |
| 293 HelperID = RuntimeHelper::H_sdiv_i32; | |
| 294 CastKind = InstCast::Sext; | |
| 295 break; | |
| 296 case InstArithmetic::Urem: | |
| 297 HelperID = RuntimeHelper::H_urem_i32; | |
| 298 CastKind = InstCast::Zext; | |
| 299 break; | |
| 300 case InstArithmetic::Srem: | |
| 301 HelperID = RuntimeHelper::H_srem_i32; | |
| 302 CastKind = InstCast::Sext; | |
| 303 break; | |
| 304 } | |
| 305 | |
| 306 if (HelperID == RuntimeHelper::H_Num) { | |
| 307 return; | |
| 308 } | |
| 309 | |
| 310 Operand *Src0 = Instr->getSrc(0); | |
| 311 Operand *Src1 = Instr->getSrc(1); | |
| 312 if (DestTy != IceType_i32) { | |
| 313 // Src0 and Src1 have to be zero-, or signed-extended to i32. For Src0, | |
| 314 // we just insert a InstCast right before the call to the helper. | |
| 315 Variable *Src0_32 = Func->makeVariable(IceType_i32); | |
| 316 Context.insert<InstCast>(CastKind, Src0_32, Src0); | |
| 317 Src0 = Src0_32; | |
| 318 | |
| 319 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Src1)) { | |
| 320 const int32_t ShAmt = (DestTy == IceType_i16) ? 16 : 24; | |
| 321 int32_t NewC = C->getValue(); | |
| 322 if (CastKind == InstCast::Zext) { | |
| 323 NewC &= ~(0x80000000l >> ShAmt); | |
| 324 } else { | |
| 325 NewC = (NewC << ShAmt) >> ShAmt; | |
| 326 } | |
| 327 Src1 = Ctx->getConstantInt32(NewC); | |
| 328 } else { | |
| 329 Variable *Src1_32 = Func->makeVariable(IceType_i32); | |
| 330 Context.insert<InstCast>(CastKind, Src1_32, Src1); | |
| 331 Src1 = Src1_32; | |
| 332 } | |
| 333 } | |
| 334 Operand *TargetHelper = Ctx->getRuntimeHelperFunc(HelperID); | |
| 335 constexpr SizeT MaxArgs = 2; | |
| 336 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | |
| 337 NoTailCall, IsTargetHelperCall); | |
| 338 assert(Src0->getType() == IceType_i32); | |
| 339 Call->addArg(Src0); | |
| 340 assert(Src1->getType() == IceType_i32); | |
| 341 Call->addArg(Src1); | |
| 342 Instr->setDeleted(); | |
| 343 return; | |
| 344 } | |
| 345 case IceType_f32: | 280 case IceType_f32: |
| 346 case IceType_f64: { | 281 case IceType_f64: { |
| 347 if (Op != InstArithmetic::Frem) { | 282 if (Op != InstArithmetic::Frem) { |
| 348 return; | 283 return; |
| 349 } | 284 } |
| 350 constexpr SizeT MaxArgs = 2; | 285 constexpr SizeT MaxArgs = 2; |
| 351 Operand *TargetHelper = Ctx->getRuntimeHelperFunc( | 286 Operand *TargetHelper = Ctx->getRuntimeHelperFunc( |
| 352 DestTy == IceType_f32 ? RuntimeHelper::H_frem_f32 | 287 DestTy == IceType_f32 ? RuntimeHelper::H_frem_f32 |
| 353 : RuntimeHelper::H_frem_f64); | 288 : RuntimeHelper::H_frem_f64); |
| 354 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, | 289 auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, |
| (...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1903 case InstArithmetic::Frem: | 1838 case InstArithmetic::Frem: |
| 1904 UnimplementedLoweringError(this, Instr); | 1839 UnimplementedLoweringError(this, Instr); |
| 1905 return; | 1840 return; |
| 1906 } | 1841 } |
| 1907 | 1842 |
| 1908 // At this point Dest->getType() is non-i64 scalar | 1843 // At this point Dest->getType() is non-i64 scalar |
| 1909 | 1844 |
| 1910 Variable *T = makeReg(Dest->getType()); | 1845 Variable *T = makeReg(Dest->getType()); |
| 1911 Variable *Src0R = legalizeToReg(Src0); | 1846 Variable *Src0R = legalizeToReg(Src0); |
| 1912 Variable *Src1R = legalizeToReg(Src1); | 1847 Variable *Src1R = legalizeToReg(Src1); |
| 1848 constexpr uint32_t DivideByZeroTrapCode = 7; |
| 1913 | 1849 |
| 1914 switch (Instr->getOp()) { | 1850 switch (Instr->getOp()) { |
| 1915 case InstArithmetic::_num: | 1851 case InstArithmetic::_num: |
| 1916 break; | 1852 break; |
| 1917 case InstArithmetic::Add: | 1853 case InstArithmetic::Add: |
| 1918 _addu(T, Src0R, Src1R); | 1854 _addu(T, Src0R, Src1R); |
| 1919 _mov(Dest, T); | 1855 _mov(Dest, T); |
| 1920 return; | 1856 return; |
| 1921 case InstArithmetic::And: | 1857 case InstArithmetic::And: |
| 1922 _and(T, Src0R, Src1R); | 1858 _and(T, Src0R, Src1R); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1950 return; | 1886 return; |
| 1951 } | 1887 } |
| 1952 case InstArithmetic::Ashr: { | 1888 case InstArithmetic::Ashr: { |
| 1953 _srav(T, Src0R, Src1R); | 1889 _srav(T, Src0R, Src1R); |
| 1954 _mov(Dest, T); | 1890 _mov(Dest, T); |
| 1955 return; | 1891 return; |
| 1956 } | 1892 } |
| 1957 case InstArithmetic::Udiv: { | 1893 case InstArithmetic::Udiv: { |
| 1958 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 1894 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
| 1959 _divu(T_Zero, Src0R, Src1R); | 1895 _divu(T_Zero, Src0R, Src1R); |
| 1896 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
| 1960 _mflo(T, T_Zero); | 1897 _mflo(T, T_Zero); |
| 1961 _mov(Dest, T); | 1898 _mov(Dest, T); |
| 1962 return; | 1899 return; |
| 1963 } | 1900 } |
| 1964 case InstArithmetic::Sdiv: { | 1901 case InstArithmetic::Sdiv: { |
| 1965 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 1902 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
| 1966 _div(T_Zero, Src0R, Src1R); | 1903 _div(T_Zero, Src0R, Src1R); |
| 1904 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
| 1967 _mflo(T, T_Zero); | 1905 _mflo(T, T_Zero); |
| 1968 _mov(Dest, T); | 1906 _mov(Dest, T); |
| 1969 return; | 1907 return; |
| 1970 } | 1908 } |
| 1971 case InstArithmetic::Urem: { | 1909 case InstArithmetic::Urem: { |
| 1972 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 1910 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
| 1973 _divu(T_Zero, Src0R, Src1R); | 1911 _divu(T_Zero, Src0R, Src1R); |
| 1912 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
| 1974 _mfhi(T, T_Zero); | 1913 _mfhi(T, T_Zero); |
| 1975 _mov(Dest, T); | 1914 _mov(Dest, T); |
| 1976 return; | 1915 return; |
| 1977 } | 1916 } |
| 1978 case InstArithmetic::Srem: { | 1917 case InstArithmetic::Srem: { |
| 1979 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 1918 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
| 1980 _div(T_Zero, Src0R, Src1R); | 1919 _div(T_Zero, Src0R, Src1R); |
| 1920 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
| 1981 _mfhi(T, T_Zero); | 1921 _mfhi(T, T_Zero); |
| 1982 _mov(Dest, T); | 1922 _mov(Dest, T); |
| 1983 return; | 1923 return; |
| 1984 } | 1924 } |
| 1985 case InstArithmetic::Fadd: { | 1925 case InstArithmetic::Fadd: { |
| 1986 if (DestTy == IceType_f32) { | 1926 if (DestTy == IceType_f32) { |
| 1987 _add_s(T, Src0R, Src1R); | 1927 _add_s(T, Src0R, Src1R); |
| 1988 _mov(Dest, T); | 1928 _mov(Dest, T); |
| 1989 return; | 1929 return; |
| 1990 } | 1930 } |
| (...skipping 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3667 Str << "\t.set\t" | 3607 Str << "\t.set\t" |
| 3668 << "nomips16\n"; | 3608 << "nomips16\n"; |
| 3669 } | 3609 } |
| 3670 | 3610 |
| 3671 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 3611 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 3672 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 3612 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 3673 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 3613 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 3674 | 3614 |
| 3675 } // end of namespace MIPS32 | 3615 } // end of namespace MIPS32 |
| 3676 } // end of namespace Ice | 3616 } // end of namespace Ice |
| OLD | NEW |