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 1595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1950 return; | 1885 return; |
1951 } | 1886 } |
1952 case InstArithmetic::Ashr: { | 1887 case InstArithmetic::Ashr: { |
1953 _srav(T, Src0R, Src1R); | 1888 _srav(T, Src0R, Src1R); |
1954 _mov(Dest, T); | 1889 _mov(Dest, T); |
1955 return; | 1890 return; |
1956 } | 1891 } |
1957 case InstArithmetic::Udiv: { | 1892 case InstArithmetic::Udiv: { |
1958 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 1893 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
1959 _divu(T_Zero, Src0R, Src1R); | 1894 _divu(T_Zero, Src0R, Src1R); |
| 1895 _teq(Src1R, T_Zero, 7); // Trap if divide-by-zero |
1960 _mflo(T, T_Zero); | 1896 _mflo(T, T_Zero); |
1961 _mov(Dest, T); | 1897 _mov(Dest, T); |
1962 return; | 1898 return; |
1963 } | 1899 } |
1964 case InstArithmetic::Sdiv: { | 1900 case InstArithmetic::Sdiv: { |
1965 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 1901 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
1966 _div(T_Zero, Src0R, Src1R); | 1902 _div(T_Zero, Src0R, Src1R); |
| 1903 _teq(Src1R, T_Zero, 7); // Trap if divide-by-zero |
1967 _mflo(T, T_Zero); | 1904 _mflo(T, T_Zero); |
1968 _mov(Dest, T); | 1905 _mov(Dest, T); |
1969 return; | 1906 return; |
1970 } | 1907 } |
1971 case InstArithmetic::Urem: { | 1908 case InstArithmetic::Urem: { |
1972 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 1909 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
1973 _divu(T_Zero, Src0R, Src1R); | 1910 _divu(T_Zero, Src0R, Src1R); |
| 1911 _teq(Src1R, T_Zero, 7); // Trap if divide-by-zero |
1974 _mfhi(T, T_Zero); | 1912 _mfhi(T, T_Zero); |
1975 _mov(Dest, T); | 1913 _mov(Dest, T); |
1976 return; | 1914 return; |
1977 } | 1915 } |
1978 case InstArithmetic::Srem: { | 1916 case InstArithmetic::Srem: { |
1979 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 1917 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
1980 _div(T_Zero, Src0R, Src1R); | 1918 _div(T_Zero, Src0R, Src1R); |
| 1919 _teq(Src1R, T_Zero, 7); // Trap if divide-by-zero |
1981 _mfhi(T, T_Zero); | 1920 _mfhi(T, T_Zero); |
1982 _mov(Dest, T); | 1921 _mov(Dest, T); |
1983 return; | 1922 return; |
1984 } | 1923 } |
1985 case InstArithmetic::Fadd: { | 1924 case InstArithmetic::Fadd: { |
1986 if (DestTy == IceType_f32) { | 1925 if (DestTy == IceType_f32) { |
1987 _add_s(T, Src0R, Src1R); | 1926 _add_s(T, Src0R, Src1R); |
1988 _mov(Dest, T); | 1927 _mov(Dest, T); |
1989 return; | 1928 return; |
1990 } | 1929 } |
(...skipping 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3667 Str << "\t.set\t" | 3606 Str << "\t.set\t" |
3668 << "nomips16\n"; | 3607 << "nomips16\n"; |
3669 } | 3608 } |
3670 | 3609 |
3671 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 3610 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
3672 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 3611 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
3673 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 3612 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
3674 | 3613 |
3675 } // end of namespace MIPS32 | 3614 } // end of namespace MIPS32 |
3676 } // end of namespace Ice | 3615 } // end of namespace Ice |
OLD | NEW |