Index: include/llvm/MC/MCAsmBackend.h =================================================================== --- include/llvm/MC/MCAsmBackend.h +++ include/llvm/MC/MCAsmBackend.h @@ -150,7 +150,8 @@ /// target cannot generate such a sequence, it should return an error. /// /// \return - True on success. - virtual bool writeNopData(raw_ostream &OS, uint64_t Count) const = 0; + virtual bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const = 0; /// Give backend an opportunity to finish layout after relaxation virtual void finishLayout(MCAssembler const &Asm, Index: lib/MC/MCAssembler.cpp =================================================================== --- lib/MC/MCAssembler.cpp +++ lib/MC/MCAssembler.cpp @@ -464,6 +464,7 @@ "Writing bundle padding for a fragment without instructions"); unsigned TotalLength = BundlePadding + static_cast(FSize); + const MCSubtargetInfo *STI = EF.getSubtargetInfo(); if (EF.alignToBundleEnd() && TotalLength > getBundleAlignSize()) { // If the padding itself crosses a bundle boundary, it must be emitted // in 2 pieces, since even nop instructions must not cross boundaries. @@ -474,12 +475,12 @@ // ---------------------------- // ^-------------------^ <- TotalLength unsigned DistanceToBoundary = TotalLength - getBundleAlignSize(); - if (!getBackend().writeNopData(OS, DistanceToBoundary)) + if (!getBackend().writeNopData(OS, DistanceToBoundary, STI)) report_fatal_error("unable to write NOP sequence of " + Twine(DistanceToBoundary) + " bytes"); BundlePadding -= DistanceToBoundary; } - if (!getBackend().writeNopData(OS, BundlePadding)) + if (!getBackend().writeNopData(OS, BundlePadding, STI)) report_fatal_error("unable to write NOP sequence of " + Twine(BundlePadding) + " bytes"); } @@ -525,7 +526,7 @@ // bytes left to fill use the Value and ValueSize to fill the rest. // If we are aligning with nops, ask that target to emit the right data. if (AF.hasEmitNops()) { - if (!Asm.getBackend().writeNopData(OS, Count)) + if (!Asm.getBackend().writeNopData(OS, Count, AF.getSubtargetInfo())) report_fatal_error("unable to write nop sequence of " + Twine(Count) + " bytes"); break; @@ -605,7 +606,9 @@ } case MCFragment::FT_Padding: { - if (!Asm.getBackend().writeNopData(OS, FragmentSize)) + const MCPaddingFragment &PF = cast(F); + const MCSubtargetInfo *STI = &PF.getSubtargetInfo(); + if (!Asm.getBackend().writeNopData(OS, FragmentSize, STI)) report_fatal_error("unable to write nop sequence of " + Twine(FragmentSize) + " bytes"); break; Index: lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -83,7 +83,8 @@ const MCAsmLayout &Layout) const override; void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, MCInst &Res) const override; - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; void HandleAssemblerFlag(MCAssemblerFlag Flag) {} @@ -346,7 +347,8 @@ llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented"); } -bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { // If the count is not 4-byte aligned, we must be writing data into the text // section (otherwise we have unaligned instructions, and thus have far // bigger problems), so just write zeros instead. Index: lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp =================================================================== --- lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp +++ lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp @@ -49,7 +49,8 @@ } unsigned getMinimumNopSize() const override; - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; }; @@ -144,7 +145,8 @@ return 4; } -bool AMDGPUAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +bool AMDGPUAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { // If the count is not 4-byte aligned, we must be writing data into the text // section (otherwise we have unaligned instructions, and thus have far // bigger problems), so just write zeros instead. Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -19,24 +19,18 @@ namespace llvm { class ARMAsmBackend : public MCAsmBackend { - // The STI from the target triple the MCAsmBackend was instantiated with - // note that MCFragments may have a different local STI that should be - // used in preference. - const MCSubtargetInfo &STI; bool isThumbMode; // Currently emitting Thumb code. public: - ARMAsmBackend(const Target &T, const MCSubtargetInfo &STI, - support::endianness Endian) - : MCAsmBackend(Endian), STI(STI), - isThumbMode(STI.getTargetTriple().isThumb()) {} + ARMAsmBackend(const Target &T, bool IsThumb, support::endianness Endian) + : MCAsmBackend(Endian), isThumbMode(IsThumb) {} unsigned getNumFixupKinds() const override { return ARM::NumTargetFixupKinds; } - // FIXME: this should be calculated per fragment as the STI may be - // different. - bool hasNOP() const { return STI.getFeatureBits()[ARM::HasV6T2Ops]; } + bool hasNOP(const MCSubtargetInfo *STI) const { + return STI->getFeatureBits()[ARM::HasV6T2Ops]; + } const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; @@ -68,7 +62,8 @@ void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, MCInst &Res) const override; - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; void handleAssemblerFlag(MCAssemblerFlag Flag) override; Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -293,14 +293,16 @@ Res.setOpcode(RelaxedOp); } -bool ARMAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { + +bool ARMAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8 const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP const uint32_t ARMv4_NopEncoding = 0xe1a00000; // using MOV r0,r0 const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP if (isThumb()) { const uint16_t nopEncoding = - hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding; + hasNOP(STI) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding; uint64_t NumNops = Count / 2; for (uint64_t i = 0; i != NumNops; ++i) support::endian::write(OS, nopEncoding, Endian); @@ -310,7 +312,7 @@ } // ARM mode const uint32_t nopEncoding = - hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding; + hasNOP(STI) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding; uint64_t NumNops = Count / 4; for (uint64_t i = 0; i != NumNops; ++i) support::endian::write(OS, nopEncoding, Endian); @@ -1172,15 +1174,16 @@ llvm_unreachable("unsupported object format"); case Triple::MachO: { MachO::CPUSubTypeARM CS = getMachOSubTypeFromArch(TheTriple.getArchName()); - return new ARMAsmBackendDarwin(T, STI, MRI, CS); + return new ARMAsmBackendDarwin(T, STI.getTargetTriple().isThumb(), MRI, CS); } case Triple::COFF: assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported"); - return new ARMAsmBackendWinCOFF(T, STI); + return new ARMAsmBackendWinCOFF(T, STI.getTargetTriple().isThumb()); case Triple::ELF: assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target"); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); - return new ARMAsmBackendELF(T, STI, OSABI, Endian); + return new ARMAsmBackendELF(T, STI.getTargetTriple().isThumb(), OSABI, + Endian); } } Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h +++ lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h @@ -19,9 +19,10 @@ const MCRegisterInfo &MRI; public: const MachO::CPUSubTypeARM Subtype; - ARMAsmBackendDarwin(const Target &T, const MCSubtargetInfo &STI, - const MCRegisterInfo &MRI, MachO::CPUSubTypeARM st) - : ARMAsmBackend(T, STI, support::little), MRI(MRI), Subtype(st) {} + ARMAsmBackendDarwin(const Target &T, bool IsThumb, const MCRegisterInfo &MRI, + MachO::CPUSubTypeARM st) + : ARMAsmBackend(T, IsThumb, support::little), MRI(MRI), + Subtype(st) {} std::unique_ptr createObjectTargetWriter() const override { Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h +++ lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h @@ -20,9 +20,9 @@ class ARMAsmBackendELF : public ARMAsmBackend { public: uint8_t OSABI; - ARMAsmBackendELF(const Target &T, const MCSubtargetInfo &STI, uint8_t OSABI, + ARMAsmBackendELF(const Target &T, bool IsThumb, uint8_t OSABI, support::endianness Endian) - : ARMAsmBackend(T, STI, Endian), OSABI(OSABI) {} + : ARMAsmBackend(T, IsThumb, Endian), OSABI(OSABI) {} std::unique_ptr createObjectTargetWriter() const override { Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h +++ lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h @@ -17,8 +17,8 @@ namespace { class ARMAsmBackendWinCOFF : public ARMAsmBackend { public: - ARMAsmBackendWinCOFF(const Target &T, const MCSubtargetInfo &STI) - : ARMAsmBackend(T, STI, support::little) {} + ARMAsmBackendWinCOFF(const Target &T, bool IsThumb) + : ARMAsmBackend(T, IsThumb, support::little) {} std::unique_ptr createObjectTargetWriter() const override { return createARMWinCOFFObjectWriter(/*Is64Bit=*/false); Index: lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp =================================================================== --- lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp +++ lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp @@ -50,12 +50,14 @@ void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, MCInst &Res) const override {} - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; }; } // end anonymous namespace -bool BPFAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +bool BPFAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { if ((Count % 8) != 0) return false; Index: lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp =================================================================== --- lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -684,7 +684,8 @@ assert(Update && "Didn't find relaxation target"); } - bool writeNopData(raw_ostream &OS, uint64_t Count) const override { + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override { static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP. ParseIn = 0x00004000, // In packet parse-bits. ParseEnd = 0x0000c000; // End of packet parse-bits. Index: lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp =================================================================== --- lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp +++ lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp @@ -79,10 +79,12 @@ const MCSubtargetInfo & /*STI*/, MCInst & /*Res*/) const override {} - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; }; -bool LanaiAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +bool LanaiAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { if ((Count % 4) != 0) return false; Index: lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h +++ lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h @@ -85,7 +85,8 @@ /// @} - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; }; // class MipsAsmBackend Index: lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -481,7 +481,8 @@ /// it should return an error. /// /// \return - True on success. -bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { // Check for a less than instruction size number of bytes // FIXME: 16 bit instructions are not handled yet here. // We shouldn't be using a hard coded number for instruction size. Index: lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -178,7 +178,8 @@ llvm_unreachable("relaxInstruction() unimplemented"); } - bool writeNopData(raw_ostream &OS, uint64_t Count) const override { + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override { uint64_t NumNops = Count / 4; for (uint64_t i = 0; i != NumNops; ++i) support::endian::write(OS, 0x60000000, Endian); Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp =================================================================== --- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -255,7 +255,8 @@ llvm_unreachable("relaxInstruction() unimplemented"); } - bool writeNopData(raw_ostream &OS, uint64_t Count) const override { + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override { // Cannot emit NOP with size not multiple of 32 bits. if (Count % 4 != 0) return false; Index: lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp =================================================================== --- lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp +++ lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp @@ -68,7 +68,8 @@ MCInst &Res) const override { llvm_unreachable("SystemZ does do not have assembler relaxation"); } - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; std::unique_ptr createObjectTargetWriter() const override { return createSystemZObjectWriter(OSABI); @@ -118,7 +119,8 @@ } } -bool SystemZMCAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +bool SystemZMCAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { for (uint64_t I = 0; I != Count; ++I) OS << '\x7'; return true; Index: lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -68,10 +68,9 @@ }; class X86AsmBackend : public MCAsmBackend { - const MCSubtargetInfo &STI; public: - X86AsmBackend(const Target &T, const MCSubtargetInfo &STI) - : MCAsmBackend(support::little), STI(STI) {} + X86AsmBackend(const Target &T) + : MCAsmBackend(support::little) {} unsigned getNumFixupKinds() const override { return X86::NumTargetFixupKinds; @@ -128,7 +127,8 @@ void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, MCInst &Res) const override; - bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const override; }; } // end anonymous namespace @@ -318,7 +318,8 @@ /// Write a sequence of optimal nops to the output, covering \p Count /// bytes. /// \return - true on success, false on failure -bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count, + const MCSubtargetInfo *STI) const { static const char Nops[10][11] = { // nop "\x90", @@ -344,7 +345,7 @@ // This CPU doesn't support long nops. If needed add more. // FIXME: We could generated something better than plain 0x90. - if (!STI.getFeatureBits()[X86::FeatureNOPL]) { + if (!(*STI).getFeatureBits()[X86::FeatureNOPL]) { for (uint64_t i = 0; i < Count; ++i) OS << '\x90'; return true; @@ -353,11 +354,11 @@ // 15-bytes is the longest single NOP instruction, but 10-bytes is // commonly the longest that can be efficiently decoded. uint64_t MaxNopLength = 10; - if (STI.getFeatureBits()[X86::ProcIntelSLM]) + if ((*STI).getFeatureBits()[X86::ProcIntelSLM]) MaxNopLength = 7; - else if (STI.getFeatureBits()[X86::FeatureFast15ByteNOP]) + else if ((*STI).getFeatureBits()[X86::FeatureFast15ByteNOP]) MaxNopLength = 15; - else if (STI.getFeatureBits()[X86::FeatureFast11ByteNOP]) + else if ((*STI).getFeatureBits()[X86::FeatureFast11ByteNOP]) MaxNopLength = 11; // Emit as many MaxNopLength NOPs as needed, then emit a NOP of the remaining @@ -383,15 +384,14 @@ class ELFX86AsmBackend : public X86AsmBackend { public: uint8_t OSABI; - ELFX86AsmBackend(const Target &T, uint8_t OSABI, const MCSubtargetInfo &STI) - : X86AsmBackend(T, STI), OSABI(OSABI) {} + ELFX86AsmBackend(const Target &T, uint8_t OSABI) + : X86AsmBackend(T), OSABI(OSABI) {} }; class ELFX86_32AsmBackend : public ELFX86AsmBackend { public: - ELFX86_32AsmBackend(const Target &T, uint8_t OSABI, - const MCSubtargetInfo &STI) - : ELFX86AsmBackend(T, OSABI, STI) {} + ELFX86_32AsmBackend(const Target &T, uint8_t OSABI) + : ELFX86AsmBackend(T, OSABI) {} std::unique_ptr createObjectTargetWriter() const override { @@ -401,9 +401,8 @@ class ELFX86_X32AsmBackend : public ELFX86AsmBackend { public: - ELFX86_X32AsmBackend(const Target &T, uint8_t OSABI, - const MCSubtargetInfo &STI) - : ELFX86AsmBackend(T, OSABI, STI) {} + ELFX86_X32AsmBackend(const Target &T, uint8_t OSABI) + : ELFX86AsmBackend(T, OSABI) {} std::unique_ptr createObjectTargetWriter() const override { @@ -414,9 +413,8 @@ class ELFX86_IAMCUAsmBackend : public ELFX86AsmBackend { public: - ELFX86_IAMCUAsmBackend(const Target &T, uint8_t OSABI, - const MCSubtargetInfo &STI) - : ELFX86AsmBackend(T, OSABI, STI) {} + ELFX86_IAMCUAsmBackend(const Target &T, uint8_t OSABI) + : ELFX86AsmBackend(T, OSABI) {} std::unique_ptr createObjectTargetWriter() const override { @@ -427,9 +425,8 @@ class ELFX86_64AsmBackend : public ELFX86AsmBackend { public: - ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, - const MCSubtargetInfo &STI) - : ELFX86AsmBackend(T, OSABI, STI) {} + ELFX86_64AsmBackend(const Target &T, uint8_t OSABI) + : ELFX86AsmBackend(T, OSABI) {} std::unique_ptr createObjectTargetWriter() const override { @@ -441,9 +438,8 @@ bool Is64Bit; public: - WindowsX86AsmBackend(const Target &T, bool is64Bit, - const MCSubtargetInfo &STI) - : X86AsmBackend(T, STI) + WindowsX86AsmBackend(const Target &T, bool is64Bit) + : X86AsmBackend(T) , Is64Bit(is64Bit) { } @@ -800,9 +796,8 @@ } public: - DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, bool Is64Bit) - : X86AsmBackend(T, STI), MRI(MRI), Is64Bit(Is64Bit) { + DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, bool Is64Bit) + : X86AsmBackend(T), MRI(MRI), Is64Bit(Is64Bit) { memset(SavedRegs, 0, sizeof(SavedRegs)); OffsetSize = Is64Bit ? 8 : 4; MoveInstrSize = Is64Bit ? 3 : 2; @@ -814,7 +809,7 @@ public: DarwinX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI) - : DarwinX86AsmBackend(T, MRI, STI, false) {} + : DarwinX86AsmBackend(T, MRI, false) {} std::unique_ptr createObjectTargetWriter() const override { @@ -834,8 +829,8 @@ const MachO::CPUSubTypeX86 Subtype; public: DarwinX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MachO::CPUSubTypeX86 st) - : DarwinX86AsmBackend(T, MRI, STI, true), Subtype(st) {} + MachO::CPUSubTypeX86 st) + : DarwinX86AsmBackend(T, MRI, true), Subtype(st) {} std::unique_ptr createObjectTargetWriter() const override { @@ -861,14 +856,14 @@ return new DarwinX86_32AsmBackend(T, MRI, STI); if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF()) - return new WindowsX86AsmBackend(T, false, STI); + return new WindowsX86AsmBackend(T, false); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); if (TheTriple.isOSIAMCU()) - return new ELFX86_IAMCUAsmBackend(T, OSABI, STI); + return new ELFX86_IAMCUAsmBackend(T, OSABI); - return new ELFX86_32AsmBackend(T, OSABI, STI); + return new ELFX86_32AsmBackend(T, OSABI); } MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, @@ -881,15 +876,15 @@ StringSwitch(TheTriple.getArchName()) .Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H) .Default(MachO::CPU_SUBTYPE_X86_64_ALL); - return new DarwinX86_64AsmBackend(T, MRI, STI, CS); + return new DarwinX86_64AsmBackend(T, MRI, CS); } if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF()) - return new WindowsX86AsmBackend(T, true, STI); + return new WindowsX86AsmBackend(T, true); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); if (TheTriple.getEnvironment() == Triple::GNUX32) - return new ELFX86_X32AsmBackend(T, OSABI, STI); - return new ELFX86_64AsmBackend(T, OSABI, STI); + return new ELFX86_X32AsmBackend(T, OSABI); + return new ELFX86_64AsmBackend(T, OSABI); } Index: test/CodeGen/ARM/subtarget-align.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/subtarget-align.ll @@ -0,0 +1,41 @@ +; RUN: llc < %s -mtriple=arm-linux-gnueabihf -filetype=obj -o - | \ +; RUN: llvm-objdump -triple=armv7 -no-show-raw-insn -disassemble - | \ +; RUN: FileCheck %s + +; Expect architectural nop to be used between func2 and func3 but not func1 +; and func2 due to lack of subtarget support in func2. + +define i32 @func1() #0 align 16 { +entry: + ret i32 0 +} + +define i32 @func2() #1 align 16 { +entry: + ret i32 0 +} + +define i32 @func3() #0 align 16 { +entry: + ret i32 0 +} + +attributes #0 = { "target-cpu"="generic" "target-features"="+armv7-a,+dsp,+neon,+vfp3,-thumb-mode" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "target-cpu"="arm7tdmi" "target-features"="+armv4t" "use-soft-float"="true" } + +; CHECK: Disassembly of section .text: +; CHECK-NEXT: func1: +; CHECK-NEXT: 0: mov r0, #0 +; CHECK-NEXT: 4: bx lr +; CHECK-NEXT: 8: mov r0, r0 +; CHECK-NEXT: c: mov r0, r0 + +; CHECK: func2: +; CHECK-NEXT: 10: mov r0, #0 +; CHECK-NEXT: 14: bx lr +; CHECK-NEXT: 18: nop +; CHECK-NEXT: 1c: nop + +; CHECK: func3: +; CHECK-NEXT: 20: mov r0, #0 +; CHECK-NEXT: 24: bx lr Index: test/MC/ARM/subtarget-nop.s =================================================================== --- /dev/null +++ test/MC/ARM/subtarget-nop.s @@ -0,0 +1,45 @@ +# RUN: llvm-mc < %s -triple arm-linux-gnueabihf -filetype=obj -o - \ +# RUN: | llvm-objdump -no-show-raw-insn -triple armv7 -disassemble - | FileCheck %s + +# Check that the architectural nop is only produced for subtargets that support +# it. This includes nop padding for alignment. + .syntax unified + .arch armv6 +foo: + mov r1, r0 + nop + .p2align 4 + bx lr + + .arch armv7-a +bar: + mov r1, r0 + nop + .p2align 4 + bx lr + + .arch armv4t +baz: + mov r1, r0 + nop + .p2align 4 + bx lr + +# CHECK: foo: +# CHECK-NEXT: 0: mov r1, r0 +# CHECK-NEXT: 4: mov r0, r0 +# CHECK-NEXT: 8: mov r0, r0 +# CHECK-NEXT: c: mov r0, r0 +# CHECK-NEXT: 10: bx lr + +# CHECK: bar: +# CHECK-NEXT: 14: mov r1, r0 +# CHECK-NEXT: 18: nop +# CHECK-NEXT: 1c: nop +# CHECK-NEXT: 20: bx lr + +# CHECK: baz: +# CHECK-NEXT: 24: mov r1, r0 +# CHECK-NEXT: 28: mov r0, r0 +# CHECK-NEXT: 2c: mov r0, r0 +# CHECK-NEXT: 30: bx lr