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 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/build-llvm/lib/Target/ARM/AsmParser -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/build-llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/build-llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/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/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../x86_64-linux-gnu/include -internal-isystem /usr/lib/llvm-13/lib/clang/13.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-13~++20210405022414+5f57793c4fe4/build-llvm/lib/Target/ARM/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4=. -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 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-04-05-202135-9119-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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-13~++20210405022414+5f57793c4fe4/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 }
3091
3092 void addMemTBBOperands(MCInst &Inst, unsigned N) const {
3093 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3093, __PRETTY_FUNCTION__))
;
3094 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3095 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3096 }
3097
3098 void addMemTBHOperands(MCInst &Inst, unsigned N) const {
3099 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3099, __PRETTY_FUNCTION__))
;
3100 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3101 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3102 }
3103
3104 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3105 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3105, __PRETTY_FUNCTION__))
;
3106 unsigned Val =
3107 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3108 Memory.ShiftImm, Memory.ShiftType);
3109 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3110 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3111 Inst.addOperand(MCOperand::createImm(Val));
3112 }
3113
3114 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3115 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3115, __PRETTY_FUNCTION__))
;
3116 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3117 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3118 Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
3119 }
3120
3121 void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
3122 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3122, __PRETTY_FUNCTION__))
;
3123 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3124 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3125 }
3126
3127 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
3128 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3128, __PRETTY_FUNCTION__))
;
3129 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
3130 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3131 Inst.addOperand(MCOperand::createImm(Val));
3132 }
3133
3134 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
3135 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3135, __PRETTY_FUNCTION__))
;
3136 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
3137 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3138 Inst.addOperand(MCOperand::createImm(Val));
3139 }
3140
3141 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
3142 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3142, __PRETTY_FUNCTION__))
;
3143 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
3144 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3145 Inst.addOperand(MCOperand::createImm(Val));
3146 }
3147
3148 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
3149 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3149, __PRETTY_FUNCTION__))
;
3150 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
3151 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3152 Inst.addOperand(MCOperand::createImm(Val));
3153 }
3154
3155 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
3156 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3156, __PRETTY_FUNCTION__))
;
3157 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3158 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3158, __PRETTY_FUNCTION__))
;
3159 int Imm = CE->getValue();
3160 bool isAdd = Imm >= 0;
3161 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3162 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
3163 Inst.addOperand(MCOperand::createImm(Imm));
3164 }
3165
3166 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
3167 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3167, __PRETTY_FUNCTION__))
;
3168 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3169 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3169, __PRETTY_FUNCTION__))
;
3170 int Imm = CE->getValue();
3171 bool isAdd = Imm >= 0;
3172 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3173 // Immediate is scaled by 4.
3174 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
3175 Inst.addOperand(MCOperand::createImm(Imm));
3176 }
3177
3178 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
3179 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3179, __PRETTY_FUNCTION__))
;
3180 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3181 Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
3182 }
3183
3184 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
3185 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3185, __PRETTY_FUNCTION__))
;
3186 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3187 // The sign, shift type, and shift amount are encoded in a single operand
3188 // using the AM2 encoding helpers.
3189 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
3190 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
3191 PostIdxReg.ShiftTy);
3192 Inst.addOperand(MCOperand::createImm(Imm));
3193 }
3194
3195 void addPowerTwoOperands(MCInst &Inst, unsigned N) const {
3196 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3196, __PRETTY_FUNCTION__))
;
3197 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3198 Inst.addOperand(MCOperand::createImm(CE->getValue()));
3199 }
3200
3201 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
3202 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3202, __PRETTY_FUNCTION__))
;
3203 Inst.addOperand(MCOperand::createImm(unsigned(getMSRMask())));
3204 }
3205
3206 void addBankedRegOperands(MCInst &Inst, unsigned N) const {
3207 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3207, __PRETTY_FUNCTION__))
;
3208 Inst.addOperand(MCOperand::createImm(unsigned(getBankedReg())));
3209 }
3210
3211 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
3212 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3212, __PRETTY_FUNCTION__))
;
3213 Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
3214 }
3215
3216 void addVecListOperands(MCInst &Inst, unsigned N) const {
3217 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3217, __PRETTY_FUNCTION__))
;
3218 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3219 }
3220
3221 void addMVEVecListOperands(MCInst &Inst, unsigned N) const {
3222 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3222, __PRETTY_FUNCTION__))
;
3223
3224 // When we come here, the VectorList field will identify a range
3225 // of q-registers by its base register and length, and it will
3226 // have already been error-checked to be the expected length of
3227 // range and contain only q-regs in the range q0-q7. So we can
3228 // count on the base register being in the range q0-q6 (for 2
3229 // regs) or q0-q4 (for 4)
3230 //
3231 // The MVE instructions taking a register range of this kind will
3232 // need an operand in the QQPR or QQQQPR class, representing the
3233 // entire range as a unit. So we must translate into that class,
3234 // by finding the index of the base register in the MQPR reg
3235 // class, and returning the super-register at the corresponding
3236 // index in the target class.
3237
3238 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3239 const MCRegisterClass *RC_out = (VectorList.Count == 2) ?
3240 &ARMMCRegisterClasses[ARM::QQPRRegClassID] :
3241 &ARMMCRegisterClasses[ARM::QQQQPRRegClassID];
3242
3243 unsigned I, E = RC_out->getNumRegs();
3244 for (I = 0; I < E; I++)
3245 if (RC_in->getRegister(I) == VectorList.RegNum)
3246 break;
3247 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3247, __PRETTY_FUNCTION__))
;
3248
3249 Inst.addOperand(MCOperand::createReg(RC_out->getRegister(I)));
3250 }
3251
3252 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
3253 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3253, __PRETTY_FUNCTION__))
;
3254 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3255 Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
3256 }
3257
3258 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
3259 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3259, __PRETTY_FUNCTION__))
;
3260 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3261 }
3262
3263 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
3264 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3264, __PRETTY_FUNCTION__))
;
3265 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3266 }
3267
3268 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
3269 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3269, __PRETTY_FUNCTION__))
;
3270 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3271 }
3272
3273 void addVectorIndex64Operands(MCInst &Inst, unsigned N) const {
3274 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3274, __PRETTY_FUNCTION__))
;
3275 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3276 }
3277
3278 void addMVEVectorIndexOperands(MCInst &Inst, unsigned N) const {
3279 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3279, __PRETTY_FUNCTION__))
;
3280 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3281 }
3282
3283 void addMVEPairVectorIndexOperands(MCInst &Inst, unsigned N) const {
3284 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3284, __PRETTY_FUNCTION__))
;
3285 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3286 }
3287
3288 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
3289 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3289, __PRETTY_FUNCTION__))
;
3290 // The immediate encodes the type of constant as well as the value.
3291 // Mask in that this is an i8 splat.
3292 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3293 Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
3294 }
3295
3296 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
3297 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3297, __PRETTY_FUNCTION__))
;
3298 // The immediate encodes the type of constant as well as the value.
3299 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3300 unsigned Value = CE->getValue();
3301 Value = ARM_AM::encodeNEONi16splat(Value);
3302 Inst.addOperand(MCOperand::createImm(Value));
3303 }
3304
3305 void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
3306 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3306, __PRETTY_FUNCTION__))
;
3307 // The immediate encodes the type of constant as well as the value.
3308 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3309 unsigned Value = CE->getValue();
3310 Value = ARM_AM::encodeNEONi16splat(~Value & 0xffff);
3311 Inst.addOperand(MCOperand::createImm(Value));
3312 }
3313
3314 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
3315 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3315, __PRETTY_FUNCTION__))
;
3316 // The immediate encodes the type of constant as well as the value.
3317 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3318 unsigned Value = CE->getValue();
3319 Value = ARM_AM::encodeNEONi32splat(Value);
3320 Inst.addOperand(MCOperand::createImm(Value));
3321 }
3322
3323 void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
3324 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3324, __PRETTY_FUNCTION__))
;
3325 // The immediate encodes the type of constant as well as the value.
3326 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3327 unsigned Value = CE->getValue();
3328 Value = ARM_AM::encodeNEONi32splat(~Value);
3329 Inst.addOperand(MCOperand::createImm(Value));
3330 }
3331
3332 void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
3333 // The immediate encodes the type of constant as well as the value.
3334 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3335 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3338, __PRETTY_FUNCTION__))
3336 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3338, __PRETTY_FUNCTION__))
3337 "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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3338, __PRETTY_FUNCTION__))
3338 "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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3338, __PRETTY_FUNCTION__))
;
3339 unsigned Value = CE->getValue();
3340 if (Inv)
3341 Value = ~Value;
3342 unsigned B = Value & 0xff;
3343 B |= 0xe00; // cmode = 0b1110
3344 Inst.addOperand(MCOperand::createImm(B));
3345 }
3346
3347 void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3348 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3348, __PRETTY_FUNCTION__))
;
3349 addNEONi8ReplicateOperands(Inst, true);
3350 }
3351
3352 static unsigned encodeNeonVMOVImmediate(unsigned Value) {
3353 if (Value >= 256 && Value <= 0xffff)
3354 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
3355 else if (Value > 0xffff && Value <= 0xffffff)
3356 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
3357 else if (Value > 0xffffff)
3358 Value = (Value >> 24) | 0x600;
3359 return Value;
3360 }
3361
3362 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
3363 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3363, __PRETTY_FUNCTION__))
;
3364 // The immediate encodes the type of constant as well as the value.
3365 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3366 unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
3367 Inst.addOperand(MCOperand::createImm(Value));
3368 }
3369
3370 void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3371 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3371, __PRETTY_FUNCTION__))
;
3372 addNEONi8ReplicateOperands(Inst, false);
3373 }
3374
3375 void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
3376 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3376, __PRETTY_FUNCTION__))
;
3377 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3378 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3383, __PRETTY_FUNCTION__))
3379 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3383, __PRETTY_FUNCTION__))
3380 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3383, __PRETTY_FUNCTION__))
3381 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3383, __PRETTY_FUNCTION__))
3382 "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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3383, __PRETTY_FUNCTION__))
3383 "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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3383, __PRETTY_FUNCTION__))
;
3384 uint64_t Value = CE->getValue();
3385 unsigned Elem = Value & 0xffff;
3386 if (Elem >= 256)
3387 Elem = (Elem >> 8) | 0x200;
3388 Inst.addOperand(MCOperand::createImm(Elem));
3389 }
3390
3391 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
3392 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3392, __PRETTY_FUNCTION__))
;
3393 // The immediate encodes the type of constant as well as the value.
3394 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3395 unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
3396 Inst.addOperand(MCOperand::createImm(Value));
3397 }
3398
3399 void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
3400 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3400, __PRETTY_FUNCTION__))
;
3401 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3402 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3407, __PRETTY_FUNCTION__))
3403 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3407, __PRETTY_FUNCTION__))
3404 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3407, __PRETTY_FUNCTION__))
3405 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3407, __PRETTY_FUNCTION__))
3406 "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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3407, __PRETTY_FUNCTION__))
3407 "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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3407, __PRETTY_FUNCTION__))
;
3408 uint64_t Value = CE->getValue();
3409 unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
3410 Inst.addOperand(MCOperand::createImm(Elem));
3411 }
3412
3413 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
3414 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3414, __PRETTY_FUNCTION__))
;
3415 // The immediate encodes the type of constant as well as the value.
3416 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3417 uint64_t Value = CE->getValue();
3418 unsigned Imm = 0;
3419 for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
3420 Imm |= (Value & 1) << i;
3421 }
3422 Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
3423 }
3424
3425 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
3426 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3426, __PRETTY_FUNCTION__))
;
3427 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3428 Inst.addOperand(MCOperand::createImm(CE->getValue() / 90));
3429 }
3430
3431 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
3432 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3432, __PRETTY_FUNCTION__))
;
3433 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3434 Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
3435 }
3436
3437 void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
3438 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3438, __PRETTY_FUNCTION__))
;
3439 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3440 unsigned Imm = CE->getValue();
3441 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3441, __PRETTY_FUNCTION__))
;
3442 Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0));
3443 }
3444
3445 void print(raw_ostream &OS) const override;
3446
3447 static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S) {
3448 auto Op = std::make_unique<ARMOperand>(k_ITCondMask);
3449 Op->ITMask.Mask = Mask;
3450 Op->StartLoc = S;
3451 Op->EndLoc = S;
3452 return Op;
3453 }
3454
3455 static std::unique_ptr<ARMOperand> CreateCondCode(ARMCC::CondCodes CC,
3456 SMLoc S) {
3457 auto Op = std::make_unique<ARMOperand>(k_CondCode);
3458 Op->CC.Val = CC;
3459 Op->StartLoc = S;
3460 Op->EndLoc = S;
3461 return Op;
3462 }
3463
3464 static std::unique_ptr<ARMOperand> CreateVPTPred(ARMVCC::VPTCodes CC,
3465 SMLoc S) {
3466 auto Op = std::make_unique<ARMOperand>(k_VPTPred);
3467 Op->VCC.Val = CC;
3468 Op->StartLoc = S;
3469 Op->EndLoc = S;
3470 return Op;
3471 }
3472
3473 static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S) {
3474 auto Op = std::make_unique<ARMOperand>(k_CoprocNum);
3475 Op->Cop.Val = CopVal;
3476 Op->StartLoc = S;
3477 Op->EndLoc = S;
3478 return Op;
3479 }
3480
3481 static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S) {
3482 auto Op = std::make_unique<ARMOperand>(k_CoprocReg);
3483 Op->Cop.Val = CopVal;
3484 Op->StartLoc = S;
3485 Op->EndLoc = S;
3486 return Op;
3487 }
3488
3489 static std::unique_ptr<ARMOperand> CreateCoprocOption(unsigned Val, SMLoc S,
3490 SMLoc E) {
3491 auto Op = std::make_unique<ARMOperand>(k_CoprocOption);
3492 Op->Cop.Val = Val;
3493 Op->StartLoc = S;
3494 Op->EndLoc = E;
3495 return Op;
3496 }
3497
3498 static std::unique_ptr<ARMOperand> CreateCCOut(unsigned RegNum, SMLoc S) {
3499 auto Op = std::make_unique<ARMOperand>(k_CCOut);
3500 Op->Reg.RegNum = RegNum;
3501 Op->StartLoc = S;
3502 Op->EndLoc = S;
3503 return Op;
3504 }
3505
3506 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S) {
3507 auto Op = std::make_unique<ARMOperand>(k_Token);
3508 Op->Tok.Data = Str.data();
3509 Op->Tok.Length = Str.size();
3510 Op->StartLoc = S;
3511 Op->EndLoc = S;
3512 return Op;
3513 }
3514
3515 static std::unique_ptr<ARMOperand> CreateReg(unsigned RegNum, SMLoc S,
3516 SMLoc E) {
3517 auto Op = std::make_unique<ARMOperand>(k_Register);
3518 Op->Reg.RegNum = RegNum;
3519 Op->StartLoc = S;
3520 Op->EndLoc = E;
3521 return Op;
3522 }
3523
3524 static std::unique_ptr<ARMOperand>
3525 CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, unsigned SrcReg,
3526 unsigned ShiftReg, unsigned ShiftImm, SMLoc S,
3527 SMLoc E) {
3528 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister);
3529 Op->RegShiftedReg.ShiftTy = ShTy;
3530 Op->RegShiftedReg.SrcReg = SrcReg;
3531 Op->RegShiftedReg.ShiftReg = ShiftReg;
3532 Op->RegShiftedReg.ShiftImm = ShiftImm;
3533 Op->StartLoc = S;
3534 Op->EndLoc = E;
3535 return Op;
3536 }
3537
3538 static std::unique_ptr<ARMOperand>
3539 CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, unsigned SrcReg,
3540 unsigned ShiftImm, SMLoc S, SMLoc E) {
3541 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate);
3542 Op->RegShiftedImm.ShiftTy = ShTy;
3543 Op->RegShiftedImm.SrcReg = SrcReg;
3544 Op->RegShiftedImm.ShiftImm = ShiftImm;
3545 Op->StartLoc = S;
3546 Op->EndLoc = E;
3547 return Op;
3548 }
3549
3550 static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm,
3551 SMLoc S, SMLoc E) {
3552 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate);
3553 Op->ShifterImm.isASR = isASR;
3554 Op->ShifterImm.Imm = Imm;
3555 Op->StartLoc = S;
3556 Op->EndLoc = E;
3557 return Op;
3558 }
3559
3560 static std::unique_ptr<ARMOperand> CreateRotImm(unsigned Imm, SMLoc S,
3561 SMLoc E) {
3562 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate);
3563 Op->RotImm.Imm = Imm;
3564 Op->StartLoc = S;
3565 Op->EndLoc = E;
3566 return Op;
3567 }
3568
3569 static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
3570 SMLoc S, SMLoc E) {
3571 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate);
3572 Op->ModImm.Bits = Bits;
3573 Op->ModImm.Rot = Rot;
3574 Op->StartLoc = S;
3575 Op->EndLoc = E;
3576 return Op;
3577 }
3578
3579 static std::unique_ptr<ARMOperand>
3580 CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E) {
3581 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate);
3582 Op->Imm.Val = Val;
3583 Op->StartLoc = S;
3584 Op->EndLoc = E;
3585 return Op;
3586 }
3587
3588 static std::unique_ptr<ARMOperand>
3589 CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) {
3590 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor);
3591 Op->Bitfield.LSB = LSB;
3592 Op->Bitfield.Width = Width;
3593 Op->StartLoc = S;
3594 Op->EndLoc = E;
3595 return Op;
3596 }
3597
3598 static std::unique_ptr<ARMOperand>
3599 CreateRegList(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs,
3600 SMLoc StartLoc, SMLoc EndLoc) {
3601 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3601, __PRETTY_FUNCTION__))
;
3602 KindTy Kind = k_RegisterList;
3603
3604 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
3605 Regs.front().second)) {
3606 if (Regs.back().second == ARM::VPR)
3607 Kind = k_FPDRegisterListWithVPR;
3608 else
3609 Kind = k_DPRRegisterList;
3610 } else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(
3611 Regs.front().second)) {
3612 if (Regs.back().second == ARM::VPR)
3613 Kind = k_FPSRegisterListWithVPR;
3614 else
3615 Kind = k_SPRRegisterList;
3616 }
3617
3618 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3619 Kind = k_RegisterListWithAPSR;
3620
3621 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3621, __PRETTY_FUNCTION__))
;
3622
3623 auto Op = std::make_unique<ARMOperand>(Kind);
3624 for (const auto &P : Regs)
3625 Op->Registers.push_back(P.second);
3626
3627 Op->StartLoc = StartLoc;
3628 Op->EndLoc = EndLoc;
3629 return Op;
3630 }
3631
3632 static std::unique_ptr<ARMOperand> CreateVectorList(unsigned RegNum,
3633 unsigned Count,
3634 bool isDoubleSpaced,
3635 SMLoc S, SMLoc E) {
3636 auto Op = std::make_unique<ARMOperand>(k_VectorList);
3637 Op->VectorList.RegNum = RegNum;
3638 Op->VectorList.Count = Count;
3639 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3640 Op->StartLoc = S;
3641 Op->EndLoc = E;
3642 return Op;
3643 }
3644
3645 static std::unique_ptr<ARMOperand>
3646 CreateVectorListAllLanes(unsigned RegNum, unsigned Count, bool isDoubleSpaced,
3647 SMLoc S, SMLoc E) {
3648 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes);
3649 Op->VectorList.RegNum = RegNum;
3650 Op->VectorList.Count = Count;
3651 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3652 Op->StartLoc = S;
3653 Op->EndLoc = E;
3654 return Op;
3655 }
3656
3657 static std::unique_ptr<ARMOperand>
3658 CreateVectorListIndexed(unsigned RegNum, unsigned Count, unsigned Index,
3659 bool isDoubleSpaced, SMLoc S, SMLoc E) {
3660 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed);
3661 Op->VectorList.RegNum = RegNum;
3662 Op->VectorList.Count = Count;
3663 Op->VectorList.LaneIndex = Index;
3664 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3665 Op->StartLoc = S;
3666 Op->EndLoc = E;
3667 return Op;
3668 }
3669
3670 static std::unique_ptr<ARMOperand>
3671 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
3672 auto Op = std::make_unique<ARMOperand>(k_VectorIndex);
3673 Op->VectorIndex.Val = Idx;
3674 Op->StartLoc = S;
3675 Op->EndLoc = E;
3676 return Op;
3677 }
3678
3679 static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S,
3680 SMLoc E) {
3681 auto Op = std::make_unique<ARMOperand>(k_Immediate);
3682 Op->Imm.Val = Val;
3683 Op->StartLoc = S;
3684 Op->EndLoc = E;
3685 return Op;
3686 }
3687
3688 static std::unique_ptr<ARMOperand>
3689 CreateMem(unsigned BaseRegNum, const MCConstantExpr *OffsetImm,
3690 unsigned OffsetRegNum, ARM_AM::ShiftOpc ShiftType,
3691 unsigned ShiftImm, unsigned Alignment, bool isNegative, SMLoc S,
3692 SMLoc E, SMLoc AlignmentLoc = SMLoc()) {
3693 auto Op = std::make_unique<ARMOperand>(k_Memory);
3694 Op->Memory.BaseRegNum = BaseRegNum;
3695 Op->Memory.OffsetImm = OffsetImm;
3696 Op->Memory.OffsetRegNum = OffsetRegNum;
3697 Op->Memory.ShiftType = ShiftType;
3698 Op->Memory.ShiftImm = ShiftImm;
3699 Op->Memory.Alignment = Alignment;
3700 Op->Memory.isNegative = isNegative;
3701 Op->StartLoc = S;
3702 Op->EndLoc = E;
3703 Op->AlignmentLoc = AlignmentLoc;
3704 return Op;
3705 }
3706
3707 static std::unique_ptr<ARMOperand>
3708 CreatePostIdxReg(unsigned RegNum, bool isAdd, ARM_AM::ShiftOpc ShiftTy,
3709 unsigned ShiftImm, SMLoc S, SMLoc E) {
3710 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister);
3711 Op->PostIdxReg.RegNum = RegNum;
3712 Op->PostIdxReg.isAdd = isAdd;
3713 Op->PostIdxReg.ShiftTy = ShiftTy;
3714 Op->PostIdxReg.ShiftImm = ShiftImm;
3715 Op->StartLoc = S;
3716 Op->EndLoc = E;
3717 return Op;
3718 }
3719
3720 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(ARM_MB::MemBOpt Opt,
3721 SMLoc S) {
3722 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt);
3723 Op->MBOpt.Val = Opt;
3724 Op->StartLoc = S;
3725 Op->EndLoc = S;
3726 return Op;
3727 }
3728
3729 static std::unique_ptr<ARMOperand>
3730 CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S) {
3731 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt);
3732 Op->ISBOpt.Val = Opt;
3733 Op->StartLoc = S;
3734 Op->EndLoc = S;
3735 return Op;
3736 }
3737
3738 static std::unique_ptr<ARMOperand>
3739 CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S) {
3740 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt);
3741 Op->TSBOpt.Val = Opt;
3742 Op->StartLoc = S;
3743 Op->EndLoc = S;
3744 return Op;
3745 }
3746
3747 static std::unique_ptr<ARMOperand> CreateProcIFlags(ARM_PROC::IFlags IFlags,
3748 SMLoc S) {
3749 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags);
3750 Op->IFlags.Val = IFlags;
3751 Op->StartLoc = S;
3752 Op->EndLoc = S;
3753 return Op;
3754 }
3755
3756 static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S) {
3757 auto Op = std::make_unique<ARMOperand>(k_MSRMask);
3758 Op->MMask.Val = MMask;
3759 Op->StartLoc = S;
3760 Op->EndLoc = S;
3761 return Op;
3762 }
3763
3764 static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S) {
3765 auto Op = std::make_unique<ARMOperand>(k_BankedReg);
3766 Op->BankedReg.Val = Reg;
3767 Op->StartLoc = S;
3768 Op->EndLoc = S;
3769 return Op;
3770 }
3771};
3772
3773} // end anonymous namespace.
3774
3775void ARMOperand::print(raw_ostream &OS) const {
3776 auto RegName = [](unsigned Reg) {
3777 if (Reg)
3778 return ARMInstPrinter::getRegisterName(Reg);
3779 else
3780 return "noreg";
3781 };
3782
3783 switch (Kind) {
3784 case k_CondCode:
3785 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
3786 break;
3787 case k_VPTPred:
3788 OS << "<ARMVCC::" << ARMVPTPredToString(getVPTPred()) << ">";
3789 break;
3790 case k_CCOut:
3791 OS << "<ccout " << RegName(getReg()) << ">";
3792 break;
3793 case k_ITCondMask: {
3794 static const char *const MaskStr[] = {
3795 "(invalid)", "(tttt)", "(ttt)", "(ttte)",
3796 "(tt)", "(ttet)", "(tte)", "(ttee)",
3797 "(t)", "(tett)", "(tet)", "(tete)",
3798 "(te)", "(teet)", "(tee)", "(teee)",
3799 };
3800 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-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 3800, __PRETTY_FUNCTION__))
;
3801 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
3802 break;
3803 }
3804 case k_CoprocNum:
3805 OS << "<coprocessor number: " << getCoproc() << ">";
3806 break;
3807 case k_CoprocReg:
3808 OS << "<coprocessor register: " << getCoproc() << ">";
3809 break;
3810 case k_CoprocOption:
3811 OS << "<coprocessor option: " << CoprocOption.Val << ">";
3812 break;
3813 case k_MSRMask:
3814 OS << "<mask: " << getMSRMask() << ">";
3815 break;
3816 case k_BankedReg:
3817 OS << "<banked reg: " << getBankedReg() << ">";
3818 break;
3819 case k_Immediate:
3820 OS << *getImm();
3821 break;
3822 case k_MemBarrierOpt:
3823 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
3824 break;
3825 case k_InstSyncBarrierOpt:
3826 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
3827 break;
3828 case k_TraceSyncBarrierOpt:
3829 OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
3830 break;
3831 case k_Memory:
3832 OS << "<memory";
3833 if (Memory.BaseRegNum)
3834 OS << " base:" << RegName(Memory.BaseRegNum);
3835 if (Memory.OffsetImm)
3836 OS << " offset-imm:" << *Memory.OffsetImm;
3837 if (Memory.OffsetRegNum)
3838 OS << " offset-reg:" << (Memory.isNegative ? "-" : "")
3839 << RegName(Memory.OffsetRegNum);
3840 if (Memory.ShiftType != ARM_AM::no_shift) {
3841 OS << " shift-type:" << ARM_AM::getShiftOpcStr(Memory.ShiftType);
3842 OS << " shift-imm:" << Memory.ShiftImm;
3843 }
3844 if (Memory.Alignment)
3845 OS << " alignment:" << Memory.Alignment;
3846 OS << ">";
3847 break;
3848 case k_PostIndexRegister:
3849 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
3850 << RegName(PostIdxReg.RegNum);
3851 if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
3852 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
3853 << PostIdxReg.ShiftImm;
3854 OS << ">";
3855 break;
3856 case k_ProcIFlags: {
3857 OS << "<ARM_PROC::";
3858 unsigned IFlags = getProcIFlags();
3859 for (int i=2; i >= 0; --i)
3860 if (IFlags & (1 << i))
3861 OS << ARM_PROC::IFlagsToString(1 << i);
3862 OS << ">";
3863 break;
3864 }
3865 case k_Register:
3866 OS << "<register " << RegName(getReg()) << ">";
3867 break;
3868 case k_ShifterImmediate:
3869 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
3870 << " #" << ShifterImm.Imm << ">";
3871 break;
3872 case k_ShiftedRegister:
3873 OS << "<so_reg_reg " << RegName(RegShiftedReg.SrcReg) << " "
3874 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) << " "
3875 << RegName(RegShiftedReg.ShiftReg) << ">";
3876 break;
3877 case k_ShiftedImmediate:
3878 OS << "<so_reg_imm " << RegName(RegShiftedImm.SrcReg) << " "
3879 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) << " #"
3880 << RegShiftedImm.ShiftImm << ">";
3881 break;
3882 case k_RotateImmediate:
3883 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
3884 break;
3885 case k_ModifiedImmediate:
3886 OS << "<mod_imm #" << ModImm.Bits << ", #"
3887 << ModImm.Rot << ")>";
3888 break;
3889 case k_ConstantPoolImmediate:
3890 OS << "<constant_pool_imm #" << *getConstantPoolImm();
3891 break;
3892 case k_BitfieldDescriptor:
3893 OS << "<bitfield " << "lsb: " << Bitfield.LSB
3894 << ", width: " << Bitfield.Width << ">";
3895 break;
3896 case k_RegisterList:
3897 case k_RegisterListWithAPSR:
3898 case k_DPRRegisterList:
3899 case k_SPRRegisterList:
3900 case k_FPSRegisterListWithVPR:
3901 case k_FPDRegisterListWithVPR: {
3902 OS << "<register_list ";
3903
3904 const SmallVectorImpl<unsigned> &RegList = getRegList();
3905 for (SmallVectorImpl<unsigned>::const_iterator
3906 I = RegList.begin(), E = RegList.end(); I != E; ) {
3907 OS << RegName(*I);
3908 if (++I < E) OS << ", ";
3909 }
3910
3911 OS << ">";
3912 break;
3913 }
3914 case k_VectorList:
3915 OS << "<vector_list " << VectorList.Count << " * "
3916 << RegName(VectorList.RegNum) << ">";
3917 break;
3918 case k_VectorListAllLanes:
3919 OS << "<vector_list(all lanes) " << VectorList.Count << " * "
3920 << RegName(VectorList.RegNum) << ">";
3921 break;
3922 case k_VectorListIndexed:
3923 OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
3924 << VectorList.Count << " * " << RegName(VectorList.RegNum) << ">";
3925 break;
3926 case k_Token:
3927 OS << "'" << getToken() << "'";
3928 break;
3929 case k_VectorIndex:
3930 OS << "<vectorindex " << getVectorIndex() << ">";
3931 break;
3932 }
3933}
3934
3935/// @name Auto-generated Match Functions
3936/// {
3937
3938static unsigned MatchRegisterName(StringRef Name);
3939
3940/// }
3941
3942bool ARMAsmParser::ParseRegister(unsigned &RegNo,
3943 SMLoc &StartLoc, SMLoc &EndLoc) {
3944 const AsmToken &Tok = getParser().getTok();
3945 StartLoc = Tok.getLoc();
3946 EndLoc = Tok.getEndLoc();
3947 RegNo = tryParseRegister();
3948
3949 return (RegNo == (unsigned)-1);
3950}
3951
3952OperandMatchResultTy ARMAsmParser::tryParseRegister(unsigned &RegNo,
3953 SMLoc &StartLoc,
3954 SMLoc &EndLoc) {
3955 if (ParseRegister(RegNo, StartLoc, EndLoc))
3956 return MatchOperand_NoMatch;
3957 return MatchOperand_Success;
3958}
3959
3960/// Try to parse a register name. The token must be an Identifier when called,
3961/// and if it is a register name the token is eaten and the register number is
3962/// returned. Otherwise return -1.
3963int ARMAsmParser::tryParseRegister() {
3964 MCAsmParser &Parser = getParser();
3965 const AsmToken &Tok = Parser.getTok();
3966 if (Tok.isNot(AsmToken::Identifier)) return -1;
3967
3968 std::string lowerCase = Tok.getString().lower();
3969 unsigned RegNum = MatchRegisterName(lowerCase);
3970 if (!RegNum) {
3971 RegNum = StringSwitch<unsigned>(lowerCase)
3972 .Case("r13", ARM::SP)
3973 .Case("r14", ARM::LR)
3974 .Case("r15", ARM::PC)
3975 .Case("ip", ARM::R12)
3976 // Additional register name aliases for 'gas' compatibility.
3977 .Case("a1", ARM::R0)
3978 .Case("a2", ARM::R1)
3979 .Case("a3", ARM::R2)
3980 .Case("a4", ARM::R3)
3981 .Case("v1", ARM::R4)
3982 .Case("v2", ARM::R5)
3983 .Case("v3", ARM::R6)
3984 .Case("v4", ARM::R7)
3985 .Case("v5", ARM::R8)
3986 .Case("v6", ARM::R9)
3987 .Case("v7", ARM::R10)
3988 .Case("v8", ARM::R11)
3989 .Case("sb", ARM::R9)
3990 .Case("sl", ARM::R10)
3991 .Case("fp", ARM::R11)
3992 .Default(0);
3993 }
3994 if (!RegNum) {
3995 // Check for aliases registered via .req. Canonicalize to lower case.
3996 // That's more consistent since register names are case insensitive, and
3997 // it's how the original entry was passed in from MC/MCParser/AsmParser.
3998 StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
3999 // If no match, return failure.
4000 if (Entry == RegisterReqs.end())
4001 return -1;
4002 Parser.Lex(); // Eat identifier token.
4003 return Entry->getValue();
4004 }
4005
4006 // Some FPUs only have 16 D registers, so D16-D31 are invalid
4007 if (!hasD32() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
4008 return -1;
4009
4010 Parser.Lex(); // Eat identifier token.
4011
4012 return RegNum;
4013}
4014
4015// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0.
4016// If a recoverable error occurs, return 1. If an irrecoverable error
4017// occurs, return -1. An irrecoverable error is one where tokens have been
4018// consumed in the process of trying to parse the shifter (i.e., when it is
4019// indeed a shifter operand, but malformed).
4020int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
4021 MCAsmParser &Parser = getParser();
4022 SMLoc S = Parser.getTok().getLoc();
4023 const AsmToken &Tok = Parser.getTok();
4024 if (Tok.isNot(AsmToken::Identifier))
4025 return -1;
4026
4027 std::string lowerCase = Tok.getString().lower();
4028 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
4029 .Case("asl", ARM_AM::lsl)
4030 .Case("lsl", ARM_AM::lsl)
4031 .Case("lsr", ARM_AM::lsr)
4032 .Case("asr", ARM_AM::asr)
4033 .Case("ror", ARM_AM::ror)
4034 .Case("rrx", ARM_AM::rrx)
4035 .Default(ARM_AM::no_shift);
4036
4037 if (ShiftTy == ARM_AM::no_shift)
4038 return 1;
4039
4040 Parser.Lex(); // Eat the operator.
4041
4042 // The source register for the shift has already been added to the
4043 // operand list, so we need to pop it off and combine it into the shifted
4044 // register operand instead.
4045 std::unique_ptr<ARMOperand> PrevOp(
4046 (ARMOperand *)Operands.pop_back_val().release());
4047 if (!PrevOp->isReg())
4048 return Error(PrevOp->getStartLoc(), "shift must be of a register");
4049 int SrcReg = PrevOp->getReg();
4050
4051 SMLoc EndLoc;
4052 int64_t Imm = 0;
4053 int ShiftReg = 0;
4054 if (ShiftTy == ARM_AM::rrx) {
4055 // RRX Doesn't have an explicit shift amount. The encoder expects
4056 // the shift register to be the same as the source register. Seems odd,
4057 // but OK.
4058 ShiftReg = SrcReg;
4059 } else {
4060 // Figure out if this is shifted by a constant or a register (for non-RRX).
4061 if (Parser.getTok().is(AsmToken::Hash) ||
4062 Parser.getTok().is(AsmToken::Dollar)) {
4063 Parser.Lex(); // Eat hash.
4064 SMLoc ImmLoc = Parser.getTok().getLoc();
4065 const MCExpr *ShiftExpr = nullptr;
4066 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4067 Error(ImmLoc, "invalid immediate shift value");
4068 return -1;
4069 }
4070 // The expression must be evaluatable as an immediate.
4071 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
4072 if (!CE) {
4073 Error(ImmLoc, "invalid immediate shift value");
4074 return -1;
4075 }
4076 // Range check the immediate.
4077 // lsl, ror: 0 <= imm <= 31
4078 // lsr, asr: 0 <= imm <= 32
4079 Imm = CE->getValue();
4080 if (Imm < 0 ||
4081 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
4082 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
4083 Error(ImmLoc, "immediate shift value out of range");
4084 return -1;
4085 }
4086 // shift by zero is a nop. Always send it through as lsl.
4087 // ('as' compatibility)
4088 if (Imm == 0)
4089 ShiftTy = ARM_AM::lsl;
4090 } else if (Parser.getTok().is(AsmToken::Identifier)) {
4091 SMLoc L = Parser.getTok().getLoc();
4092 EndLoc = Parser.getTok().getEndLoc();
4093 ShiftReg = tryParseRegister();
4094 if (ShiftReg == -1) {
4095 Error(L, "expected immediate or register in shift operand");
4096 return -1;
4097 }
4098 } else {
4099 Error(Parser.getTok().getLoc(),
4100 "expected immediate or register in shift operand");
4101 return -1;
4102 }
4103 }
4104
4105 if (ShiftReg && ShiftTy != ARM_AM::rrx)
4106 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
4107 ShiftReg, Imm,
4108 S, EndLoc));
4109 else
4110 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4111 S, EndLoc));
4112
4113 return 0;
4114}
4115
4116/// Try to parse a register name. The token must be an Identifier when called.
4117/// If it's a register, an AsmOperand is created. Another AsmOperand is created
4118/// if there is a "writeback". 'true' if it's not a register.
4119///
4120/// TODO this is likely to change to allow different register types and or to
4121/// parse for a specific register type.
4122bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) {
4123 MCAsmParser &Parser = getParser();
4124 SMLoc RegStartLoc = Parser.getTok().getLoc();
4125 SMLoc RegEndLoc = Parser.getTok().getEndLoc();
4126 int RegNo = tryParseRegister();
4127 if (RegNo == -1)
4128 return true;
4129
4130 Operands.push_back(ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc));
4131
4132 const AsmToken &ExclaimTok = Parser.getTok();
4133 if (ExclaimTok.is(AsmToken::Exclaim)) {
4134 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
4135 ExclaimTok.getLoc()));
4136 Parser.Lex(); // Eat exclaim token
4137 return false;
4138 }
4139
4140 // Also check for an index operand. This is only legal for vector registers,
4141 // but that'll get caught OK in operand matching, so we don't need to
4142 // explicitly filter everything else out here.
4143 if (Parser.getTok().is(AsmToken::LBrac)) {
4144 SMLoc SIdx = Parser.getTok().getLoc();
4145 Parser.Lex(); // Eat left bracket token.
4146
4147 const MCExpr *ImmVal;
4148 if (getParser().parseExpression(ImmVal))
4149 return true;
4150 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
4151 if (!MCE)
4152 return TokError("immediate value expected for vector index");
4153
4154 if (Parser.getTok().isNot(AsmToken::RBrac))
4155 return Error(Parser.getTok().getLoc(), "']' expected");
4156
4157 SMLoc E = Parser.getTok().getEndLoc();
4158 Parser.Lex(); // Eat right bracket token.
4159
4160 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
4161 SIdx, E,
4162 getContext()));
4163 }
4164
4165 return false;
4166}
4167
4168/// MatchCoprocessorOperandName - Try to parse an coprocessor related
4169/// instruction with a symbolic operand name.
4170/// We accept "crN" syntax for GAS compatibility.
4171/// <operand-name> ::= <prefix><number>
4172/// If CoprocOp is 'c', then:
4173/// <prefix> ::= c | cr
4174/// If CoprocOp is 'p', then :
4175/// <prefix> ::= p
4176/// <number> ::= integer in range [0, 15]
4177static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
4178 // Use the same layout as the tablegen'erated register name matcher. Ugly,
4179 // but efficient.
4180 if (Name.size() < 2 || Name[0] != CoprocOp)
4181 return -1;
4182 Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front();
4183
4184 switch (Name.size()) {
4185 default: return -1;
4186 case 1:
4187 switch (Name[0]) {
4188 default: return -1;
4189 case '0': return 0;
4190 case '1': return 1;
4191 case '2': return 2;
4192 case '3': return 3;
4193 case '4': return 4;
4194 case '5': return 5;
4195 case '6': return 6;
4196 case '7': return 7;
4197 case '8': return 8;
4198 case '9': return 9;
4199 }
4200 case 2:
4201 if (Name[0] != '1')
4202 return -1;
4203 switch (Name[1]) {
4204 default: return -1;
4205 // CP10 and CP11 are VFP/NEON and so vector instructions should be used.
4206 // However, old cores (v5/v6) did use them in that way.
4207 case '0': return 10;
4208 case '1': return 11;
4209 case '2': return 12;
4210 case '3': return 13;
4211 case '4': return 14;
4212 case '5': return 15;
4213 }
4214 }
4215}
4216
4217/// parseITCondCode - Try to parse a condition code for an IT instruction.
4218OperandMatchResultTy
4219ARMAsmParser::parseITCondCode(OperandVector &Operands) {
4220 MCAsmParser &Parser = getParser();
4221 SMLoc S = Parser.getTok().getLoc();
4222 const AsmToken &Tok = Parser.getTok();
4223 if (!Tok.is(AsmToken::Identifier))
4224 return MatchOperand_NoMatch;
4225 unsigned CC = ARMCondCodeFromString(Tok.getString());
4226 if (CC == ~0U)
4227 return MatchOperand_NoMatch;
4228 Parser.Lex(); // Eat the token.
4229
4230 Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
4231
4232 return MatchOperand_Success;
4233}
4234
4235/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
4236/// token must be an Identifier when called, and if it is a coprocessor
4237/// number, the token is eaten and the operand is added to the operand list.
4238OperandMatchResultTy
4239ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
4240 MCAsmParser &Parser = getParser();
4241 SMLoc S = Parser.getTok().getLoc();
4242 const AsmToken &Tok = Parser.getTok();
4243 if (Tok.isNot(AsmToken::Identifier))
4244 return MatchOperand_NoMatch;
4245
4246 int Num = MatchCoprocessorOperandName(Tok.getString().lower(), 'p');
4247 if (Num == -1)
4248 return MatchOperand_NoMatch;
4249 if (!isValidCoprocessorNumber(Num, getSTI().getFeatureBits()))
4250 return MatchOperand_NoMatch;
4251
4252 Parser.Lex(); // Eat identifier token.
4253 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
4254 return MatchOperand_Success;
4255}
4256
4257/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
4258/// token must be an Identifier when called, and if it is a coprocessor
4259/// number, the token is eaten and the operand is added to the operand list.
4260OperandMatchResultTy
4261ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) {
4262 MCAsmParser &Parser = getParser();
4263 SMLoc S = Parser.getTok().getLoc();
4264 const AsmToken &Tok = Parser.getTok();
4265 if (Tok.isNot(AsmToken::Identifier))
4266 return MatchOperand_NoMatch;
4267
4268 int Reg = MatchCoprocessorOperandName(Tok.getString().lower(), 'c');
4269 if (Reg == -1)
4270 return MatchOperand_NoMatch;
4271
4272 Parser.Lex(); // Eat identifier token.
4273 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
4274 return MatchOperand_Success;
4275}
4276
4277/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
4278/// coproc_option : '{' imm0_255 '}'
4279OperandMatchResultTy
4280ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) {
4281 MCAsmParser &Parser = getParser();
4282 SMLoc S = Parser.getTok().getLoc();
4283
4284 // If this isn't a '{', this isn't a coprocessor immediate operand.
4285 if (Parser.getTok().isNot(AsmToken::LCurly))
4286 return MatchOperand_NoMatch;
4287 Parser.Lex(); // Eat the '{'
4288
4289 const MCExpr *Expr;
4290 SMLoc Loc = Parser.getTok().getLoc();
4291 if (getParser().parseExpression(Expr)) {
4292 Error(Loc, "illegal expression");
4293 return MatchOperand_ParseFail;
4294 }
4295 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
4296 if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
4297 Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
4298 return MatchOperand_ParseFail;
4299 }
4300 int Val = CE->getValue();
4301
4302 // Check for and consume the closing '}'
4303 if (Parser.getTok().isNot(AsmToken::RCurly))
4304 return MatchOperand_ParseFail;
4305 SMLoc E = Parser.getTok().getEndLoc();
4306 Parser.Lex(); // Eat the '}'
4307
4308 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
4309 return MatchOperand_Success;
4310}
4311
4312// For register list parsing, we need to map from raw GPR register numbering
4313// to the enumeration values. The enumeration values aren't sorted by
4314// register number due to our using "sp", "lr" and "pc" as canonical names.
4315static unsigned getNextRegister(unsigned Reg) {
4316 // If this is a GPR, we need to do it manually, otherwise we can rely
4317 // on the sort ordering of the enumeration since the other reg-classes
4318 // are sane.
4319 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4320 return Reg + 1;
4321 switch(Reg) {
4322 default: llvm_unreachable("Invalid GPR number!")::llvm::llvm_unreachable_internal("Invalid GPR number!", "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 4322)
;
4323 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2;
4324 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4;
4325 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6;
4326 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8;
4327 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10;
4328 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
4329 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR;
4330 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0;
4331 }
4332}
4333
4334// Insert an <Encoding, Register> pair in an ordered vector. Return true on
4335// success, or false, if duplicate encoding found.
4336static bool
4337insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs,
4338 unsigned Enc, unsigned Reg) {
4339 Regs.emplace_back(Enc, Reg);
4340 for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
4341 if (J->first == Enc) {
4342 Regs.erase(J.base());
4343 return false;
4344 }
4345 if (J->first < Enc)
4346 break;
4347 std::swap(*I, *J);
4348 }
4349 return true;
4350}
4351
4352/// Parse a register list.
4353bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
4354 bool EnforceOrder) {
4355 MCAsmParser &Parser = getParser();
4356 if (Parser.getTok().isNot(AsmToken::LCurly))
4357 return TokError("Token is not a Left Curly Brace");
4358 SMLoc S = Parser.getTok().getLoc();
4359 Parser.Lex(); // Eat '{' token.
4360 SMLoc RegLoc = Parser.getTok().getLoc();
4361
4362 // Check the first register in the list to see what register class
4363 // this is a list of.
4364 int Reg = tryParseRegister();
4365 if (Reg == -1)
4366 return Error(RegLoc, "register expected");
4367
4368 // The reglist instructions have at most 16 registers, so reserve
4369 // space for that many.
4370 int EReg = 0;
4371 SmallVector<std::pair<unsigned, unsigned>, 16> Registers;
4372
4373 // Allow Q regs and just interpret them as the two D sub-registers.
4374 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4375 Reg = getDRegFromQReg(Reg);
4376 EReg = MRI->getEncodingValue(Reg);
4377 Registers.emplace_back(EReg, Reg);
4378 ++Reg;
4379 }
4380 const MCRegisterClass *RC;
4381 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4382 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
4383 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
4384 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
4385 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
4386 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
4387 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
4388 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4389 else
4390 return Error(RegLoc, "invalid register in register list");
4391
4392 // Store the register.
4393 EReg = MRI->getEncodingValue(Reg);
4394 Registers.emplace_back(EReg, Reg);
4395
4396 // This starts immediately after the first register token in the list,
4397 // so we can see either a comma or a minus (range separator) as a legal
4398 // next token.
4399 while (Parser.getTok().is(AsmToken::Comma) ||
4400 Parser.getTok().is(AsmToken::Minus)) {
4401 if (Parser.getTok().is(AsmToken::Minus)) {
4402 Parser.Lex(); // Eat the minus.
4403 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4404 int EndReg = tryParseRegister();
4405 if (EndReg == -1)
4406 return Error(AfterMinusLoc, "register expected");
4407 // Allow Q regs and just interpret them as the two D sub-registers.
4408 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
4409 EndReg = getDRegFromQReg(EndReg) + 1;
4410 // If the register is the same as the start reg, there's nothing
4411 // more to do.
4412 if (Reg == EndReg)
4413 continue;
4414 // The register must be in the same register class as the first.
4415 if (!RC->contains(EndReg))
4416 return Error(AfterMinusLoc, "invalid register in register list");
4417 // Ranges must go from low to high.
4418 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
4419 return Error(AfterMinusLoc, "bad range in register list");
4420
4421 // Add all the registers in the range to the register list.
4422 while (Reg != EndReg) {
4423 Reg = getNextRegister(Reg);
4424 EReg = MRI->getEncodingValue(Reg);
4425 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4426 Warning(AfterMinusLoc, StringRef("duplicated register (") +
4427 ARMInstPrinter::getRegisterName(Reg) +
4428 ") in register list");
4429 }
4430 }
4431 continue;
4432 }
4433 Parser.Lex(); // Eat the comma.
4434 RegLoc = Parser.getTok().getLoc();
4435 int OldReg = Reg;
4436 const AsmToken RegTok = Parser.getTok();
4437 Reg = tryParseRegister();
4438 if (Reg == -1)
4439 return Error(RegLoc, "register expected");
4440 // Allow Q regs and just interpret them as the two D sub-registers.
4441 bool isQReg = false;
4442 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4443 Reg = getDRegFromQReg(Reg);
4444 isQReg = true;
4445 }
4446 if (!RC->contains(Reg) &&
4447 RC->getID() == ARMMCRegisterClasses[ARM::GPRRegClassID].getID() &&
4448 ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg)) {
4449 // switch the register classes, as GPRwithAPSRnospRegClassID is a partial
4450 // subset of GPRRegClassId except it contains APSR as well.
4451 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4452 }
4453 if (Reg == ARM::VPR &&
4454 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4455 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4456 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
4457 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4458 EReg = MRI->getEncodingValue(Reg);
4459 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4460 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4461 ") in register list");
4462 }
4463 continue;
4464 }
4465 // The register must be in the same register class as the first.
4466 if (!RC->contains(Reg))
4467 return Error(RegLoc, "invalid register in register list");
4468 // In most cases, the list must be monotonically increasing. An
4469 // exception is CLRM, which is order-independent anyway, so
4470 // there's no potential for confusion if you write clrm {r2,r1}
4471 // instead of clrm {r1,r2}.
4472 if (EnforceOrder &&
4473 MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) {
4474 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4475 Warning(RegLoc, "register list not in ascending order");
4476 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
4477 return Error(RegLoc, "register list not in ascending order");
4478 }
4479 // VFP register lists must also be contiguous.
4480 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
4481 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
4482 Reg != OldReg + 1)
4483 return Error(RegLoc, "non-contiguous register range");
4484 EReg = MRI->getEncodingValue(Reg);
4485 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4486 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4487 ") in register list");
4488 }
4489 if (isQReg) {
4490 EReg = MRI->getEncodingValue(++Reg);
4491 Registers.emplace_back(EReg, Reg);
4492 }
4493 }
4494
4495 if (Parser.getTok().isNot(AsmToken::RCurly))
4496 return Error(Parser.getTok().getLoc(), "'}' expected");
4497 SMLoc E = Parser.getTok().getEndLoc();
4498 Parser.Lex(); // Eat '}' token.
4499
4500 // Push the register list operand.
4501 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
4502
4503 // The ARM system instruction variants for LDM/STM have a '^' token here.
4504 if (Parser.getTok().is(AsmToken::Caret)) {
4505 Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
4506 Parser.Lex(); // Eat '^' token.
4507 }
4508
4509 return false;
4510}
4511
4512// Helper function to parse the lane index for vector lists.
4513OperandMatchResultTy ARMAsmParser::
4514parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, SMLoc &EndLoc) {
4515 MCAsmParser &Parser = getParser();
4516 Index = 0; // Always return a defined index value.
4517 if (Parser.getTok().is(AsmToken::LBrac)) {
4518 Parser.Lex(); // Eat the '['.
4519 if (Parser.getTok().is(AsmToken::RBrac)) {
4520 // "Dn[]" is the 'all lanes' syntax.
4521 LaneKind = AllLanes;
4522 EndLoc = Parser.getTok().getEndLoc();
4523 Parser.Lex(); // Eat the ']'.
4524 return MatchOperand_Success;
4525 }
4526
4527 // There's an optional '#' token here. Normally there wouldn't be, but
4528 // inline assemble puts one in, and it's friendly to accept that.
4529 if (Parser.getTok().is(AsmToken::Hash))
4530 Parser.Lex(); // Eat '#' or '$'.
4531
4532 const MCExpr *LaneIndex;
4533 SMLoc Loc = Parser.getTok().getLoc();
4534 if (getParser().parseExpression(LaneIndex)) {
4535 Error(Loc, "illegal expression");
4536 return MatchOperand_ParseFail;
4537 }
4538 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
4539 if (!CE) {
4540 Error(Loc, "lane index must be empty or an integer");
4541 return MatchOperand_ParseFail;
4542 }
4543 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4544 Error(Parser.getTok().getLoc(), "']' expected");
4545 return MatchOperand_ParseFail;
4546 }
4547 EndLoc = Parser.getTok().getEndLoc();
4548 Parser.Lex(); // Eat the ']'.
4549 int64_t Val = CE->getValue();
4550
4551 // FIXME: Make this range check context sensitive for .8, .16, .32.
4552 if (Val < 0 || Val > 7) {
4553 Error(Parser.getTok().getLoc(), "lane index out of range");
4554 return MatchOperand_ParseFail;
4555 }
4556 Index = Val;
4557 LaneKind = IndexedLane;
4558 return MatchOperand_Success;
4559 }
4560 LaneKind = NoLanes;
4561 return MatchOperand_Success;
4562}
4563
4564// parse a vector register list
4565OperandMatchResultTy
4566ARMAsmParser::parseVectorList(OperandVector &Operands) {
4567 MCAsmParser &Parser = getParser();
4568 VectorLaneTy LaneKind;
4569 unsigned LaneIndex;
4570 SMLoc S = Parser.getTok().getLoc();
4571 // As an extension (to match gas), support a plain D register or Q register
4572 // (without encosing curly braces) as a single or double entry list,
4573 // respectively.
4574 if (!hasMVE() && Parser.getTok().is(AsmToken::Identifier)) {
4575 SMLoc E = Parser.getTok().getEndLoc();
4576 int Reg = tryParseRegister();
4577 if (Reg == -1)
4578 return MatchOperand_NoMatch;
4579 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
4580 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E);
4581 if (Res != MatchOperand_Success)
4582 return Res;
4583 switch (LaneKind) {
4584 case NoLanes:
4585 Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
4586 break;
4587 case AllLanes:
4588 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
4589 S, E));
4590 break;
4591 case IndexedLane:
4592 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
4593 LaneIndex,
4594 false, S, E));
4595 break;
4596 }
4597 return MatchOperand_Success;
4598 }
4599 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4600 Reg = getDRegFromQReg(Reg);
4601 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E);
4602 if (Res != MatchOperand_Success)
4603 return Res;
4604 switch (LaneKind) {
4605 case NoLanes:
4606 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
4607 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
4608 Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
4609 break;
4610 case AllLanes:
4611 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
4612 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
4613 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
4614 S, E));
4615 break;
4616 case IndexedLane:
4617 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
4618 LaneIndex,
4619 false, S, E));
4620 break;
4621 }
4622 return MatchOperand_Success;
4623 }
4624 Error(S, "vector register expected");
4625 return MatchOperand_ParseFail;
4626 }
4627
4628 if (Parser.getTok().isNot(AsmToken::LCurly))
4629 return MatchOperand_NoMatch;
4630
4631 Parser.Lex(); // Eat '{' token.
4632 SMLoc RegLoc = Parser.getTok().getLoc();
4633
4634 int Reg = tryParseRegister();
4635 if (Reg == -1) {
4636 Error(RegLoc, "register expected");
4637 return MatchOperand_ParseFail;
4638 }
4639 unsigned Count = 1;
4640 int Spacing = 0;
4641 unsigned FirstReg = Reg;
4642
4643 if (hasMVE() && !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg)) {
4644 Error(Parser.getTok().getLoc(), "vector register in range Q0-Q7 expected");
4645 return MatchOperand_ParseFail;
4646 }
4647 // The list is of D registers, but we also allow Q regs and just interpret
4648 // them as the two D sub-registers.
4649 else if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4650 FirstReg = Reg = getDRegFromQReg(Reg);
4651 Spacing = 1; // double-spacing requires explicit D registers, otherwise
4652 // it's ambiguous with four-register single spaced.
4653 ++Reg;
4654 ++Count;
4655 }
4656
4657 SMLoc E;
4658 if (parseVectorLane(LaneKind, LaneIndex, E) != MatchOperand_Success)
4659 return MatchOperand_ParseFail;
4660
4661 while (Parser.getTok().is(AsmToken::Comma) ||
4662 Parser.getTok().is(AsmToken::Minus)) {
4663 if (Parser.getTok().is(AsmToken::Minus)) {
4664 if (!Spacing)
4665 Spacing = 1; // Register range implies a single spaced list.
4666 else if (Spacing == 2) {
4667 Error(Parser.getTok().getLoc(),
4668 "sequential registers in double spaced list");
4669 return MatchOperand_ParseFail;
4670 }
4671 Parser.Lex(); // Eat the minus.
4672 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4673 int EndReg = tryParseRegister();
4674 if (EndReg == -1) {
4675 Error(AfterMinusLoc, "register expected");
4676 return MatchOperand_ParseFail;
4677 }
4678 // Allow Q regs and just interpret them as the two D sub-registers.
4679 if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
4680 EndReg = getDRegFromQReg(EndReg) + 1;
4681 // If the register is the same as the start reg, there's nothing
4682 // more to do.
4683 if (Reg == EndReg)
4684 continue;
4685 // The register must be in the same register class as the first.
4686 if ((hasMVE() &&
4687 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(EndReg)) ||
4688 (!hasMVE() &&
4689 !ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg))) {
4690 Error(AfterMinusLoc, "invalid register in register list");
4691 return MatchOperand_ParseFail;
4692 }
4693 // Ranges must go from low to high.
4694 if (Reg > EndReg) {
4695 Error(AfterMinusLoc, "bad range in register list");
4696 return MatchOperand_ParseFail;
4697 }
4698 // Parse the lane specifier if present.
4699 VectorLaneTy NextLaneKind;
4700 unsigned NextLaneIndex;
4701 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
4702 MatchOperand_Success)
4703 return MatchOperand_ParseFail;
4704 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4705 Error(AfterMinusLoc, "mismatched lane index in register list");
4706 return MatchOperand_ParseFail;
4707 }
4708
4709 // Add all the registers in the range to the register list.
4710 Count += EndReg - Reg;
4711 Reg = EndReg;
4712 continue;
4713 }
4714 Parser.Lex(); // Eat the comma.
4715 RegLoc = Parser.getTok().getLoc();
4716 int OldReg = Reg;
4717 Reg = tryParseRegister();
4718 if (Reg == -1) {
4719 Error(RegLoc, "register expected");
4720 return MatchOperand_ParseFail;
4721 }
4722
4723 if (hasMVE()) {
4724 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg)) {
4725 Error(RegLoc, "vector register in range Q0-Q7 expected");
4726 return MatchOperand_ParseFail;
4727 }
4728 Spacing = 1;
4729 }
4730 // vector register lists must be contiguous.
4731 // It's OK to use the enumeration values directly here rather, as the
4732 // VFP register classes have the enum sorted properly.
4733 //
4734 // The list is of D registers, but we also allow Q regs and just interpret
4735 // them as the two D sub-registers.
4736 else if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4737 if (!Spacing)
4738 Spacing = 1; // Register range implies a single spaced list.
4739 else if (Spacing == 2) {
4740 Error(RegLoc,
4741 "invalid register in double-spaced list (must be 'D' register')");
4742 return MatchOperand_ParseFail;
4743 }
4744 Reg = getDRegFromQReg(Reg);
4745 if (Reg != OldReg + 1) {
4746 Error(RegLoc, "non-contiguous register range");
4747 return MatchOperand_ParseFail;
4748 }
4749 ++Reg;
4750 Count += 2;
4751 // Parse the lane specifier if present.
4752 VectorLaneTy NextLaneKind;
4753 unsigned NextLaneIndex;
4754 SMLoc LaneLoc = Parser.getTok().getLoc();
4755 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
4756 MatchOperand_Success)
4757 return MatchOperand_ParseFail;
4758 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4759 Error(LaneLoc, "mismatched lane index in register list");
4760 return MatchOperand_ParseFail;
4761 }
4762 continue;
4763 }
4764 // Normal D register.
4765 // Figure out the register spacing (single or double) of the list if
4766 // we don't know it already.
4767 if (!Spacing)
4768 Spacing = 1 + (Reg == OldReg + 2);
4769
4770 // Just check that it's contiguous and keep going.
4771 if (Reg != OldReg + Spacing) {
4772 Error(RegLoc, "non-contiguous register range");
4773 return MatchOperand_ParseFail;
4774 }
4775 ++Count;
4776 // Parse the lane specifier if present.
4777 VectorLaneTy NextLaneKind;
4778 unsigned NextLaneIndex;
4779 SMLoc EndLoc = Parser.getTok().getLoc();
4780 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != MatchOperand_Success)
4781 return MatchOperand_ParseFail;
4782 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4783 Error(EndLoc, "mismatched lane index in register list");
4784 return MatchOperand_ParseFail;
4785 }
4786 }
4787
4788 if (Parser.getTok().isNot(AsmToken::RCurly)) {
4789 Error(Parser.getTok().getLoc(), "'}' expected");
4790 return MatchOperand_ParseFail;
4791 }
4792 E = Parser.getTok().getEndLoc();
4793 Parser.Lex(); // Eat '}' token.
4794
4795 switch (LaneKind) {
4796 case NoLanes:
4797 case AllLanes: {
4798 // Two-register operands have been converted to the
4799 // composite register classes.
4800 if (Count == 2 && !hasMVE()) {
4801 const MCRegisterClass *RC = (Spacing == 1) ?
4802 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
4803 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
4804 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
4805 }
4806 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
4807 ARMOperand::CreateVectorListAllLanes);
4808 Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E));
4809 break;
4810 }
4811 case IndexedLane:
4812 Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
4813 LaneIndex,
4814 (Spacing == 2),
4815 S, E));
4816 break;
4817 }
4818 return MatchOperand_Success;
4819}
4820
4821/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
4822OperandMatchResultTy
4823ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
4824 MCAsmParser &Parser = getParser();
4825 SMLoc S = Parser.getTok().getLoc();
4826 const AsmToken &Tok = Parser.getTok();
4827 unsigned Opt;
4828
4829 if (Tok.is(AsmToken::Identifier)) {
4830 StringRef OptStr = Tok.getString();
4831
4832 Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()).lower())
4833 .Case("sy", ARM_MB::SY)
4834 .Case("st", ARM_MB::ST)
4835 .Case("ld", ARM_MB::LD)
4836 .Case("sh", ARM_MB::ISH)
4837 .Case("ish", ARM_MB::ISH)
4838 .Case("shst", ARM_MB::ISHST)
4839 .Case("ishst", ARM_MB::ISHST)
4840 .Case("ishld", ARM_MB::ISHLD)
4841 .Case("nsh", ARM_MB::NSH)
4842 .Case("un", ARM_MB::NSH)
4843 .Case("nshst", ARM_MB::NSHST)
4844 .Case("nshld", ARM_MB::NSHLD)
4845 .Case("unst", ARM_MB::NSHST)
4846 .Case("osh", ARM_MB::OSH)
4847 .Case("oshst", ARM_MB::OSHST)
4848 .Case("oshld", ARM_MB::OSHLD)
4849 .Default(~0U);
4850
4851 // ishld, oshld, nshld and ld are only available from ARMv8.
4852 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD ||
4853 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD))
4854 Opt = ~0U;
4855
4856 if (Opt == ~0U)
4857 return MatchOperand_NoMatch;
4858
4859 Parser.Lex(); // Eat identifier token.
4860 } else if (Tok.is(AsmToken::Hash) ||
4861 Tok.is(AsmToken::Dollar) ||
4862 Tok.is(AsmToken::Integer)) {
4863 if (Parser.getTok().isNot(AsmToken::Integer))
4864 Parser.Lex(); // Eat '#' or '$'.
4865 SMLoc Loc = Parser.getTok().getLoc();
4866
4867 const MCExpr *MemBarrierID;
4868 if (getParser().parseExpression(MemBarrierID)) {
4869 Error(Loc, "illegal expression");
4870 return MatchOperand_ParseFail;
4871 }
4872
4873 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
4874 if (!CE) {
4875 Error(Loc, "constant expression expected");
4876 return MatchOperand_ParseFail;
4877 }
4878
4879 int Val = CE->getValue();
4880 if (Val & ~0xf) {
4881 Error(Loc, "immediate value out of range");
4882 return MatchOperand_ParseFail;
4883 }
4884
4885 Opt = ARM_MB::RESERVED_0 + Val;
4886 } else
4887 return MatchOperand_ParseFail;
4888
4889 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
4890 return MatchOperand_Success;
4891}
4892
4893OperandMatchResultTy
4894ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) {
4895 MCAsmParser &Parser = getParser();
4896 SMLoc S = Parser.getTok().getLoc();
4897 const AsmToken &Tok = Parser.getTok();
4898
4899 if (Tok.isNot(AsmToken::Identifier))
4900 return MatchOperand_NoMatch;
4901
4902 if (!Tok.getString().equals_lower("csync"))
4903 return MatchOperand_NoMatch;
4904
4905 Parser.Lex(); // Eat identifier token.
4906
4907 Operands.push_back(ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S));
4908 return MatchOperand_Success;
4909}
4910
4911/// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
4912OperandMatchResultTy
4913ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
4914 MCAsmParser &Parser = getParser();
4915 SMLoc S = Parser.getTok().getLoc();
4916 const AsmToken &Tok = Parser.getTok();
4917 unsigned Opt;
4918
4919 if (Tok.is(AsmToken::Identifier)) {
4920 StringRef OptStr = Tok.getString();
4921
4922 if (OptStr.equals_lower("sy"))
4923 Opt = ARM_ISB::SY;
4924 else
4925 return MatchOperand_NoMatch;
4926
4927 Parser.Lex(); // Eat identifier token.
4928 } else if (Tok.is(AsmToken::Hash) ||
4929 Tok.is(AsmToken::Dollar) ||
4930 Tok.is(AsmToken::Integer)) {
4931 if (Parser.getTok().isNot(AsmToken::Integer))
4932 Parser.Lex(); // Eat '#' or '$'.
4933 SMLoc Loc = Parser.getTok().getLoc();
4934
4935 const MCExpr *ISBarrierID;
4936 if (getParser().parseExpression(ISBarrierID)) {
4937 Error(Loc, "illegal expression");
4938 return MatchOperand_ParseFail;
4939 }
4940
4941 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID);
4942 if (!CE) {
4943 Error(Loc, "constant expression expected");
4944 return MatchOperand_ParseFail;
4945 }
4946
4947 int Val = CE->getValue();
4948 if (Val & ~0xf) {
4949 Error(Loc, "immediate value out of range");
4950 return MatchOperand_ParseFail;
4951 }
4952
4953 Opt = ARM_ISB::RESERVED_0 + Val;
4954 } else
4955 return MatchOperand_ParseFail;
4956
4957 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
4958 (ARM_ISB::InstSyncBOpt)Opt, S));
4959 return MatchOperand_Success;
4960}
4961
4962
4963/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
4964OperandMatchResultTy
4965ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {
4966 MCAsmParser &Parser = getParser();
4967 SMLoc S = Parser.getTok().getLoc();
4968 const AsmToken &Tok = Parser.getTok();
4969 if (!Tok.is(AsmToken::Identifier))
4970 return MatchOperand_NoMatch;
4971 StringRef IFlagsStr = Tok.getString();
4972
4973 // An iflags string of "none" is interpreted to mean that none of the AIF
4974 // bits are set. Not a terribly useful instruction, but a valid encoding.
4975 unsigned IFlags = 0;
4976 if (IFlagsStr != "none") {
4977 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
4978 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1).lower())
4979 .Case("a", ARM_PROC::A)
4980 .Case("i", ARM_PROC::I)
4981 .Case("f", ARM_PROC::F)
4982 .Default(~0U);
4983
4984 // If some specific iflag is already set, it means that some letter is
4985 // present more than once, this is not acceptable.
4986 if (Flag == ~0U || (IFlags & Flag))
4987 return MatchOperand_NoMatch;
4988
4989 IFlags |= Flag;
4990 }
4991 }
4992
4993 Parser.Lex(); // Eat identifier token.
4994 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
4995 return MatchOperand_Success;
4996}
4997
4998/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
4999OperandMatchResultTy
5000ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {
5001 MCAsmParser &Parser = getParser();
5002 SMLoc S = Parser.getTok().getLoc();
5003 const AsmToken &Tok = Parser.getTok();
5004
5005 if (Tok.is(AsmToken::Integer)) {
5006 int64_t Val = Tok.getIntVal();
5007 if (Val > 255 || Val < 0) {
5008 return MatchOperand_NoMatch;
5009 }
5010 unsigned SYSmvalue = Val & 0xFF;
5011 Parser.Lex();
5012 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
5013 return MatchOperand_Success;
5014 }
5015
5016 if (!Tok.is(AsmToken::Identifier))
5017 return MatchOperand_NoMatch;
5018 StringRef Mask = Tok.getString();
5019
5020 if (isMClass()) {
5021 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower());
5022 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5023 return MatchOperand_NoMatch;
5024
5025 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5026
5027 Parser.Lex(); // Eat identifier token.
5028 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
5029 return MatchOperand_Success;
5030 }
5031
5032 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
5033 size_t Start = 0, Next = Mask.find('_');
5034 StringRef Flags = "";
5035 std::string SpecReg = Mask.slice(Start, Next).lower();
5036 if (Next != StringRef::npos)
5037 Flags = Mask.slice(Next+1, Mask.size());
5038
5039 // FlagsVal contains the complete mask:
5040 // 3-0: Mask
5041 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5042 unsigned FlagsVal = 0;
5043
5044 if (SpecReg == "apsr") {
5045 FlagsVal = StringSwitch<unsigned>(Flags)
5046 .Case("nzcvq", 0x8) // same as CPSR_f
5047 .Case("g", 0x4) // same as CPSR_s
5048 .Case("nzcvqg", 0xc) // same as CPSR_fs
5049 .Default(~0U);
5050
5051 if (FlagsVal == ~0U) {
5052 if (!Flags.empty())
5053 return MatchOperand_NoMatch;
5054 else
5055 FlagsVal = 8; // No flag
5056 }
5057 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
5058 // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
5059 if (Flags == "all" || Flags == "")
5060 Flags = "fc";
5061 for (int i = 0, e = Flags.size(); i != e; ++i) {
5062 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
5063 .Case("c", 1)
5064 .Case("x", 2)
5065 .Case("s", 4)
5066 .Case("f", 8)
5067 .Default(~0U);
5068
5069 // If some specific flag is already set, it means that some letter is
5070 // present more than once, this is not acceptable.
5071 if (Flag == ~0U || (FlagsVal & Flag))
5072 return MatchOperand_NoMatch;
5073 FlagsVal |= Flag;
5074 }
5075 } else // No match for special register.
5076 return MatchOperand_NoMatch;
5077
5078 // Special register without flags is NOT equivalent to "fc" flags.
5079 // NOTE: This is a divergence from gas' behavior. Uncommenting the following
5080 // two lines would enable gas compatibility at the expense of breaking
5081 // round-tripping.
5082 //
5083 // if (!FlagsVal)
5084 // FlagsVal = 0x9;
5085
5086 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5087 if (SpecReg == "spsr")
5088 FlagsVal |= 16;
5089
5090 Parser.Lex(); // Eat identifier token.
5091 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
5092 return MatchOperand_Success;
5093}
5094
5095/// parseBankedRegOperand - Try to parse a banked register (e.g. "lr_irq") for
5096/// use in the MRS/MSR instructions added to support virtualization.
5097OperandMatchResultTy
5098ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
5099 MCAsmParser &Parser = getParser();
5100 SMLoc S = Parser.getTok().getLoc();
5101 const AsmToken &Tok = Parser.getTok();
5102 if (!Tok.is(AsmToken::Identifier))
5103 return MatchOperand_NoMatch;
5104 StringRef RegName = Tok.getString();
5105
5106 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.lower());
5107 if (!TheReg)
5108 return MatchOperand_NoMatch;
5109 unsigned Encoding = TheReg->Encoding;
5110
5111 Parser.Lex(); // Eat identifier token.
5112 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S));
5113 return MatchOperand_Success;
5114}
5115
5116OperandMatchResultTy
5117ARMAsmParser::parsePKHImm(OperandVector &Operands, StringRef Op, int Low,
5118 int High) {
5119 MCAsmParser &Parser = getParser();
5120 const AsmToken &Tok = Parser.getTok();
5121 if (Tok.isNot(AsmToken::Identifier)) {
5122 Error(Parser.getTok().getLoc(), Op + " operand expected.");
5123 return MatchOperand_ParseFail;
5124 }
5125 StringRef ShiftName = Tok.getString();
5126 std::string LowerOp = Op.lower();
5127 std::string UpperOp = Op.upper();
5128 if (ShiftName != LowerOp && ShiftName != UpperOp) {
5129 Error(Parser.getTok().getLoc(), Op + " operand expected.");
5130 return MatchOperand_ParseFail;
5131 }
5132 Parser.Lex(); // Eat shift type token.
5133
5134 // There must be a '#' and a shift amount.
5135 if (Parser.getTok().isNot(AsmToken::Hash) &&
5136 Parser.getTok().isNot(AsmToken::Dollar)) {
5137 Error(Parser.getTok().getLoc(), "'#' expected");
5138 return MatchOperand_ParseFail;
5139 }
5140 Parser.Lex(); // Eat hash token.
5141
5142 const MCExpr *ShiftAmount;
5143 SMLoc Loc = Parser.getTok().getLoc();
5144 SMLoc EndLoc;
5145 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
5146 Error(Loc, "illegal expression");
5147 return MatchOperand_ParseFail;
5148 }
5149 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5150 if (!CE) {
5151 Error(Loc, "constant expression expected");
5152 return MatchOperand_ParseFail;
5153 }
5154 int Val = CE->getValue();
5155 if (Val < Low || Val > High) {
5156 Error(Loc, "immediate value out of range");
5157 return MatchOperand_ParseFail;
5158 }
5159
5160 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc));
5161
5162 return MatchOperand_Success;
5163}
5164
5165OperandMatchResultTy
5166ARMAsmParser::parseSetEndImm(OperandVector &Operands) {
5167 MCAsmParser &Parser = getParser();
5168 const AsmToken &Tok = Parser.getTok();
5169 SMLoc S = Tok.getLoc();
5170 if (Tok.isNot(AsmToken::Identifier)) {
5171 Error(S, "'be' or 'le' operand expected");
5172 return MatchOperand_ParseFail;
5173 }
5174 int Val = StringSwitch<int>(Tok.getString().lower())
5175 .Case("be", 1)
5176 .Case("le", 0)
5177 .Default(-1);
5178 Parser.Lex(); // Eat the token.
5179
5180 if (Val == -1) {
5181 Error(S, "'be' or 'le' operand expected");
5182 return MatchOperand_ParseFail;
5183 }
5184 Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::create(Val,
5185 getContext()),
5186 S, Tok.getEndLoc()));
5187 return MatchOperand_Success;
5188}
5189
5190/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
5191/// instructions. Legal values are:
5192/// lsl #n 'n' in [0,31]
5193/// asr #n 'n' in [1,32]
5194/// n == 32 encoded as n == 0.
5195OperandMatchResultTy
5196ARMAsmParser::parseShifterImm(OperandVector &Operands) {
5197 MCAsmParser &Parser = getParser();
5198 const AsmToken &Tok = Parser.getTok();
5199 SMLoc S = Tok.getLoc();
5200 if (Tok.isNot(AsmToken::Identifier)) {
5201 Error(S, "shift operator 'asr' or 'lsl' expected");
5202 return MatchOperand_ParseFail;
5203 }
5204 StringRef ShiftName = Tok.getString();
5205 bool isASR;
5206 if (ShiftName == "lsl" || ShiftName == "LSL")
5207 isASR = false;
5208 else if (ShiftName == "asr" || ShiftName == "ASR")
5209 isASR = true;
5210 else {
5211 Error(S, "shift operator 'asr' or 'lsl' expected");
5212 return MatchOperand_ParseFail;
5213 }
5214 Parser.Lex(); // Eat the operator.
5215
5216 // A '#' and a shift amount.
5217 if (Parser.getTok().isNot(AsmToken::Hash) &&
5218 Parser.getTok().isNot(AsmToken::Dollar)) {
5219 Error(Parser.getTok().getLoc(), "'#' expected");
5220 return MatchOperand_ParseFail;
5221 }
5222 Parser.Lex(); // Eat hash token.
5223 SMLoc ExLoc = Parser.getTok().getLoc();
5224
5225 const MCExpr *ShiftAmount;
5226 SMLoc EndLoc;
5227 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
5228 Error(ExLoc, "malformed shift expression");
5229 return MatchOperand_ParseFail;
5230 }
5231 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5232 if (!CE) {
5233 Error(ExLoc, "shift amount must be an immediate");
5234 return MatchOperand_ParseFail;
5235 }
5236
5237 int64_t Val = CE->getValue();
5238 if (isASR) {
5239 // Shift amount must be in [1,32]
5240 if (Val < 1 || Val > 32) {
5241 Error(ExLoc, "'asr' shift amount must be in range [1,32]");
5242 return MatchOperand_ParseFail;
5243 }
5244 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
5245 if (isThumb() && Val == 32) {
5246 Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode");
5247 return MatchOperand_ParseFail;
5248 }
5249 if (Val == 32) Val = 0;
5250 } else {
5251 // Shift amount must be in [1,32]
5252 if (Val < 0 || Val > 31) {
5253 Error(ExLoc, "'lsr' shift amount must be in range [0,31]");
5254 return MatchOperand_ParseFail;
5255 }
5256 }
5257
5258 Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc));
5259
5260 return MatchOperand_Success;
5261}
5262
5263/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
5264/// of instructions. Legal values are:
5265/// ror #n 'n' in {0, 8, 16, 24}
5266OperandMatchResultTy
5267ARMAsmParser::parseRotImm(OperandVector &Operands) {
5268 MCAsmParser &Parser = getParser();
5269 const AsmToken &Tok = Parser.getTok();
5270 SMLoc S = Tok.getLoc();
5271 if (Tok.isNot(AsmToken::Identifier))
5272 return MatchOperand_NoMatch;
5273 StringRef ShiftName = Tok.getString();
5274 if (ShiftName != "ror" && ShiftName != "ROR")
5275 return MatchOperand_NoMatch;
5276 Parser.Lex(); // Eat the operator.
5277
5278 // A '#' and a rotate amount.
5279 if (Parser.getTok().isNot(AsmToken::Hash) &&
5280 Parser.getTok().isNot(AsmToken::Dollar)) {
5281 Error(Parser.getTok().getLoc(), "'#' expected");
5282 return MatchOperand_ParseFail;
5283 }
5284 Parser.Lex(); // Eat hash token.
5285 SMLoc ExLoc = Parser.getTok().getLoc();
5286
5287 const MCExpr *ShiftAmount;
5288 SMLoc EndLoc;
5289 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
5290 Error(ExLoc, "malformed rotate expression");
5291 return MatchOperand_ParseFail;
5292 }
5293 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5294 if (!CE) {
5295 Error(ExLoc, "rotate amount must be an immediate");
5296 return MatchOperand_ParseFail;
5297 }
5298
5299 int64_t Val = CE->getValue();
5300 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
5301 // normally, zero is represented in asm by omitting the rotate operand
5302 // entirely.
5303 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
5304 Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24");
5305 return MatchOperand_ParseFail;
5306 }
5307
5308 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc));
5309
5310 return MatchOperand_Success;
5311}
5312
5313OperandMatchResultTy
5314ARMAsmParser::parseModImm(OperandVector &Operands) {
5315 MCAsmParser &Parser = getParser();
5316 MCAsmLexer &Lexer = getLexer();
5317 int64_t Imm1, Imm2;
5318
5319 SMLoc S = Parser.getTok().getLoc();
5320
5321 // 1) A mod_imm operand can appear in the place of a register name:
5322 // add r0, #mod_imm
5323 // add r0, r0, #mod_imm
5324 // to correctly handle the latter, we bail out as soon as we see an
5325 // identifier.
5326 //
5327 // 2) Similarly, we do not want to parse into complex operands:
5328 // mov r0, #mod_imm
5329 // mov r0, :lower16:(_foo)
5330 if (Parser.getTok().is(AsmToken::Identifier) ||
5331 Parser.getTok().is(AsmToken::Colon))
5332 return MatchOperand_NoMatch;
5333
5334 // Hash (dollar) is optional as per the ARMARM
5335 if (Parser.getTok().is(AsmToken::Hash) ||
5336 Parser.getTok().is(AsmToken::Dollar)) {
5337 // Avoid parsing into complex operands (#:)
5338 if (Lexer.peekTok().is(AsmToken::Colon))
5339 return MatchOperand_NoMatch;
5340
5341 // Eat the hash (dollar)
5342 Parser.Lex();
5343 }
5344
5345 SMLoc Sx1, Ex1;
5346 Sx1 = Parser.getTok().getLoc();
5347 const MCExpr *Imm1Exp;
5348 if (getParser().parseExpression(Imm1Exp, Ex1)) {
5349 Error(Sx1, "malformed expression");
5350 return MatchOperand_ParseFail;
5351 }
5352
5353 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
5354
5355 if (CE) {
5356 // Immediate must fit within 32-bits
5357 Imm1 = CE->getValue();
5358 int Enc = ARM_AM::getSOImmVal(Imm1);
5359 if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) {
5360 // We have a match!
5361 Operands.push_back(ARMOperand::CreateModImm((Enc & 0xFF),
5362 (Enc & 0xF00) >> 7,
5363 Sx1, Ex1));
5364 return MatchOperand_Success;
5365 }
5366
5367 // We have parsed an immediate which is not for us, fallback to a plain
5368 // immediate. This can happen for instruction aliases. For an example,
5369 // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
5370 // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
5371 // instruction with a mod_imm operand. The alias is defined such that the
5372 // parser method is shared, that's why we have to do this here.
5373 if (Parser.getTok().is(AsmToken::EndOfStatement)) {
5374 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
5375 return MatchOperand_Success;
5376 }
5377 } else {
5378 // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
5379 // MCFixup). Fallback to a plain immediate.
5380 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
5381 return MatchOperand_Success;
5382 }
5383
5384 // From this point onward, we expect the input to be a (#bits, #rot) pair
5385 if (Parser.getTok().isNot(AsmToken::Comma)) {
5386 Error(Sx1, "expected modified immediate operand: #[0, 255], #even[0-30]");
5387 return MatchOperand_ParseFail;
5388 }
5389
5390 if (Imm1 & ~0xFF) {
5391 Error(Sx1, "immediate operand must a number in the range [0, 255]");
5392 return MatchOperand_ParseFail;
5393 }
5394
5395 // Eat the comma
5396 Parser.Lex();
5397
5398 // Repeat for #rot
5399 SMLoc Sx2, Ex2;
5400 Sx2 = Parser.getTok().getLoc();
5401
5402 // Eat the optional hash (dollar)
5403 if (Parser.getTok().is(AsmToken::Hash) ||
5404 Parser.getTok().is(AsmToken::Dollar))
5405 Parser.Lex();
5406
5407 const MCExpr *Imm2Exp;
5408 if (getParser().parseExpression(Imm2Exp, Ex2)) {
5409 Error(Sx2, "malformed expression");
5410 return MatchOperand_ParseFail;
5411 }
5412
5413 CE = dyn_cast<MCConstantExpr>(Imm2Exp);
5414
5415 if (CE) {
5416 Imm2 = CE->getValue();
5417 if (!(Imm2 & ~0x1E)) {
5418 // We have a match!
5419 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2));
5420 return MatchOperand_Success;
5421 }
5422 Error(Sx2, "immediate operand must an even number in the range [0, 30]");
5423 return MatchOperand_ParseFail;
5424 } else {
5425 Error(Sx2, "constant expression expected");
5426 return MatchOperand_ParseFail;
5427 }
5428}
5429
5430OperandMatchResultTy
5431ARMAsmParser::parseBitfield(OperandVector &Operands) {
5432 MCAsmParser &Parser = getParser();
5433 SMLoc S = Parser.getTok().getLoc();
5434 // The bitfield descriptor is really two operands, the LSB and the width.
5435 if (Parser.getTok().isNot(AsmToken::Hash) &&
5436 Parser.getTok().isNot(AsmToken::Dollar)) {
5437 Error(Parser.getTok().getLoc(), "'#' expected");
5438 return MatchOperand_ParseFail;
5439 }
5440 Parser.Lex(); // Eat hash token.
5441
5442 const MCExpr *LSBExpr;
5443 SMLoc E = Parser.getTok().getLoc();
5444 if (getParser().parseExpression(LSBExpr)) {
5445 Error(E, "malformed immediate expression");
5446 return MatchOperand_ParseFail;
5447 }
5448 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
5449 if (!CE) {
5450 Error(E, "'lsb' operand must be an immediate");
5451 return MatchOperand_ParseFail;
5452 }
5453
5454 int64_t LSB = CE->getValue();
5455 // The LSB must be in the range [0,31]
5456 if (LSB < 0 || LSB > 31) {
5457 Error(E, "'lsb' operand must be in the range [0,31]");
5458 return MatchOperand_ParseFail;
5459 }
5460 E = Parser.getTok().getLoc();
5461
5462 // Expect another immediate operand.
5463 if (Parser.getTok().isNot(AsmToken::Comma)) {
5464 Error(Parser.getTok().getLoc(), "too few operands");
5465 return MatchOperand_ParseFail;
5466 }
5467 Parser.Lex(); // Eat hash token.
5468 if (Parser.getTok().isNot(AsmToken::Hash) &&
5469 Parser.getTok().isNot(AsmToken::Dollar)) {
5470 Error(Parser.getTok().getLoc(), "'#' expected");
5471 return MatchOperand_ParseFail;
5472 }
5473 Parser.Lex(); // Eat hash token.
5474
5475 const MCExpr *WidthExpr;
5476 SMLoc EndLoc;
5477 if (getParser().parseExpression(WidthExpr, EndLoc)) {
5478 Error(E, "malformed immediate expression");
5479 return MatchOperand_ParseFail;
5480 }
5481 CE = dyn_cast<MCConstantExpr>(WidthExpr);
5482 if (!CE) {
5483 Error(E, "'width' operand must be an immediate");
5484 return MatchOperand_ParseFail;
5485 }
5486
5487 int64_t Width = CE->getValue();
5488 // The LSB must be in the range [1,32-lsb]
5489 if (Width < 1 || Width > 32 - LSB) {
5490 Error(E, "'width' operand must be in the range [1,32-lsb]");
5491 return MatchOperand_ParseFail;
5492 }
5493
5494 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc));
5495
5496 return MatchOperand_Success;
5497}
5498
5499OperandMatchResultTy
5500ARMAsmParser::parsePostIdxReg(OperandVector &Operands) {
5501 // Check for a post-index addressing register operand. Specifically:
5502 // postidx_reg := '+' register {, shift}
5503 // | '-' register {, shift}
5504 // | register {, shift}
5505
5506 // This method must return MatchOperand_NoMatch without consuming any tokens
5507 // in the case where there is no match, as other alternatives take other
5508 // parse methods.
5509 MCAsmParser &Parser = getParser();
5510 AsmToken Tok = Parser.getTok();
5511 SMLoc S = Tok.getLoc();
5512 bool haveEaten = false;
5513 bool isAdd = true;
5514 if (Tok.is(AsmToken::Plus)) {
5515 Parser.Lex(); // Eat the '+' token.
5516 haveEaten = true;
5517 } else if (Tok.is(AsmToken::Minus)) {
5518 Parser.Lex(); // Eat the '-' token.
5519 isAdd = false;
5520 haveEaten = true;
5521 }
5522
5523 SMLoc E = Parser.getTok().getEndLoc();
5524 int Reg = tryParseRegister();
5525 if (Reg == -1) {
5526 if (!haveEaten)
5527 return MatchOperand_NoMatch;
5528 Error(Parser.getTok().getLoc(), "register expected");
5529 return MatchOperand_ParseFail;
5530 }
5531
5532 ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
5533 unsigned ShiftImm = 0;
5534 if (Parser.getTok().is(AsmToken::Comma)) {
5535 Parser.Lex(); // Eat the ','.
5536 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5537 return MatchOperand_ParseFail;
5538
5539 // FIXME: Only approximates end...may include intervening whitespace.
5540 E = Parser.getTok().getLoc();
5541 }
5542
5543 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
5544 ShiftImm, S, E));
5545
5546 return MatchOperand_Success;
5547}
5548
5549OperandMatchResultTy
5550ARMAsmParser::parseAM3Offset(OperandVector &Operands) {
5551 // Check for a post-index addressing register operand. Specifically:
5552 // am3offset := '+' register
5553 // | '-' register
5554 // | register
5555 // | # imm
5556 // | # + imm
5557 // | # - imm
5558
5559 // This method must return MatchOperand_NoMatch without consuming any tokens
5560 // in the case where there is no match, as other alternatives take other
5561 // parse methods.
5562 MCAsmParser &Parser = getParser();
5563 AsmToken Tok = Parser.getTok();
5564 SMLoc S = Tok.getLoc();
5565
5566 // Do immediates first, as we always parse those if we have a '#'.
5567 if (Parser.getTok().is(AsmToken::Hash) ||
5568 Parser.getTok().is(AsmToken::Dollar)) {
5569 Parser.Lex(); // Eat '#' or '$'.
5570 // Explicitly look for a '-', as we need to encode negative zero
5571 // differently.
5572 bool isNegative = Parser.getTok().is(AsmToken::Minus);
5573 const MCExpr *Offset;
5574 SMLoc E;
5575 if (getParser().parseExpression(Offset, E))
5576 return MatchOperand_ParseFail;
5577 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
5578 if (!CE) {
5579 Error(S, "constant expression expected");
5580 return MatchOperand_ParseFail;
5581 }
5582 // Negative zero is encoded as the flag value
5583 // std::numeric_limits<int32_t>::min().
5584 int32_t Val = CE->getValue();
5585 if (isNegative && Val == 0)
5586 Val = std::numeric_limits<int32_t>::min();
5587
5588 Operands.push_back(
5589 ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S, E));
5590
5591 return MatchOperand_Success;
5592 }
5593
5594 bool haveEaten = false;
5595 bool isAdd = true;
5596 if (Tok.is(AsmToken::Plus)) {
5597 Parser.Lex(); // Eat the '+' token.
5598 haveEaten = true;
5599 } else if (Tok.is(AsmToken::Minus)) {
5600 Parser.Lex(); // Eat the '-' token.
5601 isAdd = false;
5602 haveEaten = true;
5603 }
5604
5605 Tok = Parser.getTok();
5606 int Reg = tryParseRegister();
5607 if (Reg == -1) {
5608 if (!haveEaten)
5609 return MatchOperand_NoMatch;
5610 Error(Tok.getLoc(), "register expected");
5611 return MatchOperand_ParseFail;
5612 }
5613
5614 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
5615 0, S, Tok.getEndLoc()));
5616
5617 return MatchOperand_Success;
5618}
5619
5620/// Convert parsed operands to MCInst. Needed here because this instruction
5621/// only has two register operands, but multiplication is commutative so
5622/// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN".
5623void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5624 const OperandVector &Operands) {
5625 ((ARMOperand &)*Operands[3]).addRegOperands(Inst, 1);
5626 ((ARMOperand &)*Operands[1]).addCCOutOperands(Inst, 1);
5627 // If we have a three-operand form, make sure to set Rn to be the operand
5628 // that isn't the same as Rd.
5629 unsigned RegOp = 4;
5630 if (Operands.size() == 6 &&
5631 ((ARMOperand &)*Operands[4]).getReg() ==
5632 ((ARMOperand &)*Operands[3]).getReg())
5633 RegOp = 5;
5634 ((ARMOperand &)*Operands[RegOp]).addRegOperands(Inst, 1);
5635 Inst.addOperand(Inst.getOperand(0));
5636 ((ARMOperand &)*Operands[2]).addCondCodeOperands(Inst, 2);
5637}
5638
5639void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5640 const OperandVector &Operands) {
5641 int CondOp = -1, ImmOp = -1;
5642 switch(Inst.getOpcode()) {
5643 case ARM::tB:
5644 case ARM::tBcc: CondOp = 1; ImmOp = 2; break;
5645
5646 case ARM::t2B:
5647 case ARM::t2Bcc: CondOp = 1; ImmOp = 3; break;
5648
5649 default: llvm_unreachable("Unexpected instruction in cvtThumbBranches")::llvm::llvm_unreachable_internal("Unexpected instruction in cvtThumbBranches"
, "/build/llvm-toolchain-snapshot-13~++20210405022414+5f57793c4fe4/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 5649)
;
5650 }
5651 // first decide whether or not the branch should be conditional
5652 // by looking at it's location relative to an IT block
5653 if(inITBlock()) {
5654 // inside an IT block we cannot have any conditional branches. any
5655 // such instructions needs to be converted to unconditional form
5656 switch(Inst.getOpcode()) {