blob: 42371736fef451bf2a6872b27bbdbc9b1f3168ee [file] [log] [blame]
David Peixottob9b73622014-02-04 17:22:40 +00001//===- 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//===----------------------------------------------------------------------===//
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000013
Oliver Stannard7ad2e8a2017-04-18 12:52:35 +000014#include "ARMTargetMachine.h"
Weiming Zhao8c899732014-06-18 18:17:25 +000015#include "llvm/MC/ConstantPools.h"
Chandler Carruth442f7842014-03-04 10:07:28 +000016#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCStreamer.h"
Oliver Stannard7ad2e8a2017-04-18 12:52:35 +000018#include "llvm/MC/MCSubtargetInfo.h"
19#include "llvm/Support/ARMBuildAttributes.h"
20#include "llvm/Support/TargetParser.h"
David Peixottob9b73622014-02-04 17:22:40 +000021
22using namespace llvm;
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000023
David Peixottob9b73622014-02-04 17:22:40 +000024//
25// ARMTargetStreamer Implemenation
26//
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000027
David Peixottob9b73622014-02-04 17:22:40 +000028ARMTargetStreamer::ARMTargetStreamer(MCStreamer &S)
29 : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {}
30
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000031ARMTargetStreamer::~ARMTargetStreamer() = default;
David Peixottob9b73622014-02-04 17:22:40 +000032
33// The constant pool handling is shared by all ARMTargetStreamer
34// implementations.
Oliver Stannard9327a752015-11-16 16:25:47 +000035const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc) {
36 return ConstantPools->addEntry(Streamer, Expr, 4, Loc);
David Peixottob9b73622014-02-04 17:22:40 +000037}
38
39void ARMTargetStreamer::emitCurrentConstantPool() {
40 ConstantPools->emitForCurrentSection(Streamer);
James Molloy6110be92017-05-22 09:42:07 +000041 ConstantPools->clearCacheForCurrentSection(Streamer);
David Peixottob9b73622014-02-04 17:22:40 +000042}
43
44// finish() - write out any non-empty assembler constant pools.
45void ARMTargetStreamer::finish() { ConstantPools->emitAll(Streamer); }
46
Keno Fischer00021422016-01-12 13:38:15 +000047// reset() - Reset any state
48void ARMTargetStreamer::reset() {}
49
David Peixottob9b73622014-02-04 17:22:40 +000050// The remaining callbacks should be handled separately by each
51// streamer.
Rafael Espindola1fc003e2014-06-20 13:11:28 +000052void ARMTargetStreamer::emitFnStart() {}
53void ARMTargetStreamer::emitFnEnd() {}
54void ARMTargetStreamer::emitCantUnwind() {}
55void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) {}
56void ARMTargetStreamer::emitPersonalityIndex(unsigned Index) {}
57void ARMTargetStreamer::emitHandlerData() {}
David Peixottob9b73622014-02-04 17:22:40 +000058void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
Rafael Espindola1fc003e2014-06-20 13:11:28 +000059 int64_t Offset) {}
60void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) {}
61void ARMTargetStreamer::emitPad(int64_t Offset) {}
62void ARMTargetStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
63 bool isVector) {}
64void ARMTargetStreamer::emitUnwindRaw(int64_t StackOffset,
65 const SmallVectorImpl<uint8_t> &Opcodes) {
David Peixottob9b73622014-02-04 17:22:40 +000066}
Rafael Espindola1fc003e2014-06-20 13:11:28 +000067void ARMTargetStreamer::switchVendor(StringRef Vendor) {}
68void ARMTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
David Peixottob9b73622014-02-04 17:22:40 +000069void ARMTargetStreamer::emitTextAttribute(unsigned Attribute,
Rafael Espindola1fc003e2014-06-20 13:11:28 +000070 StringRef String) {}
David Peixottob9b73622014-02-04 17:22:40 +000071void ARMTargetStreamer::emitIntTextAttribute(unsigned Attribute,
Rafael Espindola1fc003e2014-06-20 13:11:28 +000072 unsigned IntValue,
73 StringRef StringValue) {}
Florian Hahn67ddd1d2017-07-27 16:27:56 +000074void ARMTargetStreamer::emitArch(ARM::ArchKind Arch) {}
Sumanth Gundapanenia9049ea2015-02-26 18:07:35 +000075void ARMTargetStreamer::emitArchExtension(unsigned ArchExt) {}
Florian Hahn67ddd1d2017-07-27 16:27:56 +000076void ARMTargetStreamer::emitObjectArch(ARM::ArchKind Arch) {}
Rafael Espindola1fc003e2014-06-20 13:11:28 +000077void ARMTargetStreamer::emitFPU(unsigned FPU) {}
78void ARMTargetStreamer::finishAttributeSection() {}
79void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) {}
80void
81ARMTargetStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) {}
Rafael Espindola1fc003e2014-06-20 13:11:28 +000082void ARMTargetStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {}
Oliver Stannard7ad2e8a2017-04-18 12:52:35 +000083
84static ARMBuildAttrs::CPUArch getArchForCPU(const MCSubtargetInfo &STI) {
85 if (STI.getCPU() == "xscale")
86 return ARMBuildAttrs::v5TEJ;
87
88 if (STI.hasFeature(ARM::HasV8Ops)) {
89 if (STI.hasFeature(ARM::FeatureRClass))
90 return ARMBuildAttrs::v8_R;
91 return ARMBuildAttrs::v8_A;
92 } else if (STI.hasFeature(ARM::HasV8MMainlineOps))
93 return ARMBuildAttrs::v8_M_Main;
94 else if (STI.hasFeature(ARM::HasV7Ops)) {
95 if (STI.hasFeature(ARM::FeatureMClass) && STI.hasFeature(ARM::FeatureDSP))
96 return ARMBuildAttrs::v7E_M;
97 return ARMBuildAttrs::v7;
98 } else if (STI.hasFeature(ARM::HasV6T2Ops))
99 return ARMBuildAttrs::v6T2;
100 else if (STI.hasFeature(ARM::HasV8MBaselineOps))
101 return ARMBuildAttrs::v8_M_Base;
102 else if (STI.hasFeature(ARM::HasV6MOps))
103 return ARMBuildAttrs::v6S_M;
104 else if (STI.hasFeature(ARM::HasV6Ops))
105 return ARMBuildAttrs::v6;
106 else if (STI.hasFeature(ARM::HasV5TEOps))
107 return ARMBuildAttrs::v5TE;
108 else if (STI.hasFeature(ARM::HasV5TOps))
109 return ARMBuildAttrs::v5T;
110 else if (STI.hasFeature(ARM::HasV4TOps))
111 return ARMBuildAttrs::v4T;
112 else
113 return ARMBuildAttrs::v4;
114}
115
116static bool isV8M(const MCSubtargetInfo &STI) {
117 // Note that v8M Baseline is a subset of v6T2!
118 return (STI.hasFeature(ARM::HasV8MBaselineOps) &&
119 !STI.hasFeature(ARM::HasV6T2Ops)) ||
120 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.
125void ARMTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
126 switchVendor("aeabi");
127
128 const StringRef CPUString = STI.getCPU();
129 if (!CPUString.empty() && !CPUString.startswith("generic")) {
130 // FIXME: remove krait check when GNU tools support krait cpu
131 if (STI.hasFeature(ARM::ProcKrait)) {
132 emitTextAttribute(ARMBuildAttrs::CPU_name, "cortex-a9");
133 // We consider krait as a "cortex-a9" + hwdiv CPU
134 // Enable hwdiv through ".arch_extension idiv"
Diana Picus7c6dee9f2017-04-20 09:38:25 +0000135 if (STI.hasFeature(ARM::FeatureHWDivThumb) ||
Oliver Stannard7ad2e8a2017-04-18 12:52:35 +0000136 STI.hasFeature(ARM::FeatureHWDivARM))
Diana Picus7c6dee9f2017-04-20 09:38:25 +0000137 emitArchExtension(ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM);
Oliver Stannard7ad2e8a2017-04-18 12:52:35 +0000138 } else {
139 emitTextAttribute(ARMBuildAttrs::CPU_name, CPUString);
140 }
141 }
142
143 emitAttribute(ARMBuildAttrs::CPU_arch, getArchForCPU(STI));
144
145 if (STI.hasFeature(ARM::FeatureAClass)) {
146 emitAttribute(ARMBuildAttrs::CPU_arch_profile,
147 ARMBuildAttrs::ApplicationProfile);
148 } else if (STI.hasFeature(ARM::FeatureRClass)) {
149 emitAttribute(ARMBuildAttrs::CPU_arch_profile,
150 ARMBuildAttrs::RealTimeProfile);
151 } else if (STI.hasFeature(ARM::FeatureMClass)) {
152 emitAttribute(ARMBuildAttrs::CPU_arch_profile,
153 ARMBuildAttrs::MicroControllerProfile);
154 }
155
156 emitAttribute(ARMBuildAttrs::ARM_ISA_use, STI.hasFeature(ARM::FeatureNoARM)
157 ? ARMBuildAttrs::Not_Allowed
158 : ARMBuildAttrs::Allowed);
159
160 if (isV8M(STI)) {
161 emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
162 ARMBuildAttrs::AllowThumbDerived);
163 } else if (STI.hasFeature(ARM::FeatureThumb2)) {
164 emitAttribute(ARMBuildAttrs::THUMB_ISA_use,
165 ARMBuildAttrs::AllowThumb32);
166 } else if (STI.hasFeature(ARM::HasV4TOps)) {
167 emitAttribute(ARMBuildAttrs::THUMB_ISA_use, ARMBuildAttrs::Allowed);
168 }
169
170 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 if (STI.hasFeature(ARM::FeatureFPARMv8)) {
174 if (STI.hasFeature(ARM::FeatureCrypto))
175 emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8);
176 else
177 emitFPU(ARM::FK_NEON_FP_ARMV8);
178 } else if (STI.hasFeature(ARM::FeatureVFP4))
179 emitFPU(ARM::FK_NEON_VFPV4);
180 else
181 emitFPU(STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_NEON_FP16
182 : ARM::FK_NEON);
183 // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
184 if (STI.hasFeature(ARM::HasV8Ops))
185 emitAttribute(ARMBuildAttrs::Advanced_SIMD_arch,
186 STI.hasFeature(ARM::HasV8_1aOps)
187 ? ARMBuildAttrs::AllowNeonARMv8_1a
188 : ARMBuildAttrs::AllowNeonARMv8);
189 } else {
190 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 emitFPU(STI.hasFeature(ARM::FeatureD16)
194 ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV5_SP_D16
195 : ARM::FK_FPV5_D16)
196 : ARM::FK_FP_ARMV8);
197 else if (STI.hasFeature(ARM::FeatureVFP4))
198 emitFPU(STI.hasFeature(ARM::FeatureD16)
199 ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV4_SP_D16
200 : ARM::FK_VFPV4_D16)
201 : ARM::FK_VFPV4);
202 else if (STI.hasFeature(ARM::FeatureVFP3))
203 emitFPU(
204 STI.hasFeature(ARM::FeatureD16)
205 // +d16
206 ? (STI.hasFeature(ARM::FeatureVFPOnlySP)
207 ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
208 : ARM::FK_VFPV3XD)
209 : (STI.hasFeature(ARM::FeatureFP16)
210 ? ARM::FK_VFPV3_D16_FP16
211 : ARM::FK_VFPV3_D16))
212 // -d16
213 : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16
214 : ARM::FK_VFPV3));
215 else if (STI.hasFeature(ARM::FeatureVFP2))
216 emitFPU(ARM::FK_VFPV2);
217 }
218
219 // ABI_HardFP_use attribute to indicate single precision FP.
220 if (STI.hasFeature(ARM::FeatureVFPOnlySP))
221 emitAttribute(ARMBuildAttrs::ABI_HardFP_use,
222 ARMBuildAttrs::HardFPSinglePrecision);
223
224 if (STI.hasFeature(ARM::FeatureFP16))
225 emitAttribute(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP);
226
227 if (STI.hasFeature(ARM::FeatureMP))
228 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 if (STI.hasFeature(ARM::FeatureHWDivARM) && !STI.hasFeature(ARM::HasV8Ops))
237 emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt);
238
239 if (STI.hasFeature(ARM::FeatureDSP) && isV8M(STI))
240 emitAttribute(ARMBuildAttrs::DSP_extension, ARMBuildAttrs::Allowed);
241
242 if (STI.hasFeature(ARM::FeatureStrictAlign))
243 emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
244 ARMBuildAttrs::Not_Allowed);
245 else
246 emitAttribute(ARMBuildAttrs::CPU_unaligned_access,
247 ARMBuildAttrs::Allowed);
248
249 if (STI.hasFeature(ARM::FeatureTrustZone) &&
250 STI.hasFeature(ARM::FeatureVirtualization))
251 emitAttribute(ARMBuildAttrs::Virtualization_use,
252 ARMBuildAttrs::AllowTZVirtualization);
253 else if (STI.hasFeature(ARM::FeatureTrustZone))
254 emitAttribute(ARMBuildAttrs::Virtualization_use, ARMBuildAttrs::AllowTZ);
255 else if (STI.hasFeature(ARM::FeatureVirtualization))
256 emitAttribute(ARMBuildAttrs::Virtualization_use,
257 ARMBuildAttrs::AllowVirtualization);
258}