Bug Summary

File:llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Warning:line 395, 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 -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 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.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-11~++20200309111110+2c36c23f347/build-llvm/lib/Target/ARM/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

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