Bug Summary

File:llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Warning:line 11105, column 14
Called C++ object pointer is null

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 -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/build-llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/build-llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/build-llvm/include -I /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/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-10/lib/clang/10.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-10~+201911111502510600c19528f1809/build-llvm/lib/Target/ARM/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809=. -ferror-limit 19 -fmessage-length 0 -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-2019-12-11-181444-25759-1 -x c++ /build/llvm-toolchain-snapshot-10~+201911111502510600c19528f1809/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

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