Bug Summary

File:lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Warning:line 338, 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-config-compatibility-mode=true -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 -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn349319/build-llvm/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-8~svn349319/lib/Target/ARM/AsmParser -I /build/llvm-toolchain-snapshot-8~svn349319/lib/Target/ARM -I /build/llvm-toolchain-snapshot-8~svn349319/build-llvm/lib/Target/ARM -I /build/llvm-toolchain-snapshot-8~svn349319/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn349319/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/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.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++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn349319/build-llvm/lib/Target/ARM/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-8~svn349319=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-12-17-043027-19008-1 -x c++ /build/llvm-toolchain-snapshot-8~svn349319/lib/Target/ARM/AsmParser/ARMAsmParser.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn349319/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

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