Bug Summary

File:llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Warning:line 346, column 36
The result of the left shift is undefined due to shifting by '32', which is greater or equal to the width of type 'int'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ARMAsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/lib/Target/ARM/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070=. -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-08-06-171148-17323-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

1//===- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions -------===//
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#include "ARMFeatures.h"
10#include "ARMBaseInstrInfo.h"
11#include "Utils/ARMBaseInfo.h"
12#include "MCTargetDesc/ARMAddressingModes.h"
13#include "MCTargetDesc/ARMBaseInfo.h"
14#include "MCTargetDesc/ARMInstPrinter.h"
15#include "MCTargetDesc/ARMMCExpr.h"
16#include "MCTargetDesc/ARMMCTargetDesc.h"
17#include "TargetInfo/ARMTargetInfo.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/None.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/SmallSet.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/ADT/StringMap.h"
25#include "llvm/ADT/StringSet.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/ADT/Triple.h"
29#include "llvm/ADT/Twine.h"
30#include "llvm/MC/MCContext.h"
31#include "llvm/MC/MCExpr.h"
32#include "llvm/MC/MCInst.h"
33#include "llvm/MC/MCInstrDesc.h"
34#include "llvm/MC/MCInstrInfo.h"
35#include "llvm/MC/MCObjectFileInfo.h"
36#include "llvm/MC/MCParser/MCAsmLexer.h"
37#include "llvm/MC/MCParser/MCAsmParser.h"
38#include "llvm/MC/MCParser/MCAsmParserExtension.h"
39#include "llvm/MC/MCParser/MCAsmParserUtils.h"
40#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
41#include "llvm/MC/MCParser/MCTargetAsmParser.h"
42#include "llvm/MC/MCRegisterInfo.h"
43#include "llvm/MC/MCSection.h"
44#include "llvm/MC/MCStreamer.h"
45#include "llvm/MC/MCSubtargetInfo.h"
46#include "llvm/MC/MCSymbol.h"
47#include "llvm/MC/SubtargetFeature.h"
48#include "llvm/Support/ARMBuildAttributes.h"
49#include "llvm/Support/ARMEHABI.h"
50#include "llvm/Support/Casting.h"
51#include "llvm/Support/CommandLine.h"
52#include "llvm/Support/Compiler.h"
53#include "llvm/Support/ErrorHandling.h"
54#include "llvm/Support/MathExtras.h"
55#include "llvm/Support/SMLoc.h"
56#include "llvm/Support/TargetParser.h"
57#include "llvm/Support/TargetRegistry.h"
58#include "llvm/Support/raw_ostream.h"
59#include <algorithm>
60#include <cassert>
61#include <cstddef>
62#include <cstdint>
63#include <iterator>
64#include <limits>
65#include <memory>
66#include <string>
67#include <utility>
68#include <vector>
69
70#define DEBUG_TYPE"asm-parser" "asm-parser"
71
72using namespace llvm;
73
74namespace llvm {
75extern const MCInstrDesc ARMInsts[];
76} // end namespace llvm
77
78namespace {
79
80enum class ImplicitItModeTy { Always, Never, ARMOnly, ThumbOnly };
81
82static cl::opt<ImplicitItModeTy> ImplicitItMode(
83 "arm-implicit-it", cl::init(ImplicitItModeTy::ARMOnly),
84 cl::desc("Allow conditional instructions outdside of an IT block"),
85 cl::values(clEnumValN(ImplicitItModeTy::Always, "always",llvm::cl::OptionEnumValue { "always", int(ImplicitItModeTy::Always
), "Accept in both ISAs, emit implicit ITs in Thumb" }
86 "Accept in both ISAs, emit implicit ITs in Thumb")llvm::cl::OptionEnumValue { "always", int(ImplicitItModeTy::Always
), "Accept in both ISAs, emit implicit ITs in Thumb" }
,
87 clEnumValN(ImplicitItModeTy::Never, "never",llvm::cl::OptionEnumValue { "never", int(ImplicitItModeTy::Never
), "Warn in ARM, reject in Thumb" }
88 "Warn in ARM, reject in Thumb")llvm::cl::OptionEnumValue { "never", int(ImplicitItModeTy::Never
), "Warn in ARM, reject in Thumb" }
,
89 clEnumValN(ImplicitItModeTy::ARMOnly, "arm",llvm::cl::OptionEnumValue { "arm", int(ImplicitItModeTy::ARMOnly
), "Accept in ARM, reject in Thumb" }
90 "Accept in ARM, reject in Thumb")llvm::cl::OptionEnumValue { "arm", int(ImplicitItModeTy::ARMOnly
), "Accept in ARM, reject in Thumb" }
,
91 clEnumValN(ImplicitItModeTy::ThumbOnly, "thumb",llvm::cl::OptionEnumValue { "thumb", int(ImplicitItModeTy::ThumbOnly
), "Warn in ARM, emit implicit ITs in Thumb" }
92 "Warn in ARM, emit implicit ITs in Thumb")llvm::cl::OptionEnumValue { "thumb", int(ImplicitItModeTy::ThumbOnly
), "Warn in ARM, emit implicit ITs in Thumb" }
));
93
94static cl::opt<bool> AddBuildAttributes("arm-add-build-attributes",
95 cl::init(false));
96
97enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
98
99static inline unsigned extractITMaskBit(unsigned Mask, unsigned Position) {
100 // Position==0 means we're not in an IT block at all. Position==1
101 // means we want the first state bit, which is always 0 (Then).
102 // Position==2 means we want the second state bit, stored at bit 3
103 // of Mask, and so on downwards. So (5 - Position) will shift the
104 // right bit down to bit 0, including the always-0 bit at bit 4 for
105 // the mandatory initial Then.
106 return (Mask >> (5 - Position) & 1);
107}
108
109class UnwindContext {
110 using Locs = SmallVector<SMLoc, 4>;
111
112 MCAsmParser &Parser;
113 Locs FnStartLocs;
114 Locs CantUnwindLocs;
115 Locs PersonalityLocs;
116 Locs PersonalityIndexLocs;
117 Locs HandlerDataLocs;
118 int FPReg;
119
120public:
121 UnwindContext(MCAsmParser &P) : Parser(P), FPReg(ARM::SP) {}
122
123 bool hasFnStart() const { return !FnStartLocs.empty(); }
124 bool cantUnwind() const { return !CantUnwindLocs.empty(); }
125 bool hasHandlerData() const { return !HandlerDataLocs.empty(); }
126
127 bool hasPersonality() const {
128 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
129 }
130
131 void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); }
132 void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); }
133 void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); }
134 void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); }
135 void recordPersonalityIndex(SMLoc L) { PersonalityIndexLocs.push_back(L); }
136
137 void saveFPReg(int Reg) { FPReg = Reg; }
138 int getFPReg() const { return FPReg; }
139
140 void emitFnStartLocNotes() const {
141 for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end();
142 FI != FE; ++FI)
143 Parser.Note(*FI, ".fnstart was specified here");
144 }
145
146 void emitCantUnwindLocNotes() const {
147 for (Locs::const_iterator UI = CantUnwindLocs.begin(),
148 UE = CantUnwindLocs.end(); UI != UE; ++UI)
149 Parser.Note(*UI, ".cantunwind was specified here");
150 }
151
152 void emitHandlerDataLocNotes() const {
153 for (Locs::const_iterator HI = HandlerDataLocs.begin(),
154 HE = HandlerDataLocs.end(); HI != HE; ++HI)
155 Parser.Note(*HI, ".handlerdata was specified here");
156 }
157
158 void emitPersonalityLocNotes() const {
159 for (Locs::const_iterator PI = PersonalityLocs.begin(),
160 PE = PersonalityLocs.end(),
161 PII = PersonalityIndexLocs.begin(),
162 PIE = PersonalityIndexLocs.end();
163 PI != PE || PII != PIE;) {
164 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
165 Parser.Note(*PI++, ".personality was specified here");
166 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
167 Parser.Note(*PII++, ".personalityindex was specified here");
168 else
169 llvm_unreachable(".personality and .personalityindex cannot be "::llvm::llvm_unreachable_internal(".personality and .personalityindex cannot be "
"at the same location", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 170)
170 "at the same location")::llvm::llvm_unreachable_internal(".personality and .personalityindex cannot be "
"at the same location", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 170)
;
171 }
172 }
173
174 void reset() {
175 FnStartLocs = Locs();
176 CantUnwindLocs = Locs();
177 PersonalityLocs = Locs();
178 HandlerDataLocs = Locs();
179 PersonalityIndexLocs = Locs();
180 FPReg = ARM::SP;
181 }
182};
183
184// Various sets of ARM instruction mnemonics which are used by the asm parser
185class ARMMnemonicSets {
186 StringSet<> CDE;
187 StringSet<> CDEWithVPTSuffix;
188public:
189 ARMMnemonicSets(const MCSubtargetInfo &STI);
190
191 /// Returns true iff a given mnemonic is a CDE instruction
192 bool isCDEInstr(StringRef Mnemonic) {
193 // Quick check before searching the set
194 if (!Mnemonic.startswith("cx") && !Mnemonic.startswith("vcx"))
195 return false;
196 return CDE.count(Mnemonic);
197 }
198
199 /// Returns true iff a given mnemonic is a VPT-predicable CDE instruction
200 /// (possibly with a predication suffix "e" or "t")
201 bool isVPTPredicableCDEInstr(StringRef Mnemonic) {
202 if (!Mnemonic.startswith("vcx"))
203 return false;
204 return CDEWithVPTSuffix.count(Mnemonic);
205 }
206
207 /// Returns true iff a given mnemonic is an IT-predicable CDE instruction
208 /// (possibly with a condition suffix)
209 bool isITPredicableCDEInstr(StringRef Mnemonic) {
210 if (!Mnemonic.startswith("cx"))
211 return false;
212 return Mnemonic.startswith("cx1a") || Mnemonic.startswith("cx1da") ||
213 Mnemonic.startswith("cx2a") || Mnemonic.startswith("cx2da") ||
214 Mnemonic.startswith("cx3a") || Mnemonic.startswith("cx3da");
215 }
216
217 /// Return true iff a given mnemonic is an integer CDE instruction with
218 /// dual-register destination
219 bool isCDEDualRegInstr(StringRef Mnemonic) {
220 if (!Mnemonic.startswith("cx"))
221 return false;
222 return Mnemonic == "cx1d" || Mnemonic == "cx1da" ||
223 Mnemonic == "cx2d" || Mnemonic == "cx2da" ||
224 Mnemonic == "cx3d" || Mnemonic == "cx3da";
225 }
226};
227
228ARMMnemonicSets::ARMMnemonicSets(const MCSubtargetInfo &STI) {
229 for (StringRef Mnemonic: { "cx1", "cx1a", "cx1d", "cx1da",
230 "cx2", "cx2a", "cx2d", "cx2da",
231 "cx3", "cx3a", "cx3d", "cx3da", })
232 CDE.insert(Mnemonic);
233 for (StringRef Mnemonic :
234 {"vcx1", "vcx1a", "vcx2", "vcx2a", "vcx3", "vcx3a"}) {
235 CDE.insert(Mnemonic);
236 CDEWithVPTSuffix.insert(Mnemonic);
237 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "t");
238 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "e");
239 }
240}
241
242class ARMAsmParser : public MCTargetAsmParser {
243 const MCRegisterInfo *MRI;
244 UnwindContext UC;
245 ARMMnemonicSets MS;
246
247 ARMTargetStreamer &getTargetStreamer() {
248 assert(getParser().getStreamer().getTargetStreamer() &&((getParser().getStreamer().getTargetStreamer() && "do not have a target streamer"
) ? static_cast<void> (0) : __assert_fail ("getParser().getStreamer().getTargetStreamer() && \"do not have a target streamer\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 249, __PRETTY_FUNCTION__))
249 "do not have a target streamer")((getParser().getStreamer().getTargetStreamer() && "do not have a target streamer"
) ? static_cast<void> (0) : __assert_fail ("getParser().getStreamer().getTargetStreamer() && \"do not have a target streamer\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 249, __PRETTY_FUNCTION__))
;
250 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
251 return static_cast<ARMTargetStreamer &>(TS);
252 }
253
254 // Map of register aliases registers via the .req directive.
255 StringMap<unsigned> RegisterReqs;
256
257 bool NextSymbolIsThumb;
258
259 bool useImplicitITThumb() const {
260 return ImplicitItMode == ImplicitItModeTy::Always ||
261 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
262 }
263
264 bool useImplicitITARM() const {
265 return ImplicitItMode == ImplicitItModeTy::Always ||
266 ImplicitItMode == ImplicitItModeTy::ARMOnly;
267 }
268
269 struct {
270 ARMCC::CondCodes Cond; // Condition for IT block.
271 unsigned Mask:4; // Condition mask for instructions.
272 // Starting at first 1 (from lsb).
273 // '1' condition as indicated in IT.
274 // '0' inverse of condition (else).
275 // Count of instructions in IT block is
276 // 4 - trailingzeroes(mask)
277 // Note that this does not have the same encoding
278 // as in the IT instruction, which also depends
279 // on the low bit of the condition code.
280
281 unsigned CurPosition; // Current position in parsing of IT
282 // block. In range [0,4], with 0 being the IT
283 // instruction itself. Initialized according to
284 // count of instructions in block. ~0U if no
285 // active IT block.
286
287 bool IsExplicit; // true - The IT instruction was present in the
288 // input, we should not modify it.
289 // false - The IT instruction was added
290 // implicitly, we can extend it if that
291 // would be legal.
292 } ITState;
293
294 SmallVector<MCInst, 4> PendingConditionalInsts;
295
296 void flushPendingInstructions(MCStreamer &Out) override {
297 if (!inImplicitITBlock()) {
298 assert(PendingConditionalInsts.size() == 0)((PendingConditionalInsts.size() == 0) ? static_cast<void>
(0) : __assert_fail ("PendingConditionalInsts.size() == 0", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 298, __PRETTY_FUNCTION__))
;
299 return;
300 }
301
302 // Emit the IT instruction
303 MCInst ITInst;
304 ITInst.setOpcode(ARM::t2IT);
305 ITInst.addOperand(MCOperand::createImm(ITState.Cond));
306 ITInst.addOperand(MCOperand::createImm(ITState.Mask));
307 Out.emitInstruction(ITInst, getSTI());
308
309 // Emit the conditonal instructions
310 assert(PendingConditionalInsts.size() <= 4)((PendingConditionalInsts.size() <= 4) ? static_cast<void
> (0) : __assert_fail ("PendingConditionalInsts.size() <= 4"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 310, __PRETTY_FUNCTION__))
;
311 for (const MCInst &Inst : PendingConditionalInsts) {
312 Out.emitInstruction(Inst, getSTI());
313 }
314 PendingConditionalInsts.clear();
315
316 // Clear the IT state
317 ITState.Mask = 0;
318 ITState.CurPosition = ~0U;
319 }
320
321 bool inITBlock() { return ITState.CurPosition != ~0U; }
322 bool inExplicitITBlock() { return inITBlock() && ITState.IsExplicit; }
323 bool inImplicitITBlock() { return inITBlock() && !ITState.IsExplicit; }
324
325 bool lastInITBlock() {
326 return ITState.CurPosition == 4 - countTrailingZeros(ITState.Mask);
327 }
328
329 void forwardITPosition() {
330 if (!inITBlock()) return;
331 // Move to the next instruction in the IT block, if there is one. If not,
332 // mark the block as done, except for implicit IT blocks, which we leave
333 // open until we find an instruction that can't be added to it.
334 unsigned TZ = countTrailingZeros(ITState.Mask);
335 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
336 ITState.CurPosition = ~0U; // Done with the IT block after this.
337 }
338
339 // Rewind the state of the current IT block, removing the last slot from it.
340 void rewindImplicitITPosition() {
341 assert(inImplicitITBlock())((inImplicitITBlock()) ? static_cast<void> (0) : __assert_fail
("inImplicitITBlock()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 341, __PRETTY_FUNCTION__))
;
8
'?' condition is true
342 assert(ITState.CurPosition > 1)((ITState.CurPosition > 1) ? static_cast<void> (0) :
__assert_fail ("ITState.CurPosition > 1", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 342, __PRETTY_FUNCTION__))
;
9
Assuming field 'CurPosition' is > 1
10
'?' condition is true
343 ITState.CurPosition--;
344 unsigned TZ = countTrailingZeros(ITState.Mask);
11
Calling 'countTrailingZeros<unsigned int>'
18
Returning from 'countTrailingZeros<unsigned int>'
19
'TZ' initialized to 32
345 unsigned NewMask = 0;
346 NewMask |= ITState.Mask & (0xC << TZ);
20
The result of the left shift is undefined due to shifting by '32', which is greater or equal to the width of type 'int'
347 NewMask |= 0x2 << TZ;
348 ITState.Mask = NewMask;
349 }
350
351 // Rewind the state of the current IT block, removing the last slot from it.
352 // If we were at the first slot, this closes the IT block.
353 void discardImplicitITBlock() {
354 assert(inImplicitITBlock())((inImplicitITBlock()) ? static_cast<void> (0) : __assert_fail
("inImplicitITBlock()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 354, __PRETTY_FUNCTION__))
;
355 assert(ITState.CurPosition == 1)((ITState.CurPosition == 1) ? static_cast<void> (0) : __assert_fail
("ITState.CurPosition == 1", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 355, __PRETTY_FUNCTION__))
;
356 ITState.CurPosition = ~0U;
357 }
358
359 // Return the low-subreg of a given Q register.
360 unsigned getDRegFromQReg(unsigned QReg) const {
361 return MRI->getSubReg(QReg, ARM::dsub_0);
362 }
363
364 // Get the condition code corresponding to the current IT block slot.
365 ARMCC::CondCodes currentITCond() {
366 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
367 return MaskBit ? ARMCC::getOppositeCondition(ITState.Cond) : ITState.Cond;
368 }
369
370 // Invert the condition of the current IT block slot without changing any
371 // other slots in the same block.
372 void invertCurrentITCondition() {
373 if (ITState.CurPosition == 1) {
374 ITState.Cond = ARMCC::getOppositeCondition(ITState.Cond);
375 } else {
376 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
377 }
378 }
379
380 // Returns true if the current IT block is full (all 4 slots used).
381 bool isITBlockFull() {
382 return inITBlock() && (ITState.Mask & 1);
383 }
384
385 // Extend the current implicit IT block to have one more slot with the given
386 // condition code.
387 void extendImplicitITBlock(ARMCC::CondCodes Cond) {
388 assert(inImplicitITBlock())((inImplicitITBlock()) ? static_cast<void> (0) : __assert_fail
("inImplicitITBlock()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 388, __PRETTY_FUNCTION__))
;
389 assert(!isITBlockFull())((!isITBlockFull()) ? static_cast<void> (0) : __assert_fail
("!isITBlockFull()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 389, __PRETTY_FUNCTION__))
;
390 assert(Cond == ITState.Cond ||((Cond == ITState.Cond || Cond == ARMCC::getOppositeCondition
(ITState.Cond)) ? static_cast<void> (0) : __assert_fail
("Cond == ITState.Cond || Cond == ARMCC::getOppositeCondition(ITState.Cond)"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 391, __PRETTY_FUNCTION__))
391 Cond == ARMCC::getOppositeCondition(ITState.Cond))((Cond == ITState.Cond || Cond == ARMCC::getOppositeCondition
(ITState.Cond)) ? static_cast<void> (0) : __assert_fail
("Cond == ITState.Cond || Cond == ARMCC::getOppositeCondition(ITState.Cond)"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 391, __PRETTY_FUNCTION__))
;
392 unsigned TZ = countTrailingZeros(ITState.Mask);
393 unsigned NewMask = 0;
394 // Keep any existing condition bits.
395 NewMask |= ITState.Mask & (0xE << TZ);
396 // Insert the new condition bit.
397 NewMask |= (Cond != ITState.Cond) << TZ;
398 // Move the trailing 1 down one bit.
399 NewMask |= 1 << (TZ - 1);
400 ITState.Mask = NewMask;
401 }
402
403 // Create a new implicit IT block with a dummy condition code.
404 void startImplicitITBlock() {
405 assert(!inITBlock())((!inITBlock()) ? static_cast<void> (0) : __assert_fail
("!inITBlock()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 405, __PRETTY_FUNCTION__))
;
406 ITState.Cond = ARMCC::AL;
407 ITState.Mask = 8;
408 ITState.CurPosition = 1;
409 ITState.IsExplicit = false;
410 }
411
412 // Create a new explicit IT block with the given condition and mask.
413 // The mask should be in the format used in ARMOperand and
414 // MCOperand, with a 1 implying 'e', regardless of the low bit of
415 // the condition.
416 void startExplicitITBlock(ARMCC::CondCodes Cond, unsigned Mask) {
417 assert(!inITBlock())((!inITBlock()) ? static_cast<void> (0) : __assert_fail
("!inITBlock()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 417, __PRETTY_FUNCTION__))
;
418 ITState.Cond = Cond;
419 ITState.Mask = Mask;
420 ITState.CurPosition = 0;
421 ITState.IsExplicit = true;
422 }
423
424 struct {
425 unsigned Mask : 4;
426 unsigned CurPosition;
427 } VPTState;
428 bool inVPTBlock() { return VPTState.CurPosition != ~0U; }
429 void forwardVPTPosition() {
430 if (!inVPTBlock()) return;
431 unsigned TZ = countTrailingZeros(VPTState.Mask);
432 if (++VPTState.CurPosition == 5 - TZ)
433 VPTState.CurPosition = ~0U;
434 }
435
436 void Note(SMLoc L, const Twine &Msg, SMRange Range = None) {
437 return getParser().Note(L, Msg, Range);
438 }
439
440 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) {
441 return getParser().Warning(L, Msg, Range);
442 }
443
444 bool Error(SMLoc L, const Twine &Msg, SMRange Range = None) {
445 return getParser().Error(L, Msg, Range);
446 }
447
448 bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
449 unsigned ListNo, bool IsARPop = false);
450 bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands,
451 unsigned ListNo);
452
453 int tryParseRegister();
454 bool tryParseRegisterWithWriteBack(OperandVector &);
455 int tryParseShiftRegister(OperandVector &);
456 bool parseRegisterList(OperandVector &, bool EnforceOrder = true);
457 bool parseMemory(OperandVector &);
458 bool parseOperand(OperandVector &, StringRef Mnemonic);
459 bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
460 bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
461 unsigned &ShiftAmount);
462 bool parseLiteralValues(unsigned Size, SMLoc L);
463 bool parseDirectiveThumb(SMLoc L);
464 bool parseDirectiveARM(SMLoc L);
465 bool parseDirectiveThumbFunc(SMLoc L);
466 bool parseDirectiveCode(SMLoc L);
467 bool parseDirectiveSyntax(SMLoc L);
468 bool parseDirectiveReq(StringRef Name, SMLoc L);
469 bool parseDirectiveUnreq(SMLoc L);
470 bool parseDirectiveArch(SMLoc L);
471 bool parseDirectiveEabiAttr(SMLoc L);
472 bool parseDirectiveCPU(SMLoc L);
473 bool parseDirectiveFPU(SMLoc L);
474 bool parseDirectiveFnStart(SMLoc L);
475 bool parseDirectiveFnEnd(SMLoc L);
476 bool parseDirectiveCantUnwind(SMLoc L);
477 bool parseDirectivePersonality(SMLoc L);
478 bool parseDirectiveHandlerData(SMLoc L);
479 bool parseDirectiveSetFP(SMLoc L);
480 bool parseDirectivePad(SMLoc L);
481 bool parseDirectiveRegSave(SMLoc L, bool IsVector);
482 bool parseDirectiveInst(SMLoc L, char Suffix = '\0');
483 bool parseDirectiveLtorg(SMLoc L);
484 bool parseDirectiveEven(SMLoc L);
485 bool parseDirectivePersonalityIndex(SMLoc L);
486 bool parseDirectiveUnwindRaw(SMLoc L);
487 bool parseDirectiveTLSDescSeq(SMLoc L);
488 bool parseDirectiveMovSP(SMLoc L);
489 bool parseDirectiveObjectArch(SMLoc L);
490 bool parseDirectiveArchExtension(SMLoc L);
491 bool parseDirectiveAlign(SMLoc L);
492 bool parseDirectiveThumbSet(SMLoc L);
493
494 bool isMnemonicVPTPredicable(StringRef Mnemonic, StringRef ExtraToken);
495 StringRef splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
496 unsigned &PredicationCode,
497 unsigned &VPTPredicationCode, bool &CarrySetting,
498 unsigned &ProcessorIMod, StringRef &ITMask);
499 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef ExtraToken,
500 StringRef FullInst, bool &CanAcceptCarrySet,
501 bool &CanAcceptPredicationCode,
502 bool &CanAcceptVPTPredicationCode);
503
504 void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting,
505 OperandVector &Operands);
506 bool CDEConvertDualRegOperand(StringRef Mnemonic, OperandVector &Operands);
507
508 bool isThumb() const {
509 // FIXME: Can tablegen auto-generate this?
510 return getSTI().getFeatureBits()[ARM::ModeThumb];
511 }
512
513 bool isThumbOne() const {
514 return isThumb() && !getSTI().getFeatureBits()[ARM::FeatureThumb2];
515 }
516
517 bool isThumbTwo() const {
518 return isThumb() && getSTI().getFeatureBits()[ARM::FeatureThumb2];
519 }
520
521 bool hasThumb() const {
522 return getSTI().getFeatureBits()[ARM::HasV4TOps];
523 }
524
525 bool hasThumb2() const {
526 return getSTI().getFeatureBits()[ARM::FeatureThumb2];
527 }
528
529 bool hasV6Ops() const {
530 return getSTI().getFeatureBits()[ARM::HasV6Ops];
531 }
532
533 bool hasV6T2Ops() const {
534 return getSTI().getFeatureBits()[ARM::HasV6T2Ops];
535 }
536
537 bool hasV6MOps() const {
538 return getSTI().getFeatureBits()[ARM::HasV6MOps];
539 }
540
541 bool hasV7Ops() const {
542 return getSTI().getFeatureBits()[ARM::HasV7Ops];
543 }
544
545 bool hasV8Ops() const {
546 return getSTI().getFeatureBits()[ARM::HasV8Ops];
547 }
548
549 bool hasV8MBaseline() const {
550 return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps];
551 }
552
553 bool hasV8MMainline() const {
554 return getSTI().getFeatureBits()[ARM::HasV8MMainlineOps];
555 }
556 bool hasV8_1MMainline() const {
557 return getSTI().getFeatureBits()[ARM::HasV8_1MMainlineOps];
558 }
559 bool hasMVE() const {
560 return getSTI().getFeatureBits()[ARM::HasMVEIntegerOps];
561 }
562 bool hasMVEFloat() const {
563 return getSTI().getFeatureBits()[ARM::HasMVEFloatOps];
564 }
565 bool hasCDE() const {
566 return getSTI().getFeatureBits()[ARM::HasCDEOps];
567 }
568 bool has8MSecExt() const {
569 return getSTI().getFeatureBits()[ARM::Feature8MSecExt];
570 }
571
572 bool hasARM() const {
573 return !getSTI().getFeatureBits()[ARM::FeatureNoARM];
574 }
575
576 bool hasDSP() const {
577 return getSTI().getFeatureBits()[ARM::FeatureDSP];
578 }
579
580 bool hasD32() const {
581 return getSTI().getFeatureBits()[ARM::FeatureD32];
582 }
583
584 bool hasV8_1aOps() const {
585 return getSTI().getFeatureBits()[ARM::HasV8_1aOps];
586 }
587
588 bool hasRAS() const {
589 return getSTI().getFeatureBits()[ARM::FeatureRAS];
590 }
591
592 void SwitchMode() {
593 MCSubtargetInfo &STI = copySTI();
594 auto FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
595 setAvailableFeatures(FB);
596 }
597
598 void FixModeAfterArchChange(bool WasThumb, SMLoc Loc);
599
600 bool isMClass() const {
601 return getSTI().getFeatureBits()[ARM::FeatureMClass];
602 }
603
604 /// @name Auto-generated Match Functions
605 /// {
606
607#define GET_ASSEMBLER_HEADER
608#include "ARMGenAsmMatcher.inc"
609
610 /// }
611
612 OperandMatchResultTy parseITCondCode(OperandVector &);
613 OperandMatchResultTy parseCoprocNumOperand(OperandVector &);
614 OperandMatchResultTy parseCoprocRegOperand(OperandVector &);
615 OperandMatchResultTy parseCoprocOptionOperand(OperandVector &);
616 OperandMatchResultTy parseMemBarrierOptOperand(OperandVector &);
617 OperandMatchResultTy parseTraceSyncBarrierOptOperand(OperandVector &);
618 OperandMatchResultTy parseInstSyncBarrierOptOperand(OperandVector &);
619 OperandMatchResultTy parseProcIFlagsOperand(OperandVector &);
620 OperandMatchResultTy parseMSRMaskOperand(OperandVector &);
621 OperandMatchResultTy parseBankedRegOperand(OperandVector &);
622 OperandMatchResultTy parsePKHImm(OperandVector &O, StringRef Op, int Low,
623 int High);
624 OperandMatchResultTy parsePKHLSLImm(OperandVector &O) {
625 return parsePKHImm(O, "lsl", 0, 31);
626 }
627 OperandMatchResultTy parsePKHASRImm(OperandVector &O) {
628 return parsePKHImm(O, "asr", 1, 32);
629 }
630 OperandMatchResultTy parseSetEndImm(OperandVector &);
631 OperandMatchResultTy parseShifterImm(OperandVector &);
632 OperandMatchResultTy parseRotImm(OperandVector &);
633 OperandMatchResultTy parseModImm(OperandVector &);
634 OperandMatchResultTy parseBitfield(OperandVector &);
635 OperandMatchResultTy parsePostIdxReg(OperandVector &);
636 OperandMatchResultTy parseAM3Offset(OperandVector &);
637 OperandMatchResultTy parseFPImm(OperandVector &);
638 OperandMatchResultTy parseVectorList(OperandVector &);
639 OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index,
640 SMLoc &EndLoc);
641
642 // Asm Match Converter Methods
643 void cvtThumbMultiply(MCInst &Inst, const OperandVector &);
644 void cvtThumbBranches(MCInst &Inst, const OperandVector &);
645 void cvtMVEVMOVQtoDReg(MCInst &Inst, const OperandVector &);
646
647 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
648 bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out);
649 bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands);
650 bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
651 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
652 bool isITBlockTerminator(MCInst &Inst) const;
653 void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands);
654 bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
655 bool Load, bool ARMMode, bool Writeback);
656
657public:
658 enum ARMMatchResultTy {
659 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
660 Match_RequiresNotITBlock,
661 Match_RequiresV6,
662 Match_RequiresThumb2,
663 Match_RequiresV8,
664 Match_RequiresFlagSetting,
665#define GET_OPERAND_DIAGNOSTIC_TYPES
666#include "ARMGenAsmMatcher.inc"
667
668 };
669
670 ARMAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
671 const MCInstrInfo &MII, const MCTargetOptions &Options)
672 : MCTargetAsmParser(Options, STI, MII), UC(Parser), MS(STI) {
673 MCAsmParserExtension::Initialize(Parser);
674
675 // Cache the MCRegisterInfo.
676 MRI = getContext().getRegisterInfo();
677
678 // Initialize the set of available features.
679 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
680
681 // Add build attributes based on the selected target.
682 if (AddBuildAttributes)
683 getTargetStreamer().emitTargetAttributes(STI);
684
685 // Not in an ITBlock to start with.
686 ITState.CurPosition = ~0U;
687
688 VPTState.CurPosition = ~0U;
689
690 NextSymbolIsThumb = false;
691 }
692
693 // Implementation of the MCTargetAsmParser interface:
694 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
695 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
696 SMLoc &EndLoc) override;
697 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
698 SMLoc NameLoc, OperandVector &Operands) override;
699 bool ParseDirective(AsmToken DirectiveID) override;
700
701 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
702 unsigned Kind) override;
703 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
704
705 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
706 OperandVector &Operands, MCStreamer &Out,
707 uint64_t &ErrorInfo,
708 bool MatchingInlineAsm) override;
709 unsigned MatchInstruction(OperandVector &Operands, MCInst &Inst,
710 SmallVectorImpl<NearMissInfo> &NearMisses,
711 bool MatchingInlineAsm, bool &EmitInITBlock,
712 MCStreamer &Out);
713
714 struct NearMissMessage {
715 SMLoc Loc;
716 SmallString<128> Message;
717 };
718
719 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
720
721 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
722 SmallVectorImpl<NearMissMessage> &NearMissesOut,
723 SMLoc IDLoc, OperandVector &Operands);
724 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
725 OperandVector &Operands);
726
727 void doBeforeLabelEmit(MCSymbol *Symbol) override;
728
729 void onLabelParsed(MCSymbol *Symbol) override;
730};
731
732/// ARMOperand - Instances of this class represent a parsed ARM machine
733/// operand.
734class ARMOperand : public MCParsedAsmOperand {
735 enum KindTy {
736 k_CondCode,
737 k_VPTPred,
738 k_CCOut,
739 k_ITCondMask,
740 k_CoprocNum,
741 k_CoprocReg,
742 k_CoprocOption,
743 k_Immediate,
744 k_MemBarrierOpt,
745 k_InstSyncBarrierOpt,
746 k_TraceSyncBarrierOpt,
747 k_Memory,
748 k_PostIndexRegister,
749 k_MSRMask,
750 k_BankedReg,
751 k_ProcIFlags,
752 k_VectorIndex,
753 k_Register,
754 k_RegisterList,
755 k_RegisterListWithAPSR,
756 k_DPRRegisterList,
757 k_SPRRegisterList,
758 k_FPSRegisterListWithVPR,
759 k_FPDRegisterListWithVPR,
760 k_VectorList,
761 k_VectorListAllLanes,
762 k_VectorListIndexed,
763 k_ShiftedRegister,
764 k_ShiftedImmediate,
765 k_ShifterImmediate,
766 k_RotateImmediate,
767 k_ModifiedImmediate,
768 k_ConstantPoolImmediate,
769 k_BitfieldDescriptor,
770 k_Token,
771 } Kind;
772
773 SMLoc StartLoc, EndLoc, AlignmentLoc;
774 SmallVector<unsigned, 8> Registers;
775
776 struct CCOp {
777 ARMCC::CondCodes Val;
778 };
779
780 struct VCCOp {
781 ARMVCC::VPTCodes Val;
782 };
783
784 struct CopOp {
785 unsigned Val;
786 };
787
788 struct CoprocOptionOp {
789 unsigned Val;
790 };
791
792 struct ITMaskOp {
793 unsigned Mask:4;
794 };
795
796 struct MBOptOp {
797 ARM_MB::MemBOpt Val;
798 };
799
800 struct ISBOptOp {
801 ARM_ISB::InstSyncBOpt Val;
802 };
803
804 struct TSBOptOp {
805 ARM_TSB::TraceSyncBOpt Val;
806 };
807
808 struct IFlagsOp {
809 ARM_PROC::IFlags Val;
810 };
811
812 struct MMaskOp {
813 unsigned Val;
814 };
815
816 struct BankedRegOp {
817 unsigned Val;
818 };
819
820 struct TokOp {
821 const char *Data;
822 unsigned Length;
823 };
824
825 struct RegOp {
826 unsigned RegNum;
827 };
828
829 // A vector register list is a sequential list of 1 to 4 registers.
830 struct VectorListOp {
831 unsigned RegNum;
832 unsigned Count;
833 unsigned LaneIndex;
834 bool isDoubleSpaced;
835 };
836
837 struct VectorIndexOp {
838 unsigned Val;
839 };
840
841 struct ImmOp {
842 const MCExpr *Val;
843 };
844
845 /// Combined record for all forms of ARM address expressions.
846 struct MemoryOp {
847 unsigned BaseRegNum;
848 // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
849 // was specified.
850 const MCConstantExpr *OffsetImm; // Offset immediate value
851 unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL
852 ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
853 unsigned ShiftImm; // shift for OffsetReg.
854 unsigned Alignment; // 0 = no alignment specified
855 // n = alignment in bytes (2, 4, 8, 16, or 32)
856 unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit)
857 };
858
859 struct PostIdxRegOp {
860 unsigned RegNum;
861 bool isAdd;
862 ARM_AM::ShiftOpc ShiftTy;
863 unsigned ShiftImm;
864 };
865
866 struct ShifterImmOp {
867 bool isASR;
868 unsigned Imm;
869 };
870
871 struct RegShiftedRegOp {
872 ARM_AM::ShiftOpc ShiftTy;
873 unsigned SrcReg;
874 unsigned ShiftReg;
875 unsigned ShiftImm;
876 };
877
878 struct RegShiftedImmOp {
879 ARM_AM::ShiftOpc ShiftTy;
880 unsigned SrcReg;
881 unsigned ShiftImm;
882 };
883
884 struct RotImmOp {
885 unsigned Imm;
886 };
887
888 struct ModImmOp {
889 unsigned Bits;
890 unsigned Rot;
891 };
892
893 struct BitfieldOp {
894 unsigned LSB;
895 unsigned Width;
896 };
897
898 union {
899 struct CCOp CC;
900 struct VCCOp VCC;
901 struct CopOp Cop;
902 struct CoprocOptionOp CoprocOption;
903 struct MBOptOp MBOpt;
904 struct ISBOptOp ISBOpt;
905 struct TSBOptOp TSBOpt;
906 struct ITMaskOp ITMask;
907 struct IFlagsOp IFlags;
908 struct MMaskOp MMask;
909 struct BankedRegOp BankedReg;
910 struct TokOp Tok;
911 struct RegOp Reg;
912 struct VectorListOp VectorList;
913 struct VectorIndexOp VectorIndex;
914 struct ImmOp Imm;
915 struct MemoryOp Memory;
916 struct PostIdxRegOp PostIdxReg;
917 struct ShifterImmOp ShifterImm;
918 struct RegShiftedRegOp RegShiftedReg;
919 struct RegShiftedImmOp RegShiftedImm;
920 struct RotImmOp RotImm;
921 struct ModImmOp ModImm;
922 struct BitfieldOp Bitfield;
923 };
924
925public:
926 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
927
928 /// getStartLoc - Get the location of the first token of this operand.
929 SMLoc getStartLoc() const override { return StartLoc; }
930
931 /// getEndLoc - Get the location of the last token of this operand.
932 SMLoc getEndLoc() const override { return EndLoc; }
933
934 /// getLocRange - Get the range between the first and last token of this
935 /// operand.
936 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
937
938 /// getAlignmentLoc - Get the location of the Alignment token of this operand.
939 SMLoc getAlignmentLoc() const {
940 assert(Kind == k_Memory && "Invalid access!")((Kind == k_Memory && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Memory && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 940, __PRETTY_FUNCTION__))
;
941 return AlignmentLoc;
942 }
943
944 ARMCC::CondCodes getCondCode() const {
945 assert(Kind == k_CondCode && "Invalid access!")((Kind == k_CondCode && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_CondCode && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 945, __PRETTY_FUNCTION__))
;
946 return CC.Val;
947 }
948
949 ARMVCC::VPTCodes getVPTPred() const {
950 assert(isVPTPred() && "Invalid access!")((isVPTPred() && "Invalid access!") ? static_cast<
void> (0) : __assert_fail ("isVPTPred() && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 950, __PRETTY_FUNCTION__))
;
951 return VCC.Val;
952 }
953
954 unsigned getCoproc() const {
955 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!")(((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"
) ? static_cast<void> (0) : __assert_fail ("(Kind == k_CoprocNum || Kind == k_CoprocReg) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 955, __PRETTY_FUNCTION__))
;
956 return Cop.Val;
957 }
958
959 StringRef getToken() const {
960 assert(Kind == k_Token && "Invalid access!")((Kind == k_Token && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Token && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 960, __PRETTY_FUNCTION__))
;
961 return StringRef(Tok.Data, Tok.Length);
962 }
963
964 unsigned getReg() const override {
965 assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!")(((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"
) ? static_cast<void> (0) : __assert_fail ("(Kind == k_Register || Kind == k_CCOut) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 965, __PRETTY_FUNCTION__))
;
966 return Reg.RegNum;
967 }
968
969 const SmallVectorImpl<unsigned> &getRegList() const {
970 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||(((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind
== k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR
) && "Invalid access!") ? static_cast<void> (0)
: __assert_fail ("(Kind == k_RegisterList || Kind == k_RegisterListWithAPSR || Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind == k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 974, __PRETTY_FUNCTION__))
971 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||(((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind
== k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR
) && "Invalid access!") ? static_cast<void> (0)
: __assert_fail ("(Kind == k_RegisterList || Kind == k_RegisterListWithAPSR || Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind == k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 974, __PRETTY_FUNCTION__))
972 Kind == k_FPSRegisterListWithVPR ||(((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind
== k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR
) && "Invalid access!") ? static_cast<void> (0)
: __assert_fail ("(Kind == k_RegisterList || Kind == k_RegisterListWithAPSR || Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind == k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 974, __PRETTY_FUNCTION__))
973 Kind == k_FPDRegisterListWithVPR) &&(((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind
== k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR
) && "Invalid access!") ? static_cast<void> (0)
: __assert_fail ("(Kind == k_RegisterList || Kind == k_RegisterListWithAPSR || Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind == k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 974, __PRETTY_FUNCTION__))
974 "Invalid access!")(((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind
== k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR
) && "Invalid access!") ? static_cast<void> (0)
: __assert_fail ("(Kind == k_RegisterList || Kind == k_RegisterListWithAPSR || Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || Kind == k_FPSRegisterListWithVPR || Kind == k_FPDRegisterListWithVPR) && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 974, __PRETTY_FUNCTION__))
;
975 return Registers;
976 }
977
978 const MCExpr *getImm() const {
979 assert(isImm() && "Invalid access!")((isImm() && "Invalid access!") ? static_cast<void
> (0) : __assert_fail ("isImm() && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 979, __PRETTY_FUNCTION__))
;
980 return Imm.Val;
981 }
982
983 const MCExpr *getConstantPoolImm() const {
984 assert(isConstantPoolImm() && "Invalid access!")((isConstantPoolImm() && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("isConstantPoolImm() && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 984, __PRETTY_FUNCTION__))
;
985 return Imm.Val;
986 }
987
988 unsigned getVectorIndex() const {
989 assert(Kind == k_VectorIndex && "Invalid access!")((Kind == k_VectorIndex && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_VectorIndex && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 989, __PRETTY_FUNCTION__))
;
990 return VectorIndex.Val;
991 }
992
993 ARM_MB::MemBOpt getMemBarrierOpt() const {
994 assert(Kind == k_MemBarrierOpt && "Invalid access!")((Kind == k_MemBarrierOpt && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_MemBarrierOpt && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 994, __PRETTY_FUNCTION__))
;
995 return MBOpt.Val;
996 }
997
998 ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const {
999 assert(Kind == k_InstSyncBarrierOpt && "Invalid access!")((Kind == k_InstSyncBarrierOpt && "Invalid access!") ?
static_cast<void> (0) : __assert_fail ("Kind == k_InstSyncBarrierOpt && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 999, __PRETTY_FUNCTION__))
;
1000 return ISBOpt.Val;
1001 }
1002
1003 ARM_TSB::TraceSyncBOpt getTraceSyncBarrierOpt() const {
1004 assert(Kind == k_TraceSyncBarrierOpt && "Invalid access!")((Kind == k_TraceSyncBarrierOpt && "Invalid access!")
? static_cast<void> (0) : __assert_fail ("Kind == k_TraceSyncBarrierOpt && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 1004, __PRETTY_FUNCTION__))
;
1005 return TSBOpt.Val;
1006 }
1007
1008 ARM_PROC::IFlags getProcIFlags() const {
1009 assert(Kind == k_ProcIFlags && "Invalid access!")((Kind == k_ProcIFlags && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_ProcIFlags && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 1009, __PRETTY_FUNCTION__))
;
1010 return IFlags.Val;
1011 }
1012
1013 unsigned getMSRMask() const {
1014 assert(Kind == k_MSRMask && "Invalid access!")((Kind == k_MSRMask && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_MSRMask && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 1014, __PRETTY_FUNCTION__))
;
1015 return MMask.Val;
1016 }
1017
1018 unsigned getBankedReg() const {
1019 assert(Kind == k_BankedReg && "Invalid access!")((Kind == k_BankedReg && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_BankedReg && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 1019, __PRETTY_FUNCTION__))
;
1020 return BankedReg.Val;
1021 }
1022
1023 bool isCoprocNum() const { return Kind == k_CoprocNum; }
1024 bool isCoprocReg() const { return Kind == k_CoprocReg; }
1025 bool isCoprocOption() const { return Kind == k_CoprocOption; }
1026 bool isCondCode() const { return Kind == k_CondCode; }
1027 bool isVPTPred() const { return Kind == k_VPTPred; }
1028 bool isCCOut() const { return Kind == k_CCOut; }
1029 bool isITMask() const { return Kind == k_ITCondMask; }
1030 bool isITCondCode() const { return Kind == k_CondCode; }
1031 bool isImm() const override {
1032 return Kind == k_Immediate;
1033 }
1034
1035 bool isARMBranchTarget() const {
1036 if (!isImm()) return false;
1037
1038 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1039 return CE->getValue() % 4 == 0;
1040 return true;
1041 }
1042
1043
1044 bool isThumbBranchTarget() const {
1045 if (!isImm()) return false;
1046
1047 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1048 return CE->getValue() % 2 == 0;
1049 return true;
1050 }
1051
1052 // checks whether this operand is an unsigned offset which fits is a field
1053 // of specified width and scaled by a specific number of bits
1054 template<unsigned width, unsigned scale>
1055 bool isUnsignedOffset() const {
1056 if (!isImm()) return false;
1057 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1058 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1059 int64_t Val = CE->getValue();
1060 int64_t Align = 1LL << scale;
1061 int64_t Max = Align * ((1LL << width) - 1);
1062 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
1063 }
1064 return false;
1065 }
1066
1067 // checks whether this operand is an signed offset which fits is a field
1068 // of specified width and scaled by a specific number of bits
1069 template<unsigned width, unsigned scale>
1070 bool isSignedOffset() const {
1071 if (!isImm()) return false;
1072 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1073 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1074 int64_t Val = CE->getValue();
1075 int64_t Align = 1LL << scale;
1076 int64_t Max = Align * ((1LL << (width-1)) - 1);
1077 int64_t Min = -Align * (1LL << (width-1));
1078 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
1079 }
1080 return false;
1081 }
1082
1083 // checks whether this operand is an offset suitable for the LE /
1084 // LETP instructions in Arm v8.1M
1085 bool isLEOffset() const {
1086 if (!isImm()) return false;
1087 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1088 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1089 int64_t Val = CE->getValue();
1090 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1091 }
1092 return false;
1093 }
1094
1095 // checks whether this operand is a memory operand computed as an offset
1096 // applied to PC. the offset may have 8 bits of magnitude and is represented
1097 // with two bits of shift. textually it may be either [pc, #imm], #imm or
1098 // relocable expression...
1099 bool isThumbMemPC() const {
1100 int64_t Val = 0;
1101 if (isImm()) {
1102 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1103 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val);
1104 if (!CE) return false;
1105 Val = CE->getValue();
1106 }
1107 else if (isGPRMem()) {
1108 if(!Memory.OffsetImm || Memory.OffsetRegNum) return false;
1109 if(Memory.BaseRegNum != ARM::PC) return false;
1110 Val = Memory.OffsetImm->getValue();
1111 }
1112 else return false;
1113 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1114 }
1115
1116 bool isFPImm() const {
1117 if (!isImm()) return false;
1118 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1119 if (!CE) return false;
1120 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
1121 return Val != -1;
1122 }
1123
1124 template<int64_t N, int64_t M>
1125 bool isImmediate() const {
1126 if (!isImm()) return false;
1127 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1128 if (!CE) return false;
1129 int64_t Value = CE->getValue();
1130 return Value >= N && Value <= M;
1131 }
1132
1133 template<int64_t N, int64_t M>
1134 bool isImmediateS4() const {
1135 if (!isImm()) return false;
1136 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1137 if (!CE) return false;
1138 int64_t Value = CE->getValue();
1139 return ((Value & 3) == 0) && Value >= N && Value <= M;
1140 }
1141 template<int64_t N, int64_t M>
1142 bool isImmediateS2() const {
1143 if (!isImm()) return false;
1144 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1145 if (!CE) return false;
1146 int64_t Value = CE->getValue();
1147 return ((Value & 1) == 0) && Value >= N && Value <= M;
1148 }
1149 bool isFBits16() const {
1150 return isImmediate<0, 17>();
1151 }
1152 bool isFBits32() const {
1153 return isImmediate<1, 33>();
1154 }
1155 bool isImm8s4() const {
1156 return isImmediateS4<-1020, 1020>();
1157 }
1158 bool isImm7s4() const {
1159 return isImmediateS4<-508, 508>();
1160 }
1161 bool isImm7Shift0() const {
1162 return isImmediate<-127, 127>();
1163 }
1164 bool isImm7Shift1() const {
1165 return isImmediateS2<-255, 255>();
1166 }
1167 bool isImm7Shift2() const {
1168 return isImmediateS4<-511, 511>();
1169 }
1170 bool isImm7() const {
1171 return isImmediate<-127, 127>();
1172 }
1173 bool isImm0_1020s4() const {
1174 return isImmediateS4<0, 1020>();
1175 }
1176 bool isImm0_508s4() const {
1177 return isImmediateS4<0, 508>();
1178 }
1179 bool isImm0_508s4Neg() const {
1180 if (!isImm()) return false;
1181 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1182 if (!CE) return false;
1183 int64_t Value = -CE->getValue();
1184 // explicitly exclude zero. we want that to use the normal 0_508 version.
1185 return ((Value & 3) == 0) && Value > 0 && Value <= 508;
1186 }
1187
1188 bool isImm0_4095Neg() const {
1189 if (!isImm()) return false;
1190 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1191 if (!CE) return false;
1192 // isImm0_4095Neg is used with 32-bit immediates only.
1193 // 32-bit immediates are zero extended to 64-bit when parsed,
1194 // thus simple -CE->getValue() results in a big negative number,
1195 // not a small positive number as intended
1196 if ((CE->getValue() >> 32) > 0) return false;
1197 uint32_t Value = -static_cast<uint32_t>(CE->getValue());
1198 return Value > 0 && Value < 4096;
1199 }
1200
1201 bool isImm0_7() const {
1202 return isImmediate<0, 7>();
1203 }
1204
1205 bool isImm1_16() const {
1206 return isImmediate<1, 16>();
1207 }
1208
1209 bool isImm1_32() const {
1210 return isImmediate<1, 32>();
1211 }
1212
1213 bool isImm8_255() const {
1214 return isImmediate<8, 255>();
1215 }
1216
1217 bool isImm256_65535Expr() const {
1218 if (!isImm()) return false;
1219 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1220 // If it's not a constant expression, it'll generate a fixup and be
1221 // handled later.
1222 if (!CE) return true;
1223 int64_t Value = CE->getValue();
1224 return Value >= 256 && Value < 65536;
1225 }
1226
1227 bool isImm0_65535Expr() const {
1228 if (!isImm()) return false;
1229 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1230 // If it's not a constant expression, it'll generate a fixup and be
1231 // handled later.
1232 if (!CE) return true;
1233 int64_t Value = CE->getValue();
1234 return Value >= 0 && Value < 65536;
1235 }
1236
1237 bool isImm24bit() const {
1238 return isImmediate<0, 0xffffff + 1>();
1239 }
1240
1241 bool isImmThumbSR() const {
1242 return isImmediate<1, 33>();
1243 }
1244
1245 template<int shift>
1246 bool isExpImmValue(uint64_t Value) const {
1247 uint64_t mask = (1 << shift) - 1;
1248 if ((Value & mask) != 0 || (Value >> shift) > 0xff)
1249 return false;
1250 return true;
1251 }
1252
1253 template<int shift>
1254 bool isExpImm() const {
1255 if (!isImm()) return false;
1256 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1257 if (!CE) return false;
1258
1259 return isExpImmValue<shift>(CE->getValue());
1260 }
1261
1262 template<int shift, int size>
1263 bool isInvertedExpImm() const {
1264 if (!isImm()) return false;
1265 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1266 if (!CE) return false;
1267
1268 uint64_t OriginalValue = CE->getValue();
1269 uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1);
1270 return isExpImmValue<shift>(InvertedValue);
1271 }
1272
1273 bool isPKHLSLImm() const {
1274 return isImmediate<0, 32>();
1275 }
1276
1277 bool isPKHASRImm() const {
1278 return isImmediate<0, 33>();
1279 }
1280
1281 bool isAdrLabel() const {
1282 // If we have an immediate that's not a constant, treat it as a label
1283 // reference needing a fixup.
1284 if (isImm() && !isa<MCConstantExpr>(getImm()))
1285 return true;
1286
1287 // If it is a constant, it must fit into a modified immediate encoding.
1288 if (!isImm()) return false;
1289 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1290 if (!CE) return false;
1291 int64_t Value = CE->getValue();
1292 return (ARM_AM::getSOImmVal(Value) != -1 ||
1293 ARM_AM::getSOImmVal(-Value) != -1);
1294 }
1295
1296 bool isT2SOImm() const {
1297 // If we have an immediate that's not a constant, treat it as an expression
1298 // needing a fixup.
1299 if (isImm() && !isa<MCConstantExpr>(getImm())) {
1300 // We want to avoid matching :upper16: and :lower16: as we want these
1301 // expressions to match in isImm0_65535Expr()
1302 const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(getImm());
1303 return (!ARM16Expr || (ARM16Expr->getKind() != ARMMCExpr::VK_ARM_HI16 &&
1304 ARM16Expr->getKind() != ARMMCExpr::VK_ARM_LO16));
1305 }
1306 if (!isImm()) return false;
1307 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1308 if (!CE) return false;
1309 int64_t Value = CE->getValue();
1310 return ARM_AM::getT2SOImmVal(Value) != -1;
1311 }
1312
1313 bool isT2SOImmNot() const {
1314 if (!isImm()) return false;
1315 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1316 if (!CE) return false;
1317 int64_t Value = CE->getValue();
1318 return ARM_AM::getT2SOImmVal(Value) == -1 &&
1319 ARM_AM::getT2SOImmVal(~Value) != -1;
1320 }
1321
1322 bool isT2SOImmNeg() const {
1323 if (!isImm()) return false;
1324 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1325 if (!CE) return false;
1326 int64_t Value = CE->getValue();
1327 // Only use this when not representable as a plain so_imm.
1328 return ARM_AM::getT2SOImmVal(Value) == -1 &&
1329 ARM_AM::getT2SOImmVal(-Value) != -1;
1330 }
1331
1332 bool isSetEndImm() const {
1333 if (!isImm()) return false;
1334 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1335 if (!CE) return false;
1336 int64_t Value = CE->getValue();
1337 return Value == 1 || Value == 0;
1338 }
1339
1340 bool isReg() const override { return Kind == k_Register; }
1341 bool isRegList() const { return Kind == k_RegisterList; }
1342 bool isRegListWithAPSR() const {
1343 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1344 }
1345 bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
1346 bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
1347 bool isFPSRegListWithVPR() const { return Kind == k_FPSRegisterListWithVPR; }
1348 bool isFPDRegListWithVPR() const { return Kind == k_FPDRegisterListWithVPR; }
1349 bool isToken() const override { return Kind == k_Token; }
1350 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
1351 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
1352 bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; }
1353 bool isMem() const override {
1354 return isGPRMem() || isMVEMem();
1355 }
1356 bool isMVEMem() const {
1357 if (Kind != k_Memory)
1358 return false;
1359 if (Memory.BaseRegNum &&
1360 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum) &&
1361 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Memory.BaseRegNum))
1362 return false;
1363 if (Memory.OffsetRegNum &&
1364 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1365 Memory.OffsetRegNum))
1366 return false;
1367 return true;
1368 }
1369 bool isGPRMem() const {
1370 if (Kind != k_Memory)
1371 return false;
1372 if (Memory.BaseRegNum &&
1373 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum))
1374 return false;
1375 if (Memory.OffsetRegNum &&
1376 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.OffsetRegNum))
1377 return false;
1378 return true;
1379 }
1380 bool isShifterImm() const { return Kind == k_ShifterImmediate; }
1381 bool isRegShiftedReg() const {
1382 return Kind == k_ShiftedRegister &&
1383 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1384 RegShiftedReg.SrcReg) &&
1385 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1386 RegShiftedReg.ShiftReg);
1387 }
1388 bool isRegShiftedImm() const {
1389 return Kind == k_ShiftedImmediate &&
1390 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1391 RegShiftedImm.SrcReg);
1392 }
1393 bool isRotImm() const { return Kind == k_RotateImmediate; }
1394
1395 template<unsigned Min, unsigned Max>
1396 bool isPowerTwoInRange() const {
1397 if (!isImm()) return false;
1398 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1399 if (!CE) return false;
1400 int64_t Value = CE->getValue();
1401 return Value > 0 && countPopulation((uint64_t)Value) == 1 &&
1402 Value >= Min && Value <= Max;
1403 }
1404 bool isModImm() const { return Kind == k_ModifiedImmediate; }
1405
1406 bool isModImmNot() const {
1407 if (!isImm()) return false;
1408 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1409 if (!CE) return false;
1410 int64_t Value = CE->getValue();
1411 return ARM_AM::getSOImmVal(~Value) != -1;
1412 }
1413
1414 bool isModImmNeg() const {
1415 if (!isImm()) return false;
1416 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1417 if (!CE) return false;
1418 int64_t Value = CE->getValue();
1419 return ARM_AM::getSOImmVal(Value) == -1 &&
1420 ARM_AM::getSOImmVal(-Value) != -1;
1421 }
1422
1423 bool isThumbModImmNeg1_7() const {
1424 if (!isImm()) return false;
1425 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1426 if (!CE) return false;
1427 int32_t Value = -(int32_t)CE->getValue();
1428 return 0 < Value && Value < 8;
1429 }
1430
1431 bool isThumbModImmNeg8_255() const {
1432 if (!isImm()) return false;
1433 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1434 if (!CE) return false;
1435 int32_t Value = -(int32_t)CE->getValue();
1436 return 7 < Value && Value < 256;
1437 }
1438
1439 bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
1440 bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
1441 bool isPostIdxRegShifted() const {
1442 return Kind == k_PostIndexRegister &&
1443 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
1444 }
1445 bool isPostIdxReg() const {
1446 return isPostIdxRegShifted() && PostIdxReg.ShiftTy == ARM_AM::no_shift;
1447 }
1448 bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const {
1449 if (!isGPRMem())
1450 return false;
1451 // No offset of any kind.
1452 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr &&
1453 (alignOK || Memory.Alignment == Alignment);
1454 }
1455 bool isMemNoOffsetT2(bool alignOK = false, unsigned Alignment = 0) const {
1456 if (!isGPRMem())
1457 return false;
1458
1459 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1460 Memory.BaseRegNum))
1461 return false;
1462
1463 // No offset of any kind.
1464 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr &&
1465 (alignOK || Memory.Alignment == Alignment);
1466 }
1467 bool isMemNoOffsetT2NoSp(bool alignOK = false, unsigned Alignment = 0) const {
1468 if (!isGPRMem())
1469 return false;
1470
1471 if (!ARMMCRegisterClasses[ARM::rGPRRegClassID].contains(
1472 Memory.BaseRegNum))
1473 return false;
1474
1475 // No offset of any kind.
1476 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr &&
1477 (alignOK || Memory.Alignment == Alignment);
1478 }
1479 bool isMemNoOffsetT(bool alignOK = false, unsigned Alignment = 0) const {
1480 if (!isGPRMem())
1481 return false;
1482
1483 if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].contains(
1484 Memory.BaseRegNum))
1485 return false;
1486
1487 // No offset of any kind.
1488 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr &&
1489 (alignOK || Memory.Alignment == Alignment);
1490 }
1491 bool isMemPCRelImm12() const {
1492 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1493 return false;
1494 // Base register must be PC.
1495 if (Memory.BaseRegNum != ARM::PC)
1496 return false;
1497 // Immediate offset in range [-4095, 4095].
1498 if (!Memory.OffsetImm) return true;
1499 int64_t Val = Memory.OffsetImm->getValue();
1500 return (Val > -4096 && Val < 4096) ||
1501 (Val == std::numeric_limits<int32_t>::min());
1502 }
1503
1504 bool isAlignedMemory() const {
1505 return isMemNoOffset(true);
1506 }
1507
1508 bool isAlignedMemoryNone() const {
1509 return isMemNoOffset(false, 0);
1510 }
1511
1512 bool isDupAlignedMemoryNone() const {
1513 return isMemNoOffset(false, 0);
1514 }
1515
1516 bool isAlignedMemory16() const {
1517 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1518 return true;
1519 return isMemNoOffset(false, 0);
1520 }
1521
1522 bool isDupAlignedMemory16() const {
1523 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1524 return true;
1525 return isMemNoOffset(false, 0);
1526 }
1527
1528 bool isAlignedMemory32() const {
1529 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1530 return true;
1531 return isMemNoOffset(false, 0);
1532 }
1533
1534 bool isDupAlignedMemory32() const {
1535 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1536 return true;
1537 return isMemNoOffset(false, 0);
1538 }
1539
1540 bool isAlignedMemory64() const {
1541 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1542 return true;
1543 return isMemNoOffset(false, 0);
1544 }
1545
1546 bool isDupAlignedMemory64() const {
1547 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1548 return true;
1549 return isMemNoOffset(false, 0);
1550 }
1551
1552 bool isAlignedMemory64or128() const {
1553 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1554 return true;
1555 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1556 return true;
1557 return isMemNoOffset(false, 0);
1558 }
1559
1560 bool isDupAlignedMemory64or128() const {
1561 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1562 return true;
1563 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1564 return true;
1565 return isMemNoOffset(false, 0);
1566 }
1567
1568 bool isAlignedMemory64or128or256() const {
1569 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1570 return true;
1571 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1572 return true;
1573 if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32.
1574 return true;
1575 return isMemNoOffset(false, 0);
1576 }
1577
1578 bool isAddrMode2() const {
1579 if (!isGPRMem() || Memory.Alignment != 0) return false;
1580 // Check for register offset.
1581 if (Memory.OffsetRegNum) return true;
1582 // Immediate offset in range [-4095, 4095].
1583 if (!Memory.OffsetImm) return true;
1584 int64_t Val = Memory.OffsetImm->getValue();
1585 return Val > -4096 && Val < 4096;
1586 }
1587
1588 bool isAM2OffsetImm() const {
1589 if (!isImm()) return false;
1590 // Immediate offset in range [-4095, 4095].
1591 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1592 if (!CE) return false;
1593 int64_t Val = CE->getValue();
1594 return (Val == std::numeric_limits<int32_t>::min()) ||
1595 (Val > -4096 && Val < 4096);
1596 }
1597
1598 bool isAddrMode3() const {
1599 // If we have an immediate that's not a constant, treat it as a label
1600 // reference needing a fixup. If it is a constant, it's something else
1601 // and we reject it.
1602 if (isImm() && !isa<MCConstantExpr>(getImm()))
1603 return true;
1604 if (!isGPRMem() || Memory.Alignment != 0) return false;
1605 // No shifts are legal for AM3.
1606 if (Memory.ShiftType != ARM_AM::no_shift) return false;
1607 // Check for register offset.
1608 if (Memory.OffsetRegNum) return true;
1609 // Immediate offset in range [-255, 255].
1610 if (!Memory.OffsetImm) return true;
1611 int64_t Val = Memory.OffsetImm->getValue();
1612 // The #-0 offset is encoded as std::numeric_limits<int32_t>::min(), and we
1613 // have to check for this too.
1614 return (Val > -256 && Val < 256) ||
1615 Val == std::numeric_limits<int32_t>::min();
1616 }
1617
1618 bool isAM3Offset() const {
1619 if (isPostIdxReg())
1620 return true;
1621 if (!isImm())
1622 return false;
1623 // Immediate offset in range [-255, 255].
1624 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1625 if (!CE) return false;
1626 int64_t Val = CE->getValue();
1627 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1628 return (Val > -256 && Val < 256) ||
1629 Val == std::numeric_limits<int32_t>::min();
1630 }
1631
1632 bool isAddrMode5() const {
1633 // If we have an immediate that's not a constant, treat it as a label
1634 // reference needing a fixup. If it is a constant, it's something else
1635 // and we reject it.
1636 if (isImm() && !isa<MCConstantExpr>(getImm()))
1637 return true;
1638 if (!isGPRMem() || Memory.Alignment != 0) return false;
1639 // Check for register offset.
1640 if (Memory.OffsetRegNum) return false;
1641 // Immediate offset in range [-1020, 1020] and a multiple of 4.
1642 if (!Memory.OffsetImm) return true;
1643 int64_t Val = Memory.OffsetImm->getValue();
1644 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1645 Val == std::numeric_limits<int32_t>::min();
1646 }
1647
1648 bool isAddrMode5FP16() const {
1649 // If we have an immediate that's not a constant, treat it as a label
1650 // reference needing a fixup. If it is a constant, it's something else
1651 // and we reject it.
1652 if (isImm() && !isa<MCConstantExpr>(getImm()))
1653 return true;
1654 if (!isGPRMem() || Memory.Alignment != 0) return false;
1655 // Check for register offset.
1656 if (Memory.OffsetRegNum) return false;
1657 // Immediate offset in range [-510, 510] and a multiple of 2.
1658 if (!Memory.OffsetImm) return true;
1659 int64_t Val = Memory.OffsetImm->getValue();
1660 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1661 Val == std::numeric_limits<int32_t>::min();
1662 }
1663
1664 bool isMemTBB() const {
1665 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1666 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1667 return false;
1668 return true;
1669 }
1670
1671 bool isMemTBH() const {
1672 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1673 Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
1674 Memory.Alignment != 0 )
1675 return false;
1676 return true;
1677 }
1678
1679 bool isMemRegOffset() const {
1680 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1681 return false;
1682 return true;
1683 }
1684
1685 bool isT2MemRegOffset() const {
1686 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1687 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1688 return false;
1689 // Only lsl #{0, 1, 2, 3} allowed.
1690 if (Memory.ShiftType == ARM_AM::no_shift)
1691 return true;
1692 if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
1693 return false;
1694 return true;
1695 }
1696
1697 bool isMemThumbRR() const {
1698 // Thumb reg+reg addressing is simple. Just two registers, a base and
1699 // an offset. No shifts, negations or any other complicating factors.
1700 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1701 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1702 return false;
1703 return isARMLowRegister(Memory.BaseRegNum) &&
1704 (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
1705 }
1706
1707 bool isMemThumbRIs4() const {
1708 if (!isGPRMem() || Memory.OffsetRegNum != 0 ||
1709 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1710 return false;
1711 // Immediate offset, multiple of 4 in range [0, 124].
1712 if (!Memory.OffsetImm) return true;
1713 int64_t Val = Memory.OffsetImm->getValue();
1714 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1715 }
1716
1717 bool isMemThumbRIs2() const {
1718 if (!isGPRMem() || Memory.OffsetRegNum != 0 ||
1719 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1720 return false;
1721 // Immediate offset, multiple of 4 in range [0, 62].
1722 if (!Memory.OffsetImm) return true;
1723 int64_t Val = Memory.OffsetImm->getValue();
1724 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1725 }
1726
1727 bool isMemThumbRIs1() const {
1728 if (!isGPRMem() || Memory.OffsetRegNum != 0 ||
1729 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1730 return false;
1731 // Immediate offset in range [0, 31].
1732 if (!Memory.OffsetImm) return true;
1733 int64_t Val = Memory.OffsetImm->getValue();
1734 return Val >= 0 && Val <= 31;
1735 }
1736
1737 bool isMemThumbSPI() const {
1738 if (!isGPRMem() || Memory.OffsetRegNum != 0 ||
1739 Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
1740 return false;
1741 // Immediate offset, multiple of 4 in range [0, 1020].
1742 if (!Memory.OffsetImm) return true;
1743 int64_t Val = Memory.OffsetImm->getValue();
1744 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1745 }
1746
1747 bool isMemImm8s4Offset() const {
1748 // If we have an immediate that's not a constant, treat it as a label
1749 // reference needing a fixup. If it is a constant, it's something else
1750 // and we reject it.
1751 if (isImm() && !isa<MCConstantExpr>(getImm()))
1752 return true;
1753 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1754 return false;
1755 // Immediate offset a multiple of 4 in range [-1020, 1020].
1756 if (!Memory.OffsetImm) return true;
1757 int64_t Val = Memory.OffsetImm->getValue();
1758 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1759 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1760 Val == std::numeric_limits<int32_t>::min();
1761 }
1762 bool isMemImm7s4Offset() const {
1763 // If we have an immediate that's not a constant, treat it as a label
1764 // reference needing a fixup. If it is a constant, it's something else
1765 // and we reject it.
1766 if (isImm() && !isa<MCConstantExpr>(getImm()))
1767 return true;
1768 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0 ||
1769 !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1770 Memory.BaseRegNum))
1771 return false;
1772 // Immediate offset a multiple of 4 in range [-508, 508].
1773 if (!Memory.OffsetImm) return true;
1774 int64_t Val = Memory.OffsetImm->getValue();
1775 // Special case, #-0 is INT32_MIN.
1776 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN(-2147483647-1);
1777 }
1778 bool isMemImm0_1020s4Offset() const {
1779 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1780 return false;
1781 // Immediate offset a multiple of 4 in range [0, 1020].
1782 if (!Memory.OffsetImm) return true;
1783 int64_t Val = Memory.OffsetImm->getValue();
1784 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1785 }
1786
1787 bool isMemImm8Offset() const {
1788 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1789 return false;
1790 // Base reg of PC isn't allowed for these encodings.
1791 if (Memory.BaseRegNum == ARM::PC) return false;
1792 // Immediate offset in range [-255, 255].
1793 if (!Memory.OffsetImm) return true;
1794 int64_t Val = Memory.OffsetImm->getValue();
1795 return (Val == std::numeric_limits<int32_t>::min()) ||
1796 (Val > -256 && Val < 256);
1797 }
1798
1799 template<unsigned Bits, unsigned RegClassID>
1800 bool isMemImm7ShiftedOffset() const {
1801 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0 ||
1802 !ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum))
1803 return false;
1804
1805 // Expect an immediate offset equal to an element of the range
1806 // [-127, 127], shifted left by Bits.
1807
1808 if (!Memory.OffsetImm) return true;
1809 int64_t Val = Memory.OffsetImm->getValue();
1810
1811 // INT32_MIN is a special-case value (indicating the encoding with
1812 // zero offset and the subtract bit set)
1813 if (Val == INT32_MIN(-2147483647-1))
1814 return true;
1815
1816 unsigned Divisor = 1U << Bits;
1817
1818 // Check that the low bits are zero
1819 if (Val % Divisor != 0)
1820 return false;
1821
1822 // Check that the remaining offset is within range.
1823 Val /= Divisor;
1824 return (Val >= -127 && Val <= 127);
1825 }
1826
1827 template <int shift> bool isMemRegRQOffset() const {
1828 if (!isMVEMem() || Memory.OffsetImm != 0 || Memory.Alignment != 0)
1829 return false;
1830
1831 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1832 Memory.BaseRegNum))
1833 return false;
1834 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1835 Memory.OffsetRegNum))
1836 return false;
1837
1838 if (shift == 0 && Memory.ShiftType != ARM_AM::no_shift)
1839 return false;
1840
1841 if (shift > 0 &&
1842 (Memory.ShiftType != ARM_AM::uxtw || Memory.ShiftImm != shift))
1843 return false;
1844
1845 return true;
1846 }
1847
1848 template <int shift> bool isMemRegQOffset() const {
1849 if (!isMVEMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1850 return false;
1851
1852 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1853 Memory.BaseRegNum))
1854 return false;
1855
1856 if(!Memory.OffsetImm) return true;
1857 static_assert(shift < 56,
1858 "Such that we dont shift by a value higher than 62");
1859 int64_t Val = Memory.OffsetImm->getValue();
1860
1861 // The value must be a multiple of (1 << shift)
1862 if ((Val & ((1U << shift) - 1)) != 0)
1863 return false;
1864
1865 // And be in the right range, depending on the amount that it is shifted
1866 // by. Shift 0, is equal to 7 unsigned bits, the sign bit is set
1867 // separately.
1868 int64_t Range = (1U << (7+shift)) - 1;
1869 return (Val == INT32_MIN(-2147483647-1)) || (Val > -Range && Val < Range);
1870 }
1871
1872 bool isMemPosImm8Offset() const {
1873 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1874 return false;
1875 // Immediate offset in range [0, 255].
1876 if (!Memory.OffsetImm) return true;
1877 int64_t Val = Memory.OffsetImm->getValue();
1878 return Val >= 0 && Val < 256;
1879 }
1880
1881 bool isMemNegImm8Offset() const {
1882 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1883 return false;
1884 // Base reg of PC isn't allowed for these encodings.
1885 if (Memory.BaseRegNum == ARM::PC) return false;
1886 // Immediate offset in range [-255, -1].
1887 if (!Memory.OffsetImm) return false;
1888 int64_t Val = Memory.OffsetImm->getValue();
1889 return (Val == std::numeric_limits<int32_t>::min()) ||
1890 (Val > -256 && Val < 0);
1891 }
1892
1893 bool isMemUImm12Offset() const {
1894 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1895 return false;
1896 // Immediate offset in range [0, 4095].
1897 if (!Memory.OffsetImm) return true;
1898 int64_t Val = Memory.OffsetImm->getValue();
1899 return (Val >= 0 && Val < 4096);
1900 }
1901
1902 bool isMemImm12Offset() const {
1903 // If we have an immediate that's not a constant, treat it as a label
1904 // reference needing a fixup. If it is a constant, it's something else
1905 // and we reject it.
1906
1907 if (isImm() && !isa<MCConstantExpr>(getImm()))
1908 return true;
1909
1910 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1911 return false;
1912 // Immediate offset in range [-4095, 4095].
1913 if (!Memory.OffsetImm) return true;
1914 int64_t Val = Memory.OffsetImm->getValue();
1915 return (Val > -4096 && Val < 4096) ||
1916 (Val == std::numeric_limits<int32_t>::min());
1917 }
1918
1919 bool isConstPoolAsmImm() const {
1920 // Delay processing of Constant Pool Immediate, this will turn into
1921 // a constant. Match no other operand
1922 return (isConstantPoolImm());
1923 }
1924
1925 bool isPostIdxImm8() const {
1926 if (!isImm()) return false;
1927 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1928 if (!CE) return false;
1929 int64_t Val = CE->getValue();
1930 return (Val > -256 && Val < 256) ||
1931 (Val == std::numeric_limits<int32_t>::min());
1932 }
1933
1934 bool isPostIdxImm8s4() const {
1935 if (!isImm()) return false;
1936 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1937 if (!CE) return false;
1938 int64_t Val = CE->getValue();
1939 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
1940 (Val == std::numeric_limits<int32_t>::min());
1941 }
1942
1943 bool isMSRMask() const { return Kind == k_MSRMask; }
1944 bool isBankedReg() const { return Kind == k_BankedReg; }
1945 bool isProcIFlags() const { return Kind == k_ProcIFlags; }
1946
1947 // NEON operands.
1948 bool isSingleSpacedVectorList() const {
1949 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
1950 }
1951
1952 bool isDoubleSpacedVectorList() const {
1953 return Kind == k_VectorList && VectorList.isDoubleSpaced;
1954 }
1955
1956 bool isVecListOneD() const {
1957 if (!isSingleSpacedVectorList()) return false;
1958 return VectorList.Count == 1;
1959 }
1960
1961 bool isVecListTwoMQ() const {
1962 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
1963 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1964 VectorList.RegNum);
1965 }
1966
1967 bool isVecListDPair() const {
1968 if (!isSingleSpacedVectorList()) return false;
1969 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1970 .contains(VectorList.RegNum));
1971 }
1972
1973 bool isVecListThreeD() const {
1974 if (!isSingleSpacedVectorList()) return false;
1975 return VectorList.Count == 3;
1976 }
1977
1978 bool isVecListFourD() const {
1979 if (!isSingleSpacedVectorList()) return false;
1980 return VectorList.Count == 4;
1981 }
1982
1983 bool isVecListDPairSpaced() const {
1984 if (Kind != k_VectorList) return false;
1985 if (isSingleSpacedVectorList()) return false;
1986 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
1987 .contains(VectorList.RegNum));
1988 }
1989
1990 bool isVecListThreeQ() const {
1991 if (!isDoubleSpacedVectorList()) return false;
1992 return VectorList.Count == 3;
1993 }
1994
1995 bool isVecListFourQ() const {
1996 if (!isDoubleSpacedVectorList()) return false;
1997 return VectorList.Count == 4;
1998 }
1999
2000 bool isVecListFourMQ() const {
2001 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2002 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2003 VectorList.RegNum);
2004 }
2005
2006 bool isSingleSpacedVectorAllLanes() const {
2007 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2008 }
2009
2010 bool isDoubleSpacedVectorAllLanes() const {
2011 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2012 }
2013
2014 bool isVecListOneDAllLanes() const {
2015 if (!isSingleSpacedVectorAllLanes()) return false;
2016 return VectorList.Count == 1;
2017 }
2018
2019 bool isVecListDPairAllLanes() const {
2020 if (!isSingleSpacedVectorAllLanes()) return false;
2021 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2022 .contains(VectorList.RegNum));
2023 }
2024
2025 bool isVecListDPairSpacedAllLanes() const {
2026 if (!isDoubleSpacedVectorAllLanes()) return false;
2027 return VectorList.Count == 2;
2028 }
2029
2030 bool isVecListThreeDAllLanes() const {
2031 if (!isSingleSpacedVectorAllLanes()) return false;
2032 return VectorList.Count == 3;
2033 }
2034
2035 bool isVecListThreeQAllLanes() const {
2036 if (!isDoubleSpacedVectorAllLanes()) return false;
2037 return VectorList.Count == 3;
2038 }
2039
2040 bool isVecListFourDAllLanes() const {
2041 if (!isSingleSpacedVectorAllLanes()) return false;
2042 return VectorList.Count == 4;
2043 }
2044
2045 bool isVecListFourQAllLanes() const {
2046 if (!isDoubleSpacedVectorAllLanes()) return false;
2047 return VectorList.Count == 4;
2048 }
2049
2050 bool isSingleSpacedVectorIndexed() const {
2051 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2052 }
2053
2054 bool isDoubleSpacedVectorIndexed() const {
2055 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2056 }
2057
2058 bool isVecListOneDByteIndexed() const {
2059 if (!isSingleSpacedVectorIndexed()) return false;
2060 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2061 }
2062
2063 bool isVecListOneDHWordIndexed() const {
2064 if (!isSingleSpacedVectorIndexed()) return false;
2065 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2066 }
2067
2068 bool isVecListOneDWordIndexed() const {
2069 if (!isSingleSpacedVectorIndexed()) return false;
2070 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2071 }
2072
2073 bool isVecListTwoDByteIndexed() const {
2074 if (!isSingleSpacedVectorIndexed()) return false;
2075 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2076 }
2077
2078 bool isVecListTwoDHWordIndexed() const {
2079 if (!isSingleSpacedVectorIndexed()) return false;
2080 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2081 }
2082
2083 bool isVecListTwoQWordIndexed() const {
2084 if (!isDoubleSpacedVectorIndexed()) return false;
2085 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2086 }
2087
2088 bool isVecListTwoQHWordIndexed() const {
2089 if (!isDoubleSpacedVectorIndexed()) return false;
2090 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2091 }
2092
2093 bool isVecListTwoDWordIndexed() const {
2094 if (!isSingleSpacedVectorIndexed()) return false;
2095 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2096 }
2097
2098 bool isVecListThreeDByteIndexed() const {
2099 if (!isSingleSpacedVectorIndexed()) return false;
2100 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2101 }
2102
2103 bool isVecListThreeDHWordIndexed() const {
2104 if (!isSingleSpacedVectorIndexed()) return false;
2105 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2106 }
2107
2108 bool isVecListThreeQWordIndexed() const {
2109 if (!isDoubleSpacedVectorIndexed()) return false;
2110 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2111 }
2112
2113 bool isVecListThreeQHWordIndexed() const {
2114 if (!isDoubleSpacedVectorIndexed()) return false;
2115 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2116 }
2117
2118 bool isVecListThreeDWordIndexed() const {
2119 if (!isSingleSpacedVectorIndexed()) return false;
2120 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2121 }
2122
2123 bool isVecListFourDByteIndexed() const {
2124 if (!isSingleSpacedVectorIndexed()) return false;
2125 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2126 }
2127
2128 bool isVecListFourDHWordIndexed() const {
2129 if (!isSingleSpacedVectorIndexed()) return false;
2130 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2131 }
2132
2133 bool isVecListFourQWordIndexed() const {
2134 if (!isDoubleSpacedVectorIndexed()) return false;
2135 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2136 }
2137
2138 bool isVecListFourQHWordIndexed() const {
2139 if (!isDoubleSpacedVectorIndexed()) return false;
2140 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2141 }
2142
2143 bool isVecListFourDWordIndexed() const {
2144 if (!isSingleSpacedVectorIndexed()) return false;
2145 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2146 }
2147
2148 bool isVectorIndex() const { return Kind == k_VectorIndex; }
2149
2150 template <unsigned NumLanes>
2151 bool isVectorIndexInRange() const {
2152 if (Kind != k_VectorIndex) return false;
2153 return VectorIndex.Val < NumLanes;
2154 }
2155
2156 bool isVectorIndex8() const { return isVectorIndexInRange<8>(); }
2157 bool isVectorIndex16() const { return isVectorIndexInRange<4>(); }
2158 bool isVectorIndex32() const { return isVectorIndexInRange<2>(); }
2159 bool isVectorIndex64() const { return isVectorIndexInRange<1>(); }
2160
2161 template<int PermittedValue, int OtherPermittedValue>
2162 bool isMVEPairVectorIndex() const {
2163 if (Kind != k_VectorIndex) return false;
2164 return VectorIndex.Val == PermittedValue ||
2165 VectorIndex.Val == OtherPermittedValue;
2166 }
2167
2168 bool isNEONi8splat() const {
2169 if (!isImm()) return false;
2170 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2171 // Must be a constant.
2172 if (!CE) return false;
2173 int64_t Value = CE->getValue();
2174 // i8 value splatted across 8 bytes. The immediate is just the 8 byte
2175 // value.
2176 return Value >= 0 && Value < 256;
2177 }
2178
2179 bool isNEONi16splat() const {
2180 if (isNEONByteReplicate(2))
2181 return false; // Leave that for bytes replication and forbid by default.
2182 if (!isImm())
2183 return false;
2184 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2185 // Must be a constant.
2186 if (!CE) return false;
2187 unsigned Value = CE->getValue();
2188 return ARM_AM::isNEONi16splat(Value);
2189 }
2190
2191 bool isNEONi16splatNot() const {
2192 if (!isImm())
2193 return false;
2194 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2195 // Must be a constant.
2196 if (!CE) return false;
2197 unsigned Value = CE->getValue();
2198 return ARM_AM::isNEONi16splat(~Value & 0xffff);
2199 }
2200
2201 bool isNEONi32splat() const {
2202 if (isNEONByteReplicate(4))
2203 return false; // Leave that for bytes replication and forbid by default.
2204 if (!isImm())
2205 return false;
2206 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2207 // Must be a constant.
2208 if (!CE) return false;
2209 unsigned Value = CE->getValue();
2210 return ARM_AM::isNEONi32splat(Value);
2211 }
2212
2213 bool isNEONi32splatNot() const {
2214 if (!isImm())
2215 return false;
2216 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2217 // Must be a constant.
2218 if (!CE) return false;
2219 unsigned Value = CE->getValue();
2220 return ARM_AM::isNEONi32splat(~Value);
2221 }
2222
2223 static bool isValidNEONi32vmovImm(int64_t Value) {
2224 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
2225 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
2226 return ((Value & 0xffffffffffffff00) == 0) ||
2227 ((Value & 0xffffffffffff00ff) == 0) ||
2228 ((Value & 0xffffffffff00ffff) == 0) ||
2229 ((Value & 0xffffffff00ffffff) == 0) ||
2230 ((Value & 0xffffffffffff00ff) == 0xff) ||
2231 ((Value & 0xffffffffff00ffff) == 0xffff);
2232 }
2233
2234 bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const {
2235 assert((Width == 8 || Width == 16 || Width == 32) &&(((Width == 8 || Width == 16 || Width == 32) && "Invalid element width"
) ? static_cast<void> (0) : __assert_fail ("(Width == 8 || Width == 16 || Width == 32) && \"Invalid element width\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2236, __PRETTY_FUNCTION__))
2236 "Invalid element width")(((Width == 8 || Width == 16 || Width == 32) && "Invalid element width"
) ? static_cast<void> (0) : __assert_fail ("(Width == 8 || Width == 16 || Width == 32) && \"Invalid element width\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2236, __PRETTY_FUNCTION__))
;
2237 assert(NumElems * Width <= 64 && "Invalid result width")((NumElems * Width <= 64 && "Invalid result width"
) ? static_cast<void> (0) : __assert_fail ("NumElems * Width <= 64 && \"Invalid result width\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2237, __PRETTY_FUNCTION__))
;
2238
2239 if (!isImm())
2240 return false;
2241 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2242 // Must be a constant.
2243 if (!CE)
2244 return false;
2245 int64_t Value = CE->getValue();
2246 if (!Value)
2247 return false; // Don't bother with zero.
2248 if (Inv)
2249 Value = ~Value;
2250
2251 uint64_t Mask = (1ull << Width) - 1;
2252 uint64_t Elem = Value & Mask;
2253 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2254 return false;
2255 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2256 return false;
2257
2258 for (unsigned i = 1; i < NumElems; ++i) {
2259 Value >>= Width;
2260 if ((Value & Mask) != Elem)
2261 return false;
2262 }
2263 return true;
2264 }
2265
2266 bool isNEONByteReplicate(unsigned NumBytes) const {
2267 return isNEONReplicate(8, NumBytes, false);
2268 }
2269
2270 static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
2271 assert((FromW == 8 || FromW == 16 || FromW == 32) &&(((FromW == 8 || FromW == 16 || FromW == 32) && "Invalid source width"
) ? static_cast<void> (0) : __assert_fail ("(FromW == 8 || FromW == 16 || FromW == 32) && \"Invalid source width\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2272, __PRETTY_FUNCTION__))
2272 "Invalid source width")(((FromW == 8 || FromW == 16 || FromW == 32) && "Invalid source width"
) ? static_cast<void> (0) : __assert_fail ("(FromW == 8 || FromW == 16 || FromW == 32) && \"Invalid source width\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2272, __PRETTY_FUNCTION__))
;
2273 assert((ToW == 16 || ToW == 32 || ToW == 64) &&(((ToW == 16 || ToW == 32 || ToW == 64) && "Invalid destination width"
) ? static_cast<void> (0) : __assert_fail ("(ToW == 16 || ToW == 32 || ToW == 64) && \"Invalid destination width\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2274, __PRETTY_FUNCTION__))
2274 "Invalid destination width")(((ToW == 16 || ToW == 32 || ToW == 64) && "Invalid destination width"
) ? static_cast<void> (0) : __assert_fail ("(ToW == 16 || ToW == 32 || ToW == 64) && \"Invalid destination width\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2274, __PRETTY_FUNCTION__))
;
2275 assert(FromW < ToW && "ToW is not less than FromW")((FromW < ToW && "ToW is not less than FromW") ? static_cast
<void> (0) : __assert_fail ("FromW < ToW && \"ToW is not less than FromW\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2275, __PRETTY_FUNCTION__))
;
2276 }
2277
2278 template<unsigned FromW, unsigned ToW>
2279 bool isNEONmovReplicate() const {
2280 checkNeonReplicateArgs(FromW, ToW);
2281 if (ToW == 64 && isNEONi64splat())
2282 return false;
2283 return isNEONReplicate(FromW, ToW / FromW, false);
2284 }
2285
2286 template<unsigned FromW, unsigned ToW>
2287 bool isNEONinvReplicate() const {
2288 checkNeonReplicateArgs(FromW, ToW);
2289 return isNEONReplicate(FromW, ToW / FromW, true);
2290 }
2291
2292 bool isNEONi32vmov() const {
2293 if (isNEONByteReplicate(4))
2294 return false; // Let it to be classified as byte-replicate case.
2295 if (!isImm())
2296 return false;
2297 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2298 // Must be a constant.
2299 if (!CE)
2300 return false;
2301 return isValidNEONi32vmovImm(CE->getValue());
2302 }
2303
2304 bool isNEONi32vmovNeg() const {
2305 if (!isImm()) return false;
2306 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2307 // Must be a constant.
2308 if (!CE) return false;
2309 return isValidNEONi32vmovImm(~CE->getValue());
2310 }
2311
2312 bool isNEONi64splat() const {
2313 if (!isImm()) return false;
2314 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2315 // Must be a constant.
2316 if (!CE) return false;
2317 uint64_t Value = CE->getValue();
2318 // i64 value with each byte being either 0 or 0xff.
2319 for (unsigned i = 0; i < 8; ++i, Value >>= 8)
2320 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
2321 return true;
2322 }
2323
2324 template<int64_t Angle, int64_t Remainder>
2325 bool isComplexRotation() const {
2326 if (!isImm()) return false;
2327
2328 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2329 if (!CE) return false;
2330 uint64_t Value = CE->getValue();
2331
2332 return (Value % Angle == Remainder && Value <= 270);
2333 }
2334
2335 bool isMVELongShift() const {
2336 if (!isImm()) return false;
2337 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2338 // Must be a constant.
2339 if (!CE) return false;
2340 uint64_t Value = CE->getValue();
2341 return Value >= 1 && Value <= 32;
2342 }
2343
2344 bool isMveSaturateOp() const {
2345 if (!isImm()) return false;
2346 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2347 if (!CE) return false;
2348 uint64_t Value = CE->getValue();
2349 return Value == 48 || Value == 64;
2350 }
2351
2352 bool isITCondCodeNoAL() const {
2353 if (!isITCondCode()) return false;
2354 ARMCC::CondCodes CC = getCondCode();
2355 return CC != ARMCC::AL;
2356 }
2357
2358 bool isITCondCodeRestrictedI() const {
2359 if (!isITCondCode())
2360 return false;
2361 ARMCC::CondCodes CC = getCondCode();
2362 return CC == ARMCC::EQ || CC == ARMCC::NE;
2363 }
2364
2365 bool isITCondCodeRestrictedS() const {
2366 if (!isITCondCode())
2367 return false;
2368 ARMCC::CondCodes CC = getCondCode();
2369 return CC == ARMCC::LT || CC == ARMCC::GT || CC == ARMCC::LE ||
2370 CC == ARMCC::GE;
2371 }
2372
2373 bool isITCondCodeRestrictedU() const {
2374 if (!isITCondCode())
2375 return false;
2376 ARMCC::CondCodes CC = getCondCode();
2377 return CC == ARMCC::HS || CC == ARMCC::HI;
2378 }
2379
2380 bool isITCondCodeRestrictedFP() const {
2381 if (!isITCondCode())
2382 return false;
2383 ARMCC::CondCodes CC = getCondCode();
2384 return CC == ARMCC::EQ || CC == ARMCC::NE || CC == ARMCC::LT ||
2385 CC == ARMCC::GT || CC == ARMCC::LE || CC == ARMCC::GE;
2386 }
2387
2388 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2389 // Add as immediates when possible. Null MCExpr = 0.
2390 if (!Expr)
2391 Inst.addOperand(MCOperand::createImm(0));
2392 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2393 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2394 else
2395 Inst.addOperand(MCOperand::createExpr(Expr));
2396 }
2397
2398 void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const {
2399 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2399, __PRETTY_FUNCTION__))
;
2400 addExpr(Inst, getImm());
2401 }
2402
2403 void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const {
2404 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2404, __PRETTY_FUNCTION__))
;
2405 addExpr(Inst, getImm());
2406 }
2407
2408 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
2409 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2409, __PRETTY_FUNCTION__))
;
2410 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2411 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
2412 Inst.addOperand(MCOperand::createReg(RegNum));
2413 }
2414
2415 void addVPTPredNOperands(MCInst &Inst, unsigned N) const {
2416 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2416, __PRETTY_FUNCTION__))
;
2417 Inst.addOperand(MCOperand::createImm(unsigned(getVPTPred())));
2418 unsigned RegNum = getVPTPred() == ARMVCC::None ? 0: ARM::P0;
2419 Inst.addOperand(MCOperand::createReg(RegNum));
2420 }
2421
2422 void addVPTPredROperands(MCInst &Inst, unsigned N) const {
2423 assert(N == 3 && "Invalid number of operands!")((N == 3 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 3 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2423, __PRETTY_FUNCTION__))
;
2424 addVPTPredNOperands(Inst, N-1);
2425 unsigned RegNum;
2426 if (getVPTPred() == ARMVCC::None) {
2427 RegNum = 0;
2428 } else {
2429 unsigned NextOpIndex = Inst.getNumOperands();
2430 const MCInstrDesc &MCID = ARMInsts[Inst.getOpcode()];
2431 int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO);
2432 assert(TiedOp >= 0 &&((TiedOp >= 0 && "Inactive register in vpred_r is not tied to an output!"
) ? static_cast<void> (0) : __assert_fail ("TiedOp >= 0 && \"Inactive register in vpred_r is not tied to an output!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2433, __PRETTY_FUNCTION__))
2433 "Inactive register in vpred_r is not tied to an output!")((TiedOp >= 0 && "Inactive register in vpred_r is not tied to an output!"
) ? static_cast<void> (0) : __assert_fail ("TiedOp >= 0 && \"Inactive register in vpred_r is not tied to an output!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2433, __PRETTY_FUNCTION__))
;
2434 RegNum = Inst.getOperand(TiedOp).getReg();
2435 }
2436 Inst.addOperand(MCOperand::createReg(RegNum));
2437 }
2438
2439 void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
2440 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2440, __PRETTY_FUNCTION__))
;
2441 Inst.addOperand(MCOperand::createImm(getCoproc()));
2442 }
2443
2444 void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
2445 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2445, __PRETTY_FUNCTION__))
;
2446 Inst.addOperand(MCOperand::createImm(getCoproc()));
2447 }
2448
2449 void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
2450 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2450, __PRETTY_FUNCTION__))
;
2451 Inst.addOperand(MCOperand::createImm(CoprocOption.Val));
2452 }
2453
2454 void addITMaskOperands(MCInst &Inst, unsigned N) const {
2455 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2455, __PRETTY_FUNCTION__))
;
2456 Inst.addOperand(MCOperand::createImm(ITMask.Mask));
2457 }
2458
2459 void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
2460 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2460, __PRETTY_FUNCTION__))
;
2461 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2462 }
2463
2464 void addITCondCodeInvOperands(MCInst &Inst, unsigned N) const {
2465 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2465, __PRETTY_FUNCTION__))
;
2466 Inst.addOperand(MCOperand::createImm(unsigned(ARMCC::getOppositeCondition(getCondCode()))));
2467 }
2468
2469 void addCCOutOperands(MCInst &Inst, unsigned N) const {
2470 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2470, __PRETTY_FUNCTION__))
;
2471 Inst.addOperand(MCOperand::createReg(getReg()));
2472 }
2473
2474 void addRegOperands(MCInst &Inst, unsigned N) const {
2475 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2475, __PRETTY_FUNCTION__))
;
2476 Inst.addOperand(MCOperand::createReg(getReg()));
2477 }
2478
2479 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
2480 assert(N == 3 && "Invalid number of operands!")((N == 3 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 3 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2480, __PRETTY_FUNCTION__))
;
2481 assert(isRegShiftedReg() &&((isRegShiftedReg() && "addRegShiftedRegOperands() on non-RegShiftedReg!"
) ? static_cast<void> (0) : __assert_fail ("isRegShiftedReg() && \"addRegShiftedRegOperands() on non-RegShiftedReg!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2482, __PRETTY_FUNCTION__))
2482 "addRegShiftedRegOperands() on non-RegShiftedReg!")((isRegShiftedReg() && "addRegShiftedRegOperands() on non-RegShiftedReg!"
) ? static_cast<void> (0) : __assert_fail ("isRegShiftedReg() && \"addRegShiftedRegOperands() on non-RegShiftedReg!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2482, __PRETTY_FUNCTION__))
;
2483 Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg));
2484 Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg));
2485 Inst.addOperand(MCOperand::createImm(
2486 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
2487 }
2488
2489 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
2490 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2490, __PRETTY_FUNCTION__))
;
2491 assert(isRegShiftedImm() &&((isRegShiftedImm() && "addRegShiftedImmOperands() on non-RegShiftedImm!"
) ? static_cast<void> (0) : __assert_fail ("isRegShiftedImm() && \"addRegShiftedImmOperands() on non-RegShiftedImm!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2492, __PRETTY_FUNCTION__))
2492 "addRegShiftedImmOperands() on non-RegShiftedImm!")((isRegShiftedImm() && "addRegShiftedImmOperands() on non-RegShiftedImm!"
) ? static_cast<void> (0) : __assert_fail ("isRegShiftedImm() && \"addRegShiftedImmOperands() on non-RegShiftedImm!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2492, __PRETTY_FUNCTION__))
;
2493 Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg));
2494 // Shift of #32 is encoded as 0 where permitted
2495 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2496 Inst.addOperand(MCOperand::createImm(
2497 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
2498 }
2499
2500 void addShifterImmOperands(MCInst &Inst, unsigned N) const {
2501 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2501, __PRETTY_FUNCTION__))
;
2502 Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) |
2503 ShifterImm.Imm));
2504 }
2505
2506 void addRegListOperands(MCInst &Inst, unsigned N) const {
2507 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2507, __PRETTY_FUNCTION__))
;
2508 const SmallVectorImpl<unsigned> &RegList = getRegList();
2509 for (SmallVectorImpl<unsigned>::const_iterator
2510 I = RegList.begin(), E = RegList.end(); I != E; ++I)
2511 Inst.addOperand(MCOperand::createReg(*I));
2512 }
2513
2514 void addRegListWithAPSROperands(MCInst &Inst, unsigned N) const {
2515 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2515, __PRETTY_FUNCTION__))
;
2516 const SmallVectorImpl<unsigned> &RegList = getRegList();
2517 for (SmallVectorImpl<unsigned>::const_iterator
2518 I = RegList.begin(), E = RegList.end(); I != E; ++I)
2519 Inst.addOperand(MCOperand::createReg(*I));
2520 }
2521
2522 void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
2523 addRegListOperands(Inst, N);
2524 }
2525
2526 void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
2527 addRegListOperands(Inst, N);
2528 }
2529
2530 void addFPSRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2531 addRegListOperands(Inst, N);
2532 }
2533
2534 void addFPDRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2535 addRegListOperands(Inst, N);
2536 }
2537
2538 void addRotImmOperands(MCInst &Inst, unsigned N) const {
2539 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2539, __PRETTY_FUNCTION__))
;
2540 // Encoded as val>>3. The printer handles display as 8, 16, 24.
2541 Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3));
2542 }
2543
2544 void addModImmOperands(MCInst &Inst, unsigned N) const {
2545 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2545, __PRETTY_FUNCTION__))
;
2546
2547 // Support for fixups (MCFixup)
2548 if (isImm())
2549 return addImmOperands(Inst, N);
2550
2551 Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7)));
2552 }
2553
2554 void addModImmNotOperands(MCInst &Inst, unsigned N) const {
2555 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2555, __PRETTY_FUNCTION__))
;
2556 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2557 uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue());
2558 Inst.addOperand(MCOperand::createImm(Enc));
2559 }
2560
2561 void addModImmNegOperands(MCInst &Inst, unsigned N) const {
2562 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2562, __PRETTY_FUNCTION__))
;
2563 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2564 uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue());
2565 Inst.addOperand(MCOperand::createImm(Enc));
2566 }
2567
2568 void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const {
2569 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2569, __PRETTY_FUNCTION__))
;
2570 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2571 uint32_t Val = -CE->getValue();
2572 Inst.addOperand(MCOperand::createImm(Val));
2573 }
2574
2575 void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const {
2576 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2576, __PRETTY_FUNCTION__))
;
2577 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2578 uint32_t Val = -CE->getValue();
2579 Inst.addOperand(MCOperand::createImm(Val));
2580 }
2581
2582 void addBitfieldOperands(MCInst &Inst, unsigned N) const {
2583 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2583, __PRETTY_FUNCTION__))
;
2584 // Munge the lsb/width into a bitfield mask.
2585 unsigned lsb = Bitfield.LSB;
2586 unsigned width = Bitfield.Width;
2587 // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
2588 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2589 (32 - (lsb + width)));
2590 Inst.addOperand(MCOperand::createImm(Mask));
2591 }
2592
2593 void addImmOperands(MCInst &Inst, unsigned N) const {
2594 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2594, __PRETTY_FUNCTION__))
;
2595 addExpr(Inst, getImm());
2596 }
2597
2598 void addFBits16Operands(MCInst &Inst, unsigned N) const {
2599 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2599, __PRETTY_FUNCTION__))
;
2600 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2601 Inst.addOperand(MCOperand::createImm(16 - CE->getValue()));
2602 }
2603
2604 void addFBits32Operands(MCInst &Inst, unsigned N) const {
2605 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2605, __PRETTY_FUNCTION__))
;
2606 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2607 Inst.addOperand(MCOperand::createImm(32 - CE->getValue()));
2608 }
2609
2610 void addFPImmOperands(MCInst &Inst, unsigned N) const {
2611 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2611, __PRETTY_FUNCTION__))
;
2612 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2613 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
2614 Inst.addOperand(MCOperand::createImm(Val));
2615 }
2616
2617 void addImm8s4Operands(MCInst &Inst, unsigned N) const {
2618 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2618, __PRETTY_FUNCTION__))
;
2619 // FIXME: We really want to scale the value here, but the LDRD/STRD
2620 // instruction don't encode operands that way yet.
2621 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2622 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2623 }
2624
2625 void addImm7s4Operands(MCInst &Inst, unsigned N) const {
2626 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2626, __PRETTY_FUNCTION__))
;
2627 // FIXME: We really want to scale the value here, but the VSTR/VLDR_VSYSR
2628 // instruction don't encode operands that way yet.
2629 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2630 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2631 }
2632
2633 void addImm7Shift0Operands(MCInst &Inst, unsigned N) const {
2634 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2634, __PRETTY_FUNCTION__))
;
2635 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2636 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2637 }
2638
2639 void addImm7Shift1Operands(MCInst &Inst, unsigned N) const {
2640 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2640, __PRETTY_FUNCTION__))
;
2641 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2642 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2643 }
2644
2645 void addImm7Shift2Operands(MCInst &Inst, unsigned N) const {
2646 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2646, __PRETTY_FUNCTION__))
;
2647 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2648 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2649 }
2650
2651 void addImm7Operands(MCInst &Inst, unsigned N) const {
2652 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2652, __PRETTY_FUNCTION__))
;
2653 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2654 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2655 }
2656
2657 void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
2658 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2658, __PRETTY_FUNCTION__))
;
2659 // The immediate is scaled by four in the encoding and is stored
2660 // in the MCInst as such. Lop off the low two bits here.
2661 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2662 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2663 }
2664
2665 void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
2666 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2666, __PRETTY_FUNCTION__))
;
2667 // The immediate is scaled by four in the encoding and is stored
2668 // in the MCInst as such. Lop off the low two bits here.
2669 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2670 Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4)));
2671 }
2672
2673 void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
2674 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2674, __PRETTY_FUNCTION__))
;
2675 // The immediate is scaled by four in the encoding and is stored
2676 // in the MCInst as such. Lop off the low two bits here.
2677 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2678 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2679 }
2680
2681 void addImm1_16Operands(MCInst &Inst, unsigned N) const {
2682 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2682, __PRETTY_FUNCTION__))
;
2683 // The constant encodes as the immediate-1, and we store in the instruction
2684 // the bits as encoded, so subtract off one here.
2685 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2686 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2687 }
2688
2689 void addImm1_32Operands(MCInst &Inst, unsigned N) const {
2690 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2690, __PRETTY_FUNCTION__))
;
2691 // The constant encodes as the immediate-1, and we store in the instruction
2692 // the bits as encoded, so subtract off one here.
2693 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2694 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2695 }
2696
2697 void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
2698 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2698, __PRETTY_FUNCTION__))
;
2699 // The constant encodes as the immediate, except for 32, which encodes as
2700 // zero.
2701 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2702 unsigned Imm = CE->getValue();
2703 Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm)));
2704 }
2705
2706 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
2707 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2707, __PRETTY_FUNCTION__))
;
2708 // An ASR value of 32 encodes as 0, so that's how we want to add it to
2709 // the instruction as well.
2710 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2711 int Val = CE->getValue();
2712 Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val));
2713 }
2714
2715 void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
2716 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2716, __PRETTY_FUNCTION__))
;
2717 // The operand is actually a t2_so_imm, but we have its bitwise
2718 // negation in the assembly source, so twiddle it here.
2719 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2720 Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue()));
2721 }
2722
2723 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
2724 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2724, __PRETTY_FUNCTION__))
;
2725 // The operand is actually a t2_so_imm, but we have its
2726 // negation in the assembly source, so twiddle it here.
2727 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2728 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2729 }
2730
2731 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
2732 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2732, __PRETTY_FUNCTION__))
;
2733 // The operand is actually an imm0_4095, but we have its
2734 // negation in the assembly source, so twiddle it here.
2735 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2736 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2737 }
2738
2739 void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
2740 if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2741 Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2));
2742 return;
2743 }
2744 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2745 Inst.addOperand(MCOperand::createExpr(SR));
2746 }
2747
2748 void addThumbMemPCOperands(MCInst &Inst, unsigned N) const {
2749 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2749, __PRETTY_FUNCTION__))
;
2750 if (isImm()) {
2751 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2752 if (CE) {
2753 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2754 return;
2755 }
2756 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2757 Inst.addOperand(MCOperand::createExpr(SR));
2758 return;
2759 }
2760
2761 assert(isGPRMem() && "Unknown value type!")((isGPRMem() && "Unknown value type!") ? static_cast<
void> (0) : __assert_fail ("isGPRMem() && \"Unknown value type!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2761, __PRETTY_FUNCTION__))
;
2762 assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!")((isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!"
) ? static_cast<void> (0) : __assert_fail ("isa<MCConstantExpr>(Memory.OffsetImm) && \"Unknown value type!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2762, __PRETTY_FUNCTION__))
;
2763 Inst.addOperand(MCOperand::createImm(Memory.OffsetImm->getValue()));
2764 }
2765
2766 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
2767 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2767, __PRETTY_FUNCTION__))
;
2768 Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt())));
2769 }
2770
2771 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2772 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2772, __PRETTY_FUNCTION__))
;
2773 Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
2774 }
2775
2776 void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2777 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2777, __PRETTY_FUNCTION__))
;
2778 Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt())));
2779 }
2780
2781 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
2782 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2782, __PRETTY_FUNCTION__))
;
2783 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2784 }
2785
2786 void addMemNoOffsetT2Operands(MCInst &Inst, unsigned N) const {
2787 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2787, __PRETTY_FUNCTION__))
;
2788 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2789 }
2790
2791 void addMemNoOffsetT2NoSpOperands(MCInst &Inst, unsigned N) const {
2792 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2792, __PRETTY_FUNCTION__))
;
2793 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2794 }
2795
2796 void addMemNoOffsetTOperands(MCInst &Inst, unsigned N) const {
2797 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2797, __PRETTY_FUNCTION__))
;
2798 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2799 }
2800
2801 void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
2802 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2802, __PRETTY_FUNCTION__))
;
2803 int32_t Imm = Memory.OffsetImm->getValue();
2804 Inst.addOperand(MCOperand::createImm(Imm));
2805 }
2806
2807 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
2808 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2808, __PRETTY_FUNCTION__))
;
2809 assert(isImm() && "Not an immediate!")((isImm() && "Not an immediate!") ? static_cast<void
> (0) : __assert_fail ("isImm() && \"Not an immediate!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2809, __PRETTY_FUNCTION__))
;
2810
2811 // If we have an immediate that's not a constant, treat it as a label
2812 // reference needing a fixup.
2813 if (!isa<MCConstantExpr>(getImm())) {
2814 Inst.addOperand(MCOperand::createExpr(getImm()));
2815 return;
2816 }
2817
2818 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2819 int Val = CE->getValue();
2820 Inst.addOperand(MCOperand::createImm(Val));
2821 }
2822
2823 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
2824 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2824, __PRETTY_FUNCTION__))
;
2825 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2826 Inst.addOperand(MCOperand::createImm(Memory.Alignment));
2827 }
2828
2829 void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2830 addAlignedMemoryOperands(Inst, N);
2831 }
2832
2833 void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2834 addAlignedMemoryOperands(Inst, N);
2835 }
2836
2837 void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2838 addAlignedMemoryOperands(Inst, N);
2839 }
2840
2841 void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2842 addAlignedMemoryOperands(Inst, N);
2843 }
2844
2845 void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2846 addAlignedMemoryOperands(Inst, N);
2847 }
2848
2849 void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2850 addAlignedMemoryOperands(Inst, N);
2851 }
2852
2853 void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2854 addAlignedMemoryOperands(Inst, N);
2855 }
2856
2857 void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2858 addAlignedMemoryOperands(Inst, N);
2859 }
2860
2861 void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2862 addAlignedMemoryOperands(Inst, N);
2863 }
2864
2865 void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2866 addAlignedMemoryOperands(Inst, N);
2867 }
2868
2869 void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const {
2870 addAlignedMemoryOperands(Inst, N);
2871 }
2872
2873 void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
2874 assert(N == 3 && "Invalid number of operands!")((N == 3 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 3 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2874, __PRETTY_FUNCTION__))
;
2875 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
2876 if (!Memory.OffsetRegNum) {
2877 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
2878 // Special case for #-0
2879 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2880 if (Val < 0) Val = -Val;
2881 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
2882 } else {
2883 // For register offset, we encode the shift type and negation flag
2884 // here.
2885 Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
2886 Memory.ShiftImm, Memory.ShiftType);
2887 }
2888 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2889 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
2890 Inst.addOperand(MCOperand::createImm(Val));
2891 }
2892
2893 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
2894 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2894, __PRETTY_FUNCTION__))
;
2895 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2896 assert(CE && "non-constant AM2OffsetImm operand!")((CE && "non-constant AM2OffsetImm operand!") ? static_cast
<void> (0) : __assert_fail ("CE && \"non-constant AM2OffsetImm operand!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2896, __PRETTY_FUNCTION__))
;
2897 int32_t Val = CE->getValue();
2898 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
2899 // Special case for #-0
2900 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2901 if (Val < 0) Val = -Val;
2902 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
2903 Inst.addOperand(MCOperand::createReg(0));
2904 Inst.addOperand(MCOperand::createImm(Val));
2905 }
2906
2907 void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
2908 assert(N == 3 && "Invalid number of operands!")((N == 3 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 3 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2908, __PRETTY_FUNCTION__))
;
2909 // If we have an immediate that's not a constant, treat it as a label
2910 // reference needing a fixup. If it is a constant, it's something else
2911 // and we reject it.
2912 if (isImm()) {
2913 Inst.addOperand(MCOperand::createExpr(getImm()));
2914 Inst.addOperand(MCOperand::createReg(0));
2915 Inst.addOperand(MCOperand::createImm(0));
2916 return;
2917 }
2918
2919 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
2920 if (!Memory.OffsetRegNum) {
2921 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
2922 // Special case for #-0
2923 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2924 if (Val < 0) Val = -Val;
2925 Val = ARM_AM::getAM3Opc(AddSub, Val);
2926 } else {
2927 // For register offset, we encode the shift type and negation flag
2928 // here.
2929 Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
2930 }
2931 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2932 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
2933 Inst.addOperand(MCOperand::createImm(Val));
2934 }
2935
2936 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
2937 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2937, __PRETTY_FUNCTION__))
;
2938 if (Kind == k_PostIndexRegister) {
2939 int32_t Val =
2940 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
2941 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
2942 Inst.addOperand(MCOperand::createImm(Val));
2943 return;
2944 }
2945
2946 // Constant offset.
2947 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
2948 int32_t Val = CE->getValue();
2949 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
2950 // Special case for #-0
2951 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2952 if (Val < 0) Val = -Val;
2953 Val = ARM_AM::getAM3Opc(AddSub, Val);
2954 Inst.addOperand(MCOperand::createReg(0));
2955 Inst.addOperand(MCOperand::createImm(Val));
2956 }
2957
2958 void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
2959 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2959, __PRETTY_FUNCTION__))
;
2960 // If we have an immediate that's not a constant, treat it as a label
2961 // reference needing a fixup. If it is a constant, it's something else
2962 // and we reject it.
2963 if (isImm()) {
2964 Inst.addOperand(MCOperand::createExpr(getImm()));
2965 Inst.addOperand(MCOperand::createImm(0));
2966 return;
2967 }
2968
2969 // The lower two bits are always zero and as such are not encoded.
2970 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
2971 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
2972 // Special case for #-0
2973 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2974 if (Val < 0) Val = -Val;
2975 Val = ARM_AM::getAM5Opc(AddSub, Val);
2976 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2977 Inst.addOperand(MCOperand::createImm(Val));
2978 }
2979
2980 void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const {
2981 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 2981, __PRETTY_FUNCTION__))
;
2982 // If we have an immediate that's not a constant, treat it as a label
2983 // reference needing a fixup. If it is a constant, it's something else
2984 // and we reject it.
2985 if (isImm()) {
2986 Inst.addOperand(MCOperand::createExpr(getImm()));
2987 Inst.addOperand(MCOperand::createImm(0));
2988 return;
2989 }
2990
2991 // The lower bit is always zero and as such is not encoded.
2992 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 2 : 0;
2993 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
2994 // Special case for #-0
2995 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2996 if (Val < 0) Val = -Val;
2997 Val = ARM_AM::getAM5FP16Opc(AddSub, Val);
2998 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2999 Inst.addOperand(MCOperand::createImm(Val));
3000 }
3001
3002 void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
3003 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3003, __PRETTY_FUNCTION__))
;
3004 // If we have an immediate that's not a constant, treat it as a label
3005 // reference needing a fixup. If it is a constant, it's something else
3006 // and we reject it.
3007 if (isImm()) {
3008 Inst.addOperand(MCOperand::createExpr(getImm()));
3009 Inst.addOperand(MCOperand::createImm(0));
3010 return;
3011 }
3012
3013 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
3014 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3015 Inst.addOperand(MCOperand::createImm(Val));
3016 }
3017
3018 void addMemImm7s4OffsetOperands(MCInst &Inst, unsigned N) const {
3019 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3019, __PRETTY_FUNCTION__))
;
3020 // If we have an immediate that's not a constant, treat it as a label
3021 // reference needing a fixup. If it is a constant, it's something else
3022 // and we reject it.
3023 if (isImm()) {
3024 Inst.addOperand(MCOperand::createExpr(getImm()));
3025 Inst.addOperand(MCOperand::createImm(0));
3026 return;
3027 }
3028
3029 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
3030 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3031 Inst.addOperand(MCOperand::createImm(Val));
3032 }
3033
3034 void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
3035 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3035, __PRETTY_FUNCTION__))
;
3036 // The lower two bits are always zero and as such are not encoded.
3037 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
3038 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3039 Inst.addOperand(MCOperand::createImm(Val));
3040 }
3041
3042 void addMemImmOffsetOperands(MCInst &Inst, unsigned N) const {
3043 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3043, __PRETTY_FUNCTION__))
;
3044 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
3045 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3046 Inst.addOperand(MCOperand::createImm(Val));
3047 }
3048
3049 void addMemRegRQOffsetOperands(MCInst &Inst, unsigned N) const {
3050 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3050, __PRETTY_FUNCTION__))
;
3051 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3052 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3053 }
3054
3055 void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3056 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3056, __PRETTY_FUNCTION__))
;
3057 // If this is an immediate, it's a label reference.
3058 if (isImm()) {
3059 addExpr(Inst, getImm());
3060 Inst.addOperand(MCOperand::createImm(0));
3061 return;
3062 }
3063
3064 // Otherwise, it's a normal memory reg+offset.
3065 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
3066 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3067 Inst.addOperand(MCOperand::createImm(Val));
3068 }
3069
3070 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3071 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3071, __PRETTY_FUNCTION__))
;
3072 // If this is an immediate, it's a label reference.
3073 if (isImm()) {
3074 addExpr(Inst, getImm());
3075 Inst.addOperand(MCOperand::createImm(0));
3076 return;
3077 }
3078
3079 // Otherwise, it's a normal memory reg+offset.
3080 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
3081 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3082 Inst.addOperand(MCOperand::createImm(Val));
3083 }
3084
3085 void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const {
3086 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3086, __PRETTY_FUNCTION__))
;
3087 // This is container for the immediate that we will create the constant
3088 // pool from
3089 addExpr(Inst, getConstantPoolImm());
3090 return;
3091 }
3092
3093 void addMemTBBOperands(MCInst &Inst, unsigned N) const {
3094 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3094, __PRETTY_FUNCTION__))
;
3095 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3096 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3097 }
3098
3099 void addMemTBHOperands(MCInst &Inst, unsigned N) const {
3100 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3100, __PRETTY_FUNCTION__))
;
3101 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3102 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3103 }
3104
3105 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3106 assert(N == 3 && "Invalid number of operands!")((N == 3 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 3 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3106, __PRETTY_FUNCTION__))
;
3107 unsigned Val =
3108 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3109 Memory.ShiftImm, Memory.ShiftType);
3110 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3111 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3112 Inst.addOperand(MCOperand::createImm(Val));
3113 }
3114
3115 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3116 assert(N == 3 && "Invalid number of operands!")((N == 3 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 3 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3116, __PRETTY_FUNCTION__))
;
3117 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3118 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3119 Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
3120 }
3121
3122 void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
3123 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3123, __PRETTY_FUNCTION__))
;
3124 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3125 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3126 }
3127
3128 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
3129 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3129, __PRETTY_FUNCTION__))
;
3130 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
3131 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3132 Inst.addOperand(MCOperand::createImm(Val));
3133 }
3134
3135 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
3136 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3136, __PRETTY_FUNCTION__))
;
3137 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
3138 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3139 Inst.addOperand(MCOperand::createImm(Val));
3140 }
3141
3142 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
3143 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3143, __PRETTY_FUNCTION__))
;
3144 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
3145 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3146 Inst.addOperand(MCOperand::createImm(Val));
3147 }
3148
3149 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
3150 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3150, __PRETTY_FUNCTION__))
;
3151 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
3152 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3153 Inst.addOperand(MCOperand::createImm(Val));
3154 }
3155
3156 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
3157 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3157, __PRETTY_FUNCTION__))
;
3158 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3159 assert(CE && "non-constant post-idx-imm8 operand!")((CE && "non-constant post-idx-imm8 operand!") ? static_cast
<void> (0) : __assert_fail ("CE && \"non-constant post-idx-imm8 operand!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3159, __PRETTY_FUNCTION__))
;
3160 int Imm = CE->getValue();
3161 bool isAdd = Imm >= 0;
3162 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3163 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
3164 Inst.addOperand(MCOperand::createImm(Imm));
3165 }
3166
3167 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
3168 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3168, __PRETTY_FUNCTION__))
;
3169 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3170 assert(CE && "non-constant post-idx-imm8s4 operand!")((CE && "non-constant post-idx-imm8s4 operand!") ? static_cast
<void> (0) : __assert_fail ("CE && \"non-constant post-idx-imm8s4 operand!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3170, __PRETTY_FUNCTION__))
;
3171 int Imm = CE->getValue();
3172 bool isAdd = Imm >= 0;
3173 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3174 // Immediate is scaled by 4.
3175 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
3176 Inst.addOperand(MCOperand::createImm(Imm));
3177 }
3178
3179 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
3180 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3180, __PRETTY_FUNCTION__))
;
3181 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3182 Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
3183 }
3184
3185 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
3186 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3186, __PRETTY_FUNCTION__))
;
3187 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3188 // The sign, shift type, and shift amount are encoded in a single operand
3189 // using the AM2 encoding helpers.
3190 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
3191 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
3192 PostIdxReg.ShiftTy);
3193 Inst.addOperand(MCOperand::createImm(Imm));
3194 }
3195
3196 void addPowerTwoOperands(MCInst &Inst, unsigned N) const {
3197 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3197, __PRETTY_FUNCTION__))
;
3198 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3199 Inst.addOperand(MCOperand::createImm(CE->getValue()));
3200 }
3201
3202 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
3203 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3203, __PRETTY_FUNCTION__))
;
3204 Inst.addOperand(MCOperand::createImm(unsigned(getMSRMask())));
3205 }
3206
3207 void addBankedRegOperands(MCInst &Inst, unsigned N) const {
3208 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3208, __PRETTY_FUNCTION__))
;
3209 Inst.addOperand(MCOperand::createImm(unsigned(getBankedReg())));
3210 }
3211
3212 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
3213 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3213, __PRETTY_FUNCTION__))
;
3214 Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
3215 }
3216
3217 void addVecListOperands(MCInst &Inst, unsigned N) const {
3218 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3218, __PRETTY_FUNCTION__))
;
3219 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3220 }
3221
3222 void addMVEVecListOperands(MCInst &Inst, unsigned N) const {
3223 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3223, __PRETTY_FUNCTION__))
;
3224
3225 // When we come here, the VectorList field will identify a range
3226 // of q-registers by its base register and length, and it will
3227 // have already been error-checked to be the expected length of
3228 // range and contain only q-regs in the range q0-q7. So we can
3229 // count on the base register being in the range q0-q6 (for 2
3230 // regs) or q0-q4 (for 4)
3231 //
3232 // The MVE instructions taking a register range of this kind will
3233 // need an operand in the QQPR or QQQQPR class, representing the
3234 // entire range as a unit. So we must translate into that class,
3235 // by finding the index of the base register in the MQPR reg
3236 // class, and returning the super-register at the corresponding
3237 // index in the target class.
3238
3239 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3240 const MCRegisterClass *RC_out = (VectorList.Count == 2) ?
3241 &ARMMCRegisterClasses[ARM::QQPRRegClassID] :
3242 &ARMMCRegisterClasses[ARM::QQQQPRRegClassID];
3243
3244 unsigned I, E = RC_out->getNumRegs();
3245 for (I = 0; I < E; I++)
3246 if (RC_in->getRegister(I) == VectorList.RegNum)
3247 break;
3248 assert(I < E && "Invalid vector list start register!")((I < E && "Invalid vector list start register!") ?
static_cast<void> (0) : __assert_fail ("I < E && \"Invalid vector list start register!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3248, __PRETTY_FUNCTION__))
;
3249
3250 Inst.addOperand(MCOperand::createReg(RC_out->getRegister(I)));
3251 }
3252
3253 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
3254 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3254, __PRETTY_FUNCTION__))
;
3255 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3256 Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
3257 }
3258
3259 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
3260 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3260, __PRETTY_FUNCTION__))
;
3261 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3262 }
3263
3264 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
3265 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3265, __PRETTY_FUNCTION__))
;
3266 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3267 }
3268
3269 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
3270 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3270, __PRETTY_FUNCTION__))
;
3271 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3272 }
3273
3274 void addVectorIndex64Operands(MCInst &Inst, unsigned N) const {
3275 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3275, __PRETTY_FUNCTION__))
;
3276 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3277 }
3278
3279 void addMVEVectorIndexOperands(MCInst &Inst, unsigned N) const {
3280 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3280, __PRETTY_FUNCTION__))
;
3281 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3282 }
3283
3284 void addMVEPairVectorIndexOperands(MCInst &Inst, unsigned N) const {
3285 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3285, __PRETTY_FUNCTION__))
;
3286 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3287 }
3288
3289 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
3290 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3290, __PRETTY_FUNCTION__))
;
3291 // The immediate encodes the type of constant as well as the value.
3292 // Mask in that this is an i8 splat.
3293 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3294 Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
3295 }
3296
3297 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
3298 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3298, __PRETTY_FUNCTION__))
;
3299 // The immediate encodes the type of constant as well as the value.
3300 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3301 unsigned Value = CE->getValue();
3302 Value = ARM_AM::encodeNEONi16splat(Value);
3303 Inst.addOperand(MCOperand::createImm(Value));
3304 }
3305
3306 void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
3307 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3307, __PRETTY_FUNCTION__))
;
3308 // The immediate encodes the type of constant as well as the value.
3309 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3310 unsigned Value = CE->getValue();
3311 Value = ARM_AM::encodeNEONi16splat(~Value & 0xffff);
3312 Inst.addOperand(MCOperand::createImm(Value));
3313 }
3314
3315 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
3316 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3316, __PRETTY_FUNCTION__))
;
3317 // The immediate encodes the type of constant as well as the value.
3318 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3319 unsigned Value = CE->getValue();
3320 Value = ARM_AM::encodeNEONi32splat(Value);
3321 Inst.addOperand(MCOperand::createImm(Value));
3322 }
3323
3324 void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
3325 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3325, __PRETTY_FUNCTION__))
;
3326 // The immediate encodes the type of constant as well as the value.
3327 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3328 unsigned Value = CE->getValue();
3329 Value = ARM_AM::encodeNEONi32splat(~Value);
3330 Inst.addOperand(MCOperand::createImm(Value));
3331 }
3332
3333 void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
3334 // The immediate encodes the type of constant as well as the value.
3335 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3336 assert((Inst.getOpcode() == ARM::VMOVv8i8 ||(((Inst.getOpcode() == ARM::VMOVv8i8 || Inst.getOpcode() == ARM
::VMOVv16i8) && "All instructions that wants to replicate non-zero byte "
"always must be replaced with VMOVv8i8 or VMOVv16i8.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv8i8 || Inst.getOpcode() == ARM::VMOVv16i8) && \"All instructions that wants to replicate non-zero byte \" \"always must be replaced with VMOVv8i8 or VMOVv16i8.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3339, __PRETTY_FUNCTION__))
3337 Inst.getOpcode() == ARM::VMOVv16i8) &&(((Inst.getOpcode() == ARM::VMOVv8i8 || Inst.getOpcode() == ARM
::VMOVv16i8) && "All instructions that wants to replicate non-zero byte "
"always must be replaced with VMOVv8i8 or VMOVv16i8.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv8i8 || Inst.getOpcode() == ARM::VMOVv16i8) && \"All instructions that wants to replicate non-zero byte \" \"always must be replaced with VMOVv8i8 or VMOVv16i8.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3339, __PRETTY_FUNCTION__))
3338 "All instructions that wants to replicate non-zero byte "(((Inst.getOpcode() == ARM::VMOVv8i8 || Inst.getOpcode() == ARM
::VMOVv16i8) && "All instructions that wants to replicate non-zero byte "
"always must be replaced with VMOVv8i8 or VMOVv16i8.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv8i8 || Inst.getOpcode() == ARM::VMOVv16i8) && \"All instructions that wants to replicate non-zero byte \" \"always must be replaced with VMOVv8i8 or VMOVv16i8.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3339, __PRETTY_FUNCTION__))
3339 "always must be replaced with VMOVv8i8 or VMOVv16i8.")(((Inst.getOpcode() == ARM::VMOVv8i8 || Inst.getOpcode() == ARM
::VMOVv16i8) && "All instructions that wants to replicate non-zero byte "
"always must be replaced with VMOVv8i8 or VMOVv16i8.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv8i8 || Inst.getOpcode() == ARM::VMOVv16i8) && \"All instructions that wants to replicate non-zero byte \" \"always must be replaced with VMOVv8i8 or VMOVv16i8.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3339, __PRETTY_FUNCTION__))
;
3340 unsigned Value = CE->getValue();
3341 if (Inv)
3342 Value = ~Value;
3343 unsigned B = Value & 0xff;
3344 B |= 0xe00; // cmode = 0b1110
3345 Inst.addOperand(MCOperand::createImm(B));
3346 }
3347
3348 void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3349 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3349, __PRETTY_FUNCTION__))
;
3350 addNEONi8ReplicateOperands(Inst, true);
3351 }
3352
3353 static unsigned encodeNeonVMOVImmediate(unsigned Value) {
3354 if (Value >= 256 && Value <= 0xffff)
3355 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
3356 else if (Value > 0xffff && Value <= 0xffffff)
3357 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
3358 else if (Value > 0xffffff)
3359 Value = (Value >> 24) | 0x600;
3360 return Value;
3361 }
3362
3363 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
3364 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3364, __PRETTY_FUNCTION__))
;
3365 // The immediate encodes the type of constant as well as the value.
3366 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3367 unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
3368 Inst.addOperand(MCOperand::createImm(Value));
3369 }
3370
3371 void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3372 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3372, __PRETTY_FUNCTION__))
;
3373 addNEONi8ReplicateOperands(Inst, false);
3374 }
3375
3376 void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
3377 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3377, __PRETTY_FUNCTION__))
;
3378 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3379 assert((Inst.getOpcode() == ARM::VMOVv4i16 ||(((Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM
::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode
() == ARM::VMVNv8i16) && "All instructions that want to replicate non-zero half-word "
"always must be replaced with V{MOV,MVN}v{4,8}i16.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode() == ARM::VMVNv8i16) && \"All instructions that want to replicate non-zero half-word \" \"always must be replaced with V{MOV,MVN}v{4,8}i16.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3384, __PRETTY_FUNCTION__))
3380 Inst.getOpcode() == ARM::VMOVv8i16 ||(((Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM
::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode
() == ARM::VMVNv8i16) && "All instructions that want to replicate non-zero half-word "
"always must be replaced with V{MOV,MVN}v{4,8}i16.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode() == ARM::VMVNv8i16) && \"All instructions that want to replicate non-zero half-word \" \"always must be replaced with V{MOV,MVN}v{4,8}i16.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3384, __PRETTY_FUNCTION__))
3381 Inst.getOpcode() == ARM::VMVNv4i16 ||(((Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM
::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode
() == ARM::VMVNv8i16) && "All instructions that want to replicate non-zero half-word "
"always must be replaced with V{MOV,MVN}v{4,8}i16.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode() == ARM::VMVNv8i16) && \"All instructions that want to replicate non-zero half-word \" \"always must be replaced with V{MOV,MVN}v{4,8}i16.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3384, __PRETTY_FUNCTION__))
3382 Inst.getOpcode() == ARM::VMVNv8i16) &&(((Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM
::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode
() == ARM::VMVNv8i16) && "All instructions that want to replicate non-zero half-word "
"always must be replaced with V{MOV,MVN}v{4,8}i16.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode() == ARM::VMVNv8i16) && \"All instructions that want to replicate non-zero half-word \" \"always must be replaced with V{MOV,MVN}v{4,8}i16.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3384, __PRETTY_FUNCTION__))
3383 "All instructions that want to replicate non-zero half-word "(((Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM
::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode
() == ARM::VMVNv8i16) && "All instructions that want to replicate non-zero half-word "
"always must be replaced with V{MOV,MVN}v{4,8}i16.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode() == ARM::VMVNv8i16) && \"All instructions that want to replicate non-zero half-word \" \"always must be replaced with V{MOV,MVN}v{4,8}i16.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3384, __PRETTY_FUNCTION__))
3384 "always must be replaced with V{MOV,MVN}v{4,8}i16.")(((Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM
::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode
() == ARM::VMVNv8i16) && "All instructions that want to replicate non-zero half-word "
"always must be replaced with V{MOV,MVN}v{4,8}i16.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv4i16 || Inst.getOpcode() == ARM::VMOVv8i16 || Inst.getOpcode() == ARM::VMVNv4i16 || Inst.getOpcode() == ARM::VMVNv8i16) && \"All instructions that want to replicate non-zero half-word \" \"always must be replaced with V{MOV,MVN}v{4,8}i16.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3384, __PRETTY_FUNCTION__))
;
3385 uint64_t Value = CE->getValue();
3386 unsigned Elem = Value & 0xffff;
3387 if (Elem >= 256)
3388 Elem = (Elem >> 8) | 0x200;
3389 Inst.addOperand(MCOperand::createImm(Elem));
3390 }
3391
3392 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
3393 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3393, __PRETTY_FUNCTION__))
;
3394 // The immediate encodes the type of constant as well as the value.
3395 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3396 unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
3397 Inst.addOperand(MCOperand::createImm(Value));
3398 }
3399
3400 void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
3401 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3401, __PRETTY_FUNCTION__))
;
3402 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3403 assert((Inst.getOpcode() == ARM::VMOVv2i32 ||(((Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM
::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode
() == ARM::VMVNv4i32) && "All instructions that want to replicate non-zero word "
"always must be replaced with V{MOV,MVN}v{2,4}i32.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode() == ARM::VMVNv4i32) && \"All instructions that want to replicate non-zero word \" \"always must be replaced with V{MOV,MVN}v{2,4}i32.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3408, __PRETTY_FUNCTION__))
3404 Inst.getOpcode() == ARM::VMOVv4i32 ||(((Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM
::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode
() == ARM::VMVNv4i32) && "All instructions that want to replicate non-zero word "
"always must be replaced with V{MOV,MVN}v{2,4}i32.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode() == ARM::VMVNv4i32) && \"All instructions that want to replicate non-zero word \" \"always must be replaced with V{MOV,MVN}v{2,4}i32.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3408, __PRETTY_FUNCTION__))
3405 Inst.getOpcode() == ARM::VMVNv2i32 ||(((Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM
::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode
() == ARM::VMVNv4i32) && "All instructions that want to replicate non-zero word "
"always must be replaced with V{MOV,MVN}v{2,4}i32.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode() == ARM::VMVNv4i32) && \"All instructions that want to replicate non-zero word \" \"always must be replaced with V{MOV,MVN}v{2,4}i32.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3408, __PRETTY_FUNCTION__))
3406 Inst.getOpcode() == ARM::VMVNv4i32) &&(((Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM
::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode
() == ARM::VMVNv4i32) && "All instructions that want to replicate non-zero word "
"always must be replaced with V{MOV,MVN}v{2,4}i32.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode() == ARM::VMVNv4i32) && \"All instructions that want to replicate non-zero word \" \"always must be replaced with V{MOV,MVN}v{2,4}i32.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3408, __PRETTY_FUNCTION__))
3407 "All instructions that want to replicate non-zero word "(((Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM
::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode
() == ARM::VMVNv4i32) && "All instructions that want to replicate non-zero word "
"always must be replaced with V{MOV,MVN}v{2,4}i32.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode() == ARM::VMVNv4i32) && \"All instructions that want to replicate non-zero word \" \"always must be replaced with V{MOV,MVN}v{2,4}i32.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3408, __PRETTY_FUNCTION__))
3408 "always must be replaced with V{MOV,MVN}v{2,4}i32.")(((Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM
::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode
() == ARM::VMVNv4i32) && "All instructions that want to replicate non-zero word "
"always must be replaced with V{MOV,MVN}v{2,4}i32.") ? static_cast
<void> (0) : __assert_fail ("(Inst.getOpcode() == ARM::VMOVv2i32 || Inst.getOpcode() == ARM::VMOVv4i32 || Inst.getOpcode() == ARM::VMVNv2i32 || Inst.getOpcode() == ARM::VMVNv4i32) && \"All instructions that want to replicate non-zero word \" \"always must be replaced with V{MOV,MVN}v{2,4}i32.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3408, __PRETTY_FUNCTION__))
;
3409 uint64_t Value = CE->getValue();
3410 unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
3411 Inst.addOperand(MCOperand::createImm(Elem));
3412 }
3413
3414 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
3415 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3415, __PRETTY_FUNCTION__))
;
3416 // The immediate encodes the type of constant as well as the value.
3417 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3418 uint64_t Value = CE->getValue();
3419 unsigned Imm = 0;
3420 for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
3421 Imm |= (Value & 1) << i;
3422 }
3423 Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
3424 }
3425
3426 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
3427 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3427, __PRETTY_FUNCTION__))
;
3428 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3429 Inst.addOperand(MCOperand::createImm(CE->getValue() / 90));
3430 }
3431
3432 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
3433 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3433, __PRETTY_FUNCTION__))
;
3434 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3435 Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
3436 }
3437
3438 void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
3439 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3439, __PRETTY_FUNCTION__))
;
3440 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3441 unsigned Imm = CE->getValue();
3442 assert((Imm == 48 || Imm == 64) && "Invalid saturate operand")(((Imm == 48 || Imm == 64) && "Invalid saturate operand"
) ? static_cast<void> (0) : __assert_fail ("(Imm == 48 || Imm == 64) && \"Invalid saturate operand\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3442, __PRETTY_FUNCTION__))
;
3443 Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0));
3444 }
3445
3446 void print(raw_ostream &OS) const override;
3447
3448 static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S) {
3449 auto Op = std::make_unique<ARMOperand>(k_ITCondMask);
3450 Op->ITMask.Mask = Mask;
3451 Op->StartLoc = S;
3452 Op->EndLoc = S;
3453 return Op;
3454 }
3455
3456 static std::unique_ptr<ARMOperand> CreateCondCode(ARMCC::CondCodes CC,
3457 SMLoc S) {
3458 auto Op = std::make_unique<ARMOperand>(k_CondCode);
3459 Op->CC.Val = CC;
3460 Op->StartLoc = S;
3461 Op->EndLoc = S;
3462 return Op;
3463 }
3464
3465 static std::unique_ptr<ARMOperand> CreateVPTPred(ARMVCC::VPTCodes CC,
3466 SMLoc S) {
3467 auto Op = std::make_unique<ARMOperand>(k_VPTPred);
3468 Op->VCC.Val = CC;
3469 Op->StartLoc = S;
3470 Op->EndLoc = S;
3471 return Op;
3472 }
3473
3474 static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S) {
3475 auto Op = std::make_unique<ARMOperand>(k_CoprocNum);
3476 Op->Cop.Val = CopVal;
3477 Op->StartLoc = S;
3478 Op->EndLoc = S;
3479 return Op;
3480 }
3481
3482 static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S) {
3483 auto Op = std::make_unique<ARMOperand>(k_CoprocReg);
3484 Op->Cop.Val = CopVal;
3485 Op->StartLoc = S;
3486 Op->EndLoc = S;
3487 return Op;
3488 }
3489
3490 static std::unique_ptr<ARMOperand> CreateCoprocOption(unsigned Val, SMLoc S,
3491 SMLoc E) {
3492 auto Op = std::make_unique<ARMOperand>(k_CoprocOption);
3493 Op->Cop.Val = Val;
3494 Op->StartLoc = S;
3495 Op->EndLoc = E;
3496 return Op;
3497 }
3498
3499 static std::unique_ptr<ARMOperand> CreateCCOut(unsigned RegNum, SMLoc S) {
3500 auto Op = std::make_unique<ARMOperand>(k_CCOut);
3501 Op->Reg.RegNum = RegNum;
3502 Op->StartLoc = S;
3503 Op->EndLoc = S;
3504 return Op;
3505 }
3506
3507 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S) {
3508 auto Op = std::make_unique<ARMOperand>(k_Token);
3509 Op->Tok.Data = Str.data();
3510 Op->Tok.Length = Str.size();
3511 Op->StartLoc = S;
3512 Op->EndLoc = S;
3513 return Op;
3514 }
3515
3516 static std::unique_ptr<ARMOperand> CreateReg(unsigned RegNum, SMLoc S,
3517 SMLoc E) {
3518 auto Op = std::make_unique<ARMOperand>(k_Register);
3519 Op->Reg.RegNum = RegNum;
3520 Op->StartLoc = S;
3521 Op->EndLoc = E;
3522 return Op;
3523 }
3524
3525 static std::unique_ptr<ARMOperand>
3526 CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, unsigned SrcReg,
3527 unsigned ShiftReg, unsigned ShiftImm, SMLoc S,
3528 SMLoc E) {
3529 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister);
3530 Op->RegShiftedReg.ShiftTy = ShTy;
3531 Op->RegShiftedReg.SrcReg = SrcReg;
3532 Op->RegShiftedReg.ShiftReg = ShiftReg;
3533 Op->RegShiftedReg.ShiftImm = ShiftImm;
3534 Op->StartLoc = S;
3535 Op->EndLoc = E;
3536 return Op;
3537 }
3538
3539 static std::unique_ptr<ARMOperand>
3540 CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, unsigned SrcReg,
3541 unsigned ShiftImm, SMLoc S, SMLoc E) {
3542 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate);
3543 Op->RegShiftedImm.ShiftTy = ShTy;
3544 Op->RegShiftedImm.SrcReg = SrcReg;
3545 Op->RegShiftedImm.ShiftImm = ShiftImm;
3546 Op->StartLoc = S;
3547 Op->EndLoc = E;
3548 return Op;
3549 }
3550
3551 static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm,
3552 SMLoc S, SMLoc E) {
3553 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate);
3554 Op->ShifterImm.isASR = isASR;
3555 Op->ShifterImm.Imm = Imm;
3556 Op->StartLoc = S;
3557 Op->EndLoc = E;
3558 return Op;
3559 }
3560
3561 static std::unique_ptr<ARMOperand> CreateRotImm(unsigned Imm, SMLoc S,
3562 SMLoc E) {
3563 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate);
3564 Op->RotImm.Imm = Imm;
3565 Op->StartLoc = S;
3566 Op->EndLoc = E;
3567 return Op;
3568 }
3569
3570 static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
3571 SMLoc S, SMLoc E) {
3572 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate);
3573 Op->ModImm.Bits = Bits;
3574 Op->ModImm.Rot = Rot;
3575 Op->StartLoc = S;
3576 Op->EndLoc = E;
3577 return Op;
3578 }
3579
3580 static std::unique_ptr<ARMOperand>
3581 CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E) {
3582 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate);
3583 Op->Imm.Val = Val;
3584 Op->StartLoc = S;
3585 Op->EndLoc = E;
3586 return Op;
3587 }
3588
3589 static std::unique_ptr<ARMOperand>
3590 CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) {
3591 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor);
3592 Op->Bitfield.LSB = LSB;
3593 Op->Bitfield.Width = Width;
3594 Op->StartLoc = S;
3595 Op->EndLoc = E;
3596 return Op;
3597 }
3598
3599 static std::unique_ptr<ARMOperand>
3600 CreateRegList(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs,
3601 SMLoc StartLoc, SMLoc EndLoc) {
3602 assert(Regs.size() > 0 && "RegList contains no registers?")((Regs.size() > 0 && "RegList contains no registers?"
) ? static_cast<void> (0) : __assert_fail ("Regs.size() > 0 && \"RegList contains no registers?\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3602, __PRETTY_FUNCTION__))
;
3603 KindTy Kind = k_RegisterList;
3604
3605 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
3606 Regs.front().second)) {
3607 if (Regs.back().second == ARM::VPR)
3608 Kind = k_FPDRegisterListWithVPR;
3609 else
3610 Kind = k_DPRRegisterList;
3611 } else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(
3612 Regs.front().second)) {
3613 if (Regs.back().second == ARM::VPR)
3614 Kind = k_FPSRegisterListWithVPR;
3615 else
3616 Kind = k_SPRRegisterList;
3617 }
3618
3619 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3620 Kind = k_RegisterListWithAPSR;
3621
3622 assert(llvm::is_sorted(Regs) && "Register list must be sorted by encoding")((llvm::is_sorted(Regs) && "Register list must be sorted by encoding"
) ? static_cast<void> (0) : __assert_fail ("llvm::is_sorted(Regs) && \"Register list must be sorted by encoding\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3622, __PRETTY_FUNCTION__))
;
3623
3624 auto Op = std::make_unique<ARMOperand>(Kind);
3625 for (const auto &P : Regs)
3626 Op->Registers.push_back(P.second);
3627
3628 Op->StartLoc = StartLoc;
3629 Op->EndLoc = EndLoc;
3630 return Op;
3631 }
3632
3633 static std::unique_ptr<ARMOperand> CreateVectorList(unsigned RegNum,
3634 unsigned Count,
3635 bool isDoubleSpaced,
3636 SMLoc S, SMLoc E) {
3637 auto Op = std::make_unique<ARMOperand>(k_VectorList);
3638 Op->VectorList.RegNum = RegNum;
3639 Op->VectorList.Count = Count;
3640 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3641 Op->StartLoc = S;
3642 Op->EndLoc = E;
3643 return Op;
3644 }
3645
3646 static std::unique_ptr<ARMOperand>
3647 CreateVectorListAllLanes(unsigned RegNum, unsigned Count, bool isDoubleSpaced,
3648 SMLoc S, SMLoc E) {
3649 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes);
3650 Op->VectorList.RegNum = RegNum;
3651 Op->VectorList.Count = Count;
3652 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3653 Op->StartLoc = S;
3654 Op->EndLoc = E;
3655 return Op;
3656 }
3657
3658 static std::unique_ptr<ARMOperand>
3659 CreateVectorListIndexed(unsigned RegNum, unsigned Count, unsigned Index,
3660 bool isDoubleSpaced, SMLoc S, SMLoc E) {
3661 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed);
3662 Op->VectorList.RegNum = RegNum;
3663 Op->VectorList.Count = Count;
3664 Op->VectorList.LaneIndex = Index;
3665 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3666 Op->StartLoc = S;
3667 Op->EndLoc = E;
3668 return Op;
3669 }
3670
3671 static std::unique_ptr<ARMOperand>
3672 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
3673 auto Op = std::make_unique<ARMOperand>(k_VectorIndex);
3674 Op->VectorIndex.Val = Idx;
3675 Op->StartLoc = S;
3676 Op->EndLoc = E;
3677 return Op;
3678 }
3679
3680 static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S,
3681 SMLoc E) {
3682 auto Op = std::make_unique<ARMOperand>(k_Immediate);
3683 Op->Imm.Val = Val;
3684 Op->StartLoc = S;
3685 Op->EndLoc = E;
3686 return Op;
3687 }
3688
3689 static std::unique_ptr<ARMOperand>
3690 CreateMem(unsigned BaseRegNum, const MCConstantExpr *OffsetImm,
3691 unsigned OffsetRegNum, ARM_AM::ShiftOpc ShiftType,
3692 unsigned ShiftImm, unsigned Alignment, bool isNegative, SMLoc S,
3693 SMLoc E, SMLoc AlignmentLoc = SMLoc()) {
3694 auto Op = std::make_unique<ARMOperand>(k_Memory);
3695 Op->Memory.BaseRegNum = BaseRegNum;
3696 Op->Memory.OffsetImm = OffsetImm;
3697 Op->Memory.OffsetRegNum = OffsetRegNum;
3698 Op->Memory.ShiftType = ShiftType;
3699 Op->Memory.ShiftImm = ShiftImm;
3700 Op->Memory.Alignment = Alignment;
3701 Op->Memory.isNegative = isNegative;
3702 Op->StartLoc = S;
3703 Op->EndLoc = E;
3704 Op->AlignmentLoc = AlignmentLoc;
3705 return Op;
3706 }
3707
3708 static std::unique_ptr<ARMOperand>
3709 CreatePostIdxReg(unsigned RegNum, bool isAdd, ARM_AM::ShiftOpc ShiftTy,
3710 unsigned ShiftImm, SMLoc S, SMLoc E) {
3711 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister);
3712 Op->PostIdxReg.RegNum = RegNum;
3713 Op->PostIdxReg.isAdd = isAdd;
3714 Op->PostIdxReg.ShiftTy = ShiftTy;
3715 Op->PostIdxReg.ShiftImm = ShiftImm;
3716 Op->StartLoc = S;
3717 Op->EndLoc = E;
3718 return Op;
3719 }
3720
3721 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(ARM_MB::MemBOpt Opt,
3722 SMLoc S) {
3723 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt);
3724 Op->MBOpt.Val = Opt;
3725 Op->StartLoc = S;
3726 Op->EndLoc = S;
3727 return Op;
3728 }
3729
3730 static std::unique_ptr<ARMOperand>
3731 CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S) {
3732 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt);
3733 Op->ISBOpt.Val = Opt;
3734 Op->StartLoc = S;
3735 Op->EndLoc = S;
3736 return Op;
3737 }
3738
3739 static std::unique_ptr<ARMOperand>
3740 CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S) {
3741 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt);
3742 Op->TSBOpt.Val = Opt;
3743 Op->StartLoc = S;
3744 Op->EndLoc = S;
3745 return Op;
3746 }
3747
3748 static std::unique_ptr<ARMOperand> CreateProcIFlags(ARM_PROC::IFlags IFlags,
3749 SMLoc S) {
3750 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags);
3751 Op->IFlags.Val = IFlags;
3752 Op->StartLoc = S;
3753 Op->EndLoc = S;
3754 return Op;
3755 }
3756
3757 static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S) {
3758 auto Op = std::make_unique<ARMOperand>(k_MSRMask);
3759 Op->MMask.Val = MMask;
3760 Op->StartLoc = S;
3761 Op->EndLoc = S;
3762 return Op;
3763 }
3764
3765 static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S) {
3766 auto Op = std::make_unique<ARMOperand>(k_BankedReg);
3767 Op->BankedReg.Val = Reg;
3768 Op->StartLoc = S;
3769 Op->EndLoc = S;
3770 return Op;
3771 }
3772};
3773
3774} // end anonymous namespace.
3775
3776void ARMOperand::print(raw_ostream &OS) const {
3777 auto RegName = [](unsigned Reg) {
3778 if (Reg)
3779 return ARMInstPrinter::getRegisterName(Reg);
3780 else
3781 return "noreg";
3782 };
3783
3784 switch (Kind) {
3785 case k_CondCode:
3786 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
3787 break;
3788 case k_VPTPred:
3789 OS << "<ARMVCC::" << ARMVPTPredToString(getVPTPred()) << ">";
3790 break;
3791 case k_CCOut:
3792 OS << "<ccout " << RegName(getReg()) << ">";
3793 break;
3794 case k_ITCondMask: {
3795 static const char *const MaskStr[] = {
3796 "(invalid)", "(tttt)", "(ttt)", "(ttte)",
3797 "(tt)", "(ttet)", "(tte)", "(ttee)",
3798 "(t)", "(tett)", "(tet)", "(tete)",
3799 "(te)", "(teet)", "(tee)", "(teee)",
3800 };
3801 assert((ITMask.Mask & 0xf) == ITMask.Mask)(((ITMask.Mask & 0xf) == ITMask.Mask) ? static_cast<void
> (0) : __assert_fail ("(ITMask.Mask & 0xf) == ITMask.Mask"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3801, __PRETTY_FUNCTION__))
;
3802 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
3803 break;
3804 }
3805 case k_CoprocNum:
3806 OS << "<coprocessor number: " << getCoproc() << ">";
3807 break;
3808 case k_CoprocReg:
3809 OS << "<coprocessor register: " << getCoproc() << ">";
3810 break;
3811 case k_CoprocOption:
3812 OS << "<coprocessor option: " << CoprocOption.Val << ">";
3813 break;
3814 case k_MSRMask:
3815 OS << "<mask: " << getMSRMask() << ">";
3816 break;
3817 case k_BankedReg:
3818 OS << "<banked reg: " << getBankedReg() << ">";
3819 break;
3820 case k_Immediate:
3821 OS << *getImm();
3822 break;
3823 case k_MemBarrierOpt:
3824 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
3825 break;
3826 case k_InstSyncBarrierOpt:
3827 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
3828 break;
3829 case k_TraceSyncBarrierOpt:
3830 OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
3831 break;
3832 case k_Memory:
3833 OS << "<memory";
3834 if (Memory.BaseRegNum)
3835 OS << " base:" << RegName(Memory.BaseRegNum);
3836 if (Memory.OffsetImm)
3837 OS << " offset-imm:" << *Memory.OffsetImm;
3838 if (Memory.OffsetRegNum)
3839 OS << " offset-reg:" << (Memory.isNegative ? "-" : "")
3840 << RegName(Memory.OffsetRegNum);
3841 if (Memory.ShiftType != ARM_AM::no_shift) {
3842 OS << " shift-type:" << ARM_AM::getShiftOpcStr(Memory.ShiftType);
3843 OS << " shift-imm:" << Memory.ShiftImm;
3844 }
3845 if (Memory.Alignment)
3846 OS << " alignment:" << Memory.Alignment;
3847 OS << ">";
3848 break;
3849 case k_PostIndexRegister:
3850 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
3851 << RegName(PostIdxReg.RegNum);
3852 if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
3853 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
3854 << PostIdxReg.ShiftImm;
3855 OS << ">";
3856 break;
3857 case k_ProcIFlags: {
3858 OS << "<ARM_PROC::";
3859 unsigned IFlags = getProcIFlags();
3860 for (int i=2; i >= 0; --i)
3861 if (IFlags & (1 << i))
3862 OS << ARM_PROC::IFlagsToString(1 << i);
3863 OS << ">";
3864 break;
3865 }
3866 case k_Register:
3867 OS << "<register " << RegName(getReg()) << ">";
3868 break;
3869 case k_ShifterImmediate:
3870 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
3871 << " #" << ShifterImm.Imm << ">";
3872 break;
3873 case k_ShiftedRegister:
3874 OS << "<so_reg_reg " << RegName(RegShiftedReg.SrcReg) << " "
3875 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) << " "
3876 << RegName(RegShiftedReg.ShiftReg) << ">";
3877 break;
3878 case k_ShiftedImmediate:
3879 OS << "<so_reg_imm " << RegName(RegShiftedImm.SrcReg) << " "
3880 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) << " #"
3881 << RegShiftedImm.ShiftImm << ">";
3882 break;
3883 case k_RotateImmediate:
3884 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
3885 break;
3886 case k_ModifiedImmediate:
3887 OS << "<mod_imm #" << ModImm.Bits << ", #"
3888 << ModImm.Rot << ")>";
3889 break;
3890 case k_ConstantPoolImmediate:
3891 OS << "<constant_pool_imm #" << *getConstantPoolImm();
3892 break;
3893 case k_BitfieldDescriptor:
3894 OS << "<bitfield " << "lsb: " << Bitfield.LSB
3895 << ", width: " << Bitfield.Width << ">";
3896 break;
3897 case k_RegisterList:
3898 case k_RegisterListWithAPSR:
3899 case k_DPRRegisterList:
3900 case k_SPRRegisterList:
3901 case k_FPSRegisterListWithVPR:
3902 case k_FPDRegisterListWithVPR: {
3903 OS << "<register_list ";
3904
3905 const SmallVectorImpl<unsigned> &RegList = getRegList();
3906 for (SmallVectorImpl<unsigned>::const_iterator
3907 I = RegList.begin(), E = RegList.end(); I != E; ) {
3908 OS << RegName(*I);
3909 if (++I < E) OS << ", ";
3910 }
3911
3912 OS << ">";
3913 break;
3914 }
3915 case k_VectorList:
3916 OS << "<vector_list " << VectorList.Count << " * "
3917 << RegName(VectorList.RegNum) << ">";
3918 break;
3919 case k_VectorListAllLanes:
3920 OS << "<vector_list(all lanes) " << VectorList.Count << " * "
3921 << RegName(VectorList.RegNum) << ">";
3922 break;
3923 case k_VectorListIndexed:
3924 OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
3925 << VectorList.Count << " * " << RegName(VectorList.RegNum) << ">";
3926 break;
3927 case k_Token:
3928 OS << "'" << getToken() << "'";
3929 break;
3930 case k_VectorIndex:
3931 OS << "<vectorindex " << getVectorIndex() << ">";
3932 break;
3933 }
3934}
3935
3936/// @name Auto-generated Match Functions
3937/// {
3938
3939static unsigned MatchRegisterName(StringRef Name);
3940
3941/// }
3942
3943bool ARMAsmParser::ParseRegister(unsigned &RegNo,
3944 SMLoc &StartLoc, SMLoc &EndLoc) {
3945 const AsmToken &Tok = getParser().getTok();
3946 StartLoc = Tok.getLoc();
3947 EndLoc = Tok.getEndLoc();
3948 RegNo = tryParseRegister();
3949
3950 return (RegNo == (unsigned)-1);
3951}
3952
3953OperandMatchResultTy ARMAsmParser::tryParseRegister(unsigned &RegNo,
3954 SMLoc &StartLoc,
3955 SMLoc &EndLoc) {
3956 if (ParseRegister(RegNo, StartLoc, EndLoc))
3957 return MatchOperand_NoMatch;
3958 return MatchOperand_Success;
3959}
3960
3961/// Try to parse a register name. The token must be an Identifier when called,
3962/// and if it is a register name the token is eaten and the register number is
3963/// returned. Otherwise return -1.
3964int ARMAsmParser::tryParseRegister() {
3965 MCAsmParser &Parser = getParser();
3966 const AsmToken &Tok = Parser.getTok();
3967 if (Tok.isNot(AsmToken::Identifier)) return -1;
3968
3969 std::string lowerCase = Tok.getString().lower();
3970 unsigned RegNum = MatchRegisterName(lowerCase);
3971 if (!RegNum) {
3972 RegNum = StringSwitch<unsigned>(lowerCase)
3973 .Case("r13", ARM::SP)
3974 .Case("r14", ARM::LR)
3975 .Case("r15", ARM::PC)
3976 .Case("ip", ARM::R12)
3977 // Additional register name aliases for 'gas' compatibility.
3978 .Case("a1", ARM::R0)
3979 .Case("a2", ARM::R1)
3980 .Case("a3", ARM::R2)
3981 .Case("a4", ARM::R3)
3982 .Case("v1", ARM::R4)
3983 .Case("v2", ARM::R5)
3984 .Case("v3", ARM::R6)
3985 .Case("v4", ARM::R7)
3986 .Case("v5", ARM::R8)
3987 .Case("v6", ARM::R9)
3988 .Case("v7", ARM::R10)
3989 .Case("v8", ARM::R11)
3990 .Case("sb", ARM::R9)
3991 .Case("sl", ARM::R10)
3992 .Case("fp", ARM::R11)
3993 .Default(0);
3994 }
3995 if (!RegNum) {
3996 // Check for aliases registered via .req. Canonicalize to lower case.
3997 // That's more consistent since register names are case insensitive, and
3998 // it's how the original entry was passed in from MC/MCParser/AsmParser.
3999 StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
4000 // If no match, return failure.
4001 if (Entry == RegisterReqs.end())
4002 return -1;
4003 Parser.Lex(); // Eat identifier token.
4004 return Entry->getValue();
4005 }
4006
4007 // Some FPUs only have 16 D registers, so D16-D31 are invalid
4008 if (!hasD32() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
4009 return -1;
4010
4011 Parser.Lex(); // Eat identifier token.
4012
4013 return RegNum;
4014}
4015
4016// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0.
4017// If a recoverable error occurs, return 1. If an irrecoverable error
4018// occurs, return -1. An irrecoverable error is one where tokens have been
4019// consumed in the process of trying to parse the shifter (i.e., when it is
4020// indeed a shifter operand, but malformed).
4021int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
4022 MCAsmParser &Parser = getParser();
4023 SMLoc S = Parser.getTok().getLoc();
4024 const AsmToken &Tok = Parser.getTok();
4025 if (Tok.isNot(AsmToken::Identifier))
4026 return -1;
4027
4028 std::string lowerCase = Tok.getString().lower();
4029 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
4030 .Case("asl", ARM_AM::lsl)
4031 .Case("lsl", ARM_AM::lsl)
4032 .Case("lsr", ARM_AM::lsr)
4033 .Case("asr", ARM_AM::asr)
4034 .Case("ror", ARM_AM::ror)
4035 .Case("rrx", ARM_AM::rrx)
4036 .Default(ARM_AM::no_shift);
4037
4038 if (ShiftTy == ARM_AM::no_shift)
4039 return 1;
4040
4041 Parser.Lex(); // Eat the operator.
4042
4043 // The source register for the shift has already been added to the
4044 // operand list, so we need to pop it off and combine it into the shifted
4045 // register operand instead.
4046 std::unique_ptr<ARMOperand> PrevOp(
4047 (ARMOperand *)Operands.pop_back_val().release());
4048 if (!PrevOp->isReg())
4049 return Error(PrevOp->getStartLoc(), "shift must be of a register");
4050 int SrcReg = PrevOp->getReg();
4051
4052 SMLoc EndLoc;
4053 int64_t Imm = 0;
4054 int ShiftReg = 0;
4055 if (ShiftTy == ARM_AM::rrx) {
4056 // RRX Doesn't have an explicit shift amount. The encoder expects
4057 // the shift register to be the same as the source register. Seems odd,
4058 // but OK.
4059 ShiftReg = SrcReg;
4060 } else {
4061 // Figure out if this is shifted by a constant or a register (for non-RRX).
4062 if (Parser.getTok().is(AsmToken::Hash) ||
4063 Parser.getTok().is(AsmToken::Dollar)) {
4064 Parser.Lex(); // Eat hash.
4065 SMLoc ImmLoc = Parser.getTok().getLoc();
4066 const MCExpr *ShiftExpr = nullptr;
4067 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4068 Error(ImmLoc, "invalid immediate shift value");
4069 return -1;
4070 }
4071 // The expression must be evaluatable as an immediate.
4072 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
4073 if (!CE) {
4074 Error(ImmLoc, "invalid immediate shift value");
4075 return -1;
4076 }
4077 // Range check the immediate.
4078 // lsl, ror: 0 <= imm <= 31
4079 // lsr, asr: 0 <= imm <= 32
4080 Imm = CE->getValue();
4081 if (Imm < 0 ||
4082 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
4083 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
4084 Error(ImmLoc, "immediate shift value out of range");
4085 return -1;
4086 }
4087 // shift by zero is a nop. Always send it through as lsl.
4088 // ('as' compatibility)
4089 if (Imm == 0)
4090 ShiftTy = ARM_AM::lsl;
4091 } else if (Parser.getTok().is(AsmToken::Identifier)) {
4092 SMLoc L = Parser.getTok().getLoc();
4093 EndLoc = Parser.getTok().getEndLoc();
4094 ShiftReg = tryParseRegister();
4095 if (ShiftReg == -1) {
4096 Error(L, "expected immediate or register in shift operand");
4097 return -1;
4098 }
4099 } else {
4100 Error(Parser.getTok().getLoc(),
4101 "expected immediate or register in shift operand");
4102 return -1;
4103 }
4104 }
4105
4106 if (ShiftReg && ShiftTy != ARM_AM::rrx)
4107 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
4108 ShiftReg, Imm,
4109 S, EndLoc));
4110 else
4111 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4112 S, EndLoc));
4113
4114 return 0;
4115}
4116
4117/// Try to parse a register name. The token must be an Identifier when called.
4118/// If it's a register, an AsmOperand is created. Another AsmOperand is created
4119/// if there is a "writeback". 'true' if it's not a register.
4120///
4121/// TODO this is likely to change to allow different register types and or to
4122/// parse for a specific register type.
4123bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) {
4124 MCAsmParser &Parser = getParser();
4125 SMLoc RegStartLoc = Parser.getTok().getLoc();
4126 SMLoc RegEndLoc = Parser.getTok().getEndLoc();
4127 int RegNo = tryParseRegister();
4128 if (RegNo == -1)
4129 return true;
4130
4131 Operands.push_back(ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc));
4132
4133 const AsmToken &ExclaimTok = Parser.getTok();
4134 if (ExclaimTok.is(AsmToken::Exclaim)) {
4135 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
4136 ExclaimTok.getLoc()));
4137 Parser.Lex(); // Eat exclaim token
4138 return false;
4139 }
4140
4141 // Also check for an index operand. This is only legal for vector registers,
4142 // but that'll get caught OK in operand matching, so we don't need to
4143 // explicitly filter everything else out here.
4144 if (Parser.getTok().is(AsmToken::LBrac)) {
4145 SMLoc SIdx = Parser.getTok().getLoc();
4146 Parser.Lex(); // Eat left bracket token.
4147
4148 const MCExpr *ImmVal;
4149 if (getParser().parseExpression(ImmVal))
4150 return true;
4151 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
4152 if (!MCE)
4153 return TokError("immediate value expected for vector index");
4154
4155 if (Parser.getTok().isNot(AsmToken::RBrac))
4156 return Error(Parser.getTok().getLoc(), "']' expected");
4157
4158 SMLoc E = Parser.getTok().getEndLoc();
4159 Parser.Lex(); // Eat right bracket token.
4160
4161 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
4162 SIdx, E,
4163 getContext()));
4164 }
4165
4166 return false;
4167}
4168
4169/// MatchCoprocessorOperandName - Try to parse an coprocessor related
4170/// instruction with a symbolic operand name.
4171/// We accept "crN" syntax for GAS compatibility.
4172/// <operand-name> ::= <prefix><number>
4173/// If CoprocOp is 'c', then:
4174/// <prefix> ::= c | cr
4175/// If CoprocOp is 'p', then :
4176/// <prefix> ::= p
4177/// <number> ::= integer in range [0, 15]
4178static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
4179 // Use the same layout as the tablegen'erated register name matcher. Ugly,
4180 // but efficient.
4181 if (Name.size() < 2 || Name[0] != CoprocOp)
4182 return -1;
4183 Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front();
4184
4185 switch (Name.size()) {
4186 default: return -1;
4187 case 1:
4188 switch (Name[0]) {
4189 default: return -1;
4190 case '0': return 0;
4191 case '1': return 1;
4192 case '2': return 2;
4193 case '3': return 3;
4194 case '4': return 4;
4195 case '5': return 5;
4196 case '6': return 6;
4197 case '7': return 7;
4198 case '8': return 8;
4199 case '9': return 9;
4200 }
4201 case 2:
4202 if (Name[0] != '1')
4203 return -1;
4204 switch (Name[1]) {
4205 default: return -1;
4206 // CP10 and CP11 are VFP/NEON and so vector instructions should be used.
4207 // However, old cores (v5/v6) did use them in that way.
4208 case '0': return 10;
4209 case '1': return 11;
4210 case '2': return 12;
4211 case '3': return 13;
4212 case '4': return 14;
4213 case '5': return 15;
4214 }
4215 }
4216}
4217
4218/// parseITCondCode - Try to parse a condition code for an IT instruction.
4219OperandMatchResultTy
4220ARMAsmParser::parseITCondCode(OperandVector &Operands) {
4221 MCAsmParser &Parser = getParser();
4222 SMLoc S = Parser.getTok().getLoc();
4223 const AsmToken &Tok = Parser.getTok();
4224 if (!Tok.is(AsmToken::Identifier))
4225 return MatchOperand_NoMatch;
4226 unsigned CC = ARMCondCodeFromString(Tok.getString());
4227 if (CC == ~0U)
4228 return MatchOperand_NoMatch;
4229 Parser.Lex(); // Eat the token.
4230
4231 Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
4232
4233 return MatchOperand_Success;
4234}
4235
4236/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
4237/// token must be an Identifier when called, and if it is a coprocessor
4238/// number, the token is eaten and the operand is added to the operand list.
4239OperandMatchResultTy
4240ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
4241 MCAsmParser &Parser = getParser();
4242 SMLoc S = Parser.getTok().getLoc();
4243 const AsmToken &Tok = Parser.getTok();
4244 if (Tok.isNot(AsmToken::Identifier))
4245 return MatchOperand_NoMatch;
4246
4247 int Num = MatchCoprocessorOperandName(Tok.getString().lower(), 'p');
4248 if (Num == -1)
4249 return MatchOperand_NoMatch;
4250 if (!isValidCoprocessorNumber(Num, getSTI().getFeatureBits()))
4251 return MatchOperand_NoMatch;
4252
4253 Parser.Lex(); // Eat identifier token.
4254 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
4255 return MatchOperand_Success;
4256}
4257
4258/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
4259/// token must be an Identifier when called, and if it is a coprocessor
4260/// number, the token is eaten and the operand is added to the operand list.
4261OperandMatchResultTy
4262ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) {
4263 MCAsmParser &Parser = getParser();
4264 SMLoc S = Parser.getTok().getLoc();
4265 const AsmToken &Tok = Parser.getTok();
4266 if (Tok.isNot(AsmToken::Identifier))
4267 return MatchOperand_NoMatch;
4268
4269 int Reg = MatchCoprocessorOperandName(Tok.getString().lower(), 'c');
4270 if (Reg == -1)
4271 return MatchOperand_NoMatch;
4272
4273 Parser.Lex(); // Eat identifier token.
4274 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
4275 return MatchOperand_Success;
4276}
4277
4278/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
4279/// coproc_option : '{' imm0_255 '}'
4280OperandMatchResultTy
4281ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) {
4282 MCAsmParser &Parser = getParser();
4283 SMLoc S = Parser.getTok().getLoc();
4284
4285 // If this isn't a '{', this isn't a coprocessor immediate operand.
4286 if (Parser.getTok().isNot(AsmToken::LCurly))
4287 return MatchOperand_NoMatch;
4288 Parser.Lex(); // Eat the '{'
4289
4290 const MCExpr *Expr;
4291 SMLoc Loc = Parser.getTok().getLoc();
4292 if (getParser().parseExpression(Expr)) {
4293 Error(Loc, "illegal expression");
4294 return MatchOperand_ParseFail;
4295 }
4296 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
4297 if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
4298 Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
4299 return MatchOperand_ParseFail;
4300 }
4301 int Val = CE->getValue();
4302
4303 // Check for and consume the closing '}'
4304 if (Parser.getTok().isNot(AsmToken::RCurly))
4305 return MatchOperand_ParseFail;
4306 SMLoc E = Parser.getTok().getEndLoc();
4307 Parser.Lex(); // Eat the '}'
4308
4309 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
4310 return MatchOperand_Success;
4311}
4312
4313// For register list parsing, we need to map from raw GPR register numbering
4314// to the enumeration values. The enumeration values aren't sorted by
4315// register number due to our using "sp", "lr" and "pc" as canonical names.
4316static unsigned getNextRegister(unsigned Reg) {
4317 // If this is a GPR, we need to do it manually, otherwise we can rely
4318 // on the sort ordering of the enumeration since the other reg-classes
4319 // are sane.
4320 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4321 return Reg + 1;
4322 switch(Reg) {
4323 default: llvm_unreachable("Invalid GPR number!")::llvm::llvm_unreachable_internal("Invalid GPR number!", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 4323)
;
4324 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2;
4325 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4;
4326 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6;
4327 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8;
4328 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10;
4329 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
4330 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR;
4331 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0;
4332 }
4333}
4334
4335// Insert an <Encoding, Register> pair in an ordered vector. Return true on
4336// success, or false, if duplicate encoding found.
4337static bool
4338insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs,
4339 unsigned Enc, unsigned Reg) {
4340 Regs.emplace_back(Enc, Reg);
4341 for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
4342 if (J->first == Enc) {
4343 Regs.erase(J.base());
4344 return false;
4345 }
4346 if (J->first < Enc)
4347 break;
4348 std::swap(*I, *J);
4349 }
4350 return true;
4351}
4352
4353/// Parse a register list.
4354bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
4355 bool EnforceOrder) {
4356 MCAsmParser &Parser = getParser();
4357 if (Parser.getTok().isNot(AsmToken::LCurly))
4358 return TokError("Token is not a Left Curly Brace");
4359 SMLoc S = Parser.getTok().getLoc();
4360 Parser.Lex(); // Eat '{' token.
4361 SMLoc RegLoc = Parser.getTok().getLoc();
4362
4363 // Check the first register in the list to see what register class
4364 // this is a list of.
4365 int Reg = tryParseRegister();
4366 if (Reg == -1)
4367 return Error(RegLoc, "register expected");
4368
4369 // The reglist instructions have at most 16 registers, so reserve
4370 // space for that many.
4371 int EReg = 0;
4372 SmallVector<std::pair<unsigned, unsigned>, 16> Registers;
4373
4374 // Allow Q regs and just interpret them as the two D sub-registers.
4375 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4376 Reg = getDRegFromQReg(Reg);
4377 EReg = MRI->getEncodingValue(Reg);
4378 Registers.emplace_back(EReg, Reg);
4379 ++Reg;
4380 }
4381 const MCRegisterClass *RC;
4382 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4383 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
4384 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
4385 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
4386 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
4387 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
4388 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
4389 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4390 else
4391 return Error(RegLoc, "invalid register in register list");
4392
4393 // Store the register.
4394 EReg = MRI->getEncodingValue(Reg);
4395 Registers.emplace_back(EReg, Reg);
4396
4397 // This starts immediately after the first register token in the list,
4398 // so we can see either a comma or a minus (range separator) as a legal
4399 // next token.
4400 while (Parser.getTok().is(AsmToken::Comma) ||
4401 Parser.getTok().is(AsmToken::Minus)) {
4402 if (Parser.getTok().is(AsmToken::Minus)) {
4403 Parser.Lex(); // Eat the minus.
4404 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4405 int EndReg = tryParseRegister();
4406 if (EndReg == -1)
4407 return Error(AfterMinusLoc, "register expected");
4408 // Allow Q regs and just interpret them as the two D sub-registers.
4409 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
4410 EndReg = getDRegFromQReg(EndReg) + 1;
4411 // If the register is the same as the start reg, there's nothing
4412 // more to do.
4413 if (Reg == EndReg)
4414 continue;
4415 // The register must be in the same register class as the first.
4416 if (!RC->contains(EndReg))
4417 return Error(AfterMinusLoc, "invalid register in register list");
4418 // Ranges must go from low to high.
4419 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
4420 return Error(AfterMinusLoc, "bad range in register list");
4421
4422 // Add all the registers in the range to the register list.
4423 while (Reg != EndReg) {
4424 Reg = getNextRegister(Reg);
4425 EReg = MRI->getEncodingValue(Reg);
4426 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4427 Warning(AfterMinusLoc, StringRef("duplicated register (") +
4428 ARMInstPrinter::getRegisterName(Reg) +
4429 ") in register list");
4430 }
4431 }
4432 continue;
4433 }
4434 Parser.Lex(); // Eat the comma.
4435 RegLoc = Parser.getTok().getLoc();
4436 int OldReg = Reg;
4437 const AsmToken RegTok = Parser.getTok();
4438 Reg = tryParseRegister();
4439 if (Reg == -1)
4440 return Error(RegLoc, "register expected");
4441 // Allow Q regs and just interpret them as the two D sub-registers.
4442 bool isQReg = false;
4443 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4444 Reg = getDRegFromQReg(Reg);
4445 isQReg = true;
4446 }
4447 if (!RC->contains(Reg) &&
4448 RC->getID() == ARMMCRegisterClasses[ARM::GPRRegClassID].getID() &&
4449 ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg)) {
4450 // switch the register classes, as GPRwithAPSRnospRegClassID is a partial
4451 // subset of GPRRegClassId except it contains APSR as well.
4452 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4453 }
4454 if (Reg == ARM::VPR &&
4455 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4456 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4457 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
4458 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4459 EReg = MRI->getEncodingValue(Reg);
4460 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4461 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4462 ") in register list");
4463 }
4464 continue;
4465 }
4466 // The register must be in the same register class as the first.
4467 if (!RC->contains(Reg))
4468 return Error(RegLoc, "invalid register in register list");
4469 // In most cases, the list must be monotonically increasing. An
4470 // exception is CLRM, which is order-independent anyway, so
4471 // there's no potential for confusion if you write clrm {r2,r1}
4472 // instead of clrm {r1,r2}.
4473 if (EnforceOrder &&
4474 MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) {
4475 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4476 Warning(RegLoc, "register list not in ascending order");
4477 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
4478 return Error(RegLoc, "register list not in ascending order");
4479 }
4480 // VFP register lists must also be contiguous.
4481 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
4482 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
4483 Reg != OldReg + 1)
4484 return Error(RegLoc, "non-contiguous register range");
4485 EReg = MRI->getEncodingValue(Reg);
4486 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4487 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4488 ") in register list");
4489 }
4490 if (isQReg) {
4491 EReg = MRI->getEncodingValue(++Reg);
4492 Registers.emplace_back(EReg, Reg);
4493 }
4494 }
4495
4496 if (Parser.getTok().isNot(AsmToken::RCurly))
4497 return Error(Parser.getTok().getLoc(), "'}' expected");
4498 SMLoc E = Parser.getTok().getEndLoc();
4499 Parser.Lex(); // Eat '}' token.
4500
4501 // Push the register list operand.
4502 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
4503
4504 // The ARM system instruction variants for LDM/STM have a '^' token here.
4505 if (Parser.getTok().is(AsmToken::Caret)) {
4506 Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
4507 Parser.Lex(); // Eat '^' token.
4508 }
4509
4510 return false;
4511}
4512
4513// Helper function to parse the lane index for vector lists.
4514OperandMatchResultTy ARMAsmParser::
4515parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, SMLoc &EndLoc) {
4516 MCAsmParser &Parser = getParser();
4517 Index = 0; // Always return a defined index value.
4518 if (Parser.getTok().is(AsmToken::LBrac)) {
4519 Parser.Lex(); // Eat the '['.
4520 if (Parser.getTok().is(AsmToken::RBrac)) {
4521 // "Dn[]" is the 'all lanes' syntax.
4522 LaneKind = AllLanes;
4523 EndLoc = Parser.getTok().getEndLoc();
4524 Parser.Lex(); // Eat the ']'.
4525 return MatchOperand_Success;
4526 }
4527
4528 // There's an optional '#' token here. Normally there wouldn't be, but
4529 // inline assemble puts one in, and it's friendly to accept that.
4530 if (Parser.getTok().is(AsmToken::Hash))
4531 Parser.Lex(); // Eat '#' or '$'.
4532
4533 const MCExpr *LaneIndex;
4534 SMLoc Loc = Parser.getTok().getLoc();
4535 if (getParser().parseExpression(LaneIndex)) {
4536 Error(Loc, "illegal expression");
4537 return MatchOperand_ParseFail;
4538 }
4539 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
4540 if (!CE) {
4541 Error(Loc, "lane index must be empty or an integer");
4542 return MatchOperand_ParseFail;
4543 }
4544 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4545 Error(Parser.getTok().getLoc(), "']' expected");
4546 return MatchOperand_ParseFail;
4547 }
4548 EndLoc = Parser.getTok().getEndLoc();
4549 Parser.Lex(); // Eat the ']'.
4550 int64_t Val = CE->getValue();
4551
4552 // FIXME: Make this range check context sensitive for .8, .16, .32.
4553 if (Val < 0 || Val > 7) {
4554 Error(Parser.getTok().getLoc(), "lane index out of range");
4555 return MatchOperand_ParseFail;
4556 }
4557 Index = Val;
4558 LaneKind = IndexedLane;
4559 return MatchOperand_Success;
4560 }
4561 LaneKind = NoLanes;
4562 return MatchOperand_Success;
4563}
4564
4565// parse a vector register list
4566OperandMatchResultTy
4567ARMAsmParser::parseVectorList(OperandVector &Operands) {
4568 MCAsmParser &Parser = getParser();
4569 VectorLaneTy LaneKind;
4570 unsigned LaneIndex;
4571 SMLoc S = Parser.getTok().getLoc();
4572 // As an extension (to match gas), support a plain D register or Q register
4573 // (without encosing curly braces) as a single or double entry list,
4574 // respectively.
4575 if (!hasMVE() && Parser.getTok().is(AsmToken::Identifier)) {
4576 SMLoc E = Parser.getTok().getEndLoc();
4577 int Reg = tryParseRegister();
4578 if (Reg == -1)
4579 return MatchOperand_NoMatch;
4580 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
4581 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E);
4582 if (Res != MatchOperand_Success)
4583 return Res;
4584 switch (LaneKind) {
4585 case NoLanes:
4586 Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
4587 break;
4588 case AllLanes:
4589 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
4590 S, E));
4591 break;
4592 case IndexedLane:
4593 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
4594 LaneIndex,
4595 false, S, E));
4596 break;
4597 }
4598 return MatchOperand_Success;
4599 }
4600 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4601 Reg = getDRegFromQReg(Reg);
4602 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E);
4603 if (Res != MatchOperand_Success)
4604 return Res;
4605 switch (LaneKind) {
4606 case NoLanes:
4607 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
4608 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
4609 Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
4610 break;
4611 case AllLanes:
4612 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
4613 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
4614 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
4615 S, E));
4616 break;
4617 case IndexedLane:
4618 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
4619 LaneIndex,
4620 false, S, E));
4621 break;
4622 }
4623 return MatchOperand_Success;
4624 }
4625 Error(S, "vector register expected");
4626 return MatchOperand_ParseFail;
4627 }
4628
4629 if (Parser.getTok().isNot(AsmToken::LCurly))
4630 return MatchOperand_NoMatch;
4631
4632 Parser.Lex(); // Eat '{' token.
4633 SMLoc RegLoc = Parser.getTok().getLoc();
4634
4635 int Reg = tryParseRegister();
4636 if (Reg == -1) {
4637 Error(RegLoc, "register expected");
4638 return MatchOperand_ParseFail;
4639 }
4640 unsigned Count = 1;
4641 int Spacing = 0;
4642 unsigned FirstReg = Reg;
4643
4644 if (hasMVE() && !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg)) {
4645 Error(Parser.getTok().getLoc(), "vector register in range Q0-Q7 expected");
4646 return MatchOperand_ParseFail;
4647 }
4648 // The list is of D registers, but we also allow Q regs and just interpret
4649 // them as the two D sub-registers.
4650 else if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4651 FirstReg = Reg = getDRegFromQReg(Reg);
4652 Spacing = 1; // double-spacing requires explicit D registers, otherwise
4653 // it's ambiguous with four-register single spaced.
4654 ++Reg;
4655 ++Count;
4656 }
4657
4658 SMLoc E;
4659 if (parseVectorLane(LaneKind, LaneIndex, E) != MatchOperand_Success)
4660 return MatchOperand_ParseFail;
4661
4662 while (Parser.getTok().is(AsmToken::Comma) ||
4663 Parser.getTok().is(AsmToken::Minus)) {
4664 if (Parser.getTok().is(AsmToken::Minus)) {
4665 if (!Spacing)
4666 Spacing = 1; // Register range implies a single spaced list.
4667 else if (Spacing == 2) {
4668 Error(Parser.getTok().getLoc(),
4669 "sequential registers in double spaced list");
4670 return MatchOperand_ParseFail;
4671 }
4672 Parser.Lex(); // Eat the minus.
4673 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4674 int EndReg = tryParseRegister();
4675 if (EndReg == -1) {
4676 Error(AfterMinusLoc, "register expected");
4677 return MatchOperand_ParseFail;
4678 }
4679 // Allow Q regs and just interpret them as the two D sub-registers.
4680 if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
4681 EndReg = getDRegFromQReg(EndReg) + 1;
4682 // If the register is the same as the start reg, there's nothing
4683 // more to do.
4684 if (Reg == EndReg)
4685 continue;
4686 // The register must be in the same register class as the first.
4687 if ((hasMVE() &&
4688 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(EndReg)) ||
4689 (!hasMVE() &&
4690 !ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg))) {
4691 Error(AfterMinusLoc, "invalid register in register list");
4692 return MatchOperand_ParseFail;
4693 }
4694 // Ranges must go from low to high.
4695 if (Reg > EndReg) {
4696 Error(AfterMinusLoc, "bad range in register list");
4697 return MatchOperand_ParseFail;
4698 }
4699 // Parse the lane specifier if present.
4700 VectorLaneTy NextLaneKind;
4701 unsigned NextLaneIndex;
4702 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
4703 MatchOperand_Success)
4704 return MatchOperand_ParseFail;
4705 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4706 Error(AfterMinusLoc, "mismatched lane index in register list");
4707 return MatchOperand_ParseFail;
4708 }
4709
4710 // Add all the registers in the range to the register list.
4711 Count += EndReg - Reg;
4712 Reg = EndReg;
4713 continue;
4714 }
4715 Parser.Lex(); // Eat the comma.
4716 RegLoc = Parser.getTok().getLoc();
4717 int OldReg = Reg;
4718 Reg = tryParseRegister();
4719 if (Reg == -1) {
4720 Error(RegLoc, "register expected");
4721 return MatchOperand_ParseFail;
4722 }
4723
4724 if (hasMVE()) {
4725 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg)) {
4726 Error(RegLoc, "vector register in range Q0-Q7 expected");
4727 return MatchOperand_ParseFail;
4728 }
4729 Spacing = 1;
4730 }
4731 // vector register lists must be contiguous.
4732 // It's OK to use the enumeration values directly here rather, as the
4733 // VFP register classes have the enum sorted properly.
4734 //
4735 // The list is of D registers, but we also allow Q regs and just interpret
4736 // them as the two D sub-registers.
4737 else if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4738 if (!Spacing)
4739 Spacing = 1; // Register range implies a single spaced list.
4740 else if (Spacing == 2) {
4741 Error(RegLoc,
4742 "invalid register in double-spaced list (must be 'D' register')");
4743 return MatchOperand_ParseFail;
4744 }
4745 Reg = getDRegFromQReg(Reg);
4746 if (Reg != OldReg + 1) {
4747 Error(RegLoc, "non-contiguous register range");
4748 return MatchOperand_ParseFail;
4749 }
4750 ++Reg;
4751 Count += 2;
4752 // Parse the lane specifier if present.
4753 VectorLaneTy NextLaneKind;
4754 unsigned NextLaneIndex;
4755 SMLoc LaneLoc = Parser.getTok().getLoc();
4756 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
4757 MatchOperand_Success)
4758 return MatchOperand_ParseFail;
4759 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4760 Error(LaneLoc, "mismatched lane index in register list");
4761 return MatchOperand_ParseFail;
4762 }
4763 continue;
4764 }
4765 // Normal D register.
4766 // Figure out the register spacing (single or double) of the list if
4767 // we don't know it already.
4768 if (!Spacing)
4769 Spacing = 1 + (Reg == OldReg + 2);
4770
4771 // Just check that it's contiguous and keep going.
4772 if (Reg != OldReg + Spacing) {
4773 Error(RegLoc, "non-contiguous register range");
4774 return MatchOperand_ParseFail;
4775 }
4776 ++Count;
4777 // Parse the lane specifier if present.
4778 VectorLaneTy NextLaneKind;
4779 unsigned NextLaneIndex;
4780 SMLoc EndLoc = Parser.getTok().getLoc();
4781 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != MatchOperand_Success)
4782 return MatchOperand_ParseFail;
4783 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4784 Error(EndLoc, "mismatched lane index in register list");
4785 return MatchOperand_ParseFail;
4786 }
4787 }
4788
4789 if (Parser.getTok().isNot(AsmToken::RCurly)) {
4790 Error(Parser.getTok().getLoc(), "'}' expected");
4791 return MatchOperand_ParseFail;
4792 }
4793 E = Parser.getTok().getEndLoc();
4794 Parser.Lex(); // Eat '}' token.
4795
4796 switch (LaneKind) {
4797 case NoLanes:
4798 case AllLanes: {
4799 // Two-register operands have been converted to the
4800 // composite register classes.
4801 if (Count == 2 && !hasMVE()) {
4802 const MCRegisterClass *RC = (Spacing == 1) ?
4803 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
4804 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
4805 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
4806 }
4807 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
4808 ARMOperand::CreateVectorListAllLanes);
4809 Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E));
4810 break;
4811 }
4812 case IndexedLane:
4813 Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
4814 LaneIndex,
4815 (Spacing == 2),
4816 S, E));
4817 break;
4818 }
4819 return MatchOperand_Success;
4820}
4821
4822/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
4823OperandMatchResultTy
4824ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
4825 MCAsmParser &Parser = getParser();
4826 SMLoc S = Parser.getTok().getLoc();
4827 const AsmToken &Tok = Parser.getTok();
4828 unsigned Opt;
4829
4830 if (Tok.is(AsmToken::Identifier)) {
4831 StringRef OptStr = Tok.getString();
4832
4833 Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()).lower())
4834 .Case("sy", ARM_MB::SY)
4835 .Case("st", ARM_MB::ST)
4836 .Case("ld", ARM_MB::LD)
4837 .Case("sh", ARM_MB::ISH)
4838 .Case("ish", ARM_MB::ISH)
4839 .Case("shst", ARM_MB::ISHST)
4840 .Case("ishst", ARM_MB::ISHST)
4841 .Case("ishld", ARM_MB::ISHLD)
4842 .Case("nsh", ARM_MB::NSH)
4843 .Case("un", ARM_MB::NSH)
4844 .Case("nshst", ARM_MB::NSHST)
4845 .Case("nshld", ARM_MB::NSHLD)
4846 .Case("unst", ARM_MB::NSHST)
4847 .Case("osh", ARM_MB::OSH)
4848 .Case("oshst", ARM_MB::OSHST)
4849 .Case("oshld", ARM_MB::OSHLD)
4850 .Default(~0U);
4851
4852 // ishld, oshld, nshld and ld are only available from ARMv8.
4853 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD ||
4854 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD))
4855 Opt = ~0U;
4856
4857 if (Opt == ~0U)
4858 return MatchOperand_NoMatch;
4859
4860 Parser.Lex(); // Eat identifier token.
4861 } else if (Tok.is(AsmToken::Hash) ||
4862 Tok.is(AsmToken::Dollar) ||
4863 Tok.is(AsmToken::Integer)) {
4864 if (Parser.getTok().isNot(AsmToken::Integer))
4865 Parser.Lex(); // Eat '#' or '$'.
4866 SMLoc Loc = Parser.getTok().getLoc();
4867
4868 const MCExpr *MemBarrierID;
4869 if (getParser().parseExpression(MemBarrierID)) {
4870 Error(Loc, "illegal expression");
4871 return MatchOperand_ParseFail;
4872 }
4873
4874 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
4875 if (!CE) {
4876 Error(Loc, "constant expression expected");
4877 return MatchOperand_ParseFail;
4878 }
4879
4880 int Val = CE->getValue();
4881 if (Val & ~0xf) {
4882 Error(Loc, "immediate value out of range");
4883 return MatchOperand_ParseFail;
4884 }
4885
4886 Opt = ARM_MB::RESERVED_0 + Val;
4887 } else
4888 return MatchOperand_ParseFail;
4889
4890 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
4891 return MatchOperand_Success;
4892}
4893
4894OperandMatchResultTy
4895ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) {
4896 MCAsmParser &Parser = getParser();
4897 SMLoc S = Parser.getTok().getLoc();
4898 const AsmToken &Tok = Parser.getTok();
4899
4900 if (Tok.isNot(AsmToken::Identifier))
4901 return MatchOperand_NoMatch;
4902
4903 if (!Tok.getString().equals_lower("csync"))
4904 return MatchOperand_NoMatch;
4905
4906 Parser.Lex(); // Eat identifier token.
4907
4908 Operands.push_back(ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S));
4909 return MatchOperand_Success;
4910}
4911
4912/// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
4913OperandMatchResultTy
4914ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
4915 MCAsmParser &Parser = getParser();
4916 SMLoc S = Parser.getTok().getLoc();
4917 const AsmToken &Tok = Parser.getTok();
4918 unsigned Opt;
4919
4920 if (Tok.is(AsmToken::Identifier)) {
4921 StringRef OptStr = Tok.getString();
4922
4923 if (OptStr.equals_lower("sy"))
4924 Opt = ARM_ISB::SY;
4925 else
4926 return MatchOperand_NoMatch;
4927
4928 Parser.Lex(); // Eat identifier token.
4929 } else if (Tok.is(AsmToken::Hash) ||
4930 Tok.is(AsmToken::Dollar) ||
4931 Tok.is(AsmToken::Integer)) {
4932 if (Parser.getTok().isNot(AsmToken::Integer))
4933 Parser.Lex(); // Eat '#' or '$'.
4934 SMLoc Loc = Parser.getTok().getLoc();
4935
4936 const MCExpr *ISBarrierID;
4937 if (getParser().parseExpression(ISBarrierID)) {
4938 Error(Loc, "illegal expression");
4939 return MatchOperand_ParseFail;
4940 }
4941
4942 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID);
4943 if (!CE) {
4944 Error(Loc, "constant expression expected");
4945 return MatchOperand_ParseFail;
4946 }
4947
4948 int Val = CE->getValue();
4949 if (Val & ~0xf) {
4950 Error(Loc, "immediate value out of range");
4951 return MatchOperand_ParseFail;
4952 }
4953
4954 Opt = ARM_ISB::RESERVED_0 + Val;
4955 } else
4956 return MatchOperand_ParseFail;
4957
4958 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
4959 (ARM_ISB::InstSyncBOpt)Opt, S));
4960 return MatchOperand_Success;
4961}
4962
4963
4964/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
4965OperandMatchResultTy
4966ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {
4967 MCAsmParser &Parser = getParser();
4968 SMLoc S = Parser.getTok().getLoc();
4969 const AsmToken &Tok = Parser.getTok();
4970 if (!Tok.is(AsmToken::Identifier))
4971 return MatchOperand_NoMatch;
4972 StringRef IFlagsStr = Tok.getString();
4973
4974 // An iflags string of "none" is interpreted to mean that none of the AIF
4975 // bits are set. Not a terribly useful instruction, but a valid encoding.
4976 unsigned IFlags = 0;
4977 if (IFlagsStr != "none") {
4978 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
4979 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1).lower())
4980 .Case("a", ARM_PROC::A)
4981 .Case("i", ARM_PROC::I)
4982 .Case("f", ARM_PROC::F)
4983 .Default(~0U);
4984
4985 // If some specific iflag is already set, it means that some letter is
4986 // present more than once, this is not acceptable.
4987 if (Flag == ~0U || (IFlags & Flag))
4988 return MatchOperand_NoMatch;
4989
4990 IFlags |= Flag;
4991 }
4992 }
4993
4994 Parser.Lex(); // Eat identifier token.
4995 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
4996 return MatchOperand_Success;
4997}
4998
4999/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
5000OperandMatchResultTy
5001ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {
5002 MCAsmParser &Parser = getParser();
5003 SMLoc S = Parser.getTok().getLoc();
5004 const AsmToken &Tok = Parser.getTok();
5005
5006 if (Tok.is(AsmToken::Integer)) {
5007 int64_t Val = Tok.getIntVal();
5008 if (Val > 255 || Val < 0) {
5009 return MatchOperand_NoMatch;
5010 }
5011 unsigned SYSmvalue = Val & 0xFF;
5012 Parser.Lex();
5013 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
5014 return MatchOperand_Success;
5015 }
5016
5017 if (!Tok.is(AsmToken::Identifier))
5018 return MatchOperand_NoMatch;
5019 StringRef Mask = Tok.getString();
5020
5021 if (isMClass()) {
5022 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower());
5023 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5024 return MatchOperand_NoMatch;
5025
5026 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5027
5028 Parser.Lex(); // Eat identifier token.
5029 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
5030 return MatchOperand_Success;
5031 }
5032
5033 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
5034 size_t Start = 0, Next = Mask.find('_');
5035 StringRef Flags = "";
5036 std::string SpecReg = Mask.slice(Start, Next).lower();
5037 if (Next != StringRef::npos)
5038 Flags = Mask.slice(Next+1, Mask.size());
5039
5040 // FlagsVal contains the complete mask:
5041 // 3-0: Mask
5042 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5043 unsigned FlagsVal = 0;
5044
5045 if (SpecReg == "apsr") {
5046 FlagsVal = StringSwitch<unsigned>(Flags)
5047 .Case("nzcvq", 0x8) // same as CPSR_f
5048 .Case("g", 0x4) // same as CPSR_s
5049 .Case("nzcvqg", 0xc) // same as CPSR_fs
5050 .Default(~0U);
5051
5052 if (FlagsVal == ~0U) {
5053 if (!Flags.empty())
5054 return MatchOperand_NoMatch;
5055 else
5056 FlagsVal = 8; // No flag
5057 }
5058 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
5059 // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
5060 if (Flags == "all" || Flags == "")
5061 Flags = "fc";
5062 for (int i = 0, e = Flags.size(); i != e; ++i) {
5063 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
5064 .Case("c", 1)
5065 .Case("x", 2)
5066 .Case("s", 4)
5067 .Case("f", 8)
5068 .Default(~0U);
5069
5070 // If some specific flag is already set, it means that some letter is
5071 // present more than once, this is not acceptable.
5072 if (Flag == ~0U || (FlagsVal & Flag))
5073 return MatchOperand_NoMatch;
5074 FlagsVal |= Flag;
5075 }
5076 } else // No match for special register.
5077 return MatchOperand_NoMatch;
5078
5079 // Special register without flags is NOT equivalent to "fc" flags.
5080 // NOTE: This is a divergence from gas' behavior. Uncommenting the following
5081 // two lines would enable gas compatibility at the expense of breaking
5082 // round-tripping.
5083 //
5084 // if (!FlagsVal)
5085 // FlagsVal = 0x9;
5086
5087 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5088 if (SpecReg == "spsr")
5089 FlagsVal |= 16;
5090
5091 Parser.Lex(); // Eat identifier token.
5092 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
5093 return MatchOperand_Success;
5094}
5095
5096/// parseBankedRegOperand - Try to parse a banked register (e.g. "lr_irq") for
5097/// use in the MRS/MSR instructions added to support virtualization.
5098OperandMatchResultTy
5099ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
5100 MCAsmParser &Parser = getParser();
5101 SMLoc S = Parser.getTok().getLoc();
5102 const AsmToken &Tok = Parser.getTok();
5103 if (!Tok.is(AsmToken::Identifier))
5104 return MatchOperand_NoMatch;
5105 StringRef RegName = Tok.getString();
5106
5107 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.lower());
5108 if (!TheReg)
5109 return MatchOperand_NoMatch;
5110 unsigned Encoding = TheReg->Encoding;
5111
5112 Parser.Lex(); // Eat identifier token.
5113 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S));
5114 return MatchOperand_Success;
5115}
5116
5117OperandMatchResultTy
5118ARMAsmParser::parsePKHImm(OperandVector &Operands, StringRef Op, int Low,
5119 int High) {
5120 MCAsmParser &Parser = getParser();
5121 const AsmToken &Tok = Parser.getTok();
5122 if (Tok.isNot(AsmToken::Identifier)) {
5123 Error(Parser.getTok().getLoc(), Op + " operand expected.");
5124 return MatchOperand_ParseFail;
5125 }
5126 StringRef ShiftName = Tok.getString();
5127 std::string LowerOp = Op.lower();
5128 std::string UpperOp = Op.upper();
5129 if (ShiftName != LowerOp && ShiftName != UpperOp) {
5130 Error(Parser.getTok().getLoc(), Op + " operand expected.");
5131 return MatchOperand_ParseFail;
5132 }
5133 Parser.Lex(); // Eat shift type token.
5134
5135 // There must be a '#' and a shift amount.
5136 if (Parser.getTok().isNot(AsmToken::Hash) &&
5137 Parser.getTok().isNot(AsmToken::Dollar)) {
5138 Error(Parser.getTok().getLoc(), "'#' expected");
5139 return MatchOperand_ParseFail;
5140 }
5141 Parser.Lex(); // Eat hash token.
5142
5143 const MCExpr *ShiftAmount;
5144 SMLoc Loc = Parser.getTok().getLoc();
5145 SMLoc EndLoc;
5146 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
5147 Error(Loc, "illegal expression");
5148 return MatchOperand_ParseFail;
5149 }
5150 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5151 if (!CE) {
5152 Error(Loc, "constant expression expected");
5153 return MatchOperand_ParseFail;
5154 }
5155 int Val = CE->getValue();
5156 if (Val < Low || Val > High) {
5157 Error(Loc, "immediate value out of range");
5158 return MatchOperand_ParseFail;
5159 }
5160
5161 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc));
5162
5163 return MatchOperand_Success;
5164}
5165
5166OperandMatchResultTy
5167ARMAsmParser::parseSetEndImm(OperandVector &Operands) {
5168 MCAsmParser &Parser = getParser();
5169 const AsmToken &Tok = Parser.getTok();
5170 SMLoc S = Tok.getLoc();
5171 if (Tok.isNot(AsmToken::Identifier)) {
5172 Error(S, "'be' or 'le' operand expected");
5173 return MatchOperand_ParseFail;
5174 }
5175 int Val = StringSwitch<int>(Tok.getString().lower())
5176 .Case("be", 1)
5177 .Case("le", 0)
5178 .Default(-1);
5179 Parser.Lex(); // Eat the token.
5180
5181 if (Val == -1) {
5182 Error(S, "'be' or 'le' operand expected");
5183 return MatchOperand_ParseFail;
5184 }
5185 Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::create(Val,
5186 getContext()),
5187 S, Tok.getEndLoc()));
5188 return MatchOperand_Success;
5189}
5190
5191/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
5192/// instructions. Legal values are:
5193/// lsl #n 'n' in [0,31]
5194/// asr #n 'n' in [1,32]
5195/// n == 32 encoded as n == 0.
5196OperandMatchResultTy
5197ARMAsmParser::parseShifterImm(OperandVector &Operands) {
5198 MCAsmParser &Parser = getParser();
5199 const AsmToken &Tok = Parser.getTok();
5200 SMLoc S = Tok.getLoc();
5201 if (Tok.isNot(AsmToken::Identifier)) {
5202 Error(S, "shift operator 'asr' or 'lsl' expected");
5203 return MatchOperand_ParseFail;
5204 }
5205 StringRef ShiftName = Tok.getString();
5206 bool isASR;
5207 if (ShiftName == "lsl" || ShiftName == "LSL")
5208 isASR = false;
5209 else if (ShiftName == "asr" || ShiftName == "ASR")
5210 isASR = true;
5211 else {
5212 Error(S, "shift operator 'asr' or 'lsl' expected");
5213 return MatchOperand_ParseFail;
5214 }
5215 Parser.Lex(); // Eat the operator.
5216
5217 // A '#' and a shift amount.
5218 if (Parser.getTok().isNot(AsmToken::Hash) &&
5219 Parser.getTok().isNot(AsmToken::Dollar)) {
5220 Error(Parser.getTok().getLoc(), "'#' expected");
5221 return MatchOperand_ParseFail;
5222 }
5223 Parser.Lex(); // Eat hash token.
5224 SMLoc ExLoc = Parser.getTok().getLoc();
5225
5226 const MCExpr *ShiftAmount;
5227 SMLoc EndLoc;
5228 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
5229 Error(ExLoc, "malformed shift expression");
5230 return MatchOperand_ParseFail;
5231 }
5232 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5233 if (!CE) {
5234 Error(ExLoc, "shift amount must be an immediate");
5235 return MatchOperand_ParseFail;
5236 }
5237
5238 int64_t Val = CE->getValue();
5239 if (isASR) {
5240 // Shift amount must be in [1,32]
5241 if (Val < 1 || Val > 32) {
5242 Error(ExLoc, "'asr' shift amount must be in range [1,32]");
5243 return MatchOperand_ParseFail;
5244 }
5245 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
5246 if (isThumb() && Val == 32) {
5247 Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode");
5248 return MatchOperand_ParseFail;
5249 }
5250 if (Val == 32) Val = 0;
5251 } else {
5252 // Shift amount must be in [1,32]
5253 if (Val < 0 || Val > 31) {
5254 Error(ExLoc, "'lsr' shift amount must be in range [0,31]");
5255 return MatchOperand_ParseFail;
5256 }
5257 }
5258
5259 Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc));
5260
5261 return MatchOperand_Success;
5262}
5263
5264/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
5265/// of instructions. Legal values are:
5266/// ror #n 'n' in {0, 8, 16, 24}
5267OperandMatchResultTy
5268ARMAsmParser::parseRotImm(OperandVector &Operands) {
5269 MCAsmParser &Parser = getParser();
5270 const AsmToken &Tok = Parser.getTok();
5271 SMLoc S = Tok.getLoc();
5272 if (Tok.isNot(AsmToken::Identifier))
5273 return MatchOperand_NoMatch;
5274 StringRef ShiftName = Tok.getString();
5275 if (ShiftName != "ror" && ShiftName != "ROR")
5276 return MatchOperand_NoMatch;
5277 Parser.Lex(); // Eat the operator.
5278
5279 // A '#' and a rotate amount.
5280 if (Parser.getTok().isNot(AsmToken::Hash) &&
5281 Parser.getTok().isNot(AsmToken::Dollar)) {
5282 Error(Parser.getTok().getLoc(), "'#' expected");
5283 return MatchOperand_ParseFail;
5284 }
5285 Parser.Lex(); // Eat hash token.
5286 SMLoc ExLoc = Parser.getTok().getLoc();
5287
5288 const MCExpr *ShiftAmount;
5289 SMLoc EndLoc;
5290 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
5291 Error(ExLoc, "malformed rotate expression");
5292 return MatchOperand_ParseFail;
5293 }
5294 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5295 if (!CE) {
5296 Error(ExLoc, "rotate amount must be an immediate");
5297 return MatchOperand_ParseFail;
5298 }
5299
5300 int64_t Val = CE->getValue();
5301 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
5302 // normally, zero is represented in asm by omitting the rotate operand
5303 // entirely.
5304 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
5305 Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24");
5306 return MatchOperand_ParseFail;
5307 }
5308
5309 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc));
5310
5311 return MatchOperand_Success;
5312}
5313
5314OperandMatchResultTy
5315ARMAsmParser::parseModImm(OperandVector &Operands) {
5316 MCAsmParser &Parser = getParser();
5317 MCAsmLexer &Lexer = getLexer();
5318 int64_t Imm1, Imm2;
5319
5320 SMLoc S = Parser.getTok().getLoc();
5321
5322 // 1) A mod_imm operand can appear in the place of a register name:
5323 // add r0, #mod_imm
5324 // add r0, r0, #mod_imm
5325 // to correctly handle the latter, we bail out as soon as we see an
5326 // identifier.
5327 //
5328 // 2) Similarly, we do not want to parse into complex operands:
5329 // mov r0, #mod_imm
5330 // mov r0, :lower16:(_foo)
5331 if (Parser.getTok().is(AsmToken::Identifier) ||
5332 Parser.getTok().is(AsmToken::Colon))
5333 return MatchOperand_NoMatch;
5334
5335 // Hash (dollar) is optional as per the ARMARM
5336 if (Parser.getTok().is(AsmToken::Hash) ||
5337 Parser.getTok().is(AsmToken::Dollar)) {
5338 // Avoid parsing into complex operands (#:)
5339 if (Lexer.peekTok().is(AsmToken::Colon))
5340 return MatchOperand_NoMatch;
5341
5342 // Eat the hash (dollar)
5343 Parser.Lex();
5344 }
5345
5346 SMLoc Sx1, Ex1;
5347 Sx1 = Parser.getTok().getLoc();
5348 const MCExpr *Imm1Exp;
5349 if (getParser().parseExpression(Imm1Exp, Ex1)) {
5350 Error(Sx1, "malformed expression");
5351 return MatchOperand_ParseFail;
5352 }
5353
5354 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
5355
5356 if (CE) {
5357 // Immediate must fit within 32-bits
5358 Imm1 = CE->getValue();
5359 int Enc = ARM_AM::getSOImmVal(Imm1);
5360 if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) {
5361 // We have a match!
5362 Operands.push_back(ARMOperand::CreateModImm((Enc & 0xFF),
5363 (Enc & 0xF00) >> 7,
5364 Sx1, Ex1));
5365 return MatchOperand_Success;
5366 }
5367
5368 // We have parsed an immediate which is not for us, fallback to a plain
5369 // immediate. This can happen for instruction aliases. For an example,
5370 // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
5371 // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
5372 // instruction with a mod_imm operand. The alias is defined such that the
5373 // parser method is shared, that's why we have to do this here.
5374 if (Parser.getTok().is(AsmToken::EndOfStatement)) {
5375 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
5376 return MatchOperand_Success;
5377 }
5378 } else {
5379 // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
5380 // MCFixup). Fallback to a plain immediate.
5381 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
5382 return MatchOperand_Success;
5383 }
5384
5385 // From this point onward, we expect the input to be a (#bits, #rot) pair
5386 if (Parser.getTok().isNot(AsmToken::Comma)) {
5387 Error(Sx1, "expected modified immediate operand: #[0, 255], #even[0-30]");
5388 return MatchOperand_ParseFail;
5389 }
5390
5391 if (Imm1 & ~0xFF) {
5392 Error(Sx1, "immediate operand must a number in the range [0, 255]");
5393 return MatchOperand_ParseFail;
5394 }
5395
5396 // Eat the comma
5397 Parser.Lex();
5398
5399 // Repeat for #rot
5400 SMLoc Sx2, Ex2;
5401 Sx2 = Parser.getTok().getLoc();
5402
5403 // Eat the optional hash (dollar)
5404 if (Parser.getTok().is(AsmToken::Hash) ||
5405 Parser.getTok().is(AsmToken::Dollar))
5406 Parser.Lex();
5407
5408 const MCExpr *Imm2Exp;
5409 if (getParser().parseExpression(Imm2Exp, Ex2)) {
5410 Error(Sx2, "malformed expression");
5411 return MatchOperand_ParseFail;
5412 }
5413
5414 CE = dyn_cast<MCConstantExpr>(Imm2Exp);
5415
5416 if (CE) {
5417 Imm2 = CE->getValue();
5418 if (!(Imm2 & ~0x1E)) {
5419 // We have a match!
5420 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2));
5421 return MatchOperand_Success;
5422 }
5423 Error(Sx2, "immediate operand must an even number in the range [0, 30]");
5424 return MatchOperand_ParseFail;
5425 } else {
5426 Error(Sx2, "constant expression expected");
5427 return MatchOperand_ParseFail;
5428 }
5429}
5430
5431OperandMatchResultTy
5432ARMAsmParser::parseBitfield(OperandVector &Operands) {
5433 MCAsmParser &Parser = getParser();
5434 SMLoc S = Parser.getTok().getLoc();
5435 // The bitfield descriptor is really two operands, the LSB and the width.
5436 if (Parser.getTok().isNot(AsmToken::Hash) &&
5437 Parser.getTok().isNot(AsmToken::Dollar)) {
5438 Error(Parser.getTok().getLoc(), "'#' expected");
5439 return MatchOperand_ParseFail;
5440 }
5441 Parser.Lex(); // Eat hash token.
5442
5443 const MCExpr *LSBExpr;
5444 SMLoc E = Parser.getTok().getLoc();
5445 if (getParser().parseExpression(LSBExpr)) {
5446 Error(E, "malformed immediate expression");
5447 return MatchOperand_ParseFail;
5448 }
5449 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
5450 if (!CE) {
5451 Error(E, "'lsb' operand must be an immediate");
5452 return MatchOperand_ParseFail;
5453 }
5454
5455 int64_t LSB = CE->getValue();
5456 // The LSB must be in the range [0,31]
5457 if (LSB < 0 || LSB > 31) {
5458 Error(E, "'lsb' operand must be in the range [0,31]");
5459 return MatchOperand_ParseFail;
5460 }
5461 E = Parser.getTok().getLoc();
5462
5463 // Expect another immediate operand.
5464 if (Parser.getTok().isNot(AsmToken::Comma)) {
5465 Error(Parser.getTok().getLoc(), "too few operands");
5466 return MatchOperand_ParseFail;
5467 }
5468 Parser.Lex(); // Eat hash token.
5469 if (Parser.getTok().isNot(AsmToken::Hash) &&
5470 Parser.getTok().isNot(AsmToken::Dollar)) {
5471 Error(Parser.getTok().getLoc(), "'#' expected");
5472 return MatchOperand_ParseFail;
5473 }
5474 Parser.Lex(); // Eat hash token.
5475
5476 const MCExpr *WidthExpr;
5477 SMLoc EndLoc;
5478 if (getParser().parseExpression(WidthExpr, EndLoc)) {
5479 Error(E, "malformed immediate expression");
5480 return MatchOperand_ParseFail;
5481 }
5482 CE = dyn_cast<MCConstantExpr>(WidthExpr);
5483 if (!CE) {
5484 Error(E, "'width' operand must be an immediate");
5485 return MatchOperand_ParseFail;
5486 }
5487
5488 int64_t Width = CE->getValue();
5489 // The LSB must be in the range [1,32-lsb]
5490 if (Width < 1 || Width > 32 - LSB) {
5491 Error(E, "'width' operand must be in the range [1,32-lsb]");
5492 return MatchOperand_ParseFail;
5493 }
5494
5495 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc));
5496
5497 return MatchOperand_Success;
5498}
5499
5500OperandMatchResultTy
5501ARMAsmParser::parsePostIdxReg(OperandVector &Operands) {
5502 // Check for a post-index addressing register operand. Specifically:
5503 // postidx_reg := '+' register {, shift}
5504 // | '-' register {, shift}
5505 // | register {, shift}
5506
5507 // This method must return MatchOperand_NoMatch without consuming any tokens
5508 // in the case where there is no match, as other alternatives take other
5509 // parse methods.
5510 MCAsmParser &Parser = getParser();
5511 AsmToken Tok = Parser.getTok();
5512 SMLoc S = Tok.getLoc();
5513 bool haveEaten = false;
5514 bool isAdd = true;
5515 if (Tok.is(AsmToken::Plus)) {
5516 Parser.Lex(); // Eat the '+' token.
5517 haveEaten = true;
5518 } else if (Tok.is(AsmToken::Minus)) {
5519 Parser.Lex(); // Eat the '-' token.
5520 isAdd = false;
5521 haveEaten = true;
5522 }
5523
5524 SMLoc E = Parser.getTok().getEndLoc();
5525 int Reg = tryParseRegister();
5526 if (Reg == -1) {
5527 if (!haveEaten)
5528 return MatchOperand_NoMatch;
5529 Error(Parser.getTok().getLoc(), "register expected");
5530 return MatchOperand_ParseFail;
5531 }
5532
5533 ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
5534 unsigned ShiftImm = 0;
5535 if (Parser.getTok().is(AsmToken::Comma)) {
5536 Parser.Lex(); // Eat the ','.
5537 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5538 return MatchOperand_ParseFail;
5539
5540 // FIXME: Only approximates end...may include intervening whitespace.
5541 E = Parser.getTok().getLoc();
5542 }
5543
5544 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
5545 ShiftImm, S, E));
5546
5547 return MatchOperand_Success;
5548}
5549
5550OperandMatchResultTy
5551ARMAsmParser::parseAM3Offset(OperandVector &Operands) {
5552 // Check for a post-index addressing register operand. Specifically:
5553 // am3offset := '+' register
5554 // | '-' register
5555 // | register
5556 // | # imm
5557 // | # + imm
5558 // | # - imm
5559
5560 // This method must return MatchOperand_NoMatch without consuming any tokens
5561 // in the case where there is no match, as other alternatives take other
5562 // parse methods.
5563 MCAsmParser &Parser = getParser();
5564 AsmToken Tok = Parser.getTok();
5565 SMLoc S = Tok.getLoc();
5566
5567 // Do immediates first, as we always parse those if we have a '#'.
5568 if (Parser.getTok().is(AsmToken::Hash) ||
5569 Parser.getTok().is(AsmToken::Dollar)) {
5570 Parser.Lex(); // Eat '#' or '$'.
5571 // Explicitly look for a '-', as we need to encode negative zero
5572 // differently.
5573 bool isNegative = Parser.getTok().is(AsmToken::Minus);
5574 const MCExpr *Offset;
5575 SMLoc E;
5576 if (getParser().parseExpression(Offset, E))
5577 return MatchOperand_ParseFail;
5578 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
5579 if (!CE) {
5580 Error(S, "constant expression expected");
5581 return MatchOperand_ParseFail;
5582 }
5583 // Negative zero is encoded as the flag value
5584 // std::numeric_limits<int32_t>::min().
5585 int32_t Val = CE->getValue();
5586 if (isNegative && Val == 0)
5587 Val = std::numeric_limits<int32_t>::min();
5588
5589 Operands.push_back(
5590 ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S, E));
5591
5592 return MatchOperand_Success;
5593 }
5594
5595 bool haveEaten = false;
5596 bool isAdd = true;
5597 if (Tok.is(AsmToken::Plus)) {
5598 Parser.Lex(); // Eat the '+' token.
5599 haveEaten = true;
5600 } else if (Tok.is(AsmToken::Minus)) {
5601 Parser.Lex(); // Eat the '-' token.
5602 isAdd = false;
5603 haveEaten = true;
5604 }
5605
5606 Tok = Parser.getTok();
5607 int Reg = tryParseRegister();
5608 if (Reg == -1) {
5609 if (!haveEaten)
5610 return MatchOperand_NoMatch;
5611 Error(Tok.getLoc(), "register expected");
5612 return MatchOperand_ParseFail;
5613 }
5614
5615 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
5616 0, S, Tok.getEndLoc()));
5617
5618 return MatchOperand_Success;
5619}
5620
5621/// Convert parsed operands to MCInst. Needed here because this instruction
5622/// only has two register operands, but multiplication is commutative so
5623/// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN".
5624void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5625 const OperandVector &Operands) {
5626 ((ARMOperand &)*Operands[3]).addRegOperands(Inst, 1);
5627 ((ARMOperand &)*Operands[1]).addCCOutOperands(Inst, 1);
5628 // If we have a three-operand form, make sure to set Rn to be the operand
5629 // that isn't the same as Rd.
5630 unsigned RegOp = 4;
5631 if (Operands.size() == 6 &&
5632 ((ARMOperand &)*Operands[4]).getReg() ==
5633 ((ARMOperand &)*Operands[3]).getReg())
5634 RegOp = 5;
5635 ((ARMOperand &)*Operands[RegOp]).addRegOperands(Inst, 1);
5636 Inst.addOperand(Inst.getOperand(0));
5637 ((ARMOperand &)*Operands[2]).addCondCodeOperands(Inst, 2);
5638}
5639
5640void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5641 const OperandVector &Operands) {
5642 int CondOp = -1, ImmOp = -1;
5643 switch(Inst.getOpcode()) {
5644 case ARM::tB:
5645 case ARM::tBcc: CondOp = 1; ImmOp = 2; break;
5646
5647 case ARM::t2B:
5648 case ARM::t2Bcc: CondOp = 1; ImmOp = 3; break;
5649
5650 default: llvm_unreachable("Unexpected instruction in cvtThumbBranches")::llvm::llvm_unreachable_internal("Unexpected instruction in cvtThumbBranches"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 5650)
;
5651 }
5652 // first decide whether or not the branch should be conditional
5653 // by looking at it's location relative to an IT block
5654 if(inITBlock()) {
5655 // inside an IT block we cannot have any conditional branches. any
5656 // such instructions needs to be converted to unconditional form
5657 switch(Inst.getOpcode()) {
5658 case ARM::tBcc: Inst.setOpcode(ARM::tB); break;