LLVM  8.0.1
ARMTargetStreamer.cpp
Go to the documentation of this file.
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 
15 #include "llvm/MC/ConstantPools.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCStreamer.h"
23 
24 using namespace llvm;
25 
26 //
27 // ARMTargetStreamer Implemenation
28 //
29 
31  : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {}
32 
34 
35 // The constant pool handling is shared by all ARMTargetStreamer
36 // implementations.
38  return ConstantPools->addEntry(Streamer, Expr, 4, Loc);
39 }
40 
42  ConstantPools->emitForCurrentSection(Streamer);
43  ConstantPools->clearCacheForCurrentSection(Streamer);
44 }
45 
46 // finish() - write out any non-empty assembler constant pools.
47 void ARMTargetStreamer::finish() { ConstantPools->emitAll(Streamer); }
48 
49 // reset() - Reset any state
51 
52 void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) {
53  unsigned Size;
54  char Buffer[4];
55  const bool LittleEndian = getStreamer().getContext().getAsmInfo()->isLittleEndian();
56 
57  switch (Suffix) {
58  case '\0':
59  Size = 4;
60 
61  for (unsigned II = 0, IE = Size; II != IE; II++) {
62  const unsigned I = LittleEndian ? (Size - II - 1) : II;
63  Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
64  }
65 
66  break;
67  case 'n':
68  case 'w':
69  Size = (Suffix == 'n' ? 2 : 4);
70 
71  // Thumb wide instructions are emitted as a pair of 16-bit words of the
72  // appropriate endianness.
73  for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
74  const unsigned I0 = LittleEndian ? II + 0 : II + 1;
75  const unsigned I1 = LittleEndian ? II + 1 : II + 0;
76  Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
77  Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
78  }
79 
80  break;
81  default:
82  llvm_unreachable("Invalid Suffix");
83  }
84  getStreamer().EmitBytes(StringRef(Buffer, Size));
85 }
86 
87 // The remaining callbacks should be handled separately by each
88 // streamer.
92 void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) {}
95 void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
96  int64_t Offset) {}
97 void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) {}
100  bool isVector) {}
101 void ARMTargetStreamer::emitUnwindRaw(int64_t StackOffset,
102  const SmallVectorImpl<uint8_t> &Opcodes) {
103 }
107  StringRef String) {}
109  unsigned IntValue,
110  StringRef StringValue) {}
112 void ARMTargetStreamer::emitArchExtension(unsigned ArchExt) {}
114 void ARMTargetStreamer::emitFPU(unsigned FPU) {}
116 void
119 
121  if (STI.getCPU() == "xscale")
122  return ARMBuildAttrs::v5TEJ;
123 
124  if (STI.hasFeature(ARM::HasV8Ops)) {
125  if (STI.hasFeature(ARM::FeatureRClass))
126  return ARMBuildAttrs::v8_R;
127  return ARMBuildAttrs::v8_A;
128  } else if (STI.hasFeature(ARM::HasV8MMainlineOps))
130  else if (STI.hasFeature(ARM::HasV7Ops)) {
131  if (STI.hasFeature(ARM::FeatureMClass) && STI.hasFeature(ARM::FeatureDSP))
132  return ARMBuildAttrs::v7E_M;
133  return ARMBuildAttrs::v7;
134  } else if (STI.hasFeature(ARM::HasV6T2Ops))
135  return ARMBuildAttrs::v6T2;
136  else if (STI.hasFeature(ARM::HasV8MBaselineOps))
138  else if (STI.hasFeature(ARM::HasV6MOps))
139  return ARMBuildAttrs::v6S_M;
140  else if (STI.hasFeature(ARM::HasV6Ops))
141  return ARMBuildAttrs::v6;
142  else if (STI.hasFeature(ARM::HasV5TEOps))
143  return ARMBuildAttrs::v5TE;
144  else if (STI.hasFeature(ARM::HasV5TOps))
145  return ARMBuildAttrs::v5T;
146  else if (STI.hasFeature(ARM::HasV4TOps))
147  return ARMBuildAttrs::v4T;
148  else
149  return ARMBuildAttrs::v4;
150 }
151 
152 static bool isV8M(const MCSubtargetInfo &STI) {
153  // Note that v8M Baseline is a subset of v6T2!
154  return (STI.hasFeature(ARM::HasV8MBaselineOps) &&
155  !STI.hasFeature(ARM::HasV6T2Ops)) ||
156  STI.hasFeature(ARM::HasV8MMainlineOps);
157 }
158 
159 /// Emit the build attributes that only depend on the hardware that we expect
160 // /to be available, and not on the ABI, or any source-language choices.
162  switchVendor("aeabi");
163 
164  const StringRef CPUString = STI.getCPU();
165  if (!CPUString.empty() && !CPUString.startswith("generic")) {
166  // FIXME: remove krait check when GNU tools support krait cpu
167  if (STI.hasFeature(ARM::ProcKrait)) {
169  // We consider krait as a "cortex-a9" + hwdiv CPU
170  // Enable hwdiv through ".arch_extension idiv"
171  if (STI.hasFeature(ARM::FeatureHWDivThumb) ||
172  STI.hasFeature(ARM::FeatureHWDivARM))
174  } else {
176  }
177  }
178 
180 
181  if (STI.hasFeature(ARM::FeatureAClass)) {
184  } else if (STI.hasFeature(ARM::FeatureRClass)) {
187  } else if (STI.hasFeature(ARM::FeatureMClass)) {
190  }
191 
192  emitAttribute(ARMBuildAttrs::ARM_ISA_use, STI.hasFeature(ARM::FeatureNoARM)
195 
196  if (isV8M(STI)) {
199  } else if (STI.hasFeature(ARM::FeatureThumb2)) {
202  } else if (STI.hasFeature(ARM::HasV4TOps)) {
204  }
205 
206  if (STI.hasFeature(ARM::FeatureNEON)) {
207  /* NEON is not exactly a VFP architecture, but GAS emit one of
208  * neon/neon-fp-armv8/neon-vfpv4/vfpv3/vfpv2 for .fpu parameters */
209  if (STI.hasFeature(ARM::FeatureFPARMv8)) {
210  if (STI.hasFeature(ARM::FeatureCrypto))
211  emitFPU(ARM::FK_CRYPTO_NEON_FP_ARMV8);
212  else
213  emitFPU(ARM::FK_NEON_FP_ARMV8);
214  } else if (STI.hasFeature(ARM::FeatureVFP4))
215  emitFPU(ARM::FK_NEON_VFPV4);
216  else
217  emitFPU(STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_NEON_FP16
218  : ARM::FK_NEON);
219  // Emit Tag_Advanced_SIMD_arch for ARMv8 architecture
220  if (STI.hasFeature(ARM::HasV8Ops))
222  STI.hasFeature(ARM::HasV8_1aOps)
225  } else {
226  if (STI.hasFeature(ARM::FeatureFPARMv8))
227  // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
228  // FPU, but there are two different names for it depending on the CPU.
229  emitFPU(STI.hasFeature(ARM::FeatureD16)
230  ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV5_SP_D16
231  : ARM::FK_FPV5_D16)
232  : ARM::FK_FP_ARMV8);
233  else if (STI.hasFeature(ARM::FeatureVFP4))
234  emitFPU(STI.hasFeature(ARM::FeatureD16)
235  ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV4_SP_D16
236  : ARM::FK_VFPV4_D16)
237  : ARM::FK_VFPV4);
238  else if (STI.hasFeature(ARM::FeatureVFP3))
239  emitFPU(
240  STI.hasFeature(ARM::FeatureD16)
241  // +d16
242  ? (STI.hasFeature(ARM::FeatureVFPOnlySP)
243  ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
244  : ARM::FK_VFPV3XD)
245  : (STI.hasFeature(ARM::FeatureFP16)
246  ? ARM::FK_VFPV3_D16_FP16
247  : ARM::FK_VFPV3_D16))
248  // -d16
249  : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16
250  : ARM::FK_VFPV3));
251  else if (STI.hasFeature(ARM::FeatureVFP2))
252  emitFPU(ARM::FK_VFPV2);
253  }
254 
255  // ABI_HardFP_use attribute to indicate single precision FP.
256  if (STI.hasFeature(ARM::FeatureVFPOnlySP))
259 
260  if (STI.hasFeature(ARM::FeatureFP16))
262 
263  if (STI.hasFeature(ARM::FeatureMP))
265 
266  // Hardware divide in ARM mode is part of base arch, starting from ARMv8.
267  // If only Thumb hwdiv is present, it must also be in base arch (ARMv7-R/M).
268  // It is not possible to produce DisallowDIV: if hwdiv is present in the base
269  // arch, supplying -hwdiv downgrades the effective arch, via ClearImpliedBits.
270  // AllowDIVExt is only emitted if hwdiv isn't available in the base arch;
271  // otherwise, the default value (AllowDIVIfExists) applies.
272  if (STI.hasFeature(ARM::FeatureHWDivARM) && !STI.hasFeature(ARM::HasV8Ops))
274 
275  if (STI.hasFeature(ARM::FeatureDSP) && isV8M(STI))
277 
278  if (STI.hasFeature(ARM::FeatureStrictAlign))
281  else
284 
285  if (STI.hasFeature(ARM::FeatureTrustZone) &&
286  STI.hasFeature(ARM::FeatureVirtualization))
289  else if (STI.hasFeature(ARM::FeatureTrustZone))
291  else if (STI.hasFeature(ARM::FeatureVirtualization))
294 }
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:293
virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE)
virtual void emitFPU(unsigned FPU)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
virtual void emitArchExtension(unsigned ArchExt)
virtual void EmitBytes(StringRef Data)
Emit the bytes in Data into the output.
Target specific streamer interface.
Definition: MCStreamer.h:84
unsigned Reg
virtual void emitPad(int64_t Offset)
virtual void finishAttributeSection()
virtual void emitPersonality(const MCSymbol *Personality)
virtual void reset()
Reset any state between object emissions, i.e.
virtual void emitPersonalityIndex(unsigned Index)
MCContext & getContext() const
Definition: MCStreamer.h:251
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:36
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:166
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
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:189
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:92
static ARMBuildAttrs::CPUArch getArchForCPU(const MCSubtargetInfo &STI)
bool isVector(MCInstrInfo const &MCII, MCInst const &MCI)
MCStreamer & Streamer
Definition: MCStreamer.h:86
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:47
bool isLittleEndian() const
True if the target is little endian.
Definition: MCAsmInfo.h:405
LLVM Value Representation.
Definition: Value.h:73
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Represents a location in source code.
Definition: SMLoc.h:24
virtual void switchVendor(StringRef Vendor)
virtual void emitTextAttribute(unsigned Attribute, StringRef String)