| OLD | NEW |
| 1 //===- subzero/src/IceTargetLowering.cpp - Basic lowering implementation --===// | 1 //===- subzero/src/IceTargetLowering.cpp - Basic lowering 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 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 if (!BuildDefs::dump()) | 722 if (!BuildDefs::dump()) |
| 723 return; | 723 return; |
| 724 Ostream &Str = Ctx->getStrEmit(); | 724 Ostream &Str = Ctx->getStrEmit(); |
| 725 const IceString &EmitStr = C->getEmitString(); | 725 const IceString &EmitStr = C->getEmitString(); |
| 726 if (!EmitStr.empty()) { | 726 if (!EmitStr.empty()) { |
| 727 // C has a custom emit string, so we use it instead of the canonical | 727 // C has a custom emit string, so we use it instead of the canonical |
| 728 // Name + Offset form. | 728 // Name + Offset form. |
| 729 Str << EmitStr; | 729 Str << EmitStr; |
| 730 return; | 730 return; |
| 731 } | 731 } |
| 732 if (C->getSuppressMangling()) | 732 Str << C->getName() << Suffix; |
| 733 Str << C->getName(); | |
| 734 else | |
| 735 Str << Ctx->mangleName(C->getName()); | |
| 736 Str << Suffix; | |
| 737 RelocOffsetT Offset = C->getOffset(); | 733 RelocOffsetT Offset = C->getOffset(); |
| 738 if (Offset) { | 734 if (Offset) { |
| 739 if (Offset > 0) | 735 if (Offset > 0) |
| 740 Str << "+"; | 736 Str << "+"; |
| 741 Str << Offset; | 737 Str << Offset; |
| 742 } | 738 } |
| 743 } | 739 } |
| 744 | 740 |
| 745 std::unique_ptr<TargetDataLowering> | 741 std::unique_ptr<TargetDataLowering> |
| 746 TargetDataLowering::createLowering(GlobalContext *Ctx) { | 742 TargetDataLowering::createLowering(GlobalContext *Ctx) { |
| 747 TargetArch Target = Ctx->getFlags().getTargetArch(); | 743 TargetArch Target = Ctx->getFlags().getTargetArch(); |
| 748 switch (Target) { | 744 switch (Target) { |
| 749 default: | 745 default: |
| 750 badTargetFatalError(Target); | 746 badTargetFatalError(Target); |
| 751 #define SUBZERO_TARGET(X) \ | 747 #define SUBZERO_TARGET(X) \ |
| 752 case Target_##X: \ | 748 case Target_##X: \ |
| 753 return ::X::createTargetDataLowering(Ctx); | 749 return ::X::createTargetDataLowering(Ctx); |
| 754 #include "llvm/Config/SZTargets.def" | 750 #include "llvm/Config/SZTargets.def" |
| 755 #undef SUBZERO_TARGET | 751 #undef SUBZERO_TARGET |
| 756 } | 752 } |
| 757 } | 753 } |
| 758 | 754 |
| 759 TargetDataLowering::~TargetDataLowering() = default; | 755 TargetDataLowering::~TargetDataLowering() = default; |
| 760 | 756 |
| 761 namespace { | 757 namespace { |
| 762 | 758 |
| 763 // dataSectionSuffix decides whether to use SectionSuffix or MangledVarName as | 759 // dataSectionSuffix decides whether to use SectionSuffix or VarName as data |
| 764 // data section suffix. Essentially, when using separate data sections for | 760 // section suffix. Essentially, when using separate data sections for globals |
| 765 // globals SectionSuffix is not necessary. | 761 // SectionSuffix is not necessary. |
| 766 IceString dataSectionSuffix(const IceString &SectionSuffix, | 762 IceString dataSectionSuffix(const IceString &SectionSuffix, |
| 767 const IceString &MangledVarName, | 763 const IceString &VarName, const bool DataSections) { |
| 768 const bool DataSections) { | |
| 769 if (SectionSuffix.empty() && !DataSections) { | 764 if (SectionSuffix.empty() && !DataSections) { |
| 770 return ""; | 765 return ""; |
| 771 } | 766 } |
| 772 | 767 |
| 773 if (DataSections) { | 768 if (DataSections) { |
| 774 // With data sections we don't need to use the SectionSuffix. | 769 // With data sections we don't need to use the SectionSuffix. |
| 775 return "." + MangledVarName; | 770 return "." + VarName; |
| 776 } | 771 } |
| 777 | 772 |
| 778 assert(!SectionSuffix.empty()); | 773 assert(!SectionSuffix.empty()); |
| 779 return "." + SectionSuffix; | 774 return "." + SectionSuffix; |
| 780 } | 775 } |
| 781 | 776 |
| 782 } // end of anonymous namespace | 777 } // end of anonymous namespace |
| 783 | 778 |
| 784 void TargetDataLowering::emitGlobal(const VariableDeclaration &Var, | 779 void TargetDataLowering::emitGlobal(const VariableDeclaration &Var, |
| 785 const IceString &SectionSuffix) { | 780 const IceString &SectionSuffix) { |
| 786 if (!BuildDefs::dump()) | 781 if (!BuildDefs::dump()) |
| 787 return; | 782 return; |
| 788 | 783 |
| 789 // If external and not initialized, this must be a cross test. Don't generate | 784 // If external and not initialized, this must be a cross test. Don't generate |
| 790 // a declaration for such cases. | 785 // a declaration for such cases. |
| 791 const bool IsExternal = | 786 const bool IsExternal = |
| 792 Var.isExternal() || Ctx->getFlags().getDisableInternal(); | 787 Var.isExternal() || Ctx->getFlags().getDisableInternal(); |
| 793 if (IsExternal && !Var.hasInitializer()) | 788 if (IsExternal && !Var.hasInitializer()) |
| 794 return; | 789 return; |
| 795 | 790 |
| 796 Ostream &Str = Ctx->getStrEmit(); | 791 Ostream &Str = Ctx->getStrEmit(); |
| 797 const bool HasNonzeroInitializer = Var.hasNonzeroInitializer(); | 792 const bool HasNonzeroInitializer = Var.hasNonzeroInitializer(); |
| 798 const bool IsConstant = Var.getIsConstant(); | 793 const bool IsConstant = Var.getIsConstant(); |
| 799 const SizeT Size = Var.getNumBytes(); | 794 const SizeT Size = Var.getNumBytes(); |
| 800 const IceString MangledName = Var.mangleName(Ctx); | 795 const IceString &Name = Var.getName(); |
| 801 | 796 |
| 802 Str << "\t.type\t" << MangledName << ",%object\n"; | 797 Str << "\t.type\t" << Name << ",%object\n"; |
| 803 | 798 |
| 804 const bool UseDataSections = Ctx->getFlags().getDataSections(); | 799 const bool UseDataSections = Ctx->getFlags().getDataSections(); |
| 805 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); | 800 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); |
| 806 const IceString Suffix = | 801 const IceString Suffix = |
| 807 dataSectionSuffix(SectionSuffix, MangledName, UseDataSections); | 802 dataSectionSuffix(SectionSuffix, Name, UseDataSections); |
| 808 if (IsConstant && UseNonsfi) | 803 if (IsConstant && UseNonsfi) |
| 809 Str << "\t.section\t.data.rel.ro" << Suffix << ",\"aw\",%progbits\n"; | 804 Str << "\t.section\t.data.rel.ro" << Suffix << ",\"aw\",%progbits\n"; |
| 810 else if (IsConstant) | 805 else if (IsConstant) |
| 811 Str << "\t.section\t.rodata" << Suffix << ",\"a\",%progbits\n"; | 806 Str << "\t.section\t.rodata" << Suffix << ",\"a\",%progbits\n"; |
| 812 else if (HasNonzeroInitializer) | 807 else if (HasNonzeroInitializer) |
| 813 Str << "\t.section\t.data" << Suffix << ",\"aw\",%progbits\n"; | 808 Str << "\t.section\t.data" << Suffix << ",\"aw\",%progbits\n"; |
| 814 else | 809 else |
| 815 Str << "\t.section\t.bss" << Suffix << ",\"aw\",%nobits\n"; | 810 Str << "\t.section\t.bss" << Suffix << ",\"aw\",%nobits\n"; |
| 816 | 811 |
| 817 if (IsExternal) | 812 if (IsExternal) |
| 818 Str << "\t.globl\t" << MangledName << "\n"; | 813 Str << "\t.globl\t" << Name << "\n"; |
| 819 | 814 |
| 820 const uint32_t Align = Var.getAlignment(); | 815 const uint32_t Align = Var.getAlignment(); |
| 821 if (Align > 1) { | 816 if (Align > 1) { |
| 822 assert(llvm::isPowerOf2_32(Align)); | 817 assert(llvm::isPowerOf2_32(Align)); |
| 823 // Use the .p2align directive, since the .align N directive can either | 818 // Use the .p2align directive, since the .align N directive can either |
| 824 // interpret N as bytes, or power of 2 bytes, depending on the target. | 819 // interpret N as bytes, or power of 2 bytes, depending on the target. |
| 825 Str << "\t.p2align\t" << llvm::Log2_32(Align) << "\n"; | 820 Str << "\t.p2align\t" << llvm::Log2_32(Align) << "\n"; |
| 826 } | 821 } |
| 827 | 822 |
| 828 Str << MangledName << ":\n"; | 823 Str << Name << ":\n"; |
| 829 | 824 |
| 830 if (HasNonzeroInitializer) { | 825 if (HasNonzeroInitializer) { |
| 831 for (const std::unique_ptr<VariableDeclaration::Initializer> &Init : | 826 for (const std::unique_ptr<VariableDeclaration::Initializer> &Init : |
| 832 Var.getInitializers()) { | 827 Var.getInitializers()) { |
| 833 switch (Init->getKind()) { | 828 switch (Init->getKind()) { |
| 834 case VariableDeclaration::Initializer::DataInitializerKind: { | 829 case VariableDeclaration::Initializer::DataInitializerKind: { |
| 835 const auto &Data = | 830 const auto &Data = |
| 836 llvm::cast<VariableDeclaration::DataInitializer>(Init.get()) | 831 llvm::cast<VariableDeclaration::DataInitializer>(Init.get()) |
| 837 ->getContents(); | 832 ->getContents(); |
| 838 for (SizeT i = 0; i < Init->getNumBytes(); ++i) { | 833 for (SizeT i = 0; i < Init->getNumBytes(); ++i) { |
| 839 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 834 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 840 } | 835 } |
| 841 break; | 836 break; |
| 842 } | 837 } |
| 843 case VariableDeclaration::Initializer::ZeroInitializerKind: | 838 case VariableDeclaration::Initializer::ZeroInitializerKind: |
| 844 Str << "\t.zero\t" << Init->getNumBytes() << "\n"; | 839 Str << "\t.zero\t" << Init->getNumBytes() << "\n"; |
| 845 break; | 840 break; |
| 846 case VariableDeclaration::Initializer::RelocInitializerKind: { | 841 case VariableDeclaration::Initializer::RelocInitializerKind: { |
| 847 const auto *Reloc = | 842 const auto *Reloc = |
| 848 llvm::cast<VariableDeclaration::RelocInitializer>(Init.get()); | 843 llvm::cast<VariableDeclaration::RelocInitializer>(Init.get()); |
| 849 Str << "\t" << getEmit32Directive() << "\t"; | 844 Str << "\t" << getEmit32Directive() << "\t"; |
| 850 Str << Reloc->getDeclaration()->mangleName(Ctx); | 845 Str << Reloc->getDeclaration()->getName(); |
| 851 if (Reloc->hasFixup()) { | 846 if (Reloc->hasFixup()) { |
| 852 // TODO(jpp): this is ARM32 specific. | 847 // TODO(jpp): this is ARM32 specific. |
| 853 Str << "(GOTOFF)"; | 848 Str << "(GOTOFF)"; |
| 854 } | 849 } |
| 855 if (RelocOffsetT Offset = Reloc->getOffset()) { | 850 if (RelocOffsetT Offset = Reloc->getOffset()) { |
| 856 if (Offset >= 0 || (Offset == INT32_MIN)) | 851 if (Offset >= 0 || (Offset == INT32_MIN)) |
| 857 Str << " + " << Offset; | 852 Str << " + " << Offset; |
| 858 else | 853 else |
| 859 Str << " - " << -Offset; | 854 Str << " - " << -Offset; |
| 860 } | 855 } |
| 861 Str << "\n"; | 856 Str << "\n"; |
| 862 break; | 857 break; |
| 863 } | 858 } |
| 864 } | 859 } |
| 865 } | 860 } |
| 866 } else { | 861 } else { |
| 867 // NOTE: for non-constant zero initializers, this is BSS (no bits), so an | 862 // NOTE: for non-constant zero initializers, this is BSS (no bits), so an |
| 868 // ELF writer would not write to the file, and only track virtual offsets, | 863 // ELF writer would not write to the file, and only track virtual offsets, |
| 869 // but the .s writer still needs this .zero and cannot simply use the .size | 864 // but the .s writer still needs this .zero and cannot simply use the .size |
| 870 // to advance offsets. | 865 // to advance offsets. |
| 871 Str << "\t.zero\t" << Size << "\n"; | 866 Str << "\t.zero\t" << Size << "\n"; |
| 872 } | 867 } |
| 873 | 868 |
| 874 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 869 Str << "\t.size\t" << Name << ", " << Size << "\n"; |
| 875 } | 870 } |
| 876 | 871 |
| 877 std::unique_ptr<TargetHeaderLowering> | 872 std::unique_ptr<TargetHeaderLowering> |
| 878 TargetHeaderLowering::createLowering(GlobalContext *Ctx) { | 873 TargetHeaderLowering::createLowering(GlobalContext *Ctx) { |
| 879 TargetArch Target = Ctx->getFlags().getTargetArch(); | 874 TargetArch Target = Ctx->getFlags().getTargetArch(); |
| 880 switch (Target) { | 875 switch (Target) { |
| 881 default: | 876 default: |
| 882 badTargetFatalError(Target); | 877 badTargetFatalError(Target); |
| 883 #define SUBZERO_TARGET(X) \ | 878 #define SUBZERO_TARGET(X) \ |
| 884 case Target_##X: \ | 879 case Target_##X: \ |
| 885 return ::X::createTargetHeaderLowering(Ctx); | 880 return ::X::createTargetHeaderLowering(Ctx); |
| 886 #include "llvm/Config/SZTargets.def" | 881 #include "llvm/Config/SZTargets.def" |
| 887 #undef SUBZERO_TARGET | 882 #undef SUBZERO_TARGET |
| 888 } | 883 } |
| 889 } | 884 } |
| 890 | 885 |
| 891 TargetHeaderLowering::~TargetHeaderLowering() = default; | 886 TargetHeaderLowering::~TargetHeaderLowering() = default; |
| 892 | 887 |
| 893 } // end of namespace Ice | 888 } // end of namespace Ice |
| OLD | NEW |