OLD | NEW |
1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// | 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 return true; | 347 return true; |
348 } | 348 } |
349 } | 349 } |
350 return false; | 350 return false; |
351 } | 351 } |
352 | 352 |
353 OperandARM32FlexFpImm::OperandARM32FlexFpImm(Cfg * /*Func*/, Type Ty, | 353 OperandARM32FlexFpImm::OperandARM32FlexFpImm(Cfg * /*Func*/, Type Ty, |
354 uint32_t ModifiedImm) | 354 uint32_t ModifiedImm) |
355 : OperandARM32Flex(kFlexFpImm, Ty), ModifiedImm(ModifiedImm) {} | 355 : OperandARM32Flex(kFlexFpImm, Ty), ModifiedImm(ModifiedImm) {} |
356 | 356 |
357 bool OperandARM32FlexFpImm::canHoldImm(Operand *C, uint32_t *ModifiedImm) { | 357 bool OperandARM32FlexFpImm::canHoldImm(const Operand *C, |
| 358 uint32_t *ModifiedImm) { |
358 switch (C->getType()) { | 359 switch (C->getType()) { |
359 default: | 360 default: |
360 llvm::report_fatal_error("Unhandled fp constant type."); | 361 llvm::report_fatal_error("Unhandled fp constant type."); |
361 case IceType_f32: { | 362 case IceType_f32: { |
362 // We violate llvm naming conventions a bit here so that the constants are | 363 // We violate llvm naming conventions a bit here so that the constants are |
363 // named after the bit fields they represent. See "A7.5.1 Operation of | 364 // named after the bit fields they represent. See "A7.5.1 Operation of |
364 // modified immediate constants, Floating-point" in the ARM ARM. | 365 // modified immediate constants, Floating-point" in the ARM ARM. |
365 static constexpr uint32_t a = 0x80000000u; | 366 static constexpr uint32_t a = 0x80000000u; |
366 static constexpr uint32_t B = 0x40000000; | 367 static constexpr uint32_t B = 0x40000000; |
367 static constexpr uint32_t bbbbb = 0x3E000000; | 368 static constexpr uint32_t bbbbb = 0x3E000000; |
368 static constexpr uint32_t cdefgh = 0x01F80000; | 369 static constexpr uint32_t cdefgh = 0x01F80000; |
369 static constexpr uint32_t AllowedBits = a | B | bbbbb | cdefgh; | 370 static constexpr uint32_t AllowedBits = a | B | bbbbb | cdefgh; |
370 static_assert(AllowedBits == 0xFFF80000u, | 371 static_assert(AllowedBits == 0xFFF80000u, |
371 "Invalid mask for f32 modified immediates."); | 372 "Invalid mask for f32 modified immediates."); |
372 const float F32 = llvm::cast<ConstantFloat>(C)->getValue(); | 373 const float F32 = llvm::cast<const ConstantFloat>(C)->getValue(); |
373 const uint32_t I32 = Utils::bitCopy<uint32_t>(F32); | 374 const uint32_t I32 = Utils::bitCopy<uint32_t>(F32); |
374 if (I32 & ~AllowedBits) { | 375 if (I32 & ~AllowedBits) { |
375 // constant has disallowed bits. | 376 // constant has disallowed bits. |
376 return false; | 377 return false; |
377 } | 378 } |
378 | 379 |
379 if ((I32 & bbbbb) != bbbbb && (I32 & bbbbb)) { | 380 if ((I32 & bbbbb) != bbbbb && (I32 & bbbbb)) { |
380 // not all bbbbb bits are 0 or 1. | 381 // not all bbbbb bits are 0 or 1. |
381 return false; | 382 return false; |
382 } | 383 } |
383 | 384 |
384 if (((I32 & B) != 0) == ((I32 & bbbbb) != 0)) { | 385 if (((I32 & B) != 0) == ((I32 & bbbbb) != 0)) { |
385 // B ^ b = 0; | 386 // B ^ b = 0; |
386 return false; | 387 return false; |
387 } | 388 } |
388 | 389 |
389 *ModifiedImm = ((I32 & a) ? 0x80 : 0x00) | ((I32 & bbbbb) ? 0x40 : 0x00) | | 390 *ModifiedImm = ((I32 & a) ? 0x80 : 0x00) | ((I32 & bbbbb) ? 0x40 : 0x00) | |
390 ((I32 & cdefgh) >> 19); | 391 ((I32 & cdefgh) >> 19); |
391 return true; | 392 return true; |
392 } | 393 } |
393 case IceType_f64: { | 394 case IceType_f64: { |
394 static constexpr uint32_t a = 0x80000000u; | 395 static constexpr uint32_t a = 0x80000000u; |
395 static constexpr uint32_t B = 0x40000000; | 396 static constexpr uint32_t B = 0x40000000; |
396 static constexpr uint32_t bbbbbbbb = 0x3FC00000; | 397 static constexpr uint32_t bbbbbbbb = 0x3FC00000; |
397 static constexpr uint32_t cdefgh = 0x003F0000; | 398 static constexpr uint32_t cdefgh = 0x003F0000; |
398 static constexpr uint32_t AllowedBits = a | B | bbbbbbbb | cdefgh; | 399 static constexpr uint32_t AllowedBits = a | B | bbbbbbbb | cdefgh; |
399 static_assert(AllowedBits == 0xFFFF0000u, | 400 static_assert(AllowedBits == 0xFFFF0000u, |
400 "Invalid mask for f64 modified immediates."); | 401 "Invalid mask for f64 modified immediates."); |
401 const double F64 = llvm::cast<ConstantDouble>(C)->getValue(); | 402 const double F64 = llvm::cast<const ConstantDouble>(C)->getValue(); |
402 const uint64_t I64 = Utils::bitCopy<uint64_t>(F64); | 403 const uint64_t I64 = Utils::bitCopy<uint64_t>(F64); |
403 if (I64 & 0xFFFFFFFFu) { | 404 if (I64 & 0xFFFFFFFFu) { |
404 // constant has disallowed bits. | 405 // constant has disallowed bits. |
405 return false; | 406 return false; |
406 } | 407 } |
407 const uint32_t I32 = I64 >> 32; | 408 const uint32_t I32 = I64 >> 32; |
408 | 409 |
409 if (I32 & ~AllowedBits) { | 410 if (I32 & ~AllowedBits) { |
410 // constant has disallowed bits. | 411 // constant has disallowed bits. |
411 return false; | 412 return false; |
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1718 // emitted text size. | 1719 // emitted text size. |
1719 if (auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>()) | 1720 if (auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>()) |
1720 Asm->decEmitTextSize(InstSize); | 1721 Asm->decEmitTextSize(InstSize); |
1721 Ostream &Str = Func->getContext()->getStrEmit(); | 1722 Ostream &Str = Func->getContext()->getStrEmit(); |
1722 Str << getName(Func) << ":"; | 1723 Str << getName(Func) << ":"; |
1723 } | 1724 } |
1724 | 1725 |
1725 void InstARM32Label::emitIAS(const Cfg *Func) const { | 1726 void InstARM32Label::emitIAS(const Cfg *Func) const { |
1726 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1727 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
1727 Asm->bindLocalLabel(Func, this, Number); | 1728 Asm->bindLocalLabel(Func, this, Number); |
| 1729 if (OffsetReloc != nullptr) { |
| 1730 Asm->bindRelocOffset(OffsetReloc); |
| 1731 } |
1728 if (Asm->needsTextFixup()) | 1732 if (Asm->needsTextFixup()) |
1729 emitUsingTextFixup(Func); | 1733 emitUsingTextFixup(Func); |
1730 } | 1734 } |
1731 | 1735 |
1732 void InstARM32Label::dump(const Cfg *Func) const { | 1736 void InstARM32Label::dump(const Cfg *Func) const { |
1733 if (!BuildDefs::dump()) | 1737 if (!BuildDefs::dump()) |
1734 return; | 1738 return; |
1735 Ostream &Str = Func->getContext()->getStrDump(); | 1739 Ostream &Str = Func->getContext()->getStrDump(); |
1736 Str << getName(Func) << ":"; | 1740 Str << getName(Func) << ":"; |
1737 } | 1741 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 return; | 1864 return; |
1861 Ostream &Str = Func->getContext()->getStrEmit(); | 1865 Ostream &Str = Func->getContext()->getStrEmit(); |
1862 assert(getSrcSize() == 1); | 1866 assert(getSrcSize() == 1); |
1863 Str << "\t" << Opcode << getPredicate() << "\t"; | 1867 Str << "\t" << Opcode << getPredicate() << "\t"; |
1864 getDest()->emit(Func); | 1868 getDest()->emit(Func); |
1865 Str << ", "; | 1869 Str << ", "; |
1866 auto *Src0 = llvm::cast<Constant>(getSrc(0)); | 1870 auto *Src0 = llvm::cast<Constant>(getSrc(0)); |
1867 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { | 1871 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { |
1868 Str << "#:lower16:"; | 1872 Str << "#:lower16:"; |
1869 CR->emitWithoutPrefix(Func->getTarget()); | 1873 CR->emitWithoutPrefix(Func->getTarget()); |
| 1874 if (Func->getContext()->getFlags().getUseNonsfi()) { |
| 1875 Str << " - ."; |
| 1876 } |
1870 } else { | 1877 } else { |
1871 Src0->emit(Func); | 1878 Src0->emit(Func); |
1872 } | 1879 } |
1873 } | 1880 } |
1874 | 1881 |
1875 template <> void InstARM32Movw::emitIAS(const Cfg *Func) const { | 1882 template <> void InstARM32Movw::emitIAS(const Cfg *Func) const { |
1876 assert(getSrcSize() == 1); | 1883 assert(getSrcSize() == 1); |
1877 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1884 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
1878 Asm->movw(getDest(), getSrc(0), getPredicate()); | 1885 Asm->movw(getDest(), getSrc(0), getPredicate()); |
1879 if (Asm->needsTextFixup()) | 1886 if (Asm->needsTextFixup()) |
1880 emitUsingTextFixup(Func); | 1887 emitUsingTextFixup(Func); |
1881 } | 1888 } |
1882 | 1889 |
1883 template <> void InstARM32Movt::emit(const Cfg *Func) const { | 1890 template <> void InstARM32Movt::emit(const Cfg *Func) const { |
1884 if (!BuildDefs::dump()) | 1891 if (!BuildDefs::dump()) |
1885 return; | 1892 return; |
1886 Ostream &Str = Func->getContext()->getStrEmit(); | 1893 Ostream &Str = Func->getContext()->getStrEmit(); |
1887 assert(getSrcSize() == 2); | 1894 assert(getSrcSize() == 2); |
1888 Variable *Dest = getDest(); | 1895 Variable *Dest = getDest(); |
1889 auto *Src1 = llvm::cast<Constant>(getSrc(1)); | 1896 auto *Src1 = llvm::cast<Constant>(getSrc(1)); |
1890 Str << "\t" << Opcode << getPredicate() << "\t"; | 1897 Str << "\t" << Opcode << getPredicate() << "\t"; |
1891 Dest->emit(Func); | 1898 Dest->emit(Func); |
1892 Str << ", "; | 1899 Str << ", "; |
1893 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { | 1900 if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { |
1894 Str << "#:upper16:"; | 1901 Str << "#:upper16:"; |
1895 CR->emitWithoutPrefix(Func->getTarget()); | 1902 CR->emitWithoutPrefix(Func->getTarget()); |
| 1903 if (Func->getContext()->getFlags().getUseNonsfi()) { |
| 1904 Str << " - ."; |
| 1905 } |
1896 } else { | 1906 } else { |
1897 Src1->emit(Func); | 1907 Src1->emit(Func); |
1898 } | 1908 } |
1899 } | 1909 } |
1900 | 1910 |
1901 template <> void InstARM32Movt::emitIAS(const Cfg *Func) const { | 1911 template <> void InstARM32Movt::emitIAS(const Cfg *Func) const { |
1902 assert(getSrcSize() == 2); | 1912 assert(getSrcSize() == 2); |
1903 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); | 1913 auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); |
1904 Asm->movt(getDest(), getSrc(1), getPredicate()); | 1914 Asm->movt(getDest(), getSrc(1), getPredicate()); |
1905 if (Asm->needsTextFixup()) | 1915 if (Asm->needsTextFixup()) |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2759 | 2769 |
2760 template class InstARM32FourAddrGPR<InstARM32::Mla>; | 2770 template class InstARM32FourAddrGPR<InstARM32::Mla>; |
2761 template class InstARM32FourAddrGPR<InstARM32::Mls>; | 2771 template class InstARM32FourAddrGPR<InstARM32::Mls>; |
2762 | 2772 |
2763 template class InstARM32CmpLike<InstARM32::Cmn>; | 2773 template class InstARM32CmpLike<InstARM32::Cmn>; |
2764 template class InstARM32CmpLike<InstARM32::Cmp>; | 2774 template class InstARM32CmpLike<InstARM32::Cmp>; |
2765 template class InstARM32CmpLike<InstARM32::Tst>; | 2775 template class InstARM32CmpLike<InstARM32::Tst>; |
2766 | 2776 |
2767 } // end of namespace ARM32 | 2777 } // end of namespace ARM32 |
2768 } // end of namespace Ice | 2778 } // end of namespace Ice |
OLD | NEW |