LLVM 17.0.0git
ARMTargetStreamer.cpp
Go to the documentation of this file.
1//===- ARMTargetStreamer.cpp - ARMTargetStreamer class --*- C++ -*---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the ARMTargetStreamer class.
10//
11//===----------------------------------------------------------------------===//
12
15#include "llvm/MC/MCAsmInfo.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCStreamer.h"
22
23using namespace llvm;
24
25//
26// ARMTargetStreamer Implemenation
27//
28
30 : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {}
31
33
34// The constant pool handling is shared by all ARMTargetStreamer
35// implementations.
37 return ConstantPools->addEntry(Streamer, Expr, 4, Loc);
38}
39
41 ConstantPools->emitForCurrentSection(Streamer);
42 ConstantPools->clearCacheForCurrentSection(Streamer);
43}
44
45// finish() - write out any non-empty assembler constant pools.
47 ConstantPools->emitAll(Streamer);
48}
49
50// reset() - Reset any state
52
53void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) {
54 unsigned Size;
55 char Buffer[4];
56 const bool LittleEndian = getStreamer().getContext().getAsmInfo()->isLittleEndian();
57
58 switch (Suffix) {
59 case '\0':
60 Size = 4;
61
62 for (unsigned II = 0, IE = Size; II != IE; II++) {
63 const unsigned I = LittleEndian ? (Size - II - 1) : II;
64 Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
65 }
66
67 break;
68 case 'n':
69 case 'w':
70 Size = (Suffix == 'n' ? 2 : 4);
71
72 // Thumb wide instructions are emitted as a pair of 16-bit words of the
73 // appropriate endianness.
74 for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
75 const unsigned I0 = LittleEndian ? II + 0 : II + 1;
76 const unsigned I1 = LittleEndian ? II + 1 : II + 0;
77 Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
78 Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
79 }
80
81 break;
82 default:
83 llvm_unreachable("Invalid Suffix");
84 }
86}
87
88// The remaining callbacks should be handled separately by each
89// streamer.
96void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
97 int64_t Offset) {}
98void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) {}
101 bool isVector) {}
103 const SmallVectorImpl<uint8_t> &Opcodes) {
104}
108 StringRef String) {}
110 unsigned IntValue,
111 StringRef StringValue) {}
115void ARMTargetStreamer::emitFPU(unsigned FPU) {}
118 const MCSymbolRefExpr *SRE) {}
120
122void ARMTargetStreamer::emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) {}
124void ARMTargetStreamer::emitARMWinCFISaveFRegs(unsigned First, unsigned Last) {}
131
133 if (STI.getCPU() == "xscale")
135
136 if (STI.hasFeature(ARM::HasV9_0aOps))
137 return ARMBuildAttrs::v9_A;
138 else if (STI.hasFeature(ARM::HasV8Ops)) {
139 if (STI.hasFeature(ARM::FeatureRClass))
140 return ARMBuildAttrs::v8_R;
141 return ARMBuildAttrs::v8_A;
142 } else if (STI.hasFeature(ARM::HasV8_1MMainlineOps))
144 else if (STI.hasFeature(ARM::HasV8MMainlineOps))
146 else if (STI.hasFeature(ARM::HasV7Ops)) {
147 if (STI.hasFeature(ARM::FeatureMClass) && STI.hasFeature(ARM::FeatureDSP))
149 return ARMBuildAttrs::v7;
150 } else if (STI.hasFeature(ARM::HasV6T2Ops))
151 return ARMBuildAttrs::v6T2;
152 else if (STI.hasFeature(ARM::HasV8MBaselineOps))
154 else if (STI.hasFeature(ARM::HasV6MOps))
156 else if (STI.hasFeature(ARM::HasV6Ops))
157 return ARMBuildAttrs::v6;
158 else if (STI.hasFeature(ARM::HasV5TEOps))
159 return ARMBuildAttrs::v5TE;
160 else if (STI.hasFeature(ARM::HasV5TOps))
161 return ARMBuildAttrs::v5T;
162 else if (STI.hasFeature(ARM::HasV4TOps))
163 return ARMBuildAttrs::v4T;
164 else
165 return ARMBuildAttrs::v4;
166}
167
168static bool isV8M(const MCSubtargetInfo &STI) {
169 // Note that v8M Baseline is a subset of v6T2!
170 return (STI.hasFeature(ARM::HasV8MBaselineOps) &&
171 !STI.hasFeature(ARM::HasV6T2Ops)) ||
172 STI.hasFeature(ARM::HasV8MMainlineOps);
173}
174
175/// Emit the build attributes that only depend on the hardware that we expect
176// /to be available, and not on the ABI, or any source-language choices.
178 switchVendor("aeabi");
179
180 const StringRef CPUString = STI.getCPU();
181 if (!CPUString.empty() && !CPUString.startswith("generic")) {
182 // FIXME: remove krait check when GNU tools support krait cpu
183 if (STI.hasFeature(ARM::ProcKrait)) {
185 // We consider krait as a "cortex-a9" + hwdiv CPU
186 // Enable hwdiv through ".arch_extension idiv"
187 if (STI.hasFeature(ARM::FeatureHWDivThumb) ||
188 STI.hasFeature(ARM::FeatureHWDivARM))
190 } else {
192 }
193 }
194
196
197 if (STI.hasFeature(ARM::FeatureAClass)) {
200 } else if (STI.hasFeature(ARM::FeatureRClass)) {
203 } else if (STI.hasFeature(ARM::FeatureMClass)) {
206 }
207
211
212 if (isV8M(STI)) {
215 } else if (STI.hasFeature(ARM::FeatureThumb2)) {
218 } else if (STI.hasFeature(ARM::HasV4TOps)) {
220 }
221
222 if (STI.hasFeature(ARM::FeatureNEON)) {
223 /* NEON is not exactly a VFP architecture, but GAS emit one of
224 * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
225 if (STI.hasFeature(ARM::FeatureFPARMv8)) {
226 if (STI.hasFeature(ARM::FeatureCrypto))
227 emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8);
228 else
229 emitFPU(ARM::FK_NEON_FP_ARMV8);
230 } else if (STI.hasFeature(ARM::FeatureVFP4))
231 emitFPU(ARM::FK_NEON_VFPV4);
232 else
233 emitFPU(STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_NEON_FP16
234 : ARM::FK_NEON);
235 // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
236 if (STI.hasFeature(ARM::HasV8Ops))
238 STI.hasFeature(ARM::HasV8_1aOps)
241 } else {
242 if (STI.hasFeature(ARM::FeatureFPARMv8_D16_SP))
243 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
244 // FPU, but there are two different names for it depending on the CPU.
245 emitFPU(STI.hasFeature(ARM::FeatureD32)
246 ? ARM::FK_FP_ARMV8
247 : (STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_FPV5_D16
248 : ARM::FK_FPV5_SP_D16));
249 else if (STI.hasFeature(ARM::FeatureVFP4_D16_SP))
250 emitFPU(STI.hasFeature(ARM::FeatureD32)
251 ? ARM::FK_VFPV4
252 : (STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_VFPV4_D16
253 : ARM::FK_FPV4_SP_D16));
254 else if (STI.hasFeature(ARM::FeatureVFP3_D16_SP))
255 emitFPU(
256 STI.hasFeature(ARM::FeatureD32)
257 // +d32
258 ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16
259 : ARM::FK_VFPV3)
260 // -d32
261 : (STI.hasFeature(ARM::FeatureFP64)
262 ? (STI.hasFeature(ARM::FeatureFP16)
263 ? ARM::FK_VFPV3_D16_FP16
264 : ARM::FK_VFPV3_D16)
265 : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
266 : ARM::FK_VFPV3XD)));
267 else if (STI.hasFeature(ARM::FeatureVFP2_SP))
268 emitFPU(ARM::FK_VFPV2);
269 }
270
271 // ABI_HardFP_use attribute to indicate single precision FP.
272 if (STI.hasFeature(ARM::FeatureVFP2_SP) && !STI.hasFeature(ARM::FeatureFP64))
275
276 if (STI.hasFeature(ARM::FeatureFP16))
278
279 if (STI.hasFeature(ARM::FeatureMP))
281
282 if (STI.hasFeature(ARM::HasMVEFloatOps))
284 else if (STI.hasFeature(ARM::HasMVEIntegerOps))
286
287 // Hardware divide in ARM mode is part of base arch, starting from ARMv8.
288 // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M).
289 // It is not possible to produce DisallowDIV: if hwdiv is present in the base
290 // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits.
291 // AllowDIVExt is only emitted if hwdiv isn't available in the base arch;
292 // otherwise, the default value (AllowDIVIfExists) applies.
293 if (STI.hasFeature(ARM::FeatureHWDivARM) && !STI.hasFeature(ARM::HasV8Ops))
295
296 if (STI.hasFeature(ARM::FeatureDSP) && isV8M(STI))
298
299 if (STI.hasFeature(ARM::FeatureStrictAlign))
302 else
305
306 if (STI.hasFeature(ARM::FeatureTrustZone) &&
307 STI.hasFeature(ARM::FeatureVirtualization))
310 else if (STI.hasFeature(ARM::FeatureTrustZone))
312 else if (STI.hasFeature(ARM::FeatureVirtualization))
315
316 if (STI.hasFeature(ARM::FeaturePACBTI)) {
319 }
320}
321
324 const Triple &TT = STI.getTargetTriple();
325 if (TT.isOSBinFormatELF())
327 if (TT.isOSBinFormatCOFF())
329 return new ARMTargetStreamer(S);
330}
static bool isV8M(const MCSubtargetInfo &STI)
static ARMBuildAttrs::CPUArch getArchForCPU(const MCSubtargetInfo &STI)
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
This header is deprecated in favour of llvm/TargetParser/TargetParser.h.
virtual void emitUnwindRaw(int64_t StackOffset, const SmallVectorImpl< uint8_t > &Opcodes)
~ARMTargetStreamer() override
void emitTargetAttributes(const MCSubtargetInfo &STI)
Emit the build attributes that only depend on the hardware that we expect.
virtual void reset()
Reset any state between object emissions, i.e.
virtual void emitFPU(unsigned FPU)
virtual void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE)
virtual void finishAttributeSection()
ARMTargetStreamer(MCStreamer &S)
virtual void emitARMWinCFISaveSP(unsigned Reg)
virtual void emitPersonalityIndex(unsigned Index)
virtual void emitInst(uint32_t Inst, char Suffix='\0')
virtual void emitARMWinCFISaveLR(unsigned Offset)
virtual void emitArchExtension(uint64_t ArchExt)
virtual void emitRegSave(const SmallVectorImpl< unsigned > &RegList, bool isVector)
virtual void emitTextAttribute(unsigned Attribute, StringRef String)
virtual void emitARMWinCFIAllocStack(unsigned Size, bool Wide)
virtual void emitMovSP(unsigned Reg, int64_t Offset=0)
virtual void emitARMWinCFICustom(unsigned Opcode)
virtual void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide)
virtual void emitARMWinCFIEpilogEnd()
virtual void emitARMWinCFIPrologEnd(bool Fragment)
virtual void switchVendor(StringRef Vendor)
virtual void emitPersonality(const MCSymbol *Personality)
virtual void emitObjectArch(ARM::ArchKind Arch)
const MCExpr * addConstantPoolEntry(const MCExpr *, SMLoc Loc)
Callback used to implement the ldr= pseudo.
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue="")
virtual void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value)
virtual void emitARMWinCFISaveFRegs(unsigned First, unsigned Last)
virtual void emitARMWinCFIEpilogStart(unsigned Condition)
virtual void emitPad(int64_t Offset)
void emitCurrentConstantPool()
Callback used to implement the .ltorg directive.
virtual void emitAttribute(unsigned Attribute, unsigned Value)
virtual void emitARMWinCFINop(bool Wide)
virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset=0)
void emitConstantPools() override
virtual void emitArch(ARM::ArchKind Arch)
bool isLittleEndian() const
True if the target is little endian.
Definition: MCAsmInfo.h:559
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:446
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Streaming machine code generation interface.
Definition: MCStreamer.h:212
MCContext & getContext() const
Definition: MCStreamer.h:297
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
StringRef getCPU() const
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
Target specific streamer interface.
Definition: MCStreamer.h:93
MCStreamer & getStreamer()
Definition: MCStreamer.h:101
MCStreamer & Streamer
Definition: MCStreamer.h:95
Represents a location in source code.
Definition: SMLoc.h:23
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:36
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
bool startswith(StringRef Prefix) const
Definition: StringRef.h:261
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
LLVM Value Representation.
Definition: Value.h:74
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
MCTargetStreamer * createARMObjectTargetELFStreamer(MCStreamer &S)
MCTargetStreamer * createARMObjectTargetWinCOFFStreamer(MCStreamer &S)
MCTargetStreamer * createARMObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI)