Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ARMAsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-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~++20200112100611+7fa5290d5bd/build-llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/include -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/build-llvm/lib/Target/ARM/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd=. -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-2020-01-13-084841-49055-1 -x c++ /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 282, __PRETTY_FUNCTION__))
;
8
'?' condition is true
283 assert(ITState.CurPosition > 1)((ITState.CurPosition > 1) ? static_cast<void> (0) :
__assert_fail ("ITState.CurPosition > 1", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp"
, 283, __PRETTY_FUNCTION__))
;
9
Assuming field 'CurPosition' is > 1
10
'?' condition is true
284 ITState.CurPosition--;
285 unsigned TZ = countTrailingZeros(ITState.Mask);
11
Calling 'countTrailingZeros<unsigned int>'
18
Returning from 'countTrailingZeros<unsigned int>'
19
'TZ' initialized to 32
286 unsigned NewMask = 0;
287 NewMask |= ITState.Mask & (0xC << TZ);
20
The result of the left shift is undefined due to shifting by '32', which is greater or equal to the width of type 'int'
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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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~++20200112100611+7fa5290d5bd/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");