/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | ARMTargetStreamer::ARMTargetStreamer(MCStreamer &S) |
29 | 6.06k | : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {} |
30 | | |
31 | 6.03k | 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 | 290 | return ConstantPools->addEntry(Streamer, Expr, 4, Loc); |
37 | 290 | } |
38 | | |
39 | 44 | void ARMTargetStreamer::emitCurrentConstantPool() { |
40 | 44 | ConstantPools->emitForCurrentSection(Streamer); |
41 | 44 | ConstantPools->clearCacheForCurrentSection(Streamer); |
42 | 44 | } |
43 | | |
44 | | // finish() - write out any non-empty assembler constant pools. |
45 | 5.67k | 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 | | 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 | | void ARMTargetStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, |
63 | 0 | bool isVector) {} |
64 | | void ARMTargetStreamer::emitUnwindRaw(int64_t StackOffset, |
65 | 0 | const SmallVectorImpl<uint8_t> &Opcodes) { |
66 | 0 | } |
67 | 652 | void ARMTargetStreamer::switchVendor(StringRef Vendor) {} |
68 | 4.42k | void ARMTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} |
69 | | void ARMTargetStreamer::emitTextAttribute(unsigned Attribute, |
70 | 417 | StringRef String) {} |
71 | | 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 | 596 | void ARMTargetStreamer::emitFPU(unsigned FPU) {} |
78 | 1.86k | 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 | 2.41k | static ARMBuildAttrs::CPUArch getArchForCPU(const MCSubtargetInfo &STI) { |
85 | 2.41k | if (STI.getCPU() == "xscale") |
86 | 1 | return ARMBuildAttrs::v5TEJ; |
87 | 2.41k | |
88 | 2.41k | if (2.41k STI.hasFeature(ARM::HasV8Ops)2.41k ) { |
89 | 118 | if (STI.hasFeature(ARM::FeatureRClass)) |
90 | 4 | return ARMBuildAttrs::v8_R; |
91 | 114 | return ARMBuildAttrs::v8_A; |
92 | 2.29k | } else if (2.29k STI.hasFeature(ARM::HasV8MMainlineOps)2.29k ) |
93 | 27 | return ARMBuildAttrs::v8_M_Main; |
94 | 2.27k | else if (2.27k STI.hasFeature(ARM::HasV7Ops)2.27k ) { |
95 | 1.44k | if (STI.hasFeature(ARM::FeatureMClass) && 1.44k STI.hasFeature(ARM::FeatureDSP)241 ) |
96 | 139 | return ARMBuildAttrs::v7E_M; |
97 | 1.30k | return ARMBuildAttrs::v7; |
98 | 826 | } else if (826 STI.hasFeature(ARM::HasV6T2Ops)826 ) |
99 | 105 | return ARMBuildAttrs::v6T2; |
100 | 721 | else if (721 STI.hasFeature(ARM::HasV8MBaselineOps)721 ) |
101 | 18 | return ARMBuildAttrs::v8_M_Base; |
102 | 703 | else if (703 STI.hasFeature(ARM::HasV6MOps)703 ) |
103 | 75 | return ARMBuildAttrs::v6S_M; |
104 | 628 | else if (628 STI.hasFeature(ARM::HasV6Ops)628 ) |
105 | 80 | return ARMBuildAttrs::v6; |
106 | 548 | else if (548 STI.hasFeature(ARM::HasV5TEOps)548 ) |
107 | 12 | return ARMBuildAttrs::v5TE; |
108 | 536 | else if (536 STI.hasFeature(ARM::HasV5TOps)536 ) |
109 | 16 | return ARMBuildAttrs::v5T; |
110 | 520 | else if (520 STI.hasFeature(ARM::HasV4TOps)520 ) |
111 | 97 | return ARMBuildAttrs::v4T; |
112 | 520 | else |
113 | 423 | return ARMBuildAttrs::v4; |
114 | 0 | } |
115 | | |
116 | 3.97k | static bool isV8M(const MCSubtargetInfo &STI) { |
117 | 3.97k | // Note that v8M Baseline is a subset of v6T2! |
118 | 3.97k | return (STI.hasFeature(ARM::HasV8MBaselineOps) && |
119 | 3.26k | !STI.hasFeature(ARM::HasV6T2Ops)) || |
120 | 3.95k | STI.hasFeature(ARM::HasV8MMainlineOps); |
121 | 3.97k | } |
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 | 2.41k | void ARMTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) { |
126 | 2.41k | switchVendor("aeabi"); |
127 | 2.41k | |
128 | 2.41k | const StringRef CPUString = STI.getCPU(); |
129 | 2.41k | if (!CPUString.empty() && 2.41k !CPUString.startswith("generic")1.17k ) { |
130 | 933 | // FIXME: remove krait check when GNU tools support krait cpu |
131 | 933 | if (STI.hasFeature(ARM::ProcKrait)933 ) { |
132 | 6 | emitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a9"); |
133 | 6 | // We consider krait as a "cortex-a9" + hwdiv CPU |
134 | 6 | // Enable hwdiv through ".arch_extension idiv" |
135 | 6 | if (STI.hasFeature(ARM::FeatureHWDivThumb) || |
136 | 1 | STI.hasFeature(ARM::FeatureHWDivARM)) |
137 | 5 | emitArchExtension(ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM); |
138 | 933 | } else { |
139 | 927 | emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString); |
140 | 927 | } |
141 | 933 | } |
142 | 2.41k | |
143 | 2.41k | emitAttribute(ARMBuildAttrs::CPU_arch, getArchForCPU(STI)); |
144 | 2.41k | |
145 | 2.41k | if (STI.hasFeature(ARM::FeatureAClass)2.41k ) { |
146 | 1.28k | emitAttribute(ARMBuildAttrs::CPU_arch_profile, |
147 | 1.28k | ARMBuildAttrs::ApplicationProfile); |
148 | 2.41k | } else if (1.13k STI.hasFeature(ARM::FeatureRClass)1.13k ) { |
149 | 17 | emitAttribute(ARMBuildAttrs::CPU_arch_profile, |
150 | 17 | ARMBuildAttrs::RealTimeProfile); |
151 | 1.13k | } else if (1.11k STI.hasFeature(ARM::FeatureMClass)1.11k ) { |
152 | 361 | emitAttribute(ARMBuildAttrs::CPU_arch_profile, |
153 | 361 | ARMBuildAttrs::MicroControllerProfile); |
154 | 361 | } |
155 | 2.41k | |
156 | 2.41k | emitAttribute(ARMBuildAttrs::ARM_ISA_use, STI.hasFeature(ARM::FeatureNoARM) |
157 | 361 | ? ARMBuildAttrs::Not_Allowed |
158 | 2.05k | : ARMBuildAttrs::Allowed); |
159 | 2.41k | |
160 | 2.41k | if (isV8M(STI)2.41k ) { |
161 | 45 | emitAttribute(ARMBuildAttrs::THUMB_ISA_use, |
162 | 45 | ARMBuildAttrs::AllowThumbDerived); |
163 | 2.41k | } else if (2.37k STI.hasFeature(ARM::FeatureThumb2)2.37k ) { |
164 | 1.66k | emitAttribute(ARMBuildAttrs::THUMB_ISA_use, |
165 | 1.66k | ARMBuildAttrs::AllowThumb32); |
166 | 2.37k | } else if (704 STI.hasFeature(ARM::HasV4TOps)704 ) { |
167 | 281 | emitAttribute(ARMBuildAttrs::THUMB_ISA_use, ARMBuildAttrs::Allowed); |
168 | 281 | } |
169 | 2.41k | |
170 | 2.41k | if (STI.hasFeature(ARM::FeatureNEON)2.41k ) { |
171 | 1.29k | /* NEON is not exactly a VFP architecture, but GAS emit one of |
172 | 1.29k | * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */ |
173 | 1.29k | if (STI.hasFeature(ARM::FeatureFPARMv8)1.29k ) { |
174 | 116 | if (STI.hasFeature(ARM::FeatureCrypto)) |
175 | 111 | emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8); |
176 | 116 | else |
177 | 5 | emitFPU(ARM::FK_NEON_FP_ARMV8); |
178 | 1.29k | } else if (1.18k STI.hasFeature(ARM::FeatureVFP4)1.18k ) |
179 | 369 | emitFPU(ARM::FK_NEON_VFPV4); |
180 | 1.18k | else |
181 | 812 | emitFPU(STI.hasFeature(ARM::FeatureFP16) ? 812 ARM::FK_NEON_FP1645 |
182 | 1.18k | : ARM::FK_NEON); |
183 | 1.29k | // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture |
184 | 1.29k | if (STI.hasFeature(ARM::HasV8Ops)) |
185 | 115 | emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch, |
186 | 115 | STI.hasFeature(ARM::HasV8_1aOps) |
187 | 7 | ? ARMBuildAttrs::AllowNeonARMv8_1a |
188 | 115 | : ARMBuildAttrs::AllowNeonARMv8); |
189 | 2.41k | } else { |
190 | 1.12k | if (STI.hasFeature(ARM::FeatureFPARMv8)) |
191 | 1.12k | // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one |
192 | 1.12k | // FPU, but there are two different names for it depending on the CPU. |
193 | 25 | emitFPU(STI.hasFeature(ARM::FeatureD16) |
194 | 20 | ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? 20 ARM::FK_FPV5_SP_D1612 |
195 | 20 | : ARM::FK_FPV5_D16) |
196 | 25 | : ARM::FK_FP_ARMV8); |
197 | 1.09k | else if (1.09k STI.hasFeature(ARM::FeatureVFP4)1.09k ) |
198 | 119 | emitFPU(STI.hasFeature(ARM::FeatureD16) |
199 | 117 | ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? 117 ARM::FK_FPV4_SP_D16115 |
200 | 117 | : ARM::FK_VFPV4_D16) |
201 | 119 | : ARM::FK_VFPV4); |
202 | 977 | else if (977 STI.hasFeature(ARM::FeatureVFP3)977 ) |
203 | 103 | emitFPU( |
204 | 103 | STI.hasFeature(ARM::FeatureD16) |
205 | 103 | // +d16 |
206 | 15 | ? (STI.hasFeature(ARM::FeatureVFPOnlySP) |
207 | 2 | ? (STI.hasFeature(ARM::FeatureFP16) ? 2 ARM::FK_VFPV3XD_FP161 |
208 | 2 | : ARM::FK_VFPV3XD) |
209 | 13 | : (STI.hasFeature(ARM::FeatureFP16) |
210 | 7 | ? ARM::FK_VFPV3_D16_FP16 |
211 | 15 | : ARM::FK_VFPV3_D16)) |
212 | 103 | // -d16 |
213 | 88 | : (STI.hasFeature(ARM::FeatureFP16) ? 88 ARM::FK_VFPV3_FP161 |
214 | 103 | : ARM::FK_VFPV3)); |
215 | 874 | else if (874 STI.hasFeature(ARM::FeatureVFP2)874 ) |
216 | 58 | emitFPU(ARM::FK_VFPV2); |
217 | 1.12k | } |
218 | 2.41k | |
219 | 2.41k | // ABI_HardFP_use attribute to indicate single precision FP. |
220 | 2.41k | if (STI.hasFeature(ARM::FeatureVFPOnlySP)) |
221 | 132 | emitAttribute(ARMBuildAttrs::ABI_HardFP_use, |
222 | 132 | ARMBuildAttrs::HardFPSinglePrecision); |
223 | 2.41k | |
224 | 2.41k | if (STI.hasFeature(ARM::FeatureFP16)) |
225 | 692 | emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP); |
226 | 2.41k | |
227 | 2.41k | if (STI.hasFeature(ARM::FeatureMP)) |
228 | 537 | emitAttribute(ARMBuildAttrs::MPextension_use, ARMBuildAttrs::AllowMP); |
229 | 2.41k | |
230 | 2.41k | // Hardware divide in ARM mode is part of base arch, starting from ARMv8. |
231 | 2.41k | // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M). |
232 | 2.41k | // It is not possible to produce DisallowDIV: if hwdiv is present in the base |
233 | 2.41k | // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits. |
234 | 2.41k | // AllowDIVExt is only emitted if hwdiv isn't available in the base arch; |
235 | 2.41k | // otherwise, the default value (AllowDIVIfExists) applies. |
236 | 2.41k | if (STI.hasFeature(ARM::FeatureHWDivARM) && 2.41k !STI.hasFeature(ARM::HasV8Ops)505 ) |
237 | 387 | emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt); |
238 | 2.41k | |
239 | 2.41k | if (STI.hasFeature(ARM::FeatureDSP) && 2.41k isV8M(STI)1.55k ) |
240 | 14 | emitAttribute(ARMBuildAttrs::DSP_extension, ARMBuildAttrs::Allowed); |
241 | 2.41k | |
242 | 2.41k | if (STI.hasFeature(ARM::FeatureStrictAlign)) |
243 | 447 | emitAttribute(ARMBuildAttrs::CPU_unaligned_access, |
244 | 447 | ARMBuildAttrs::Not_Allowed); |
245 | 2.41k | else |
246 | 1.97k | emitAttribute(ARMBuildAttrs::CPU_unaligned_access, |
247 | 1.97k | ARMBuildAttrs::Allowed); |
248 | 2.41k | |
249 | 2.41k | if (STI.hasFeature(ARM::FeatureTrustZone) && |
250 | 517 | STI.hasFeature(ARM::FeatureVirtualization)) |
251 | 364 | emitAttribute(ARMBuildAttrs::Virtualization_use, |
252 | 364 | ARMBuildAttrs::AllowTZVirtualization); |
253 | 2.05k | else if (2.05k STI.hasFeature(ARM::FeatureTrustZone)2.05k ) |
254 | 153 | emitAttribute(ARMBuildAttrs::Virtualization_use, ARMBuildAttrs::AllowTZ); |
255 | 1.90k | else if (1.90k STI.hasFeature(ARM::FeatureVirtualization)1.90k ) |
256 | 4 | emitAttribute(ARMBuildAttrs::Virtualization_use, |
257 | 4 | ARMBuildAttrs::AllowVirtualization); |
258 | 2.41k | } |