LCOV - code coverage report
Current view: top level - lib/Target/ARM/MCTargetDesc - ARMTargetStreamer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 123 144 85.4 %
Date: 2017-09-14 15:23:50 Functions: 13 30 43.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ARMTargetStreamer.cpp - ARMTargetStreamer class --*- C++ -*---------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file implements the ARMTargetStreamer class.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "ARMTargetMachine.h"
      15             : #include "llvm/MC/ConstantPools.h"
      16             : #include "llvm/MC/MCExpr.h"
      17             : #include "llvm/MC/MCStreamer.h"
      18             : #include "llvm/MC/MCSubtargetInfo.h"
      19             : #include "llvm/Support/ARMBuildAttributes.h"
      20             : #include "llvm/Support/TargetParser.h"
      21             : 
      22             : using namespace llvm;
      23             : 
      24             : //
      25             : // ARMTargetStreamer Implemenation
      26             : //
      27             : 
      28        3591 : ARMTargetStreamer::ARMTargetStreamer(MCStreamer &S)
      29       10773 :     : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {}
      30             : 
      31             : ARMTargetStreamer::~ARMTargetStreamer() = default;
      32             : 
      33             : // The constant pool handling is shared by all ARMTargetStreamer
      34             : // implementations.
      35         290 : const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc) {
      36         580 :   return ConstantPools->addEntry(Streamer, Expr, 4, Loc);
      37             : }
      38             : 
      39          44 : void ARMTargetStreamer::emitCurrentConstantPool() {
      40          88 :   ConstantPools->emitForCurrentSection(Streamer);
      41          88 :   ConstantPools->clearCacheForCurrentSection(Streamer);
      42          44 : }
      43             : 
      44             : // finish() - write out any non-empty assembler constant pools.
      45        6430 : void ARMTargetStreamer::finish() { ConstantPools->emitAll(Streamer); }
      46             : 
      47             : // reset() - Reset any state
      48           0 : void ARMTargetStreamer::reset() {}
      49             : 
      50             : // The remaining callbacks should be handled separately by each
      51             : // streamer.
      52           3 : void ARMTargetStreamer::emitFnStart() {}
      53           1 : void ARMTargetStreamer::emitFnEnd() {}
      54           0 : void ARMTargetStreamer::emitCantUnwind() {}
      55           0 : void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) {}
      56           0 : void ARMTargetStreamer::emitPersonalityIndex(unsigned Index) {}
      57           0 : void ARMTargetStreamer::emitHandlerData() {}
      58           0 : void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
      59           0 :                                   int64_t Offset) {}
      60           0 : void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) {}
      61           0 : void ARMTargetStreamer::emitPad(int64_t Offset) {}
      62           0 : void ARMTargetStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
      63           0 :                                     bool isVector) {}
      64           0 : void ARMTargetStreamer::emitUnwindRaw(int64_t StackOffset,
      65             :                                       const SmallVectorImpl<uint8_t> &Opcodes) {
      66           0 : }
      67           2 : void ARMTargetStreamer::switchVendor(StringRef Vendor) {}
      68          11 : void ARMTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
      69           1 : void ARMTargetStreamer::emitTextAttribute(unsigned Attribute,
      70           1 :                                           StringRef String) {}
      71           0 : void ARMTargetStreamer::emitIntTextAttribute(unsigned Attribute,
      72             :                                              unsigned IntValue,
      73           0 :                                              StringRef StringValue) {}
      74           0 : void ARMTargetStreamer::emitArch(ARM::ArchKind Arch) {}
      75           2 : void ARMTargetStreamer::emitArchExtension(unsigned ArchExt) {}
      76           0 : void ARMTargetStreamer::emitObjectArch(ARM::ArchKind Arch) {}
      77           0 : void ARMTargetStreamer::emitFPU(unsigned FPU) {}
      78          59 : void ARMTargetStreamer::finishAttributeSection() {}
      79           0 : void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) {}
      80             : void
      81           0 : ARMTargetStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) {}
      82           0 : void ARMTargetStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {}
      83             : 
      84        1760 : static ARMBuildAttrs::CPUArch getArchForCPU(const MCSubtargetInfo &STI) {
      85        3520 :   if (STI.getCPU() == "xscale")
      86             :     return ARMBuildAttrs::v5TEJ;
      87             : 
      88        1759 :   if (STI.hasFeature(ARM::HasV8Ops)) {
      89         118 :     if (STI.hasFeature(ARM::FeatureRClass))
      90             :       return ARMBuildAttrs::v8_R;
      91         114 :     return ARMBuildAttrs::v8_A;
      92        1641 :   } else if (STI.hasFeature(ARM::HasV8MMainlineOps))
      93             :     return ARMBuildAttrs::v8_M_Main;
      94        1614 :   else if (STI.hasFeature(ARM::HasV7Ops)) {
      95         901 :     if (STI.hasFeature(ARM::FeatureMClass) && STI.hasFeature(ARM::FeatureDSP))
      96             :       return ARMBuildAttrs::v7E_M;
      97             :     return ARMBuildAttrs::v7;
      98         816 :   } else if (STI.hasFeature(ARM::HasV6T2Ops))
      99             :     return ARMBuildAttrs::v6T2;
     100         711 :   else if (STI.hasFeature(ARM::HasV8MBaselineOps))
     101             :     return ARMBuildAttrs::v8_M_Base;
     102         693 :   else if (STI.hasFeature(ARM::HasV6MOps))
     103             :     return ARMBuildAttrs::v6S_M;
     104         627 :   else if (STI.hasFeature(ARM::HasV6Ops))
     105             :     return ARMBuildAttrs::v6;
     106         547 :   else if (STI.hasFeature(ARM::HasV5TEOps))
     107             :     return ARMBuildAttrs::v5TE;
     108         535 :   else if (STI.hasFeature(ARM::HasV5TOps))
     109             :     return ARMBuildAttrs::v5T;
     110         519 :   else if (STI.hasFeature(ARM::HasV4TOps))
     111             :     return ARMBuildAttrs::v4T;
     112             :   else
     113         422 :     return ARMBuildAttrs::v4;
     114             : }
     115             : 
     116             : static bool isV8M(const MCSubtargetInfo &STI) {
     117             :   // Note that v8M Baseline is a subset of v6T2!
     118        4732 :   return (STI.hasFeature(ARM::HasV8MBaselineOps) &&
     119        7430 :           !STI.hasFeature(ARM::HasV6T2Ops)) ||
     120        2698 :          STI.hasFeature(ARM::HasV8MMainlineOps);
     121             : }
     122             : 
     123             : /// Emit the build attributes that only depend on the hardware that we expect
     124             : // /to be available, and not on the ABI, or any source-language choices.
     125        1760 : void ARMTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
     126        3520 :   switchVendor("aeabi");
     127             : 
     128        1760 :   const StringRef CPUString = STI.getCPU();
     129        1760 :   if (!CPUString.empty() && !CPUString.startswith("generic")) {
     130             :     // FIXME: remove krait check when GNU tools support krait cpu
     131         517 :     if (STI.hasFeature(ARM::ProcKrait)) {
     132          12 :       emitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a9");
     133             :       // We consider krait as a "cortex-a9" + hwdiv CPU
     134             :       // Enable hwdiv through ".arch_extension idiv"
     135           7 :       if (STI.hasFeature(ARM::FeatureHWDivThumb) ||
     136           1 :           STI.hasFeature(ARM::FeatureHWDivARM))
     137           5 :         emitArchExtension(ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM);
     138             :     } else {
     139         511 :       emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
     140             :     }
     141             :   }
     142             : 
     143        1760 :   emitAttribute(ARMBuildAttrs::CPU_arch, getArchForCPU(STI));
     144             : 
     145        1760 :   if (STI.hasFeature(ARM::FeatureAClass)) {
     146         775 :     emitAttribute(ARMBuildAttrs::CPU_arch_profile,
     147         775 :                       ARMBuildAttrs::ApplicationProfile);
     148         985 :   } else if (STI.hasFeature(ARM::FeatureRClass)) {
     149          17 :     emitAttribute(ARMBuildAttrs::CPU_arch_profile,
     150          17 :                       ARMBuildAttrs::RealTimeProfile);
     151         968 :   } else if (STI.hasFeature(ARM::FeatureMClass)) {
     152         214 :     emitAttribute(ARMBuildAttrs::CPU_arch_profile,
     153         214 :                       ARMBuildAttrs::MicroControllerProfile);
     154             :   }
     155             : 
     156        1760 :   emitAttribute(ARMBuildAttrs::ARM_ISA_use, STI.hasFeature(ARM::FeatureNoARM)
     157             :                                                 ? ARMBuildAttrs::Not_Allowed
     158        1760 :                                                 : ARMBuildAttrs::Allowed);
     159             : 
     160        1715 :   if (isV8M(STI)) {
     161          45 :     emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
     162          45 :                       ARMBuildAttrs::AllowThumbDerived);
     163        1715 :   } else if (STI.hasFeature(ARM::FeatureThumb2)) {
     164        1021 :     emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
     165        1021 :                       ARMBuildAttrs::AllowThumb32);
     166         694 :   } else if (STI.hasFeature(ARM::HasV4TOps)) {
     167         272 :     emitAttribute(ARMBuildAttrs::THUMB_ISA_use, ARMBuildAttrs::Allowed);
     168             :   }
     169             : 
     170        1760 :   if (STI.hasFeature(ARM::FeatureNEON)) {
     171             :     /* NEON is not exactly a VFP architecture, but GAS emit one of
     172             :      * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
     173         852 :     if (STI.hasFeature(ARM::FeatureFPARMv8)) {
     174         115 :       if (STI.hasFeature(ARM::FeatureCrypto))
     175         110 :         emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8);
     176             :       else
     177           5 :         emitFPU(ARM::FK_NEON_FP_ARMV8);
     178         737 :     } else if (STI.hasFeature(ARM::FeatureVFP4))
     179          99 :       emitFPU(ARM::FK_NEON_VFPV4);
     180             :     else
     181         638 :       emitFPU(STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_NEON_FP16
     182         638 :                                                : ARM::FK_NEON);
     183             :     // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
     184         852 :     if (STI.hasFeature(ARM::HasV8Ops))
     185         114 :       emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
     186         114 :                     STI.hasFeature(ARM::HasV8_1aOps)
     187             :                         ? ARMBuildAttrs::AllowNeonARMv8_1a
     188         114 :                         : ARMBuildAttrs::AllowNeonARMv8);
     189             :   } else {
     190         908 :     if (STI.hasFeature(ARM::FeatureFPARMv8))
     191             :       // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
     192             :       // FPU, but there are two different names for it depending on the CPU.
     193          52 :       emitFPU(STI.hasFeature(ARM::FeatureD16)
     194          20 :                   ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV5_SP_D16
     195             :                                                            : ARM::FK_FPV5_D16)
     196          26 :                   : ARM::FK_FP_ARMV8);
     197         882 :     else if (STI.hasFeature(ARM::FeatureVFP4))
     198          54 :       emitFPU(STI.hasFeature(ARM::FeatureD16)
     199          25 :                   ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV4_SP_D16
     200             :                                                            : ARM::FK_VFPV4_D16)
     201          27 :                   : ARM::FK_VFPV4);
     202         855 :     else if (STI.hasFeature(ARM::FeatureVFP3))
     203          72 :       emitFPU(
     204          36 :           STI.hasFeature(ARM::FeatureD16)
     205             :               // +d16
     206          51 :               ? (STI.hasFeature(ARM::FeatureVFPOnlySP)
     207           2 :                      ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
     208             :                                                          : ARM::FK_VFPV3XD)
     209          13 :                      : (STI.hasFeature(ARM::FeatureFP16)
     210             :                             ? ARM::FK_VFPV3_D16_FP16
     211             :                             : ARM::FK_VFPV3_D16))
     212             :               // -d16
     213          21 :               : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16
     214          36 :                                                   : ARM::FK_VFPV3));
     215         819 :     else if (STI.hasFeature(ARM::FeatureVFP2))
     216          58 :       emitFPU(ARM::FK_VFPV2);
     217             :   }
     218             : 
     219             :   // ABI_HardFP_use attribute to indicate single precision FP.
     220        1760 :   if (STI.hasFeature(ARM::FeatureVFPOnlySP))
     221          40 :     emitAttribute(ARMBuildAttrs::ABI_HardFP_use,
     222          40 :                   ARMBuildAttrs::HardFPSinglePrecision);
     223             : 
     224        1760 :   if (STI.hasFeature(ARM::FeatureFP16))
     225         330 :     emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP);
     226             : 
     227        1760 :   if (STI.hasFeature(ARM::FeatureMP))
     228         267 :     emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP);
     229             : 
     230             :   // Hardware divide in ARM mode is part of base arch, starting from ARMv8.
     231             :   // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M).
     232             :   // It is not possible to produce DisallowDIV: if hwdiv is present in the base
     233             :   // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits.
     234             :   // AllowDIVExt is only emitted if hwdiv isn't available in the base arch;
     235             :   // otherwise, the default value (AllowDIVIfExists) applies.
     236        1995 :   if (STI.hasFeature(ARM::FeatureHWDivARM) && !STI.hasFeature(ARM::HasV8Ops))
     237         117 :     emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt);
     238             : 
     239        1760 :   if (STI.hasFeature(ARM::FeatureDSP) && isV8M(STI))
     240          14 :     emitAttribute(ARMBuildAttrs::DSP_extension, ARMBuildAttrs::Allowed);
     241             : 
     242        1760 :   if (STI.hasFeature(ARM::FeatureStrictAlign))
     243          73 :     emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
     244          73 :                   ARMBuildAttrs::Not_Allowed);
     245             :   else
     246        1687 :     emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
     247        1687 :                   ARMBuildAttrs::Allowed);
     248             : 
     249        2109 :   if (STI.hasFeature(ARM::FeatureTrustZone) &&
     250         349 :       STI.hasFeature(ARM::FeatureVirtualization))
     251         196 :     emitAttribute(ARMBuildAttrs::Virtualization_use,
     252         196 :                   ARMBuildAttrs::AllowTZVirtualization);
     253        1564 :   else if (STI.hasFeature(ARM::FeatureTrustZone))
     254         153 :     emitAttribute(ARMBuildAttrs::Virtualization_use, ARMBuildAttrs::AllowTZ);
     255        1411 :   else if (STI.hasFeature(ARM::FeatureVirtualization))
     256           4 :     emitAttribute(ARMBuildAttrs::Virtualization_use,
     257           4 :                   ARMBuildAttrs::AllowVirtualization);
     258        1760 : }

Generated by: LCOV version 1.13