10b57cec5SDimitry Andric //===- ARMTargetStreamer.cpp - ARMTargetStreamer class --*- C++ -*---------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the ARMTargetStreamer class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "MCTargetDesc/ARMMCTargetDesc.h" 140b57cec5SDimitry Andric #include "llvm/MC/ConstantPools.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 200b57cec5SDimitry Andric #include "llvm/Support/ARMBuildAttributes.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric using namespace llvm; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric // 250b57cec5SDimitry Andric // ARMTargetStreamer Implemenation 260b57cec5SDimitry Andric // 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric ARMTargetStreamer::ARMTargetStreamer(MCStreamer &S) 290b57cec5SDimitry Andric : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {} 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric ARMTargetStreamer::~ARMTargetStreamer() = default; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric // The constant pool handling is shared by all ARMTargetStreamer 340b57cec5SDimitry Andric // implementations. 350b57cec5SDimitry Andric const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc) { 360b57cec5SDimitry Andric return ConstantPools->addEntry(Streamer, Expr, 4, Loc); 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric void ARMTargetStreamer::emitCurrentConstantPool() { 400b57cec5SDimitry Andric ConstantPools->emitForCurrentSection(Streamer); 410b57cec5SDimitry Andric ConstantPools->clearCacheForCurrentSection(Streamer); 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric // finish() - write out any non-empty assembler constant pools. 45349cc55cSDimitry Andric void ARMTargetStreamer::emitConstantPools() { 46349cc55cSDimitry Andric ConstantPools->emitAll(Streamer); 47349cc55cSDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric // reset() - Reset any state 500b57cec5SDimitry Andric void ARMTargetStreamer::reset() {} 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) { 530b57cec5SDimitry Andric unsigned Size; 540b57cec5SDimitry Andric char Buffer[4]; 550b57cec5SDimitry Andric const bool LittleEndian = getStreamer().getContext().getAsmInfo()->isLittleEndian(); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric switch (Suffix) { 580b57cec5SDimitry Andric case '\0': 590b57cec5SDimitry Andric Size = 4; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric for (unsigned II = 0, IE = Size; II != IE; II++) { 620b57cec5SDimitry Andric const unsigned I = LittleEndian ? (Size - II - 1) : II; 630b57cec5SDimitry Andric Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT); 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric break; 670b57cec5SDimitry Andric case 'n': 680b57cec5SDimitry Andric case 'w': 690b57cec5SDimitry Andric Size = (Suffix == 'n' ? 2 : 4); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric // Thumb wide instructions are emitted as a pair of 16-bit words of the 720b57cec5SDimitry Andric // appropriate endianness. 730b57cec5SDimitry Andric for (unsigned II = 0, IE = Size; II != IE; II = II + 2) { 740b57cec5SDimitry Andric const unsigned I0 = LittleEndian ? II + 0 : II + 1; 750b57cec5SDimitry Andric const unsigned I1 = LittleEndian ? II + 1 : II + 0; 760b57cec5SDimitry Andric Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT); 770b57cec5SDimitry Andric Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT); 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric break; 810b57cec5SDimitry Andric default: 820b57cec5SDimitry Andric llvm_unreachable("Invalid Suffix"); 830b57cec5SDimitry Andric } 845ffd83dbSDimitry Andric getStreamer().emitBytes(StringRef(Buffer, Size)); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric // The remaining callbacks should be handled separately by each 880b57cec5SDimitry Andric // streamer. 890b57cec5SDimitry Andric void ARMTargetStreamer::emitFnStart() {} 900b57cec5SDimitry Andric void ARMTargetStreamer::emitFnEnd() {} 910b57cec5SDimitry Andric void ARMTargetStreamer::emitCantUnwind() {} 920b57cec5SDimitry Andric void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) {} 930b57cec5SDimitry Andric void ARMTargetStreamer::emitPersonalityIndex(unsigned Index) {} 940b57cec5SDimitry Andric void ARMTargetStreamer::emitHandlerData() {} 950b57cec5SDimitry Andric void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 960b57cec5SDimitry Andric int64_t Offset) {} 970b57cec5SDimitry Andric void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) {} 980b57cec5SDimitry Andric void ARMTargetStreamer::emitPad(int64_t Offset) {} 990b57cec5SDimitry Andric void ARMTargetStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 1000b57cec5SDimitry Andric bool isVector) {} 1010b57cec5SDimitry Andric void ARMTargetStreamer::emitUnwindRaw(int64_t StackOffset, 1020b57cec5SDimitry Andric const SmallVectorImpl<uint8_t> &Opcodes) { 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric void ARMTargetStreamer::switchVendor(StringRef Vendor) {} 1050b57cec5SDimitry Andric void ARMTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} 1060b57cec5SDimitry Andric void ARMTargetStreamer::emitTextAttribute(unsigned Attribute, 1070b57cec5SDimitry Andric StringRef String) {} 1080b57cec5SDimitry Andric void ARMTargetStreamer::emitIntTextAttribute(unsigned Attribute, 1090b57cec5SDimitry Andric unsigned IntValue, 1100b57cec5SDimitry Andric StringRef StringValue) {} 1110b57cec5SDimitry Andric void ARMTargetStreamer::emitArch(ARM::ArchKind Arch) {} 1125ffd83dbSDimitry Andric void ARMTargetStreamer::emitArchExtension(uint64_t ArchExt) {} 1130b57cec5SDimitry Andric void ARMTargetStreamer::emitObjectArch(ARM::ArchKind Arch) {} 11406c3fb27SDimitry Andric void ARMTargetStreamer::emitFPU(ARM::FPUKind FPU) {} 1150b57cec5SDimitry Andric void ARMTargetStreamer::finishAttributeSection() {} 11681ad6265SDimitry Andric void ARMTargetStreamer::annotateTLSDescriptorSequence( 11781ad6265SDimitry Andric const MCSymbolRefExpr *SRE) {} 1180b57cec5SDimitry Andric void ARMTargetStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {} 1190b57cec5SDimitry Andric 12081ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFIAllocStack(unsigned Size, bool Wide) {} 12181ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) {} 12281ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFISaveSP(unsigned Reg) {} 12381ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFISaveFRegs(unsigned First, unsigned Last) {} 12481ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFISaveLR(unsigned Offset) {} 12581ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFINop(bool Wide) {} 12681ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFIPrologEnd(bool Fragment) {} 12781ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFIEpilogStart(unsigned Condition) {} 12881ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFIEpilogEnd() {} 12981ad6265SDimitry Andric void ARMTargetStreamer::emitARMWinCFICustom(unsigned Opcode) {} 13081ad6265SDimitry Andric 1310b57cec5SDimitry Andric static ARMBuildAttrs::CPUArch getArchForCPU(const MCSubtargetInfo &STI) { 1320b57cec5SDimitry Andric if (STI.getCPU() == "xscale") 1330b57cec5SDimitry Andric return ARMBuildAttrs::v5TEJ; 1340b57cec5SDimitry Andric 13581ad6265SDimitry Andric if (STI.hasFeature(ARM::HasV9_0aOps)) 13681ad6265SDimitry Andric return ARMBuildAttrs::v9_A; 13781ad6265SDimitry Andric else if (STI.hasFeature(ARM::HasV8Ops)) { 1380b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureRClass)) 1390b57cec5SDimitry Andric return ARMBuildAttrs::v8_R; 1400b57cec5SDimitry Andric return ARMBuildAttrs::v8_A; 1410b57cec5SDimitry Andric } else if (STI.hasFeature(ARM::HasV8_1MMainlineOps)) 1420b57cec5SDimitry Andric return ARMBuildAttrs::v8_1_M_Main; 1430b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasV8MMainlineOps)) 1440b57cec5SDimitry Andric return ARMBuildAttrs::v8_M_Main; 1450b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasV7Ops)) { 1460b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureMClass) && STI.hasFeature(ARM::FeatureDSP)) 1470b57cec5SDimitry Andric return ARMBuildAttrs::v7E_M; 1480b57cec5SDimitry Andric return ARMBuildAttrs::v7; 1490b57cec5SDimitry Andric } else if (STI.hasFeature(ARM::HasV6T2Ops)) 1500b57cec5SDimitry Andric return ARMBuildAttrs::v6T2; 1510b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasV8MBaselineOps)) 1520b57cec5SDimitry Andric return ARMBuildAttrs::v8_M_Base; 1530b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasV6MOps)) 1540b57cec5SDimitry Andric return ARMBuildAttrs::v6S_M; 1550b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasV6Ops)) 1560b57cec5SDimitry Andric return ARMBuildAttrs::v6; 1570b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasV5TEOps)) 1580b57cec5SDimitry Andric return ARMBuildAttrs::v5TE; 1590b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasV5TOps)) 1600b57cec5SDimitry Andric return ARMBuildAttrs::v5T; 1610b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasV4TOps)) 1620b57cec5SDimitry Andric return ARMBuildAttrs::v4T; 1630b57cec5SDimitry Andric else 1640b57cec5SDimitry Andric return ARMBuildAttrs::v4; 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric static bool isV8M(const MCSubtargetInfo &STI) { 1680b57cec5SDimitry Andric // Note that v8M Baseline is a subset of v6T2! 1690b57cec5SDimitry Andric return (STI.hasFeature(ARM::HasV8MBaselineOps) && 1700b57cec5SDimitry Andric !STI.hasFeature(ARM::HasV6T2Ops)) || 1710b57cec5SDimitry Andric STI.hasFeature(ARM::HasV8MMainlineOps); 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric /// Emit the build attributes that only depend on the hardware that we expect 1750b57cec5SDimitry Andric // /to be available, and not on the ABI, or any source-language choices. 1760b57cec5SDimitry Andric void ARMTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) { 1770b57cec5SDimitry Andric switchVendor("aeabi"); 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric const StringRef CPUString = STI.getCPU(); 180*5f757f3fSDimitry Andric if (!CPUString.empty() && !CPUString.starts_with("generic")) { 1810b57cec5SDimitry Andric // FIXME: remove krait check when GNU tools support krait cpu 1820b57cec5SDimitry Andric if (STI.hasFeature(ARM::ProcKrait)) { 1830b57cec5SDimitry Andric emitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a9"); 1840b57cec5SDimitry Andric // We consider krait as a "cortex-a9" + hwdiv CPU 1850b57cec5SDimitry Andric // Enable hwdiv through ".arch_extension idiv" 1860b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureHWDivThumb) || 1870b57cec5SDimitry Andric STI.hasFeature(ARM::FeatureHWDivARM)) 1880b57cec5SDimitry Andric emitArchExtension(ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM); 1890b57cec5SDimitry Andric } else { 1900b57cec5SDimitry Andric emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString); 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::CPU_arch, getArchForCPU(STI)); 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureAClass)) { 1970b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::CPU_arch_profile, 1980b57cec5SDimitry Andric ARMBuildAttrs::ApplicationProfile); 1990b57cec5SDimitry Andric } else if (STI.hasFeature(ARM::FeatureRClass)) { 2000b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::CPU_arch_profile, 2010b57cec5SDimitry Andric ARMBuildAttrs::RealTimeProfile); 2020b57cec5SDimitry Andric } else if (STI.hasFeature(ARM::FeatureMClass)) { 2030b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::CPU_arch_profile, 2040b57cec5SDimitry Andric ARMBuildAttrs::MicroControllerProfile); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::ARM_ISA_use, STI.hasFeature(ARM::FeatureNoARM) 2080b57cec5SDimitry Andric ? ARMBuildAttrs::Not_Allowed 2090b57cec5SDimitry Andric : ARMBuildAttrs::Allowed); 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric if (isV8M(STI)) { 2120b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::THUMB_ISA_use, 2130b57cec5SDimitry Andric ARMBuildAttrs::AllowThumbDerived); 2140b57cec5SDimitry Andric } else if (STI.hasFeature(ARM::FeatureThumb2)) { 2150b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::THUMB_ISA_use, 2160b57cec5SDimitry Andric ARMBuildAttrs::AllowThumb32); 2170b57cec5SDimitry Andric } else if (STI.hasFeature(ARM::HasV4TOps)) { 2180b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::THUMB_ISA_use, ARMBuildAttrs::Allowed); 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureNEON)) { 2220b57cec5SDimitry Andric /* NEON is not exactly a VFP architecture, but GAS emit one of 2230b57cec5SDimitry Andric * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */ 2240b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureFPARMv8)) { 2250b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureCrypto)) 2260b57cec5SDimitry Andric emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8); 2270b57cec5SDimitry Andric else 2280b57cec5SDimitry Andric emitFPU(ARM::FK_NEON_FP_ARMV8); 2290b57cec5SDimitry Andric } else if (STI.hasFeature(ARM::FeatureVFP4)) 2300b57cec5SDimitry Andric emitFPU(ARM::FK_NEON_VFPV4); 2310b57cec5SDimitry Andric else 2320b57cec5SDimitry Andric emitFPU(STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_NEON_FP16 2330b57cec5SDimitry Andric : ARM::FK_NEON); 2340b57cec5SDimitry Andric // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture 2350b57cec5SDimitry Andric if (STI.hasFeature(ARM::HasV8Ops)) 2360b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, 2370b57cec5SDimitry Andric STI.hasFeature(ARM::HasV8_1aOps) 2380b57cec5SDimitry Andric ? ARMBuildAttrs::AllowNeonARMv8_1a 2390b57cec5SDimitry Andric : ARMBuildAttrs::AllowNeonARMv8); 2400b57cec5SDimitry Andric } else { 241*5f757f3fSDimitry Andric if (STI.hasFeature(ARM::FeatureFPARMv8_D16_SP)) { 2420b57cec5SDimitry Andric // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one 2430b57cec5SDimitry Andric // FPU, but there are two different names for it depending on the CPU. 244*5f757f3fSDimitry Andric if (STI.hasFeature(ARM::FeatureD32)) 245*5f757f3fSDimitry Andric emitFPU(ARM::FK_FP_ARMV8); 246*5f757f3fSDimitry Andric else { 247*5f757f3fSDimitry Andric emitFPU(STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_FPV5_D16 248*5f757f3fSDimitry Andric : ARM::FK_FPV5_SP_D16); 249*5f757f3fSDimitry Andric if (STI.hasFeature(ARM::HasMVEFloatOps)) 250*5f757f3fSDimitry Andric emitArchExtension(ARM::AEK_SIMD | ARM::AEK_DSP | ARM::AEK_FP); 251*5f757f3fSDimitry Andric } 252*5f757f3fSDimitry Andric } else if (STI.hasFeature(ARM::FeatureVFP4_D16_SP)) 2530b57cec5SDimitry Andric emitFPU(STI.hasFeature(ARM::FeatureD32) 2540b57cec5SDimitry Andric ? ARM::FK_VFPV4 2550b57cec5SDimitry Andric : (STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_VFPV4_D16 2560b57cec5SDimitry Andric : ARM::FK_FPV4_SP_D16)); 2570b57cec5SDimitry Andric else if (STI.hasFeature(ARM::FeatureVFP3_D16_SP)) 2580b57cec5SDimitry Andric emitFPU( 2590b57cec5SDimitry Andric STI.hasFeature(ARM::FeatureD32) 2600b57cec5SDimitry Andric // +d32 2610b57cec5SDimitry Andric ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16 2620b57cec5SDimitry Andric : ARM::FK_VFPV3) 2630b57cec5SDimitry Andric // -d32 2640b57cec5SDimitry Andric : (STI.hasFeature(ARM::FeatureFP64) 2650b57cec5SDimitry Andric ? (STI.hasFeature(ARM::FeatureFP16) 2660b57cec5SDimitry Andric ? ARM::FK_VFPV3_D16_FP16 2670b57cec5SDimitry Andric : ARM::FK_VFPV3_D16) 2680b57cec5SDimitry Andric : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16 2690b57cec5SDimitry Andric : ARM::FK_VFPV3XD))); 2708bcb0991SDimitry Andric else if (STI.hasFeature(ARM::FeatureVFP2_SP)) 2710b57cec5SDimitry Andric emitFPU(ARM::FK_VFPV2); 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric // ABI_HardFP_use attribute to indicate single precision FP. 2758bcb0991SDimitry Andric if (STI.hasFeature(ARM::FeatureVFP2_SP) && !STI.hasFeature(ARM::FeatureFP64)) 2760b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::ABI_HardFP_use, 2770b57cec5SDimitry Andric ARMBuildAttrs::HardFPSinglePrecision); 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureFP16)) 2800b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP); 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureMP)) 2830b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP); 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric if (STI.hasFeature(ARM::HasMVEFloatOps)) 2860b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::MVE_arch, ARMBuildAttrs::AllowMVEIntegerAndFloat); 2870b57cec5SDimitry Andric else if (STI.hasFeature(ARM::HasMVEIntegerOps)) 2880b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::MVE_arch, ARMBuildAttrs::AllowMVEInteger); 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric // Hardware divide in ARM mode is part of base arch, starting from ARMv8. 2910b57cec5SDimitry Andric // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M). 2920b57cec5SDimitry Andric // It is not possible to produce DisallowDIV: if hwdiv is present in the base 2930b57cec5SDimitry Andric // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits. 2940b57cec5SDimitry Andric // AllowDIVExt is only emitted if hwdiv isn't available in the base arch; 2950b57cec5SDimitry Andric // otherwise, the default value (AllowDIVIfExists) applies. 2960b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureHWDivARM) && !STI.hasFeature(ARM::HasV8Ops)) 2970b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureDSP) && isV8M(STI)) 3000b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::DSP_extension, ARMBuildAttrs::Allowed); 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureStrictAlign)) 3030b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::CPU_unaligned_access, 3040b57cec5SDimitry Andric ARMBuildAttrs::Not_Allowed); 3050b57cec5SDimitry Andric else 3060b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::CPU_unaligned_access, 3070b57cec5SDimitry Andric ARMBuildAttrs::Allowed); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric if (STI.hasFeature(ARM::FeatureTrustZone) && 3100b57cec5SDimitry Andric STI.hasFeature(ARM::FeatureVirtualization)) 3110b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::Virtualization_use, 3120b57cec5SDimitry Andric ARMBuildAttrs::AllowTZVirtualization); 3130b57cec5SDimitry Andric else if (STI.hasFeature(ARM::FeatureTrustZone)) 3140b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::Virtualization_use, ARMBuildAttrs::AllowTZ); 3150b57cec5SDimitry Andric else if (STI.hasFeature(ARM::FeatureVirtualization)) 3160b57cec5SDimitry Andric emitAttribute(ARMBuildAttrs::Virtualization_use, 3170b57cec5SDimitry Andric ARMBuildAttrs::AllowVirtualization); 3184824e7fdSDimitry Andric 3194824e7fdSDimitry Andric if (STI.hasFeature(ARM::FeaturePACBTI)) { 3204824e7fdSDimitry Andric emitAttribute(ARMBuildAttrs::PAC_extension, ARMBuildAttrs::AllowPAC); 3214824e7fdSDimitry Andric emitAttribute(ARMBuildAttrs::BTI_extension, ARMBuildAttrs::AllowBTI); 3224824e7fdSDimitry Andric } 3230b57cec5SDimitry Andric } 32481ad6265SDimitry Andric 32581ad6265SDimitry Andric MCTargetStreamer * 32681ad6265SDimitry Andric llvm::createARMObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { 32781ad6265SDimitry Andric const Triple &TT = STI.getTargetTriple(); 32881ad6265SDimitry Andric if (TT.isOSBinFormatELF()) 32981ad6265SDimitry Andric return createARMObjectTargetELFStreamer(S); 33081ad6265SDimitry Andric if (TT.isOSBinFormatCOFF()) 33181ad6265SDimitry Andric return createARMObjectTargetWinCOFFStreamer(S); 33281ad6265SDimitry Andric return new ARMTargetStreamer(S); 33381ad6265SDimitry Andric } 334