LLVM  10.0.0svn
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 
14 #include "llvm/MC/ConstantPools.h"
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 
23 using 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.
46 void ARMTargetStreamer::finish() { ConstantPools->emitAll(Streamer); }
47 
48 // reset() - Reset any state
50 
51 void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) {
52  unsigned Size;
53  char Buffer[4];
54  const bool LittleEndian = getStreamer().getContext().getAsmInfo()->isLittleEndian();
55 
56  switch (Suffix) {
57  case '\0':
58  Size = 4;
59 
60  for (unsigned II = 0, IE = Size; II != IE; II++) {
61  const unsigned I = LittleEndian ? (Size - II - 1) : II;
62  Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
63  }
64 
65  break;
66  case 'n':
67  case 'w':
68  Size = (Suffix == 'n' ? 2 : 4);
69 
70  // Thumb wide instructions are emitted as a pair of 16-bit words of the
71  // appropriate endianness.
72  for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
73  const unsigned I0 = LittleEndian ? II + 0 : II + 1;
74  const unsigned I1 = LittleEndian ? II + 1 : II + 0;
75  Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
76  Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
77  }
78 
79  break;
80  default:
81  llvm_unreachable("Invalid Suffix");
82  }
83  getStreamer().EmitBytes(StringRef(Buffer, Size));
84 }
85 
86 // The remaining callbacks should be handled separately by each
87 // streamer.
91 void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) {}
94 void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
95  int64_t Offset) {}
96 void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) {}
99  bool isVector) {}
101  const SmallVectorImpl<uint8_t> &Opcodes) {
102 }
106  StringRef String) {}
108  unsigned IntValue,
109  StringRef StringValue) {}
111 void ARMTargetStreamer::emitArchExtension(unsigned ArchExt) {}
113 void ARMTargetStreamer::emitFPU(unsigned FPU) {}
115 void
118 
120  if (STI.getCPU() == "xscale")
121  return ARMBuildAttrs::v5TEJ;
122 
123  if (STI.hasFeature(ARM::HasV8Ops)) {
124  if (STI.hasFeature(ARM::FeatureRClass))
125  return ARMBuildAttrs::v8_R;
126  return ARMBuildAttrs::v8_A;
127  } else if (STI.hasFeature(ARM::HasV8_1MMainlineOps))
129  else if (STI.hasFeature(ARM::HasV8MMainlineOps))
131  else if (STI.hasFeature(ARM::HasV7Ops)) {
132  if (STI.hasFeature(ARM::FeatureMClass) && STI.hasFeature(ARM::FeatureDSP))
133  return ARMBuildAttrs::v7E_M;
134  return ARMBuildAttrs::v7;
135  } else if (STI.hasFeature(ARM::HasV6T2Ops))
136  return ARMBuildAttrs::v6T2;
137  else if (STI.hasFeature(ARM::HasV8MBaselineOps))
139  else if (STI.hasFeature(ARM::HasV6MOps))
140  return ARMBuildAttrs::v6S_M;
141  else if (STI.hasFeature(ARM::HasV6Ops))
142  return ARMBuildAttrs::v6;
143  else if (STI.hasFeature(ARM::HasV5TEOps))
144  return ARMBuildAttrs::v5TE;
145  else if (STI.hasFeature(ARM::HasV5TOps))
146  return ARMBuildAttrs::v5T;
147  else if (STI.hasFeature(ARM::HasV4TOps))
148  return ARMBuildAttrs::v4T;
149  else
150  return ARMBuildAttrs::v4;
151 }
152 
153 static bool isV8M(const MCSubtargetInfo &STI) {
154  // Note that v8M Baseline is a subset of v6T2!
155  return (STI.hasFeature(ARM::HasV8MBaselineOps) &&
156  !STI.hasFeature(ARM::HasV6T2Ops)) ||
157  STI.hasFeature(ARM::HasV8MMainlineOps);
158 }
159 
160 /// Emit the build attributes that only depend on the hardware that we expect
161 // /to be available, and not on the ABI, or any source-language choices.
163  switchVendor("aeabi");
164 
165  const StringRef CPUString = STI.getCPU();
166  if (!CPUString.empty() && !CPUString.startswith("generic")) {
167  // FIXME: remove krait check when GNU tools support krait cpu
168  if (STI.hasFeature(ARM::ProcKrait)) {
170  // We consider krait as a "cortex-a9" + hwdiv CPU
171  // Enable hwdiv through ".arch_extension idiv"
172  if (STI.hasFeature(ARM::FeatureHWDivThumb) ||
173  STI.hasFeature(ARM::FeatureHWDivARM))
175  } else {
177  }
178  }
179 
181 
182  if (STI.hasFeature(ARM::FeatureAClass)) {
185  } else if (STI.hasFeature(ARM::FeatureRClass)) {
188  } else if (STI.hasFeature(ARM::FeatureMClass)) {
191  }
192 
193  emitAttribute(ARMBuildAttrs::ARM_ISA_use, STI.hasFeature(ARM::FeatureNoARM)
196 
197  if (isV8M(STI)) {
200  } else if (STI.hasFeature(ARM::FeatureThumb2)) {
203  } else if (STI.hasFeature(ARM::HasV4TOps)) {
205  }
206 
207  if (STI.hasFeature(ARM::FeatureNEON)) {
208  /* NEON is not exactly a VFP architecture, but GAS emit one of
209  * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
210  if (STI.hasFeature(ARM::FeatureFPARMv8)) {
211  if (STI.hasFeature(ARM::FeatureCrypto))
212  emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8);
213  else
214  emitFPU(ARM::FK_NEON_FP_ARMV8);
215  } else if (STI.hasFeature(ARM::FeatureVFP4))
216  emitFPU(ARM::FK_NEON_VFPV4);
217  else
218  emitFPU(STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_NEON_FP16
219  : ARM::FK_NEON);
220  // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
221  if (STI.hasFeature(ARM::HasV8Ops))
223  STI.hasFeature(ARM::HasV8_1aOps)
226  } else {
227  if (STI.hasFeature(ARM::FeatureFPARMv8_D16_SP))
228  // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
229  // FPU, but there are two different names for it depending on the CPU.
230  emitFPU(STI.hasFeature(ARM::FeatureD32)
231  ? ARM::FK_FP_ARMV8
232  : (STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_FPV5_D16
233  : ARM::FK_FPV5_SP_D16));
234  else if (STI.hasFeature(ARM::FeatureVFP4_D16_SP))
235  emitFPU(STI.hasFeature(ARM::FeatureD32)
236  ? ARM::FK_VFPV4
237  : (STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_VFPV4_D16
238  : ARM::FK_FPV4_SP_D16));
239  else if (STI.hasFeature(ARM::FeatureVFP3_D16_SP))
240  emitFPU(
241  STI.hasFeature(ARM::FeatureD32)
242  // +d32
243  ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16
244  : ARM::FK_VFPV3)
245  // -d32
246  : (STI.hasFeature(ARM::FeatureFP64)
247  ? (STI.hasFeature(ARM::FeatureFP16)
248  ? ARM::FK_VFPV3_D16_FP16
249  : ARM::FK_VFPV3_D16)
250  : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
251  : ARM::FK_VFPV3XD)));
252  else if (STI.hasFeature(ARM::FeatureVFP2_SP))
253  emitFPU(ARM::FK_VFPV2);
254  }
255 
256  // ABI_HardFP_use attribute to indicate single precision FP.
257  if (STI.hasFeature(ARM::FeatureVFP2_SP) && !STI.hasFeature(ARM::FeatureFP64))
260 
261  if (STI.hasFeature(ARM::FeatureFP16))
263 
264  if (STI.hasFeature(ARM::FeatureMP))
266 
267  if (STI.hasFeature(ARM::HasMVEFloatOps))
269  else if (STI.hasFeature(ARM::HasMVEIntegerOps))
271 
272  // Hardware divide in ARM mode is part of base arch, starting from ARMv8.
273  // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M).
274  // It is not possible to produce DisallowDIV: if hwdiv is present in the base
275  // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits.
276  // AllowDIVExt is only emitted if hwdiv isn't available in the base arch;
277  // otherwise, the default value (AllowDIVIfExists) applies.
278  if (STI.hasFeature(ARM::FeatureHWDivARM) && !STI.hasFeature(ARM::HasV8Ops))
280 
281  if (STI.hasFeature(ARM::FeatureDSP) && isV8M(STI))
283 
284  if (STI.hasFeature(ARM::FeatureStrictAlign))
287  else
290 
291  if (STI.hasFeature(ARM::FeatureTrustZone) &&
292  STI.hasFeature(ARM::FeatureVirtualization))
295  else if (STI.hasFeature(ARM::FeatureTrustZone))
297  else if (STI.hasFeature(ARM::FeatureVirtualization))
300 }
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:318
virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE)
virtual void emitFPU(unsigned FPU)
StackOffset is a wrapper around scalable and non-scalable offsets and is used in several functions su...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
virtual void emitArchExtension(unsigned ArchExt)
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:270
virtual void EmitBytes(StringRef Data)
Emit the bytes in Data into the output.
Target specific streamer interface.
Definition: MCStreamer.h:85
unsigned Reg
virtual void emitPad(int64_t Offset)
virtual void finishAttributeSection()
virtual void emitPersonality(const MCSymbol *Personality)
LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
virtual void reset()
Reset any state between object emissions, i.e.
virtual void emitPersonalityIndex(unsigned Index)
MCContext & getContext() const
Definition: MCStreamer.h:252
void emitCurrentConstantPool()
Callback used to implemnt the .ltorg directive.
virtual void emitInst(uint32_t Inst, char Suffix='\0')
virtual void emitObjectArch(ARM::ArchKind Arch)
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:169
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:140
virtual void emitMovSP(unsigned Reg, int64_t Offset=0)
static bool isV8M(const MCSubtargetInfo &STI)
ARMTargetStreamer(MCStreamer &S)
virtual void emitAttribute(unsigned Attribute, unsigned Value)
Streaming machine code generation interface.
Definition: MCStreamer.h:190
virtual void emitRegSave(const SmallVectorImpl< unsigned > &RegList, bool isVector)
virtual void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value)
virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset=0)
virtual void emitUnwindRaw(int64_t StackOffset, const SmallVectorImpl< uint8_t > &Opcodes)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
~ARMTargetStreamer() override
MCStreamer & getStreamer()
Definition: MCStreamer.h:93
static ARMBuildAttrs::CPUArch getArchForCPU(const MCSubtargetInfo &STI)
MCStreamer & Streamer
Definition: MCStreamer.h:87
void emitTargetAttributes(const MCSubtargetInfo &STI)
Emit the build attributes that only depend on the hardware that we expect.
const MCExpr * addConstantPoolEntry(const MCExpr *, SMLoc Loc)
Callback used to implement the ldr= pseudo.
virtual void emitArch(ARM::ArchKind Arch)
StringRef getCPU() const
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue="")
#define I(x, y, z)
Definition: MD5.cpp:58
bool hasFeature(unsigned Feature) const
Generic base class for all target subtargets.
uint32_t Size
Definition: Profile.cpp:46
bool isLittleEndian() const
True if the target is little endian.
Definition: MCAsmInfo.h:409
LLVM Value Representation.
Definition: Value.h:73
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Represents a location in source code.
Definition: SMLoc.h:23
virtual void switchVendor(StringRef Vendor)
virtual void emitTextAttribute(unsigned Attribute, StringRef String)