LLVM  9.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) {}
100 void ARMTargetStreamer::emitUnwindRaw(int64_t StackOffset,
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::HasV8MMainlineOps))
129  else if (STI.hasFeature(ARM::HasV7Ops)) {
130  if (STI.hasFeature(ARM::FeatureMClass) && STI.hasFeature(ARM::FeatureDSP))
131  return ARMBuildAttrs::v7E_M;
132  return ARMBuildAttrs::v7;
133  } else if (STI.hasFeature(ARM::HasV6T2Ops))
134  return ARMBuildAttrs::v6T2;
135  else if (STI.hasFeature(ARM::HasV8MBaselineOps))
137  else if (STI.hasFeature(ARM::HasV6MOps))
138  return ARMBuildAttrs::v6S_M;
139  else if (STI.hasFeature(ARM::HasV6Ops))
140  return ARMBuildAttrs::v6;
141  else if (STI.hasFeature(ARM::HasV5TEOps))
142  return ARMBuildAttrs::v5TE;
143  else if (STI.hasFeature(ARM::HasV5TOps))
144  return ARMBuildAttrs::v5T;
145  else if (STI.hasFeature(ARM::HasV4TOps))
146  return ARMBuildAttrs::v4T;
147  else
148  return ARMBuildAttrs::v4;
149 }
150 
151 static bool isV8M(const MCSubtargetInfo &STI) {
152  // Note that v8M Baseline is a subset of v6T2!
153  return (STI.hasFeature(ARM::HasV8MBaselineOps) &&
154  !STI.hasFeature(ARM::HasV6T2Ops)) ||
155  STI.hasFeature(ARM::HasV8MMainlineOps);
156 }
157 
158 /// Emit the build attributes that only depend on the hardware that we expect
159 // /to be available, and not on the ABI, or any source-language choices.
161  switchVendor("aeabi");
162 
163  const StringRef CPUString = STI.getCPU();
164  if (!CPUString.empty() && !CPUString.startswith("generic")) {
165  // FIXME: remove krait check when GNU tools support krait cpu
166  if (STI.hasFeature(ARM::ProcKrait)) {
168  // We consider krait as a "cortex-a9" + hwdiv CPU
169  // Enable hwdiv through ".arch_extension idiv"
170  if (STI.hasFeature(ARM::FeatureHWDivThumb) ||
171  STI.hasFeature(ARM::FeatureHWDivARM))
173  } else {
175  }
176  }
177 
179 
180  if (STI.hasFeature(ARM::FeatureAClass)) {
183  } else if (STI.hasFeature(ARM::FeatureRClass)) {
186  } else if (STI.hasFeature(ARM::FeatureMClass)) {
189  }
190 
191  emitAttribute(ARMBuildAttrs::ARM_ISA_use, STI.hasFeature(ARM::FeatureNoARM)
194 
195  if (isV8M(STI)) {
198  } else if (STI.hasFeature(ARM::FeatureThumb2)) {
201  } else if (STI.hasFeature(ARM::HasV4TOps)) {
203  }
204 
205  if (STI.hasFeature(ARM::FeatureNEON)) {
206  /* NEON is not exactly a VFP architecture, but GAS emit one of
207  * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
208  if (STI.hasFeature(ARM::FeatureFPARMv8)) {
209  if (STI.hasFeature(ARM::FeatureCrypto))
210  emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8);
211  else
212  emitFPU(ARM::FK_NEON_FP_ARMV8);
213  } else if (STI.hasFeature(ARM::FeatureVFP4))
214  emitFPU(ARM::FK_NEON_VFPV4);
215  else
216  emitFPU(STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_NEON_FP16
217  : ARM::FK_NEON);
218  // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
219  if (STI.hasFeature(ARM::HasV8Ops))
221  STI.hasFeature(ARM::HasV8_1aOps)
224  } else {
225  if (STI.hasFeature(ARM::FeatureFPARMv8))
226  // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
227  // FPU, but there are two different names for it depending on the CPU.
228  emitFPU(STI.hasFeature(ARM::FeatureD16)
229  ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV5_SP_D16
230  : ARM::FK_FPV5_D16)
231  : ARM::FK_FP_ARMV8);
232  else if (STI.hasFeature(ARM::FeatureVFP4))
233  emitFPU(STI.hasFeature(ARM::FeatureD16)
234  ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV4_SP_D16
235  : ARM::FK_VFPV4_D16)
236  : ARM::FK_VFPV4);
237  else if (STI.hasFeature(ARM::FeatureVFP3))
238  emitFPU(
239  STI.hasFeature(ARM::FeatureD16)
240  // +d16
241  ? (STI.hasFeature(ARM::FeatureVFPOnlySP)
242  ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
243  : ARM::FK_VFPV3XD)
244  : (STI.hasFeature(ARM::FeatureFP16)
245  ? ARM::FK_VFPV3_D16_FP16
246  : ARM::FK_VFPV3_D16))
247  // -d16
248  : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16
249  : ARM::FK_VFPV3));
250  else if (STI.hasFeature(ARM::FeatureVFP2))
251  emitFPU(ARM::FK_VFPV2);
252  }
253 
254  // ABI_HardFP_use attribute to indicate single precision FP.
255  if (STI.hasFeature(ARM::FeatureVFPOnlySP))
258 
259  if (STI.hasFeature(ARM::FeatureFP16))
261 
262  if (STI.hasFeature(ARM::FeatureMP))
264 
265  // Hardware divide in ARM mode is part of base arch, starting from ARMv8.
266  // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M).
267  // It is not possible to produce DisallowDIV: if hwdiv is present in the base
268  // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits.
269  // AllowDIVExt is only emitted if hwdiv isn't available in the base arch;
270  // otherwise, the default value (AllowDIVIfExists) applies.
271  if (STI.hasFeature(ARM::FeatureHWDivARM) && !STI.hasFeature(ARM::HasV8Ops))
273 
274  if (STI.hasFeature(ARM::FeatureDSP) && isV8M(STI))
276 
277  if (STI.hasFeature(ARM::FeatureStrictAlign))
280  else
283 
284  if (STI.hasFeature(ARM::FeatureTrustZone) &&
285  STI.hasFeature(ARM::FeatureVirtualization))
288  else if (STI.hasFeature(ARM::FeatureTrustZone))
290  else if (STI.hasFeature(ARM::FeatureVirtualization))
293 }
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:292
virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE)
virtual void emitFPU(unsigned FPU)
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:256
virtual void EmitBytes(StringRef Data)
Emit the bytes in Data into the output.
Target specific streamer interface.
Definition: MCStreamer.h:83
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:250
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:165
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:126
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:188
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:91
static ARMBuildAttrs::CPUArch getArchForCPU(const MCSubtargetInfo &STI)
MCStreamer & Streamer
Definition: MCStreamer.h:85
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:404
LLVM Value Representation.
Definition: Value.h:72
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)