llvm.org GIT mirror llvm / 24dded2
Make the ARM AsmPrinter independent of global subtarget initialization. Initialize the subtarget once per function and migrate Emit{Start|End}OfAsmFile to either use attributes on the TargetMachine or get information from the subtarget we'd use for assembling. One bit (getISAEncoding) touched the general AsmPrinter and the debug output. Handle this one by passing the function for the subprogram down and updating all callers and users. The top-level-ness of the ARM attribute output for assembly is, by nature, contrary to how we'd want to do this for an LTO situation where we have multiple cpu architectures so this solution is good enough for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229528 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Christopher 5 years ago
5 changed file(s) with 94 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
405405 const MCSymbol *SectionLabel) const;
406406
407407 /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
408 virtual unsigned getISAEncoding() { return 0; }
408 virtual unsigned getISAEncoding(const Function *) { return 0; }
409409
410410 /// Emit a dwarf register operation for describing
411411 /// - a small value occupying only part of a register or
13431343 if (SP.isOptimized())
13441344 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
13451345
1346 if (unsigned isa = Asm->getISAEncoding()) {
1346 if (unsigned isa = Asm->getISAEncoding(SP.getFunction())) {
13471347 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
13481348 }
13491349
5959 ARMAsmPrinter::ARMAsmPrinter(TargetMachine &TM,
6060 std::unique_ptr Streamer)
6161 : AsmPrinter(TM, std::move(Streamer)), AFI(nullptr), MCP(nullptr),
62 InConstantPool(false) {
63 Subtarget = &TM.getSubtarget();
64 }
62 InConstantPool(false) {}
6563
6664 void ARMAsmPrinter::EmitFunctionBodyEnd() {
6765 // Make sure to terminate any constant pools that were at the end
104102 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
105103 AFI = MF.getInfo();
106104 MCP = MF.getConstantPool();
105 Subtarget = &MF.getSubtarget();
107106
108107 SetupMachineFunction(MF);
109108
436435 }
437436
438437 void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
439 if (Subtarget->isTargetMachO()) {
438 Triple TT(TM.getTargetTriple());
439 if (TT.isOSBinFormatMachO()) {
440440 Reloc::Model RelocM = TM.getRelocationModel();
441441 if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
442442 // Declare all the text sections up front (before the DWARF sections
499499 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified);
500500
501501 // Emit ARM Build Attributes
502 if (Subtarget->isTargetELF())
502 if (TT.isOSBinFormatELF())
503503 emitAttributes();
504504
505 if (!M.getModuleInlineAsm().empty() && Subtarget->isThumb())
505 // Use the triple's architecture and subarchitecture to determine
506 // if we're thumb for the purposes of the top level code16 assembler
507 // flag.
508 bool isThumb = TT.getArch() == Triple::thumb ||
509 TT.getArch() == Triple::thumbeb ||
510 TT.getSubArch() == Triple::ARMSubArch_v7m ||
511 TT.getSubArch() == Triple::ARMSubArch_v6m;
512 if (!M.getModuleInlineAsm().empty() && isThumb)
506513 OutStreamer.EmitAssemblerFlag(MCAF_Code16);
507514 }
508515
531538
532539
533540 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
534 if (Subtarget->isTargetMachO()) {
541 Triple TT(TM.getTargetTriple());
542 if (TT.isOSBinFormatMachO()) {
535543 // All darwin targets use mach-o.
536544 const TargetLoweringObjectFileMachO &TLOFMacho =
537545 static_cast(getObjFileLowering());
574582 }
575583
576584 // Emit a .data.rel section containing any stubs that were created.
577 if (Subtarget->isTargetELF()) {
585 if (TT.isOSBinFormatELF()) {
578586 const TargetLoweringObjectFileELF &TLOFELF =
579587 static_cast(getObjFileLowering());
580588
638646
639647 ATS.switchVendor("aeabi");
640648
641 std::string CPUString = Subtarget->getCPUString();
649 // Compute ARM ELF Attributes based on the default subtarget that
650 // we'd have constructed. The existing ARM behavior isn't LTO clean
651 // anyhow.
652 // FIXME: For ifunc related functions we could iterate over and look
653 // for a feature string that doesn't match the default one.
654 StringRef TT = TM.getTargetTriple();
655 StringRef CPU = TM.getTargetCPU();
656 StringRef FS = TM.getTargetFeatureString();
657 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
658 if (!FS.empty()) {
659 if (!ArchFS.empty())
660 ArchFS = ArchFS + "," + FS.str();
661 else
662 ArchFS = FS;
663 }
664 const ARMBaseTargetMachine &ATM =
665 static_cast(TM);
666 const ARMSubtarget STI(TT, CPU, ArchFS, ATM, ATM.isLittleEndian());
667
668 std::string CPUString = STI.getCPUString();
642669
643670 // FIXME: remove krait check when GNU tools support krait cpu
644671 if (CPUString != "generic" && CPUString != "krait")
645672 ATS.emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
646673
647 ATS.emitAttribute(ARMBuildAttrs::CPU_arch,
648 getArchForCPU(CPUString, Subtarget));
674 ATS.emitAttribute(ARMBuildAttrs::CPU_arch, getArchForCPU(CPUString, &STI));
649675
650676 // Tag_CPU_arch_profile must have the default value of 0 when "Architecture
651677 // profile is not applicable (e.g. pre v7, or cross-profile code)".
652 if (Subtarget->hasV7Ops()) {
653 if (Subtarget->isAClass()) {
678 if (STI.hasV7Ops()) {
679 if (STI.isAClass()) {
654680 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
655681 ARMBuildAttrs::ApplicationProfile);
656 } else if (Subtarget->isRClass()) {
682 } else if (STI.isRClass()) {
657683 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
658684 ARMBuildAttrs::RealTimeProfile);
659 } else if (Subtarget->isMClass()) {
685 } else if (STI.isMClass()) {
660686 ATS.emitAttribute(ARMBuildAttrs::CPU_arch_profile,
661687 ARMBuildAttrs::MicroControllerProfile);
662688 }
663689 }
664690
665 ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use, Subtarget->hasARMOps() ?
666 ARMBuildAttrs::Allowed : ARMBuildAttrs::Not_Allowed);
667 if (Subtarget->isThumb1Only()) {
668 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
669 ARMBuildAttrs::Allowed);
670 } else if (Subtarget->hasThumb2()) {
691 ATS.emitAttribute(ARMBuildAttrs::ARM_ISA_use,
692 STI.hasARMOps() ? ARMBuildAttrs::Allowed
693 : ARMBuildAttrs::Not_Allowed);
694 if (STI.isThumb1Only()) {
695 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use, ARMBuildAttrs::Allowed);
696 } else if (STI.hasThumb2()) {
671697 ATS.emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
672698 ARMBuildAttrs::AllowThumb32);
673699 }
674700
675 if (Subtarget->hasNEON()) {
701 if (STI.hasNEON()) {
676702 /* NEON is not exactly a VFP architecture, but GAS emit one of
677703 * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
678 if (Subtarget->hasFPARMv8()) {
679 if (Subtarget->hasCrypto())
704 if (STI.hasFPARMv8()) {
705 if (STI.hasCrypto())
680706 ATS.emitFPU(ARM::CRYPTO_NEON_FP_ARMV8);
681707 else
682708 ATS.emitFPU(ARM::NEON_FP_ARMV8);
683 }
684 else if (Subtarget->hasVFP4())
709 } else if (STI.hasVFP4())
685710 ATS.emitFPU(ARM::NEON_VFPV4);
686711 else
687712 ATS.emitFPU(ARM::NEON);
688713 // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
689 if (Subtarget->hasV8Ops())
714 if (STI.hasV8Ops())
690715 ATS.emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
691716 ARMBuildAttrs::AllowNeonARMv8);
692717 } else {
693 if (Subtarget->hasFPARMv8())
718 if (STI.hasFPARMv8())
694719 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
695720 // FPU, but there are two different names for it depending on the CPU.
696 ATS.emitFPU(Subtarget->hasD16() ? ARM::FPV5_D16 : ARM::FP_ARMV8);
697 else if (Subtarget->hasVFP4())
698 ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4);
699 else if (Subtarget->hasVFP3())
700 ATS.emitFPU(Subtarget->hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3);
701 else if (Subtarget->hasVFP2())
721 ATS.emitFPU(STI.hasD16() ? ARM::FPV5_D16 : ARM::FP_ARMV8);
722 else if (STI.hasVFP4())
723 ATS.emitFPU(STI.hasD16() ? ARM::VFPV4_D16 : ARM::VFPV4);
724 else if (STI.hasVFP3())
725 ATS.emitFPU(STI.hasD16() ? ARM::VFPV3_D16 : ARM::VFPV3);
726 else if (STI.hasVFP2())
702727 ATS.emitFPU(ARM::VFPV2);
703728 }
704729
720745 if (!TM.Options.UnsafeFPMath) {
721746 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
722747 ARMBuildAttrs::IEEEDenormals);
723 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions,
724 ARMBuildAttrs::Allowed);
748 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, ARMBuildAttrs::Allowed);
725749
726750 // If the user has permitted this code to choose the IEEE 754
727751 // rounding at run-time, emit the rounding attribute.
728752 if (TM.Options.HonorSignDependentRoundingFPMathOption)
729 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_rounding,
730 ARMBuildAttrs::Allowed);
753 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_rounding, ARMBuildAttrs::Allowed);
731754 } else {
732 if (!Subtarget->hasVFP2()) {
755 if (!STI.hasVFP2()) {
733756 // When the target doesn't have an FPU (by design or
734757 // intention), the assumptions made on the software support
735758 // mirror that of the equivalent hardware support *if it
736759 // existed*. For v7 and better we indicate that denormals are
737760 // flushed preserving sign, and for V6 we indicate that
738761 // denormals are flushed to positive zero.
739 if (Subtarget->hasV7Ops())
762 if (STI.hasV7Ops())
740763 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
741764 ARMBuildAttrs::PreserveFPSign);
742 } else if (Subtarget->hasVFP3()) {
765 } else if (STI.hasVFP3()) {
743766 // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is,
744767 // the sign bit of the zero matches the sign bit of the input or
745768 // result that is being flushed to zero.
763786 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_number_model,
764787 ARMBuildAttrs::AllowIEE754);
765788
766 if (Subtarget->allowsUnalignedMem())
789 if (STI.allowsUnalignedMem())
767790 ATS.emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
768791 ARMBuildAttrs::Allowed);
769792 else
776799 ATS.emitAttribute(ARMBuildAttrs::ABI_align_preserved, 1);
777800
778801 // ABI_HardFP_use attribute to indicate single precision FP.
779 if (Subtarget->isFPOnlySP())
802 if (STI.isFPOnlySP())
780803 ATS.emitAttribute(ARMBuildAttrs::ABI_HardFP_use,
781804 ARMBuildAttrs::HardFPSinglePrecision);
782805
783806 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
784 if (Subtarget->isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard)
807 if (STI.isAAPCS_ABI() && TM.Options.FloatABIType == FloatABI::Hard)
785808 ATS.emitAttribute(ARMBuildAttrs::ABI_VFP_args, ARMBuildAttrs::HardFPAAPCS);
786809
787810 // FIXME: Should we signal R9 usage?
788811
789 if (Subtarget->hasFP16())
790 ATS.emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP);
812 if (STI.hasFP16())
813 ATS.emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP);
791814
792815 // FIXME: To support emitting this build attribute as GCC does, the
793816 // -mfp16-format option and associated plumbing must be
796819 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_16bit_format,
797820 ARMBuildAttrs::FP16FormatIEEE);
798821
799 if (Subtarget->hasMPExtension())
800 ATS.emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP);
822 if (STI.hasMPExtension())
823 ATS.emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP);
801824
802825 // Hardware divide in ARM mode is part of base arch, starting from ARMv8.
803826 // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M).
805828 // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits.
806829 // AllowDIVExt is only emitted if hwdiv isn't available in the base arch;
807830 // otherwise, the default value (AllowDIVIfExists) applies.
808 if (Subtarget->hasDivideInARMMode() && !Subtarget->hasV8Ops())
809 ATS.emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt);
831 if (STI.hasDivideInARMMode() && !STI.hasV8Ops())
832 ATS.emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt);
810833
811834 if (MMI) {
812835 if (const Module *SourceModule = MMI->getModule()) {
838861 // it as another callee-saved register, but not as SB or a TLS pointer; It
839862 // would instead be nicer to push this from the frontend as metadata, as we do
840863 // for the wchar and enum size tags
841 if (Subtarget->isR9Reserved())
842 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use,
843 ARMBuildAttrs::R9Reserved);
864 if (STI.isR9Reserved())
865 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, ARMBuildAttrs::R9Reserved);
844866 else
845 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use,
846 ARMBuildAttrs::R9IsGPR);
847
848 if (Subtarget->hasTrustZone() && Subtarget->hasVirtualization())
849 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
850 ARMBuildAttrs::AllowTZVirtualization);
851 else if (Subtarget->hasTrustZone())
852 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
853 ARMBuildAttrs::AllowTZ);
854 else if (Subtarget->hasVirtualization())
855 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
856 ARMBuildAttrs::AllowVirtualization);
867 ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, ARMBuildAttrs::R9IsGPR);
868
869 if (STI.hasTrustZone() && STI.hasVirtualization())
870 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
871 ARMBuildAttrs::AllowTZVirtualization);
872 else if (STI.hasTrustZone())
873 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
874 ARMBuildAttrs::AllowTZ);
875 else if (STI.hasVirtualization())
876 ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
877 ARMBuildAttrs::AllowVirtualization);
857878
858879 ATS.finishAttributeSection();
859880 }
102102 const MachineInstr *MI);
103103
104104 public:
105 unsigned getISAEncoding() override {
105 unsigned getISAEncoding(const Function *F) override {
106106 // ARM/Darwin adds ISA to the DWARF info for each function.
107 if (!Subtarget->isTargetMachO())
107 Triple TT(TM.getTargetTriple());
108 if (!TT.isOSBinFormatMachO())
108109 return 0;
109 return Subtarget->isThumb() ?
110 ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
110 const ARMSubtarget &STI = TM.getSubtarget(F);
111 return STI.isThumb() ? ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
111112 }
112113
113114 private:
4747 const ARMSubtarget *getSubtargetImpl() const override { return &Subtarget; }
4848 const ARMSubtarget *getSubtargetImpl(const Function &F) const override;
4949 const DataLayout *getDataLayout() const override { return &DL; }
50 bool isLittleEndian() const { return isLittle; }
5051
5152 /// \brief Get the TargetIRAnalysis for this target.
5253 TargetIRAnalysis getTargetIRAnalysis() override;