| 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 |