LLVM 24.0.0git
ARMAsmParser.cpp
Go to the documentation of this file.
1//===- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ARMBaseInstrInfo.h"
10#include "ARMFeatures.h"
17#include "Utils/ARMBaseInfo.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/SmallSet.h"
24#include "llvm/ADT/StringMap.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/ADT/StringSet.h"
28#include "llvm/ADT/Twine.h"
29#include "llvm/MC/MCContext.h"
30#include "llvm/MC/MCExpr.h"
31#include "llvm/MC/MCInst.h"
32#include "llvm/MC/MCInstrDesc.h"
33#include "llvm/MC/MCInstrInfo.h"
41#include "llvm/MC/MCSection.h"
42#include "llvm/MC/MCStreamer.h"
44#include "llvm/MC/MCSymbol.h"
51#include "llvm/Support/Debug.h"
54#include "llvm/Support/SMLoc.h"
58#include <algorithm>
59#include <cassert>
60#include <cstddef>
61#include <cstdint>
62#include <iterator>
63#include <limits>
64#include <memory>
65#include <optional>
66#include <string>
67#include <utility>
68#include <vector>
69
70#define DEBUG_TYPE "asm-parser"
71
72using namespace llvm;
73
74namespace {
75class ARMOperand;
76
77enum class ImplicitItModeTy { Always, Never, ARMOnly, ThumbOnly };
78
79static cl::opt<ImplicitItModeTy> ImplicitItMode(
80 "arm-implicit-it", cl::init(ImplicitItModeTy::ARMOnly),
81 cl::desc("Allow conditional instructions outside of an IT block"),
82 cl::values(clEnumValN(ImplicitItModeTy::Always, "always",
83 "Accept in both ISAs, emit implicit ITs in Thumb"),
84 clEnumValN(ImplicitItModeTy::Never, "never",
85 "Warn in ARM, reject in Thumb"),
86 clEnumValN(ImplicitItModeTy::ARMOnly, "arm",
87 "Accept in ARM, reject in Thumb"),
88 clEnumValN(ImplicitItModeTy::ThumbOnly, "thumb",
89 "Warn in ARM, emit implicit ITs in Thumb")));
90
91static cl::opt<bool> AddBuildAttributes("arm-add-build-attributes",
92 cl::init(false));
93
94enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
95
96static inline unsigned extractITMaskBit(unsigned Mask, unsigned Position) {
97 // Position==0 means we're not in an IT block at all. Position==1
98 // means we want the first state bit, which is always 0 (Then).
99 // Position==2 means we want the second state bit, stored at bit 3
100 // of Mask, and so on downwards. So (5 - Position) will shift the
101 // right bit down to bit 0, including the always-0 bit at bit 4 for
102 // the mandatory initial Then.
103 return (Mask >> (5 - Position) & 1);
104}
105
106class UnwindContext {
107 using Locs = SmallVector<SMLoc, 4>;
108
109 MCAsmParser &Parser;
110 Locs FnStartLocs;
111 Locs CantUnwindLocs;
112 Locs PersonalityLocs;
113 Locs PersonalityIndexLocs;
114 Locs HandlerDataLocs;
116
117public:
118 UnwindContext(MCAsmParser &P) : Parser(P), FPReg(ARM::SP) {}
119
120 bool hasFnStart() const { return !FnStartLocs.empty(); }
121 bool cantUnwind() const { return !CantUnwindLocs.empty(); }
122 bool hasHandlerData() const { return !HandlerDataLocs.empty(); }
123
124 bool hasPersonality() const {
125 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
126 }
127
128 void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); }
129 void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); }
130 void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); }
131 void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); }
132 void recordPersonalityIndex(SMLoc L) { PersonalityIndexLocs.push_back(L); }
133
134 void saveFPReg(MCRegister Reg) { FPReg = Reg; }
135 MCRegister getFPReg() const { return FPReg; }
136
137 void emitFnStartLocNotes() const {
138 for (SMLoc Loc : FnStartLocs)
139 Parser.Note(Loc, ".fnstart was specified here");
140 }
141
142 void emitCantUnwindLocNotes() const {
143 for (SMLoc Loc : CantUnwindLocs)
144 Parser.Note(Loc, ".cantunwind was specified here");
145 }
146
147 void emitHandlerDataLocNotes() const {
148 for (SMLoc Loc : HandlerDataLocs)
149 Parser.Note(Loc, ".handlerdata was specified here");
150 }
151
152 void emitPersonalityLocNotes() const {
153 for (Locs::const_iterator PI = PersonalityLocs.begin(),
154 PE = PersonalityLocs.end(),
155 PII = PersonalityIndexLocs.begin(),
156 PIE = PersonalityIndexLocs.end();
157 PI != PE || PII != PIE;) {
158 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
159 Parser.Note(*PI++, ".personality was specified here");
160 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
161 Parser.Note(*PII++, ".personalityindex was specified here");
162 else
163 llvm_unreachable(".personality and .personalityindex cannot be "
164 "at the same location");
165 }
166 }
167
168 void reset() {
169 FnStartLocs = Locs();
170 CantUnwindLocs = Locs();
171 PersonalityLocs = Locs();
172 HandlerDataLocs = Locs();
173 PersonalityIndexLocs = Locs();
174 FPReg = ARM::SP;
175 }
176};
177
178// Various sets of ARM instruction mnemonics which are used by the asm parser
179class ARMMnemonicSets {
180 StringSet<> CDE;
181 StringSet<> CDEWithVPTSuffix;
182public:
183 ARMMnemonicSets(const MCSubtargetInfo &STI);
184
185 /// Returns true iff a given mnemonic is a CDE instruction
186 bool isCDEInstr(StringRef Mnemonic) {
187 // Quick check before searching the set
188 if (!Mnemonic.starts_with("cx") && !Mnemonic.starts_with("vcx"))
189 return false;
190 return CDE.count(Mnemonic);
191 }
192
193 /// Returns true iff a given mnemonic is a VPT-predicable CDE instruction
194 /// (possibly with a predication suffix "e" or "t")
195 bool isVPTPredicableCDEInstr(StringRef Mnemonic) {
196 if (!Mnemonic.starts_with("vcx"))
197 return false;
198 return CDEWithVPTSuffix.count(Mnemonic);
199 }
200
201 /// Returns true iff a given mnemonic is an IT-predicable CDE instruction
202 /// (possibly with a condition suffix)
203 bool isITPredicableCDEInstr(StringRef Mnemonic) {
204 if (!Mnemonic.starts_with("cx"))
205 return false;
206 return Mnemonic.starts_with("cx1a") || Mnemonic.starts_with("cx1da") ||
207 Mnemonic.starts_with("cx2a") || Mnemonic.starts_with("cx2da") ||
208 Mnemonic.starts_with("cx3a") || Mnemonic.starts_with("cx3da");
209 }
210
211 /// Return true iff a given mnemonic is an integer CDE instruction with
212 /// dual-register destination
213 bool isCDEDualRegInstr(StringRef Mnemonic) {
214 if (!Mnemonic.starts_with("cx"))
215 return false;
216 return Mnemonic == "cx1d" || Mnemonic == "cx1da" ||
217 Mnemonic == "cx2d" || Mnemonic == "cx2da" ||
218 Mnemonic == "cx3d" || Mnemonic == "cx3da";
219 }
220};
221
222ARMMnemonicSets::ARMMnemonicSets(const MCSubtargetInfo &STI) {
223 for (StringRef Mnemonic: { "cx1", "cx1a", "cx1d", "cx1da",
224 "cx2", "cx2a", "cx2d", "cx2da",
225 "cx3", "cx3a", "cx3d", "cx3da", })
226 CDE.insert(Mnemonic);
227 for (StringRef Mnemonic :
228 {"vcx1", "vcx1a", "vcx2", "vcx2a", "vcx3", "vcx3a"}) {
229 CDE.insert(Mnemonic);
230 CDEWithVPTSuffix.insert(Mnemonic);
231 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "t");
232 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "e");
233 }
234}
235
236class ARMAsmParser : public MCTargetAsmParser {
237 const MCRegisterInfo *MRI;
238 UnwindContext UC;
239 ARMMnemonicSets MS;
240
241 ARMTargetStreamer &getTargetStreamer() {
242 assert(getParser().getStreamer().getTargetStreamer() &&
243 "do not have a target streamer");
244 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
245 return static_cast<ARMTargetStreamer &>(TS);
246 }
247
248 // Map of register aliases registers via the .req directive.
249 StringMap<MCRegister> RegisterReqs;
250
251 bool NextSymbolIsThumb;
252
253 bool useImplicitITThumb() const {
254 return ImplicitItMode == ImplicitItModeTy::Always ||
255 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
256 }
257
258 bool useImplicitITARM() const {
259 return ImplicitItMode == ImplicitItModeTy::Always ||
260 ImplicitItMode == ImplicitItModeTy::ARMOnly;
261 }
262
263 struct {
264 ARMCC::CondCodes Cond; // Condition for IT block.
265 unsigned Mask:4; // Condition mask for instructions.
266 // Starting at first 1 (from lsb).
267 // '1' condition as indicated in IT.
268 // '0' inverse of condition (else).
269 // Count of instructions in IT block is
270 // 4 - trailingzeroes(mask)
271 // Note that this does not have the same encoding
272 // as in the IT instruction, which also depends
273 // on the low bit of the condition code.
274
275 unsigned CurPosition; // Current position in parsing of IT
276 // block. In range [0,4], with 0 being the IT
277 // instruction itself. Initialized according to
278 // count of instructions in block. ~0U if no
279 // active IT block.
280
281 bool IsExplicit; // true - The IT instruction was present in the
282 // input, we should not modify it.
283 // false - The IT instruction was added
284 // implicitly, we can extend it if that
285 // would be legal.
286 } ITState;
287
288 SmallVector<MCInst, 4> PendingConditionalInsts;
289
290 void onEndOfFile() override {
291 flushPendingInstructions(getParser().getStreamer());
292 }
293
294 void flushPendingInstructions(MCStreamer &Out) override {
295 if (!inImplicitITBlock()) {
296 assert(PendingConditionalInsts.size() == 0);
297 return;
298 }
299
300 // Emit the IT instruction
301 MCInst ITInst;
302 ITInst.setOpcode(ARM::t2IT);
303 ITInst.addOperand(MCOperand::createImm(ITState.Cond));
304 ITInst.addOperand(MCOperand::createImm(ITState.Mask));
305 Out.emitInstruction(ITInst, getSTI());
306
307 // Emit the conditional instructions
308 assert(PendingConditionalInsts.size() <= 4);
309 for (const MCInst &Inst : PendingConditionalInsts) {
310 Out.emitInstruction(Inst, getSTI());
311 }
312 PendingConditionalInsts.clear();
313
314 // Clear the IT state
315 ITState.Mask = 0;
316 ITState.CurPosition = ~0U;
317 }
318
319 bool inITBlock() { return ITState.CurPosition != ~0U; }
320 bool inExplicitITBlock() { return inITBlock() && ITState.IsExplicit; }
321 bool inImplicitITBlock() { return inITBlock() && !ITState.IsExplicit; }
322
323 bool lastInITBlock() {
324 return ITState.CurPosition == 4 - (unsigned)llvm::countr_zero(ITState.Mask);
325 }
326
327 void forwardITPosition() {
328 if (!inITBlock()) return;
329 // Move to the next instruction in the IT block, if there is one. If not,
330 // mark the block as done, except for implicit IT blocks, which we leave
331 // open until we find an instruction that can't be added to it.
332 unsigned TZ = llvm::countr_zero(ITState.Mask);
333 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
334 ITState.CurPosition = ~0U; // Done with the IT block after this.
335 }
336
337 // Rewind the state of the current IT block, removing the last slot from it.
338 void rewindImplicitITPosition() {
339 assert(inImplicitITBlock());
340 assert(ITState.CurPosition > 1);
341 ITState.CurPosition--;
342 unsigned TZ = llvm::countr_zero(ITState.Mask);
343 unsigned NewMask = 0;
344 NewMask |= ITState.Mask & (0xC << TZ);
345 NewMask |= 0x2 << TZ;
346 ITState.Mask = NewMask;
347 }
348
349 // Rewind the state of the current IT block, removing the last slot from it.
350 // If we were at the first slot, this closes the IT block.
351 void discardImplicitITBlock() {
352 assert(inImplicitITBlock());
353 assert(ITState.CurPosition == 1);
354 ITState.CurPosition = ~0U;
355 }
356
357 // Get the condition code corresponding to the current IT block slot.
358 ARMCC::CondCodes currentITCond() {
359 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
360 return MaskBit ? ARMCC::getOppositeCondition(ITState.Cond) : ITState.Cond;
361 }
362
363 // Invert the condition of the current IT block slot without changing any
364 // other slots in the same block.
365 void invertCurrentITCondition() {
366 if (ITState.CurPosition == 1) {
367 ITState.Cond = ARMCC::getOppositeCondition(ITState.Cond);
368 } else {
369 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
370 }
371 }
372
373 // Returns true if the current IT block is full (all 4 slots used).
374 bool isITBlockFull() {
375 return inITBlock() && (ITState.Mask & 1);
376 }
377
378 // Extend the current implicit IT block to have one more slot with the given
379 // condition code.
380 void extendImplicitITBlock(ARMCC::CondCodes Cond) {
381 assert(inImplicitITBlock());
382 assert(!isITBlockFull());
383 assert(Cond == ITState.Cond ||
384 Cond == ARMCC::getOppositeCondition(ITState.Cond));
385 unsigned TZ = llvm::countr_zero(ITState.Mask);
386 unsigned NewMask = 0;
387 // Keep any existing condition bits.
388 NewMask |= ITState.Mask & (0xE << TZ);
389 // Insert the new condition bit.
390 NewMask |= (Cond != ITState.Cond) << TZ;
391 // Move the trailing 1 down one bit.
392 NewMask |= 1 << (TZ - 1);
393 ITState.Mask = NewMask;
394 }
395
396 // Create a new implicit IT block with a dummy condition code.
397 void startImplicitITBlock() {
398 assert(!inITBlock());
399 ITState.Cond = ARMCC::AL;
400 ITState.Mask = 8;
401 ITState.CurPosition = 1;
402 ITState.IsExplicit = false;
403 }
404
405 // Create a new explicit IT block with the given condition and mask.
406 // The mask should be in the format used in ARMOperand and
407 // MCOperand, with a 1 implying 'e', regardless of the low bit of
408 // the condition.
409 void startExplicitITBlock(ARMCC::CondCodes Cond, unsigned Mask) {
410 assert(!inITBlock());
411 ITState.Cond = Cond;
412 ITState.Mask = Mask;
413 ITState.CurPosition = 0;
414 ITState.IsExplicit = true;
415 }
416
417 struct {
418 unsigned Mask : 4;
419 unsigned CurPosition;
420 } VPTState;
421 bool inVPTBlock() { return VPTState.CurPosition != ~0U; }
422 void forwardVPTPosition() {
423 if (!inVPTBlock()) return;
424 unsigned TZ = llvm::countr_zero(VPTState.Mask);
425 if (++VPTState.CurPosition == 5 - TZ)
426 VPTState.CurPosition = ~0U;
427 }
428
429 void Note(SMLoc L, const Twine &Msg, SMRange Range = {}) {
430 return getParser().Note(L, Msg, Range);
431 }
432
433 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = {}) {
434 return getParser().Warning(L, Msg, Range);
435 }
436
437 bool Error(SMLoc L, const Twine &Msg, SMRange Range = {}) {
438 return getParser().Error(L, Msg, Range);
439 }
440
441 bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
442 unsigned MnemonicOpsEndInd, unsigned ListIndex,
443 bool IsARPop = false);
444 bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands,
445 unsigned MnemonicOpsEndInd, unsigned ListIndex);
446
447 MCRegister tryParseRegister(bool AllowOutofBoundReg = false);
448 bool tryParseRegisterWithWriteBack(OperandVector &);
449 int tryParseShiftRegister(OperandVector &);
450 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
451 bool parseRegisterList(OperandVector &, bool EnforceOrder = true,
452 bool AllowRAAC = false, bool IsLazyLoadStore = false,
453 bool IsVSCCLRM = false);
454 bool parseMemory(OperandVector &);
455 bool parseOperand(OperandVector &, StringRef Mnemonic);
456 bool parseImmExpr(int64_t &Out);
457 bool parsePrefix(ARM::Specifier &);
458 bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
459 unsigned &ShiftAmount);
460 bool parseLiteralValues(unsigned Size, SMLoc L);
461 bool parseDirectiveThumb(SMLoc L);
462 bool parseDirectiveARM(SMLoc L);
463 bool parseDirectiveThumbFunc(SMLoc L);
464 bool parseDirectiveCode(SMLoc L);
465 bool parseDirectiveSyntax(SMLoc L);
466 bool parseDirectiveReq(StringRef Name, SMLoc L);
467 bool parseDirectiveUnreq(SMLoc L);
468 bool parseDirectiveArch(SMLoc L);
469 bool parseDirectiveEabiAttr(SMLoc L);
470 bool parseDirectiveCPU(SMLoc L);
471 bool parseDirectiveFPU(SMLoc L);
472 bool parseDirectiveFnStart(SMLoc L);
473 bool parseDirectiveFnEnd(SMLoc L);
474 bool parseDirectiveCantUnwind(SMLoc L);
475 bool parseDirectivePersonality(SMLoc L);
476 bool parseDirectiveHandlerData(SMLoc L);
477 bool parseDirectiveSetFP(SMLoc L);
478 bool parseDirectivePad(SMLoc L);
479 bool parseDirectiveRegSave(SMLoc L, bool IsVector);
480 bool parseDirectiveInst(SMLoc L, char Suffix = '\0');
481 bool parseDirectiveLtorg(SMLoc L);
482 bool parseDirectiveEven(SMLoc L);
483 bool parseDirectivePersonalityIndex(SMLoc L);
484 bool parseDirectiveUnwindRaw(SMLoc L);
485 bool parseDirectiveTLSDescSeq(SMLoc L);
486 bool parseDirectiveMovSP(SMLoc L);
487 bool parseDirectiveObjectArch(SMLoc L);
488 bool parseDirectiveArchExtension(SMLoc L);
489 bool parseDirectiveAlign(SMLoc L);
490 bool parseDirectiveThumbSet(SMLoc L);
491
492 bool parseDirectiveSEHAllocStack(SMLoc L, bool Wide);
493 bool parseDirectiveSEHSaveRegs(SMLoc L, bool Wide);
494 bool parseDirectiveSEHSaveSP(SMLoc L);
495 bool parseDirectiveSEHSaveFRegs(SMLoc L);
496 bool parseDirectiveSEHSaveLR(SMLoc L);
497 bool parseDirectiveSEHPrologEnd(SMLoc L, bool Fragment);
498 bool parseDirectiveSEHNop(SMLoc L, bool Wide);
499 bool parseDirectiveSEHEpilogStart(SMLoc L, bool Condition);
500 bool parseDirectiveSEHEpilogEnd(SMLoc L);
501 bool parseDirectiveSEHCustom(SMLoc L);
502
503 std::unique_ptr<ARMOperand> defaultCondCodeOp();
504 std::unique_ptr<ARMOperand> defaultCCOutOp();
505 std::unique_ptr<ARMOperand> defaultVPTPredOp();
506
507 bool isMnemonicVPTPredicable(StringRef Mnemonic, StringRef ExtraToken);
508 StringRef splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
509 ARMCC::CondCodes &PredicationCode,
510 ARMVCC::VPTCodes &VPTPredicationCode,
511 bool &CarrySetting, unsigned &ProcessorIMod,
512 StringRef &ITMask);
513 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef ExtraToken,
514 StringRef FullInst, bool &CanAcceptCarrySet,
515 bool &CanAcceptPredicationCode,
516 bool &CanAcceptVPTPredicationCode);
517 bool enableArchExtFeature(StringRef Name, SMLoc &ExtLoc);
518
519 void tryConvertingToTwoOperandForm(StringRef Mnemonic,
520 ARMCC::CondCodes PredicationCode,
521 bool CarrySetting, OperandVector &Operands,
522 unsigned MnemonicOpsEndInd);
523
524 bool CDEConvertDualRegOperand(StringRef Mnemonic, OperandVector &Operands,
525 unsigned MnemonicOpsEndInd);
526
527 bool isThumb() const {
528 // FIXME: Can tablegen auto-generate this?
529 return getSTI().hasFeature(ARM::ModeThumb);
530 }
531
532 bool isThumbOne() const {
533 return isThumb() && !getSTI().hasFeature(ARM::FeatureThumb2);
534 }
535
536 bool isThumbTwo() const {
537 return isThumb() && getSTI().hasFeature(ARM::FeatureThumb2);
538 }
539
540 bool hasThumb() const {
541 return getSTI().hasFeature(ARM::HasV4TOps);
542 }
543
544 bool hasThumb2() const {
545 return getSTI().hasFeature(ARM::FeatureThumb2);
546 }
547
548 bool hasV6Ops() const {
549 return getSTI().hasFeature(ARM::HasV6Ops);
550 }
551
552 bool hasV6T2Ops() const {
553 return getSTI().hasFeature(ARM::HasV6T2Ops);
554 }
555
556 bool hasV6MOps() const {
557 return getSTI().hasFeature(ARM::HasV6MOps);
558 }
559
560 bool hasV7Ops() const {
561 return getSTI().hasFeature(ARM::HasV7Ops);
562 }
563
564 bool hasV8Ops() const {
565 return getSTI().hasFeature(ARM::HasV8Ops);
566 }
567
568 bool hasV8MBaseline() const {
569 return getSTI().hasFeature(ARM::HasV8MBaselineOps);
570 }
571
572 bool hasV8MMainline() const {
573 return getSTI().hasFeature(ARM::HasV8MMainlineOps);
574 }
575 bool hasV8_1MMainline() const {
576 return getSTI().hasFeature(ARM::HasV8_1MMainlineOps);
577 }
578 bool hasMVEFloat() const {
579 return getSTI().hasFeature(ARM::HasMVEFloatOps);
580 }
581 bool hasCDE() const {
582 return getSTI().hasFeature(ARM::HasCDEOps);
583 }
584 bool has8MSecExt() const {
585 return getSTI().hasFeature(ARM::Feature8MSecExt);
586 }
587
588 bool hasARM() const {
589 return !getSTI().hasFeature(ARM::FeatureNoARM);
590 }
591
592 bool hasDSP() const {
593 return getSTI().hasFeature(ARM::FeatureDSP);
594 }
595
596 bool hasD32() const {
597 return getSTI().hasFeature(ARM::FeatureD32);
598 }
599
600 bool hasV8_1aOps() const {
601 return getSTI().hasFeature(ARM::HasV8_1aOps);
602 }
603
604 bool hasRAS() const {
605 return getSTI().hasFeature(ARM::FeatureRAS);
606 }
607
608 void SwitchMode() {
609 MCSubtargetInfo &STI = copySTI();
610 auto FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
611 setAvailableFeatures(FB);
612 }
613
614 void FixModeAfterArchChange(bool WasThumb, SMLoc Loc);
615
616 bool isMClass() const {
617 return getSTI().hasFeature(ARM::FeatureMClass);
618 }
619
620 /// @name Auto-generated Match Functions
621 /// {
622
623#define GET_ASSEMBLER_HEADER
624#include "ARMGenAsmMatcher.inc"
625
626 /// }
627
628 ParseStatus parseITCondCode(OperandVector &);
629 ParseStatus parseCoprocNumOperand(OperandVector &);
630 ParseStatus parseCoprocRegOperand(OperandVector &);
631 ParseStatus parseCoprocOptionOperand(OperandVector &);
632 ParseStatus parseMemBarrierOptOperand(OperandVector &);
633 ParseStatus parseTraceSyncBarrierOptOperand(OperandVector &);
634 ParseStatus parseInstSyncBarrierOptOperand(OperandVector &);
635 ParseStatus parseProcIFlagsOperand(OperandVector &);
636 ParseStatus parseMSRMaskOperand(OperandVector &);
637 ParseStatus parseBankedRegOperand(OperandVector &);
638 ParseStatus parsePKHImm(OperandVector &O, ARM_AM::ShiftOpc, int Low,
639 int High);
640 ParseStatus parsePKHLSLImm(OperandVector &O) {
641 return parsePKHImm(O, ARM_AM::lsl, 0, 31);
642 }
643 ParseStatus parsePKHASRImm(OperandVector &O) {
644 return parsePKHImm(O, ARM_AM::asr, 1, 32);
645 }
646 ParseStatus parseSetEndImm(OperandVector &);
647 ParseStatus parseShifterImm(OperandVector &);
648 ParseStatus parseRotImm(OperandVector &);
649 ParseStatus parseModImm(OperandVector &);
650 ParseStatus parseBitfield(OperandVector &);
651 ParseStatus parsePostIdxReg(OperandVector &);
652 ParseStatus parseAM3Offset(OperandVector &);
653 ParseStatus parseFPImm(OperandVector &);
654 ParseStatus parseVectorList(OperandVector &);
655 ParseStatus parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index,
656 SMLoc &EndLoc);
657
658 // Asm Match Converter Methods
659 void cvtThumbMultiply(MCInst &Inst, const OperandVector &);
660 void cvtThumbBranches(MCInst &Inst, const OperandVector &);
661 void cvtMVEVMOVQtoDReg(MCInst &Inst, const OperandVector &);
662
663 bool validateInstruction(MCInst &Inst, const OperandVector &Ops,
664 unsigned MnemonicOpsEndInd);
665 bool processInstruction(MCInst &Inst, const OperandVector &Ops,
666 unsigned MnemonicOpsEndInd, MCStreamer &Out);
667 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic,
669 unsigned MnemonicOpsEndInd);
670 bool isITBlockTerminator(MCInst &Inst) const;
671
672 void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands,
673 unsigned MnemonicOpsEndInd);
674 bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands, bool Load,
675 bool ARMMode, bool Writeback,
676 unsigned MnemonicOpsEndInd);
677
678public:
679 enum ARMMatchResultTy {
680 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
681 Match_RequiresNotITBlock,
682 Match_RequiresV6,
683 Match_RequiresThumb2,
684 Match_RequiresV8,
685 Match_RequiresFlagSetting,
686#define GET_OPERAND_DIAGNOSTIC_TYPES
687#include "ARMGenAsmMatcher.inc"
688
689 };
690
691 ARMAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
692 const MCInstrInfo &MII)
693 : MCTargetAsmParser(STI, MII), UC(Parser), MS(STI) {
695
696 // Cache the MCRegisterInfo.
697 MRI = getContext().getRegisterInfo();
698
699 // Initialize the set of available features.
700 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
701
702 // Add build attributes based on the selected target.
704 getTargetStreamer().emitTargetAttributes(STI);
705
706 // Not in an ITBlock to start with.
707 ITState.CurPosition = ~0U;
708
709 VPTState.CurPosition = ~0U;
710
711 NextSymbolIsThumb = false;
712 }
713
714 // Implementation of the MCTargetAsmParser interface:
715 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
716 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
717 SMLoc &EndLoc) override;
718 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
719 SMLoc NameLoc, OperandVector &Operands) override;
720 bool ParseDirective(AsmToken DirectiveID) override;
721
722 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
723 unsigned Kind) override;
724 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
725 unsigned
726 checkEarlyTargetMatchPredicate(MCInst &Inst,
727 const OperandVector &Operands) override;
728
729 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
730 OperandVector &Operands, MCStreamer &Out,
731 uint64_t &ErrorInfo,
732 bool MatchingInlineAsm) override;
733 unsigned MatchInstruction(OperandVector &Operands, MCInst &Inst,
734 SmallVectorImpl<NearMissInfo> &NearMisses,
735 bool MatchingInlineAsm, bool &EmitInITBlock,
736 MCStreamer &Out);
737
738 struct NearMissMessage {
739 SMLoc Loc;
740 SmallString<128> Message;
741 };
742
743 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
744
745 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
746 SmallVectorImpl<NearMissMessage> &NearMissesOut,
747 SMLoc IDLoc, OperandVector &Operands);
748 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
750
751 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) override;
752
753 void onLabelParsed(MCSymbol *Symbol) override;
754
755 const MCInstrDesc &getInstrDesc(unsigned int Opcode) const {
756 return MII.get(Opcode);
757 }
758
759 bool hasMVE() const { return getSTI().hasFeature(ARM::HasMVEIntegerOps); }
760
761 // Return the low-subreg of a given Q register.
762 MCRegister getDRegFromQReg(MCRegister QReg) const {
763 return MRI->getSubReg(QReg, ARM::dsub_0);
764 }
765
766 const MCRegisterInfo *getMRI() const { return MRI; }
767};
768
769/// ARMOperand - Instances of this class represent a parsed ARM machine
770/// operand.
771class ARMOperand : public MCParsedAsmOperand {
772 enum KindTy {
773 k_CondCode,
774 k_VPTPred,
775 k_CCOut,
776 k_ITCondMask,
777 k_CoprocNum,
778 k_CoprocReg,
779 k_CoprocOption,
780 k_Immediate,
781 k_MemBarrierOpt,
782 k_InstSyncBarrierOpt,
783 k_TraceSyncBarrierOpt,
784 k_Memory,
785 k_PostIndexRegister,
786 k_MSRMask,
787 k_BankedReg,
788 k_ProcIFlags,
789 k_VectorIndex,
790 k_Register,
791 k_RegisterList,
792 k_RegisterListWithAPSR,
793 k_DPRRegisterList,
794 k_SPRRegisterList,
795 k_FPSRegisterListWithVPR,
796 k_FPDRegisterListWithVPR,
797 k_VectorList,
798 k_VectorListAllLanes,
799 k_VectorListIndexed,
800 k_ShiftedRegister,
801 k_ShiftedImmediate,
802 k_ShifterImmediate,
803 k_RotateImmediate,
804 k_ModifiedImmediate,
805 k_ConstantPoolImmediate,
806 k_BitfieldDescriptor,
807 k_Token,
808 } Kind;
809
810 SMLoc StartLoc, EndLoc, AlignmentLoc;
812
813 ARMAsmParser *Parser;
814
815 struct CCOp {
817 };
818
819 struct VCCOp {
821 };
822
823 struct CopOp {
824 unsigned Val;
825 };
826
827 struct CoprocOptionOp {
828 unsigned Val;
829 };
830
831 struct ITMaskOp {
832 unsigned Mask:4;
833 };
834
835 struct MBOptOp {
836 ARM_MB::MemBOpt Val;
837 };
838
839 struct ISBOptOp {
841 };
842
843 struct TSBOptOp {
845 };
846
847 struct IFlagsOp {
849 };
850
851 struct MMaskOp {
852 unsigned Val;
853 };
854
855 struct BankedRegOp {
856 unsigned Val;
857 };
858
859 struct TokOp {
860 const char *Data;
861 unsigned Length;
862 };
863
864 struct RegOp {
865 MCRegister RegNum;
866 };
867
868 // A vector register list is a sequential list of 1 to 4 registers.
869 struct VectorListOp {
870 MCRegister RegNum;
871 unsigned Count;
872 unsigned LaneIndex;
873 bool isDoubleSpaced;
874 };
875
876 struct VectorIndexOp {
877 unsigned Val;
878 };
879
880 struct ImmOp {
881 const MCExpr *Val;
882 };
883
884 /// Combined record for all forms of ARM address expressions.
885 struct MemoryOp {
886 MCRegister BaseRegNum;
887 // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
888 // was specified.
889 const MCExpr *OffsetImm; // Offset immediate value
890 MCRegister OffsetRegNum; // Offset register num, when OffsetImm == NULL
891 ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
892 unsigned ShiftImm; // shift for OffsetReg.
893 unsigned Alignment; // 0 = no alignment specified
894 // n = alignment in bytes (2, 4, 8, 16, or 32)
895 unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit)
896 };
897
898 struct PostIdxRegOp {
899 MCRegister RegNum;
900 bool isAdd;
901 ARM_AM::ShiftOpc ShiftTy;
902 unsigned ShiftImm;
903 };
904
905 struct ShifterImmOp {
906 bool isASR;
907 unsigned Imm;
908 };
909
910 struct RegShiftedRegOp {
911 ARM_AM::ShiftOpc ShiftTy;
912 MCRegister SrcReg;
913 MCRegister ShiftReg;
914 unsigned ShiftImm;
915 };
916
917 struct RegShiftedImmOp {
918 ARM_AM::ShiftOpc ShiftTy;
919 MCRegister SrcReg;
920 unsigned ShiftImm;
921 };
922
923 struct RotImmOp {
924 unsigned Imm;
925 };
926
927 struct ModImmOp {
928 unsigned Bits;
929 unsigned Rot;
930 };
931
932 struct BitfieldOp {
933 unsigned LSB;
934 unsigned Width;
935 };
936
937 union {
938 struct CCOp CC;
939 struct VCCOp VCC;
940 struct CopOp Cop;
941 struct CoprocOptionOp CoprocOption;
942 struct MBOptOp MBOpt;
943 struct ISBOptOp ISBOpt;
944 struct TSBOptOp TSBOpt;
945 struct ITMaskOp ITMask;
946 struct IFlagsOp IFlags;
947 struct MMaskOp MMask;
948 struct BankedRegOp BankedReg;
949 struct TokOp Tok;
950 struct RegOp Reg;
951 struct VectorListOp VectorList;
952 struct VectorIndexOp VectorIndex;
953 struct ImmOp Imm;
954 struct MemoryOp Memory;
955 struct PostIdxRegOp PostIdxReg;
956 struct ShifterImmOp ShifterImm;
957 struct RegShiftedRegOp RegShiftedReg;
958 struct RegShiftedImmOp RegShiftedImm;
959 struct RotImmOp RotImm;
960 struct ModImmOp ModImm;
961 struct BitfieldOp Bitfield;
962 };
963
964public:
965 ARMOperand(KindTy K, ARMAsmParser &Parser) : Kind(K), Parser(&Parser) {}
966
967 /// getStartLoc - Get the location of the first token of this operand.
968 SMLoc getStartLoc() const override { return StartLoc; }
969
970 /// getEndLoc - Get the location of the last token of this operand.
971 SMLoc getEndLoc() const override { return EndLoc; }
972
973 /// getLocRange - Get the range between the first and last token of this
974 /// operand.
975 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
976
977 /// getAlignmentLoc - Get the location of the Alignment token of this operand.
978 SMLoc getAlignmentLoc() const {
979 assert(Kind == k_Memory && "Invalid access!");
980 return AlignmentLoc;
981 }
982
984 assert(Kind == k_CondCode && "Invalid access!");
985 return CC.Val;
986 }
987
988 ARMVCC::VPTCodes getVPTPred() const {
989 assert(isVPTPred() && "Invalid access!");
990 return VCC.Val;
991 }
992
993 unsigned getCoproc() const {
994 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
995 return Cop.Val;
996 }
997
998 StringRef getToken() const {
999 assert(Kind == k_Token && "Invalid access!");
1000 return StringRef(Tok.Data, Tok.Length);
1001 }
1002
1003 MCRegister getReg() const override {
1004 assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
1005 return Reg.RegNum;
1006 }
1007
1008 const SmallVectorImpl<MCRegister> &getRegList() const {
1009 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
1010 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
1011 Kind == k_FPSRegisterListWithVPR ||
1012 Kind == k_FPDRegisterListWithVPR) &&
1013 "Invalid access!");
1014 return Registers;
1015 }
1016
1017 const MCExpr *getImm() const {
1018 assert(isImm() && "Invalid access!");
1019 return Imm.Val;
1020 }
1021
1022 const MCExpr *getConstantPoolImm() const {
1023 assert(isConstantPoolImm() && "Invalid access!");
1024 return Imm.Val;
1025 }
1026
1027 unsigned getVectorIndex() const {
1028 assert(Kind == k_VectorIndex && "Invalid access!");
1029 return VectorIndex.Val;
1030 }
1031
1032 ARM_MB::MemBOpt getMemBarrierOpt() const {
1033 assert(Kind == k_MemBarrierOpt && "Invalid access!");
1034 return MBOpt.Val;
1035 }
1036
1037 ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const {
1038 assert(Kind == k_InstSyncBarrierOpt && "Invalid access!");
1039 return ISBOpt.Val;
1040 }
1041
1042 ARM_TSB::TraceSyncBOpt getTraceSyncBarrierOpt() const {
1043 assert(Kind == k_TraceSyncBarrierOpt && "Invalid access!");
1044 return TSBOpt.Val;
1045 }
1046
1047 ARM_PROC::IFlags getProcIFlags() const {
1048 assert(Kind == k_ProcIFlags && "Invalid access!");
1049 return IFlags.Val;
1050 }
1051
1052 unsigned getMSRMask() const {
1053 assert(Kind == k_MSRMask && "Invalid access!");
1054 return MMask.Val;
1055 }
1056
1057 unsigned getBankedReg() const {
1058 assert(Kind == k_BankedReg && "Invalid access!");
1059 return BankedReg.Val;
1060 }
1061
1062 bool isCoprocNum() const { return Kind == k_CoprocNum; }
1063 bool isCoprocReg() const { return Kind == k_CoprocReg; }
1064 bool isCoprocOption() const { return Kind == k_CoprocOption; }
1065 bool isCondCode() const { return Kind == k_CondCode; }
1066 bool isVPTPred() const { return Kind == k_VPTPred; }
1067 bool isCCOut() const { return Kind == k_CCOut; }
1068 bool isITMask() const { return Kind == k_ITCondMask; }
1069 bool isITCondCode() const { return Kind == k_CondCode; }
1070 bool isImm() const override {
1071 return Kind == k_Immediate;
1072 }
1073
1074 bool isARMBranchTarget() const {
1075 if (!isImm()) return false;
1076
1077 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1078 return CE->getValue() % 4 == 0;
1079 return true;
1080 }
1081
1082
1083 bool isThumbBranchTarget() const {
1084 if (!isImm()) return false;
1085
1086 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1087 return CE->getValue() % 2 == 0;
1088 return true;
1089 }
1090
1091 // checks whether this operand is an unsigned offset which fits is a field
1092 // of specified width and scaled by a specific number of bits
1093 template<unsigned width, unsigned scale>
1094 bool isUnsignedOffset() const {
1095 if (!isImm()) return false;
1096 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1097 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1098 int64_t Val = CE->getValue();
1099 int64_t Align = 1LL << scale;
1100 int64_t Max = Align * ((1LL << width) - 1);
1101 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
1102 }
1103 return false;
1104 }
1105
1106 // checks whether this operand is an signed offset which fits is a field
1107 // of specified width and scaled by a specific number of bits
1108 template<unsigned width, unsigned scale>
1109 bool isSignedOffset() const {
1110 if (!isImm()) return false;
1111 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1112 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1113 int64_t Val = CE->getValue();
1114 int64_t Align = 1LL << scale;
1115 int64_t Max = Align * ((1LL << (width-1)) - 1);
1116 int64_t Min = -Align * (1LL << (width-1));
1117 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
1118 }
1119 return false;
1120 }
1121
1122 // checks whether this operand is an offset suitable for the LE /
1123 // LETP instructions in Arm v8.1M
1124 bool isLEOffset() const {
1125 if (!isImm()) return false;
1126 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1127 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1128 int64_t Val = CE->getValue();
1129 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1130 }
1131 return false;
1132 }
1133
1134 // checks whether this operand is a memory operand computed as an offset
1135 // applied to PC. the offset may have 8 bits of magnitude and is represented
1136 // with two bits of shift. textually it may be either [pc, #imm], #imm or
1137 // relocable expression...
1138 bool isThumbMemPC() const {
1139 int64_t Val = 0;
1140 if (isImm()) {
1141 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1142 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val);
1143 if (!CE) return false;
1144 Val = CE->getValue();
1145 }
1146 else if (isGPRMem()) {
1147 if(!Memory.OffsetImm || Memory.OffsetRegNum) return false;
1148 if(Memory.BaseRegNum != ARM::PC) return false;
1149 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
1150 Val = CE->getValue();
1151 else
1152 return false;
1153 }
1154 else return false;
1155 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1156 }
1157
1158 bool isFPImm() const {
1159 if (!isImm()) return false;
1160 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1161 if (!CE || !isUInt<32>(CE->getValue()))
1162 return false;
1163 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
1164 return Val != -1;
1165 }
1166
1167 template<int64_t N, int64_t M>
1168 bool isImmediate() const {
1169 if (!isImm()) return false;
1170 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1171 if (!CE) return false;
1172 int64_t Value = CE->getValue();
1173 return Value >= N && Value <= M;
1174 }
1175
1176 template<int64_t N, int64_t M>
1177 bool isImmediateS4() const {
1178 if (!isImm()) return false;
1179 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1180 if (!CE) return false;
1181 int64_t Value = CE->getValue();
1182 // ARM assembly uses #-0 to request the subtract-zero encoding,
1183 // which is distinct from the add-zero spelling even though both
1184 // have zero magnitude. The rather odd std::numeric_limits
1185 // invocation gives us this.
1186 return (((Value & 3) == 0) && Value >= N && Value <= M) ||
1187 Value == std::numeric_limits<int32_t>::min();
1188 }
1189 template<int64_t N, int64_t M>
1190 bool isImmediateS2() const {
1191 if (!isImm()) return false;
1192 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1193 if (!CE) return false;
1194 int64_t Value = CE->getValue();
1195 return ((Value & 1) == 0) && Value >= N && Value <= M;
1196 }
1197 bool isFBits16() const {
1198 return isImmediate<0, 17>();
1199 }
1200 bool isFBits32() const {
1201 return isImmediate<1, 33>();
1202 }
1203 bool isImm8s4() const {
1204 return isImmediateS4<-1020, 1020>();
1205 }
1206 bool isImm7s4() const {
1207 return isImmediateS4<-508, 508>();
1208 }
1209 bool isImm7Shift0() const {
1210 return isImmediate<-127, 127>();
1211 }
1212 bool isImm7Shift1() const {
1213 return isImmediateS2<-255, 255>();
1214 }
1215 bool isImm7Shift2() const {
1216 return isImmediateS4<-511, 511>();
1217 }
1218 bool isImm7() const {
1219 return isImmediate<-127, 127>();
1220 }
1221 bool isImm0_1020s4() const {
1222 return isImmediateS4<0, 1020>();
1223 }
1224 bool isImm0_508s4() const {
1225 return isImmediateS4<0, 508>();
1226 }
1227 bool isImm0_508s4Neg() const {
1228 if (!isImm()) return false;
1229 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1230 if (!CE) return false;
1231 int64_t Value = -CE->getValue();
1232 // explicitly exclude zero. we want that to use the normal 0_508 version.
1233 return ((Value & 3) == 0) && Value > 0 && Value <= 508;
1234 }
1235
1236 bool isImm0_4095Neg() const {
1237 if (!isImm()) return false;
1238 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1239 if (!CE) return false;
1240 // isImm0_4095Neg is used with 32-bit immediates only.
1241 // 32-bit immediates are zero extended to 64-bit when parsed,
1242 // thus simple -CE->getValue() results in a big negative number,
1243 // not a small positive number as intended
1244 if ((CE->getValue() >> 32) > 0) return false;
1245 uint32_t Value = -static_cast<uint32_t>(CE->getValue());
1246 return Value > 0 && Value < 4096;
1247 }
1248
1249 bool isImm0_7() const {
1250 return isImmediate<0, 7>();
1251 }
1252
1253 bool isImm1_16() const {
1254 return isImmediate<1, 16>();
1255 }
1256
1257 bool isImm1_32() const {
1258 return isImmediate<1, 32>();
1259 }
1260
1261 bool isImm8_255() const {
1262 return isImmediate<8, 255>();
1263 }
1264
1265 bool isImm0_255Expr() const {
1266 if (!isImm())
1267 return false;
1268 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1269 // If it's not a constant expression, it'll generate a fixup and be
1270 // handled later.
1271 if (!CE)
1272 return true;
1273 int64_t Value = CE->getValue();
1274 return isUInt<8>(Value);
1275 }
1276
1277 bool isImm256_65535Expr() const {
1278 if (!isImm()) return false;
1279 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1280 // If it's not a constant expression, it'll generate a fixup and be
1281 // handled later.
1282 if (!CE) return true;
1283 int64_t Value = CE->getValue();
1284 return Value >= 256 && Value < 65536;
1285 }
1286
1287 bool isImm0_65535Expr() const {
1288 if (!isImm()) return false;
1289 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1290 // If it's not a constant expression, it'll generate a fixup and be
1291 // handled later.
1292 if (!CE) return true;
1293 int64_t Value = CE->getValue();
1294 return Value >= 0 && Value < 65536;
1295 }
1296
1297 bool isImm24bit() const {
1298 return isImmediate<0, 0xffffff + 1>();
1299 }
1300
1301 bool isImmThumbSR() const {
1302 return isImmediate<1, 33>();
1303 }
1304
1305 bool isPKHLSLImm() const {
1306 return isImmediate<0, 32>();
1307 }
1308
1309 bool isPKHASRImm() const {
1310 return isImmediate<0, 33>();
1311 }
1312
1313 bool isAdrLabel() const {
1314 // If we have an immediate that's not a constant, treat it as a label
1315 // reference needing a fixup.
1316 if (isImm() && !isa<MCConstantExpr>(getImm()))
1317 return true;
1318
1319 // If it is a constant, it must fit into a modified immediate encoding.
1320 if (!isImm()) return false;
1321 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1322 if (!CE) return false;
1323 int64_t Value = CE->getValue();
1324 return (ARM_AM::getSOImmVal(Value) != -1 ||
1325 ARM_AM::getSOImmVal(-Value) != -1);
1326 }
1327
1328 bool isT2SOImm() const {
1329 // If we have an immediate that's not a constant, treat it as an expression
1330 // needing a fixup.
1331 if (isImm() && !isa<MCConstantExpr>(getImm())) {
1332 // We want to avoid matching :upper16: and :lower16: as we want these
1333 // expressions to match in isImm0_65535Expr()
1334 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(getImm());
1335 return (!ARM16Expr || (ARM16Expr->getSpecifier() != ARM::S_HI16 &&
1336 ARM16Expr->getSpecifier() != ARM::S_LO16));
1337 }
1338 if (!isImm()) return false;
1339 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1340 if (!CE) return false;
1341 int64_t Value = CE->getValue();
1342 return ARM_AM::getT2SOImmVal(Value) != -1;
1343 }
1344
1345 bool isT2SOImmNot() const {
1346 if (!isImm()) return false;
1347 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1348 if (!CE) return false;
1349 int64_t Value = CE->getValue();
1350 return ARM_AM::getT2SOImmVal(Value) == -1 &&
1352 }
1353
1354 bool isT2SOImmNeg() const {
1355 if (!isImm()) return false;
1356 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1357 if (!CE) return false;
1358 int64_t Value = CE->getValue();
1359 // Only use this when not representable as a plain so_imm.
1360 return ARM_AM::getT2SOImmVal(Value) == -1 &&
1362 }
1363
1364 bool isSetEndImm() const {
1365 if (!isImm()) return false;
1366 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1367 if (!CE) return false;
1368 int64_t Value = CE->getValue();
1369 return Value == 1 || Value == 0;
1370 }
1371
1372 bool isReg() const override { return Kind == k_Register; }
1373 bool isRegList() const { return Kind == k_RegisterList; }
1374 bool isRegListWithAPSR() const {
1375 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1376 }
1377 bool isDReg() const {
1378 return isReg() &&
1379 getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg.RegNum);
1380 }
1381 bool isQReg() const {
1382 return isReg() &&
1383 getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg.RegNum);
1384 }
1385 bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
1386 bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
1387 bool isFPSRegListWithVPR() const { return Kind == k_FPSRegisterListWithVPR; }
1388 bool isFPDRegListWithVPR() const { return Kind == k_FPDRegisterListWithVPR; }
1389 bool isToken() const override { return Kind == k_Token; }
1390 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
1391 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
1392 bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; }
1393 bool isMem() const override {
1394 return isGPRMem() || isMVEMem();
1395 }
1396 bool isMVEMem() const {
1397 if (Kind != k_Memory)
1398 return false;
1399 if (Memory.BaseRegNum &&
1400 !getARMMCRegisterClass(ARM::GPRRegClassID)
1401 .contains(Memory.BaseRegNum) &&
1402 !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Memory.BaseRegNum))
1403 return false;
1404 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::MQPRRegClassID)
1405 .contains(Memory.OffsetRegNum))
1406 return false;
1407 return true;
1408 }
1409 bool isGPRMem() const {
1410 if (Kind != k_Memory)
1411 return false;
1412 if (Memory.BaseRegNum &&
1413 !getARMMCRegisterClass(ARM::GPRRegClassID).contains(Memory.BaseRegNum))
1414 return false;
1415 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::GPRRegClassID)
1416 .contains(Memory.OffsetRegNum))
1417 return false;
1418 return true;
1419 }
1420 bool isShifterImm() const { return Kind == k_ShifterImmediate; }
1421 bool isRegShiftedReg() const {
1422 return Kind == k_ShiftedRegister &&
1423 getARMMCRegisterClass(ARM::GPRRegClassID)
1424 .contains(RegShiftedReg.SrcReg) &&
1425 getARMMCRegisterClass(ARM::GPRRegClassID)
1426 .contains(RegShiftedReg.ShiftReg);
1427 }
1428 bool isRegShiftedImm() const {
1429 return Kind == k_ShiftedImmediate &&
1430 getARMMCRegisterClass(ARM::GPRRegClassID)
1431 .contains(RegShiftedImm.SrcReg);
1432 }
1433 bool isRotImm() const { return Kind == k_RotateImmediate; }
1434
1435 template<unsigned Min, unsigned Max>
1436 bool isPowerTwoInRange() const {
1437 if (!isImm()) return false;
1438 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1439 if (!CE) return false;
1440 int64_t Value = CE->getValue();
1441 return Value > 0 && llvm::popcount((uint64_t)Value) == 1 && Value >= Min &&
1442 Value <= Max;
1443 }
1444 bool isModImm() const { return Kind == k_ModifiedImmediate; }
1445
1446 bool isModImmNot() const {
1447 if (!isImm()) return false;
1448 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1449 if (!CE) return false;
1450 int64_t Value = CE->getValue();
1451 return ARM_AM::getSOImmVal(~Value) != -1;
1452 }
1453
1454 bool isModImmNeg() const {
1455 if (!isImm()) return false;
1456 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1457 if (!CE) return false;
1458 int64_t Value = CE->getValue();
1459 return ARM_AM::getSOImmVal(Value) == -1 &&
1460 ARM_AM::getSOImmVal(-Value) != -1;
1461 }
1462
1463 bool isThumbModImmNeg1_7() const {
1464 if (!isImm()) return false;
1465 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1466 if (!CE) return false;
1467 int32_t Value = -(int32_t)CE->getValue();
1468 return 0 < Value && Value < 8;
1469 }
1470
1471 bool isThumbModImmNeg8_255() const {
1472 if (!isImm()) return false;
1473 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1474 if (!CE) return false;
1475 int32_t Value = -(int32_t)CE->getValue();
1476 return 7 < Value && Value < 256;
1477 }
1478
1479 bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
1480 bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
1481 bool isPostIdxRegShifted() const {
1482 return Kind == k_PostIndexRegister &&
1483 getARMMCRegisterClass(ARM::GPRRegClassID)
1484 .contains(PostIdxReg.RegNum);
1485 }
1486 bool isPostIdxReg() const {
1487 return isPostIdxRegShifted() && PostIdxReg.ShiftTy == ARM_AM::no_shift;
1488 }
1489 bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const {
1490 if (!isGPRMem())
1491 return false;
1492 // No offset of any kind.
1493 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1494 (alignOK || Memory.Alignment == Alignment);
1495 }
1496 bool isMemNoOffsetT2(bool alignOK = false, unsigned Alignment = 0) const {
1497 if (!isGPRMem())
1498 return false;
1499
1500 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1501 .contains(Memory.BaseRegNum))
1502 return false;
1503
1504 // No offset of any kind.
1505 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1506 (alignOK || Memory.Alignment == Alignment);
1507 }
1508 bool isMemNoOffsetT2NoSp(bool alignOK = false, unsigned Alignment = 0) const {
1509 if (!isGPRMem())
1510 return false;
1511
1512 if (!getARMMCRegisterClass(ARM::rGPRRegClassID).contains(Memory.BaseRegNum))
1513 return false;
1514
1515 // No offset of any kind.
1516 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1517 (alignOK || Memory.Alignment == Alignment);
1518 }
1519 bool isMemNoOffsetT(bool alignOK = false, unsigned Alignment = 0) const {
1520 if (!isGPRMem())
1521 return false;
1522
1523 if (!getARMMCRegisterClass(ARM::tGPRRegClassID).contains(Memory.BaseRegNum))
1524 return false;
1525
1526 // No offset of any kind.
1527 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1528 (alignOK || Memory.Alignment == Alignment);
1529 }
1530 bool isMemPCRelImm12() const {
1531 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1532 return false;
1533 // Base register must be PC.
1534 if (Memory.BaseRegNum != ARM::PC)
1535 return false;
1536 // Immediate offset in range [-4095, 4095].
1537 if (!Memory.OffsetImm) return true;
1538 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1539 int64_t Val = CE->getValue();
1540 return (Val > -4096 && Val < 4096) ||
1541 (Val == std::numeric_limits<int32_t>::min());
1542 }
1543 return false;
1544 }
1545
1546 bool isAlignedMemory() const {
1547 return isMemNoOffset(true);
1548 }
1549
1550 bool isAlignedMemoryNone() const {
1551 return isMemNoOffset(false, 0);
1552 }
1553
1554 bool isDupAlignedMemoryNone() const {
1555 return isMemNoOffset(false, 0);
1556 }
1557
1558 bool isAlignedMemory16() const {
1559 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1560 return true;
1561 return isMemNoOffset(false, 0);
1562 }
1563
1564 bool isDupAlignedMemory16() const {
1565 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1566 return true;
1567 return isMemNoOffset(false, 0);
1568 }
1569
1570 bool isAlignedMemory32() const {
1571 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1572 return true;
1573 return isMemNoOffset(false, 0);
1574 }
1575
1576 bool isDupAlignedMemory32() const {
1577 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1578 return true;
1579 return isMemNoOffset(false, 0);
1580 }
1581
1582 bool isAlignedMemory64() const {
1583 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1584 return true;
1585 return isMemNoOffset(false, 0);
1586 }
1587
1588 bool isDupAlignedMemory64() const {
1589 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1590 return true;
1591 return isMemNoOffset(false, 0);
1592 }
1593
1594 bool isAlignedMemory64or128() const {
1595 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1596 return true;
1597 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1598 return true;
1599 return isMemNoOffset(false, 0);
1600 }
1601
1602 bool isDupAlignedMemory64or128() const {
1603 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1604 return true;
1605 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1606 return true;
1607 return isMemNoOffset(false, 0);
1608 }
1609
1610 bool isAlignedMemory64or128or256() const {
1611 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1612 return true;
1613 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1614 return true;
1615 if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32.
1616 return true;
1617 return isMemNoOffset(false, 0);
1618 }
1619
1620 bool isAddrMode2() const {
1621 if (!isGPRMem() || Memory.Alignment != 0) return false;
1622 // Check for register offset.
1623 if (Memory.OffsetRegNum) return true;
1624 // Immediate offset in range [-4095, 4095].
1625 if (!Memory.OffsetImm) return true;
1626 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1627 int64_t Val = CE->getValue();
1628 return Val > -4096 && Val < 4096;
1629 }
1630 return false;
1631 }
1632
1633 bool isAM2OffsetImm() const {
1634 if (!isImm()) return false;
1635 // Immediate offset in range [-4095, 4095].
1636 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1637 if (!CE) return false;
1638 int64_t Val = CE->getValue();
1639 return (Val == std::numeric_limits<int32_t>::min()) ||
1640 (Val > -4096 && Val < 4096);
1641 }
1642
1643 bool isAddrMode3() const {
1644 // If we have an immediate that's not a constant, treat it as a label
1645 // reference needing a fixup. If it is a constant, it's something else
1646 // and we reject it.
1647 if (isImm() && !isa<MCConstantExpr>(getImm()))
1648 return true;
1649 if (!isGPRMem() || Memory.Alignment != 0) return false;
1650 // No shifts are legal for AM3.
1651 if (Memory.ShiftType != ARM_AM::no_shift) return false;
1652 // Check for register offset.
1653 if (Memory.OffsetRegNum) return true;
1654 // Immediate offset in range [-255, 255].
1655 if (!Memory.OffsetImm) return true;
1656 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1657 int64_t Val = CE->getValue();
1658 // The #-0 offset is encoded as std::numeric_limits<int32_t>::min(), and
1659 // we have to check for this too.
1660 return (Val > -256 && Val < 256) ||
1661 Val == std::numeric_limits<int32_t>::min();
1662 }
1663 return false;
1664 }
1665
1666 bool isAM3Offset() const {
1667 if (isPostIdxReg())
1668 return true;
1669 if (!isImm())
1670 return false;
1671 // Immediate offset in range [-255, 255].
1672 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1673 if (!CE) return false;
1674 int64_t Val = CE->getValue();
1675 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1676 return (Val > -256 && Val < 256) ||
1677 Val == std::numeric_limits<int32_t>::min();
1678 }
1679
1680 bool isAddrMode5() const {
1681 // If we have an immediate that's not a constant, treat it as a label
1682 // reference needing a fixup. If it is a constant, it's something else
1683 // and we reject it.
1684 if (isImm() && !isa<MCConstantExpr>(getImm()))
1685 return true;
1686 if (!isGPRMem() || Memory.Alignment != 0) return false;
1687 // Check for register offset.
1688 if (Memory.OffsetRegNum) return false;
1689 // Immediate offset in range [-1020, 1020] and a multiple of 4.
1690 if (!Memory.OffsetImm) return true;
1691 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1692 int64_t Val = CE->getValue();
1693 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1694 Val == std::numeric_limits<int32_t>::min();
1695 }
1696 return false;
1697 }
1698
1699 bool isAddrMode5FP16() const {
1700 // If we have an immediate that's not a constant, treat it as a label
1701 // reference needing a fixup. If it is a constant, it's something else
1702 // and we reject it.
1703 if (isImm() && !isa<MCConstantExpr>(getImm()))
1704 return true;
1705 if (!isGPRMem() || Memory.Alignment != 0) return false;
1706 // Check for register offset.
1707 if (Memory.OffsetRegNum) return false;
1708 // Immediate offset in range [-510, 510] and a multiple of 2.
1709 if (!Memory.OffsetImm) return true;
1710 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1711 int64_t Val = CE->getValue();
1712 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1713 Val == std::numeric_limits<int32_t>::min();
1714 }
1715 return false;
1716 }
1717
1718 bool isMemTBB() const {
1719 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1720 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1721 return false;
1722 return true;
1723 }
1724
1725 bool isMemTBH() const {
1726 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1727 Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
1728 Memory.Alignment != 0 )
1729 return false;
1730 return true;
1731 }
1732
1733 bool isMemRegOffset() const {
1734 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1735 return false;
1736 return true;
1737 }
1738
1739 bool isT2MemRegOffset() const {
1740 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1741 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1742 return false;
1743 // Only lsl #{0, 1, 2, 3} allowed.
1744 if (Memory.ShiftType == ARM_AM::no_shift)
1745 return true;
1746 if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
1747 return false;
1748 return true;
1749 }
1750
1751 bool isMemThumbRR() const {
1752 // Thumb reg+reg addressing is simple. Just two registers, a base and
1753 // an offset. No shifts, negations or any other complicating factors.
1754 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1755 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1756 return false;
1757 return isARMLowRegister(Memory.BaseRegNum) &&
1758 (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
1759 }
1760
1761 bool isMemThumbRIs4() const {
1762 if (!isGPRMem() || Memory.OffsetRegNum ||
1763 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1764 return false;
1765 // Immediate offset, multiple of 4 in range [0, 124].
1766 if (!Memory.OffsetImm) return true;
1767 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1768 int64_t Val = CE->getValue();
1769 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1770 }
1771 return false;
1772 }
1773
1774 bool isMemThumbRIs2() const {
1775 if (!isGPRMem() || Memory.OffsetRegNum ||
1776 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1777 return false;
1778 // Immediate offset, multiple of 4 in range [0, 62].
1779 if (!Memory.OffsetImm) return true;
1780 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1781 int64_t Val = CE->getValue();
1782 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1783 }
1784 return false;
1785 }
1786
1787 bool isMemThumbRIs1() const {
1788 if (!isGPRMem() || Memory.OffsetRegNum ||
1789 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1790 return false;
1791 // Immediate offset in range [0, 31].
1792 if (!Memory.OffsetImm) return true;
1793 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1794 int64_t Val = CE->getValue();
1795 return Val >= 0 && Val <= 31;
1796 }
1797 return false;
1798 }
1799
1800 bool isMemThumbSPI() const {
1801 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1802 Memory.Alignment != 0)
1803 return false;
1804 // Immediate offset, multiple of 4 in range [0, 1020].
1805 if (!Memory.OffsetImm) return true;
1806 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1807 int64_t Val = CE->getValue();
1808 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1809 }
1810 return false;
1811 }
1812
1813 bool isMemImm8s4Offset() const {
1814 // If we have an immediate that's not a constant, treat it as a label
1815 // reference needing a fixup. If it is a constant, it's something else
1816 // and we reject it.
1817 if (isImm() && !isa<MCConstantExpr>(getImm()))
1818 return true;
1819 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1820 return false;
1821 // Immediate offset a multiple of 4 in range [-1020, 1020].
1822 if (!Memory.OffsetImm) return true;
1823 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1824 int64_t Val = CE->getValue();
1825 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1826 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1827 Val == std::numeric_limits<int32_t>::min();
1828 }
1829 return false;
1830 }
1831
1832 bool isMemImm7s4Offset() const {
1833 // If we have an immediate that's not a constant, treat it as a label
1834 // reference needing a fixup. If it is a constant, it's something else
1835 // and we reject it.
1836 if (isImm() && !isa<MCConstantExpr>(getImm()))
1837 return true;
1838 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1839 !getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1840 .contains(Memory.BaseRegNum))
1841 return false;
1842 // Immediate offset a multiple of 4 in range [-508, 508].
1843 if (!Memory.OffsetImm) return true;
1844 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1845 int64_t Val = CE->getValue();
1846 // Special case, #-0 is INT32_MIN.
1847 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1848 }
1849 return false;
1850 }
1851
1852 bool isMemImm0_1020s4Offset() const {
1853 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1854 return false;
1855 // Immediate offset a multiple of 4 in range [0, 1020].
1856 if (!Memory.OffsetImm) return true;
1857 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1858 int64_t Val = CE->getValue();
1859 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1860 }
1861 return false;
1862 }
1863
1864 bool isMemImm8Offset() const {
1865 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1866 return false;
1867 // Base reg of PC isn't allowed for these encodings.
1868 if (Memory.BaseRegNum == ARM::PC) return false;
1869 // Immediate offset in range [-255, 255].
1870 if (!Memory.OffsetImm) return true;
1871 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1872 int64_t Val = CE->getValue();
1873 return (Val == std::numeric_limits<int32_t>::min()) ||
1874 (Val > -256 && Val < 256);
1875 }
1876 return false;
1877 }
1878
1879 template<unsigned Bits, unsigned RegClassID>
1880 bool isMemImm7ShiftedOffset() const {
1881 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1882 !getARMMCRegisterClass(RegClassID).contains(Memory.BaseRegNum))
1883 return false;
1884
1885 // Expect an immediate offset equal to an element of the range
1886 // [-127, 127], shifted left by Bits.
1887
1888 if (!Memory.OffsetImm) return true;
1889 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1890 int64_t Val = CE->getValue();
1891
1892 // INT32_MIN is a special-case value (indicating the encoding with
1893 // zero offset and the subtract bit set)
1894 if (Val == INT32_MIN)
1895 return true;
1896
1897 unsigned Divisor = 1U << Bits;
1898
1899 // Check that the low bits are zero
1900 if (Val % Divisor != 0)
1901 return false;
1902
1903 // Check that the remaining offset is within range.
1904 Val /= Divisor;
1905 return (Val >= -127 && Val <= 127);
1906 }
1907 return false;
1908 }
1909
1910 template <int shift> bool isMemRegRQOffset() const {
1911 if (!isMVEMem() || Memory.OffsetImm != nullptr || Memory.Alignment != 0)
1912 return false;
1913
1914 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1915 .contains(Memory.BaseRegNum))
1916 return false;
1917 if (!getARMMCRegisterClass(ARM::MQPRRegClassID)
1918 .contains(Memory.OffsetRegNum))
1919 return false;
1920
1921 if (shift == 0 && Memory.ShiftType != ARM_AM::no_shift)
1922 return false;
1923
1924 if (shift > 0 &&
1925 (Memory.ShiftType != ARM_AM::uxtw || Memory.ShiftImm != shift))
1926 return false;
1927
1928 return true;
1929 }
1930
1931 template <int shift> bool isMemRegQOffset() const {
1932 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1933 return false;
1934
1935 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Memory.BaseRegNum))
1936 return false;
1937
1938 if (!Memory.OffsetImm)
1939 return true;
1940 static_assert(shift < 56,
1941 "Such that we dont shift by a value higher than 62");
1942 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1943 int64_t Val = CE->getValue();
1944
1945 // The value must be a multiple of (1 << shift)
1946 if ((Val & ((1U << shift) - 1)) != 0)
1947 return false;
1948
1949 // And be in the right range, depending on the amount that it is shifted
1950 // by. Shift 0, is equal to 7 unsigned bits, the sign bit is set
1951 // separately.
1952 int64_t Range = (1U << (7 + shift)) - 1;
1953 return (Val == INT32_MIN) || (Val > -Range && Val < Range);
1954 }
1955 return false;
1956 }
1957
1958 bool isMemPosImm8Offset() const {
1959 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1960 return false;
1961 // Immediate offset in range [0, 255].
1962 if (!Memory.OffsetImm) return true;
1963 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1964 int64_t Val = CE->getValue();
1965 return Val >= 0 && Val < 256;
1966 }
1967 return false;
1968 }
1969
1970 bool isMemNegImm8Offset() const {
1971 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1972 return false;
1973 // Base reg of PC isn't allowed for these encodings.
1974 if (Memory.BaseRegNum == ARM::PC) return false;
1975 // Immediate offset in range [-255, -1].
1976 if (!Memory.OffsetImm) return false;
1977 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1978 int64_t Val = CE->getValue();
1979 return (Val == std::numeric_limits<int32_t>::min()) ||
1980 (Val > -256 && Val < 0);
1981 }
1982 return false;
1983 }
1984
1985 bool isMemUImm12Offset() const {
1986 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1987 return false;
1988 // Immediate offset in range [0, 4095].
1989 if (!Memory.OffsetImm) return true;
1990 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1991 int64_t Val = CE->getValue();
1992 return (Val >= 0 && Val < 4096);
1993 }
1994 return false;
1995 }
1996
1997 bool isMemImm12Offset() const {
1998 // If we have an immediate that's not a constant, treat it as a label
1999 // reference needing a fixup. If it is a constant, it's something else
2000 // and we reject it.
2001
2002 if (isImm() && !isa<MCConstantExpr>(getImm()))
2003 return true;
2004
2005 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2006 return false;
2007 // Immediate offset in range [-4095, 4095].
2008 if (!Memory.OffsetImm) return true;
2009 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
2010 int64_t Val = CE->getValue();
2011 return (Val > -4096 && Val < 4096) ||
2012 (Val == std::numeric_limits<int32_t>::min());
2013 }
2014 // If we have an immediate that's not a constant, treat it as a
2015 // symbolic expression needing a fixup.
2016 return true;
2017 }
2018
2019 bool isConstPoolAsmImm() const {
2020 // Delay processing of Constant Pool Immediate, this will turn into
2021 // a constant. Match no other operand
2022 return (isConstantPoolImm());
2023 }
2024
2025 bool isPostIdxImm8() const {
2026 if (!isImm()) return false;
2027 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2028 if (!CE) return false;
2029 int64_t Val = CE->getValue();
2030 return (Val > -256 && Val < 256) ||
2031 (Val == std::numeric_limits<int32_t>::min());
2032 }
2033
2034 bool isPostIdxImm8s4() const {
2035 if (!isImm()) return false;
2036 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2037 if (!CE) return false;
2038 int64_t Val = CE->getValue();
2039 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2040 (Val == std::numeric_limits<int32_t>::min());
2041 }
2042
2043 bool isMSRMask() const { return Kind == k_MSRMask; }
2044 bool isBankedReg() const { return Kind == k_BankedReg; }
2045 bool isProcIFlags() const { return Kind == k_ProcIFlags; }
2046
2047 // NEON operands.
2048 bool isAnyVectorList() const {
2049 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2050 Kind == k_VectorListIndexed;
2051 }
2052
2053 bool isVectorList() const { return Kind == k_VectorList; }
2054
2055 bool isSingleSpacedVectorList() const {
2056 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2057 }
2058
2059 bool isDoubleSpacedVectorList() const {
2060 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2061 }
2062
2063 bool isVecListOneD() const {
2064 // We convert a single D reg to a list containing a D reg
2065 if (isDReg() && !Parser->hasMVE())
2066 return true;
2067 if (!isSingleSpacedVectorList()) return false;
2068 return VectorList.Count == 1;
2069 }
2070
2071 bool isVecListTwoMQ() const {
2072 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2073 getARMMCRegisterClass(ARM::MQPRRegClassID)
2074 .contains(VectorList.RegNum);
2075 }
2076
2077 bool isVecListDPair() const {
2078 // We convert a single Q reg to a list with the two corresponding D
2079 // registers
2080 if (isQReg() && !Parser->hasMVE())
2081 return true;
2082 if (!isSingleSpacedVectorList()) return false;
2083 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2084 .contains(VectorList.RegNum));
2085 }
2086
2087 bool isVecListThreeD() const {
2088 if (!isSingleSpacedVectorList()) return false;
2089 return VectorList.Count == 3;
2090 }
2091
2092 bool isVecListFourD() const {
2093 if (!isSingleSpacedVectorList()) return false;
2094 return VectorList.Count == 4;
2095 }
2096
2097 bool isVecListDPairSpaced() const {
2098 if (Kind != k_VectorList) return false;
2099 if (isSingleSpacedVectorList()) return false;
2100 return (getARMMCRegisterClass(ARM::DPairSpcRegClassID)
2101 .contains(VectorList.RegNum));
2102 }
2103
2104 bool isVecListThreeQ() const {
2105 if (!isDoubleSpacedVectorList()) return false;
2106 return VectorList.Count == 3;
2107 }
2108
2109 bool isVecListFourQ() const {
2110 if (!isDoubleSpacedVectorList()) return false;
2111 return VectorList.Count == 4;
2112 }
2113
2114 bool isVecListFourMQ() const {
2115 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2116 getARMMCRegisterClass(ARM::MQPRRegClassID)
2117 .contains(VectorList.RegNum);
2118 }
2119
2120 bool isSingleSpacedVectorAllLanes() const {
2121 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2122 }
2123
2124 bool isDoubleSpacedVectorAllLanes() const {
2125 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2126 }
2127
2128 bool isVecListOneDAllLanes() const {
2129 if (!isSingleSpacedVectorAllLanes()) return false;
2130 return VectorList.Count == 1;
2131 }
2132
2133 bool isVecListDPairAllLanes() const {
2134 if (!isSingleSpacedVectorAllLanes()) return false;
2135 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2136 .contains(VectorList.RegNum));
2137 }
2138
2139 bool isVecListDPairSpacedAllLanes() const {
2140 if (!isDoubleSpacedVectorAllLanes()) return false;
2141 return VectorList.Count == 2;
2142 }
2143
2144 bool isVecListThreeDAllLanes() const {
2145 if (!isSingleSpacedVectorAllLanes()) return false;
2146 return VectorList.Count == 3;
2147 }
2148
2149 bool isVecListThreeQAllLanes() const {
2150 if (!isDoubleSpacedVectorAllLanes()) return false;
2151 return VectorList.Count == 3;
2152 }
2153
2154 bool isVecListFourDAllLanes() const {
2155 if (!isSingleSpacedVectorAllLanes()) return false;
2156 return VectorList.Count == 4;
2157 }
2158
2159 bool isVecListFourQAllLanes() const {
2160 if (!isDoubleSpacedVectorAllLanes()) return false;
2161 return VectorList.Count == 4;
2162 }
2163
2164 bool isSingleSpacedVectorIndexed() const {
2165 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2166 }
2167
2168 bool isDoubleSpacedVectorIndexed() const {
2169 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2170 }
2171
2172 bool isVecListOneDByteIndexed() const {
2173 if (!isSingleSpacedVectorIndexed()) return false;
2174 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2175 }
2176
2177 bool isVecListOneDHWordIndexed() const {
2178 if (!isSingleSpacedVectorIndexed()) return false;
2179 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2180 }
2181
2182 bool isVecListOneDWordIndexed() const {
2183 if (!isSingleSpacedVectorIndexed()) return false;
2184 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2185 }
2186
2187 bool isVecListTwoDByteIndexed() const {
2188 if (!isSingleSpacedVectorIndexed()) return false;
2189 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2190 }
2191
2192 bool isVecListTwoDHWordIndexed() const {
2193 if (!isSingleSpacedVectorIndexed()) return false;
2194 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2195 }
2196
2197 bool isVecListTwoQWordIndexed() const {
2198 if (!isDoubleSpacedVectorIndexed()) return false;
2199 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2200 }
2201
2202 bool isVecListTwoQHWordIndexed() const {
2203 if (!isDoubleSpacedVectorIndexed()) return false;
2204 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2205 }
2206
2207 bool isVecListTwoDWordIndexed() const {
2208 if (!isSingleSpacedVectorIndexed()) return false;
2209 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2210 }
2211
2212 bool isVecListThreeDByteIndexed() const {
2213 if (!isSingleSpacedVectorIndexed()) return false;
2214 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2215 }
2216
2217 bool isVecListThreeDHWordIndexed() const {
2218 if (!isSingleSpacedVectorIndexed()) return false;
2219 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2220 }
2221
2222 bool isVecListThreeQWordIndexed() const {
2223 if (!isDoubleSpacedVectorIndexed()) return false;
2224 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2225 }
2226
2227 bool isVecListThreeQHWordIndexed() const {
2228 if (!isDoubleSpacedVectorIndexed()) return false;
2229 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2230 }
2231
2232 bool isVecListThreeDWordIndexed() const {
2233 if (!isSingleSpacedVectorIndexed()) return false;
2234 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2235 }
2236
2237 bool isVecListFourDByteIndexed() const {
2238 if (!isSingleSpacedVectorIndexed()) return false;
2239 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2240 }
2241
2242 bool isVecListFourDHWordIndexed() const {
2243 if (!isSingleSpacedVectorIndexed()) return false;
2244 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2245 }
2246
2247 bool isVecListFourQWordIndexed() const {
2248 if (!isDoubleSpacedVectorIndexed()) return false;
2249 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2250 }
2251
2252 bool isVecListFourQHWordIndexed() const {
2253 if (!isDoubleSpacedVectorIndexed()) return false;
2254 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2255 }
2256
2257 bool isVecListFourDWordIndexed() const {
2258 if (!isSingleSpacedVectorIndexed()) return false;
2259 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2260 }
2261
2262 bool isVectorIndex() const { return Kind == k_VectorIndex; }
2263
2264 template <unsigned NumLanes>
2265 bool isVectorIndexInRange() const {
2266 if (Kind != k_VectorIndex) return false;
2267 return VectorIndex.Val < NumLanes;
2268 }
2269
2270 bool isVectorIndex8() const { return isVectorIndexInRange<8>(); }
2271 bool isVectorIndex16() const { return isVectorIndexInRange<4>(); }
2272 bool isVectorIndex32() const { return isVectorIndexInRange<2>(); }
2273 bool isVectorIndex64() const { return isVectorIndexInRange<1>(); }
2274
2275 template<int PermittedValue, int OtherPermittedValue>
2276 bool isMVEPairVectorIndex() const {
2277 if (Kind != k_VectorIndex) return false;
2278 return VectorIndex.Val == PermittedValue ||
2279 VectorIndex.Val == OtherPermittedValue;
2280 }
2281
2282 bool isNEONi8splat() const {
2283 if (!isImm()) return false;
2284 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2285 // Must be a constant.
2286 if (!CE) return false;
2287 int64_t Value = CE->getValue();
2288 // i8 value splatted across 8 bytes. The immediate is just the 8 byte
2289 // value.
2290 return Value >= 0 && Value < 256;
2291 }
2292
2293 bool isNEONi16splat() const {
2294 if (isNEONByteReplicate(2))
2295 return false; // Leave that for bytes replication and forbid by default.
2296 if (!isImm())
2297 return false;
2298 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2299 // Must be a constant.
2300 if (!CE) return false;
2301 unsigned Value = CE->getValue();
2303 }
2304
2305 bool isNEONi16splatNot() const {
2306 if (!isImm())
2307 return false;
2308 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2309 // Must be a constant.
2310 if (!CE) return false;
2311 unsigned Value = CE->getValue();
2312 return ARM_AM::isNEONi16splat(~Value & 0xffff);
2313 }
2314
2315 bool isNEONi32splat() const {
2316 if (isNEONByteReplicate(4))
2317 return false; // Leave that for bytes replication and forbid by default.
2318 if (!isImm())
2319 return false;
2320 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2321 // Must be a constant.
2322 if (!CE) return false;
2323 unsigned Value = CE->getValue();
2325 }
2326
2327 bool isNEONi32splatNot() const {
2328 if (!isImm())
2329 return false;
2330 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2331 // Must be a constant.
2332 if (!CE) return false;
2333 unsigned Value = CE->getValue();
2335 }
2336
2337 static bool isValidNEONi32vmovImm(int64_t Value) {
2338 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
2339 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
2340 return ((Value & 0xffffffffffffff00) == 0) ||
2341 ((Value & 0xffffffffffff00ff) == 0) ||
2342 ((Value & 0xffffffffff00ffff) == 0) ||
2343 ((Value & 0xffffffff00ffffff) == 0) ||
2344 ((Value & 0xffffffffffff00ff) == 0xff) ||
2345 ((Value & 0xffffffffff00ffff) == 0xffff);
2346 }
2347
2348 bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const {
2349 assert((Width == 8 || Width == 16 || Width == 32) &&
2350 "Invalid element width");
2351 assert(NumElems * Width <= 64 && "Invalid result width");
2352
2353 if (!isImm())
2354 return false;
2355 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2356 // Must be a constant.
2357 if (!CE)
2358 return false;
2359 int64_t Value = CE->getValue();
2360 if (!Value)
2361 return false; // Don't bother with zero.
2362 if (Inv)
2363 Value = ~Value;
2364
2365 uint64_t Mask = (1ull << Width) - 1;
2366 uint64_t Elem = Value & Mask;
2367 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2368 return false;
2369 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2370 return false;
2371
2372 for (unsigned i = 1; i < NumElems; ++i) {
2373 Value >>= Width;
2374 if ((Value & Mask) != Elem)
2375 return false;
2376 }
2377 return true;
2378 }
2379
2380 bool isNEONByteReplicate(unsigned NumBytes) const {
2381 return isNEONReplicate(8, NumBytes, false);
2382 }
2383
2384 static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
2385 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2386 "Invalid source width");
2387 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2388 "Invalid destination width");
2389 assert(FromW < ToW && "ToW is not less than FromW");
2390 }
2391
2392 template<unsigned FromW, unsigned ToW>
2393 bool isNEONmovReplicate() const {
2394 checkNeonReplicateArgs(FromW, ToW);
2395 if (ToW == 64 && isNEONi64splat())
2396 return false;
2397 return isNEONReplicate(FromW, ToW / FromW, false);
2398 }
2399
2400 template<unsigned FromW, unsigned ToW>
2401 bool isNEONinvReplicate() const {
2402 checkNeonReplicateArgs(FromW, ToW);
2403 return isNEONReplicate(FromW, ToW / FromW, true);
2404 }
2405
2406 bool isNEONi32vmov() const {
2407 if (isNEONByteReplicate(4))
2408 return false; // Let it to be classified as byte-replicate case.
2409 if (!isImm())
2410 return false;
2411 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2412 // Must be a constant.
2413 if (!CE)
2414 return false;
2415 return isValidNEONi32vmovImm(CE->getValue());
2416 }
2417
2418 bool isNEONi32vmovNeg() const {
2419 if (!isImm()) return false;
2420 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2421 // Must be a constant.
2422 if (!CE) return false;
2423 return isValidNEONi32vmovImm(~CE->getValue());
2424 }
2425
2426 bool isNEONi64splat() const {
2427 if (!isImm()) return false;
2428 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2429 // Must be a constant.
2430 if (!CE) return false;
2431 uint64_t Value = CE->getValue();
2432 // i64 value with each byte being either 0 or 0xff.
2433 for (unsigned i = 0; i < 8; ++i, Value >>= 8)
2434 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
2435 return true;
2436 }
2437
2438 template<int64_t Angle, int64_t Remainder>
2439 bool isComplexRotation() const {
2440 if (!isImm()) return false;
2441
2442 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2443 if (!CE) return false;
2444 uint64_t Value = CE->getValue();
2445
2446 return (Value % Angle == Remainder && Value <= 270);
2447 }
2448
2449 bool isMVELongShift() const {
2450 if (!isImm()) return false;
2451 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2452 // Must be a constant.
2453 if (!CE) return false;
2454 uint64_t Value = CE->getValue();
2455 return Value >= 1 && Value <= 32;
2456 }
2457
2458 bool isMveSaturateOp() const {
2459 if (!isImm()) return false;
2460 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2461 if (!CE) return false;
2462 uint64_t Value = CE->getValue();
2463 return Value == 48 || Value == 64;
2464 }
2465
2466 bool isITCondCodeNoAL() const {
2467 if (!isITCondCode()) return false;
2469 return CC != ARMCC::AL;
2470 }
2471
2472 bool isITCondCodeRestrictedI() const {
2473 if (!isITCondCode())
2474 return false;
2476 return CC == ARMCC::EQ || CC == ARMCC::NE;
2477 }
2478
2479 bool isITCondCodeRestrictedS() const {
2480 if (!isITCondCode())
2481 return false;
2483 return CC == ARMCC::LT || CC == ARMCC::GT || CC == ARMCC::LE ||
2484 CC == ARMCC::GE;
2485 }
2486
2487 bool isITCondCodeRestrictedU() const {
2488 if (!isITCondCode())
2489 return false;
2491 return CC == ARMCC::HS || CC == ARMCC::HI;
2492 }
2493
2494 bool isITCondCodeRestrictedFP() const {
2495 if (!isITCondCode())
2496 return false;
2498 return CC == ARMCC::EQ || CC == ARMCC::NE || CC == ARMCC::LT ||
2499 CC == ARMCC::GT || CC == ARMCC::LE || CC == ARMCC::GE;
2500 }
2501
2502 void setVecListDPair(unsigned int DPair) {
2503 Kind = k_VectorList;
2504 VectorList.RegNum = DPair;
2505 VectorList.Count = 2;
2506 VectorList.isDoubleSpaced = false;
2507 }
2508
2509 void setVecListOneD(unsigned int DReg) {
2510 Kind = k_VectorList;
2511 VectorList.RegNum = DReg;
2512 VectorList.Count = 1;
2513 VectorList.isDoubleSpaced = false;
2514 }
2515
2516 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2517 // Add as immediates when possible. Null MCExpr = 0.
2518 if (!Expr)
2520 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2521 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2522 else
2524 }
2525
2526 void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const {
2527 assert(N == 1 && "Invalid number of operands!");
2528 addExpr(Inst, getImm());
2529 }
2530
2531 void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const {
2532 assert(N == 1 && "Invalid number of operands!");
2533 addExpr(Inst, getImm());
2534 }
2535
2536 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
2537 assert(N == 2 && "Invalid number of operands!");
2538 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2539 unsigned RegNum = getCondCode() == ARMCC::AL ? ARM::NoRegister : ARM::CPSR;
2540 Inst.addOperand(MCOperand::createReg(RegNum));
2541 }
2542
2543 void addVPTPredNOperands(MCInst &Inst, unsigned N) const {
2544 assert(N == 3 && "Invalid number of operands!");
2545 Inst.addOperand(MCOperand::createImm(unsigned(getVPTPred())));
2546 unsigned RegNum = getVPTPred() == ARMVCC::None ? ARM::NoRegister : ARM::P0;
2547 Inst.addOperand(MCOperand::createReg(RegNum));
2549 }
2550
2551 void addVPTPredROperands(MCInst &Inst, unsigned N) const {
2552 assert(N == 4 && "Invalid number of operands!");
2553 addVPTPredNOperands(Inst, N-1);
2554 MCRegister RegNum;
2555 if (getVPTPred() == ARMVCC::None) {
2556 RegNum = ARM::NoRegister;
2557 } else {
2558 unsigned NextOpIndex = Inst.getNumOperands();
2559 auto &MCID = Parser->getInstrDesc(Inst.getOpcode());
2560 int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO);
2561 assert(TiedOp >= 0 &&
2562 "Inactive register in vpred_r is not tied to an output!");
2563 RegNum = Inst.getOperand(TiedOp).getReg();
2564 }
2565 Inst.addOperand(MCOperand::createReg(RegNum));
2566 }
2567
2568 void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
2569 assert(N == 1 && "Invalid number of operands!");
2570 Inst.addOperand(MCOperand::createImm(getCoproc()));
2571 }
2572
2573 void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
2574 assert(N == 1 && "Invalid number of operands!");
2575 Inst.addOperand(MCOperand::createImm(getCoproc()));
2576 }
2577
2578 void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
2579 assert(N == 1 && "Invalid number of operands!");
2580 Inst.addOperand(MCOperand::createImm(CoprocOption.Val));
2581 }
2582
2583 void addITMaskOperands(MCInst &Inst, unsigned N) const {
2584 assert(N == 1 && "Invalid number of operands!");
2585 Inst.addOperand(MCOperand::createImm(ITMask.Mask));
2586 }
2587
2588 void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
2589 assert(N == 1 && "Invalid number of operands!");
2590 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2591 }
2592
2593 void addITCondCodeInvOperands(MCInst &Inst, unsigned N) const {
2594 assert(N == 1 && "Invalid number of operands!");
2596 }
2597
2598 void addCCOutOperands(MCInst &Inst, unsigned N) const {
2599 assert(N == 1 && "Invalid number of operands!");
2601 }
2602
2603 void addRegOperands(MCInst &Inst, unsigned N) const {
2604 assert(N == 1 && "Invalid number of operands!");
2606 }
2607
2608 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
2609 assert(N == 3 && "Invalid number of operands!");
2610 assert(isRegShiftedReg() &&
2611 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2612 Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg));
2613 Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg));
2615 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
2616 }
2617
2618 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
2619 assert(N == 2 && "Invalid number of operands!");
2620 assert(isRegShiftedImm() &&
2621 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2622 Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg));
2623 // Shift of #32 is encoded as 0 where permitted
2624 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2626 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
2627 }
2628
2629 void addShifterImmOperands(MCInst &Inst, unsigned N) const {
2630 assert(N == 1 && "Invalid number of operands!");
2631 Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) |
2632 ShifterImm.Imm));
2633 }
2634
2635 void addRegListOperands(MCInst &Inst, unsigned N) const {
2636 assert(N == 1 && "Invalid number of operands!");
2637 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2638 for (MCRegister Reg : RegList)
2640 }
2641
2642 void addRegListWithAPSROperands(MCInst &Inst, unsigned N) const {
2643 assert(N == 1 && "Invalid number of operands!");
2644 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2645 for (MCRegister Reg : RegList)
2647 }
2648
2649 void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
2650 addRegListOperands(Inst, N);
2651 }
2652
2653 void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
2654 addRegListOperands(Inst, N);
2655 }
2656
2657 void addFPSRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2658 addRegListOperands(Inst, N);
2659 }
2660
2661 void addFPDRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2662 addRegListOperands(Inst, N);
2663 }
2664
2665 void addRotImmOperands(MCInst &Inst, unsigned N) const {
2666 assert(N == 1 && "Invalid number of operands!");
2667 // Encoded as val>>3. The printer handles display as 8, 16, 24.
2668 Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3));
2669 }
2670
2671 void addModImmOperands(MCInst &Inst, unsigned N) const {
2672 assert(N == 1 && "Invalid number of operands!");
2673
2674 // Support for fixups (MCFixup)
2675 if (isImm())
2676 return addImmOperands(Inst, N);
2677
2678 Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7)));
2679 }
2680
2681 void addModImmNotOperands(MCInst &Inst, unsigned N) const {
2682 assert(N == 1 && "Invalid number of operands!");
2683 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2684 uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue());
2686 }
2687
2688 void addModImmNegOperands(MCInst &Inst, unsigned N) const {
2689 assert(N == 1 && "Invalid number of operands!");
2690 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2691 uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue());
2693 }
2694
2695 void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const {
2696 assert(N == 1 && "Invalid number of operands!");
2697 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2698 uint32_t Val = -CE->getValue();
2700 }
2701
2702 void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const {
2703 assert(N == 1 && "Invalid number of operands!");
2704 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2705 uint32_t Val = -CE->getValue();
2707 }
2708
2709 void addBitfieldOperands(MCInst &Inst, unsigned N) const {
2710 assert(N == 1 && "Invalid number of operands!");
2711 // Munge the lsb/width into a bitfield mask.
2712 unsigned lsb = Bitfield.LSB;
2713 unsigned width = Bitfield.Width;
2714 // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
2715 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2716 (32 - (lsb + width)));
2717 Inst.addOperand(MCOperand::createImm(Mask));
2718 }
2719
2720 void addImmOperands(MCInst &Inst, unsigned N) const {
2721 assert(N == 1 && "Invalid number of operands!");
2722 addExpr(Inst, getImm());
2723 }
2724
2725 void addFBits16Operands(MCInst &Inst, unsigned N) const {
2726 assert(N == 1 && "Invalid number of operands!");
2727 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2728 Inst.addOperand(MCOperand::createImm(16 - CE->getValue()));
2729 }
2730
2731 void addFBits32Operands(MCInst &Inst, unsigned N) const {
2732 assert(N == 1 && "Invalid number of operands!");
2733 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2734 Inst.addOperand(MCOperand::createImm(32 - CE->getValue()));
2735 }
2736
2737 void addFPImmOperands(MCInst &Inst, unsigned N) const {
2738 assert(N == 1 && "Invalid number of operands!");
2739 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2740 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
2742 }
2743
2744 void addImm8s4Operands(MCInst &Inst, unsigned N) const {
2745 assert(N == 1 && "Invalid number of operands!");
2746 // FIXME: We really want to scale the value here, but the LDRD/STRD
2747 // instruction don't encode operands that way yet.
2748 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2749 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2750 }
2751
2752 void addImm7s4Operands(MCInst &Inst, unsigned N) const {
2753 assert(N == 1 && "Invalid number of operands!");
2754 // FIXME: We really want to scale the value here, but the VSTR/VLDR_VSYSR
2755 // instruction don't encode operands that way yet.
2756 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2757 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2758 }
2759
2760 void addImm7Shift0Operands(MCInst &Inst, unsigned N) const {
2761 assert(N == 1 && "Invalid number of operands!");
2762 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2763 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2764 }
2765
2766 void addImm7Shift1Operands(MCInst &Inst, unsigned N) const {
2767 assert(N == 1 && "Invalid number of operands!");
2768 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2769 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2770 }
2771
2772 void addImm7Shift2Operands(MCInst &Inst, unsigned N) const {
2773 assert(N == 1 && "Invalid number of operands!");
2774 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2775 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2776 }
2777
2778 void addImm7Operands(MCInst &Inst, unsigned N) const {
2779 assert(N == 1 && "Invalid number of operands!");
2780 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2781 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2782 }
2783
2784 void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
2785 assert(N == 1 && "Invalid number of operands!");
2786 // The immediate is scaled by four in the encoding and is stored
2787 // in the MCInst as such. Lop off the low two bits here.
2788 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2789 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2790 }
2791
2792 void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
2793 assert(N == 1 && "Invalid number of operands!");
2794 // The immediate is scaled by four in the encoding and is stored
2795 // in the MCInst as such. Lop off the low two bits here.
2796 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2797 Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4)));
2798 }
2799
2800 void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
2801 assert(N == 1 && "Invalid number of operands!");
2802 // The immediate is scaled by four in the encoding and is stored
2803 // in the MCInst as such. Lop off the low two bits here.
2804 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2805 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2806 }
2807
2808 void addImm1_16Operands(MCInst &Inst, unsigned N) const {
2809 assert(N == 1 && "Invalid number of operands!");
2810 // The constant encodes as the immediate-1, and we store in the instruction
2811 // the bits as encoded, so subtract off one here.
2812 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2813 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2814 }
2815
2816 void addImm1_32Operands(MCInst &Inst, unsigned N) const {
2817 assert(N == 1 && "Invalid number of operands!");
2818 // The constant encodes as the immediate-1, and we store in the instruction
2819 // the bits as encoded, so subtract off one here.
2820 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2821 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2822 }
2823
2824 void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
2825 assert(N == 1 && "Invalid number of operands!");
2826 // The constant encodes as the immediate, except for 32, which encodes as
2827 // zero.
2828 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2829 unsigned Imm = CE->getValue();
2830 Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm)));
2831 }
2832
2833 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
2834 assert(N == 1 && "Invalid number of operands!");
2835 // An ASR value of 32 encodes as 0, so that's how we want to add it to
2836 // the instruction as well.
2837 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2838 int Val = CE->getValue();
2839 Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val));
2840 }
2841
2842 void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
2843 assert(N == 1 && "Invalid number of operands!");
2844 // The operand is actually a t2_so_imm, but we have its bitwise
2845 // negation in the assembly source, so twiddle it here.
2846 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2847 Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue()));
2848 }
2849
2850 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
2851 assert(N == 1 && "Invalid number of operands!");
2852 // The operand is actually a t2_so_imm, but we have its
2853 // negation in the assembly source, so twiddle it here.
2854 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2855 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2856 }
2857
2858 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
2859 assert(N == 1 && "Invalid number of operands!");
2860 // The operand is actually an imm0_4095, but we have its
2861 // negation in the assembly source, so twiddle it here.
2862 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2863 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2864 }
2865
2866 void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
2867 if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2868 Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2));
2869 return;
2870 }
2871 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2873 }
2874
2875 void addThumbMemPCOperands(MCInst &Inst, unsigned N) const {
2876 assert(N == 1 && "Invalid number of operands!");
2877 if (isImm()) {
2878 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2879 if (CE) {
2880 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2881 return;
2882 }
2883 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2885 return;
2886 }
2887
2888 assert(isGPRMem() && "Unknown value type!");
2889 assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!");
2890 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
2891 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2892 else
2893 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
2894 }
2895
2896 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
2897 assert(N == 1 && "Invalid number of operands!");
2898 Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt())));
2899 }
2900
2901 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2902 assert(N == 1 && "Invalid number of operands!");
2903 Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
2904 }
2905
2906 void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2907 assert(N == 1 && "Invalid number of operands!");
2908 Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt())));
2909 }
2910
2911 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
2912 assert(N == 1 && "Invalid number of operands!");
2913 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2914 }
2915
2916 void addMemNoOffsetT2Operands(MCInst &Inst, unsigned N) const {
2917 assert(N == 1 && "Invalid number of operands!");
2918 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2919 }
2920
2921 void addMemNoOffsetT2NoSpOperands(MCInst &Inst, unsigned N) const {
2922 assert(N == 1 && "Invalid number of operands!");
2923 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2924 }
2925
2926 void addMemNoOffsetTOperands(MCInst &Inst, unsigned N) const {
2927 assert(N == 1 && "Invalid number of operands!");
2928 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2929 }
2930
2931 void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
2932 assert(N == 1 && "Invalid number of operands!");
2933 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
2934 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2935 else
2936 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
2937 }
2938
2939 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
2940 assert(N == 1 && "Invalid number of operands!");
2941 assert(isImm() && "Not an immediate!");
2942
2943 // If we have an immediate that's not a constant, treat it as a label
2944 // reference needing a fixup.
2945 if (!isa<MCConstantExpr>(getImm())) {
2947 return;
2948 }
2949
2950 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2951 int Val = CE->getValue();
2953 }
2954
2955 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
2956 assert(N == 2 && "Invalid number of operands!");
2957 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2958 Inst.addOperand(MCOperand::createImm(Memory.Alignment));
2959 }
2960
2961 void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2962 addAlignedMemoryOperands(Inst, N);
2963 }
2964
2965 void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2966 addAlignedMemoryOperands(Inst, N);
2967 }
2968
2969 void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2970 addAlignedMemoryOperands(Inst, N);
2971 }
2972
2973 void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2974 addAlignedMemoryOperands(Inst, N);
2975 }
2976
2977 void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2978 addAlignedMemoryOperands(Inst, N);
2979 }
2980
2981 void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2982 addAlignedMemoryOperands(Inst, N);
2983 }
2984
2985 void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2986 addAlignedMemoryOperands(Inst, N);
2987 }
2988
2989 void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2990 addAlignedMemoryOperands(Inst, N);
2991 }
2992
2993 void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2994 addAlignedMemoryOperands(Inst, N);
2995 }
2996
2997 void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2998 addAlignedMemoryOperands(Inst, N);
2999 }
3000
3001 void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const {
3002 addAlignedMemoryOperands(Inst, N);
3003 }
3004
3005 void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
3006 assert(N == 3 && "Invalid number of operands!");
3007 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3008 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3009 if (!Memory.OffsetRegNum) {
3010 if (!Memory.OffsetImm)
3012 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3013 int32_t Val = CE->getValue();
3015 // Special case for #-0
3016 if (Val == std::numeric_limits<int32_t>::min())
3017 Val = 0;
3018 if (Val < 0)
3019 Val = -Val;
3020 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
3022 } else
3023 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3024 } else {
3025 // For register offset, we encode the shift type and negation flag
3026 // here.
3027 int32_t Val =
3028 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3029 Memory.ShiftImm, Memory.ShiftType);
3031 }
3032 }
3033
3034 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
3035 assert(N == 2 && "Invalid number of operands!");
3036 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3037 assert(CE && "non-constant AM2OffsetImm operand!");
3038 int32_t Val = CE->getValue();
3040 // Special case for #-0
3041 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3042 if (Val < 0) Val = -Val;
3043 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
3046 }
3047
3048 void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
3049 assert(N == 3 && "Invalid number of operands!");
3050 // If we have an immediate that's not a constant, treat it as a label
3051 // reference needing a fixup. If it is a constant, it's something else
3052 // and we reject it.
3053 if (isImm()) {
3057 return;
3058 }
3059
3060 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3061 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3062 if (!Memory.OffsetRegNum) {
3063 if (!Memory.OffsetImm)
3065 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3066 int32_t Val = CE->getValue();
3068 // Special case for #-0
3069 if (Val == std::numeric_limits<int32_t>::min())
3070 Val = 0;
3071 if (Val < 0)
3072 Val = -Val;
3073 Val = ARM_AM::getAM3Opc(AddSub, Val);
3075 } else
3076 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3077 } else {
3078 // For register offset, we encode the shift type and negation flag
3079 // here.
3080 int32_t Val =
3081 ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
3083 }
3084 }
3085
3086 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
3087 assert(N == 2 && "Invalid number of operands!");
3088 if (Kind == k_PostIndexRegister) {
3089 int32_t Val =
3090 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
3091 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3093 return;
3094 }
3095
3096 // Constant offset.
3097 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
3098 int32_t Val = CE->getValue();
3100 // Special case for #-0
3101 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3102 if (Val < 0) Val = -Val;
3103 Val = ARM_AM::getAM3Opc(AddSub, Val);
3106 }
3107
3108 void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
3109 assert(N == 2 && "Invalid number of operands!");
3110 // If we have an immediate that's not a constant, treat it as a label
3111 // reference needing a fixup. If it is a constant, it's something else
3112 // and we reject it.
3113 if (isImm()) {
3116 return;
3117 }
3118
3119 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3120 if (!Memory.OffsetImm)
3122 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3123 // The lower two bits are always zero and as such are not encoded.
3124 int32_t Val = CE->getValue() / 4;
3126 // Special case for #-0
3127 if (Val == std::numeric_limits<int32_t>::min())
3128 Val = 0;
3129 if (Val < 0)
3130 Val = -Val;
3131 Val = ARM_AM::getAM5Opc(AddSub, Val);
3133 } else
3134 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3135 }
3136
3137 void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const {
3138 assert(N == 2 && "Invalid number of operands!");
3139 // If we have an immediate that's not a constant, treat it as a label
3140 // reference needing a fixup. If it is a constant, it's something else
3141 // and we reject it.
3142 if (isImm()) {
3145 return;
3146 }
3147
3148 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3149 // The lower bit is always zero and as such is not encoded.
3150 if (!Memory.OffsetImm)
3152 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3153 int32_t Val = CE->getValue() / 2;
3155 // Special case for #-0
3156 if (Val == std::numeric_limits<int32_t>::min())
3157 Val = 0;
3158 if (Val < 0)
3159 Val = -Val;
3160 Val = ARM_AM::getAM5FP16Opc(AddSub, Val);
3162 } else
3163 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3164 }
3165
3166 void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
3167 assert(N == 2 && "Invalid number of operands!");
3168 // If we have an immediate that's not a constant, treat it as a label
3169 // reference needing a fixup. If it is a constant, it's something else
3170 // and we reject it.
3171 if (isImm()) {
3174 return;
3175 }
3176
3177 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3178 addExpr(Inst, Memory.OffsetImm);
3179 }
3180
3181 void addMemImm7s4OffsetOperands(MCInst &Inst, unsigned N) const {
3182 assert(N == 2 && "Invalid number of operands!");
3183 // If we have an immediate that's not a constant, treat it as a label
3184 // reference needing a fixup. If it is a constant, it's something else
3185 // and we reject it.
3186 if (isImm()) {
3189 return;
3190 }
3191
3192 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3193 addExpr(Inst, Memory.OffsetImm);
3194 }
3195
3196 void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
3197 assert(N == 2 && "Invalid number of operands!");
3198 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3199 if (!Memory.OffsetImm)
3201 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3202 // The lower two bits are always zero and as such are not encoded.
3203 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3204 else
3205 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3206 }
3207
3208 void addMemImmOffsetOperands(MCInst &Inst, unsigned N) const {
3209 assert(N == 2 && "Invalid number of operands!");
3210 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3211 addExpr(Inst, Memory.OffsetImm);
3212 }
3213
3214 void addMemRegRQOffsetOperands(MCInst &Inst, unsigned N) const {
3215 assert(N == 2 && "Invalid number of operands!");
3216 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3217 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3218 }
3219
3220 void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3221 assert(N == 2 && "Invalid number of operands!");
3222 // If this is an immediate, it's a label reference.
3223 if (isImm()) {
3224 addExpr(Inst, getImm());
3226 return;
3227 }
3228
3229 // Otherwise, it's a normal memory reg+offset.
3230 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3231 addExpr(Inst, Memory.OffsetImm);
3232 }
3233
3234 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3235 assert(N == 2 && "Invalid number of operands!");
3236 // If this is an immediate, it's a label reference.
3237 if (isImm()) {
3238 addExpr(Inst, getImm());
3240 return;
3241 }
3242
3243 // Otherwise, it's a normal memory reg+offset.
3244 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3245 addExpr(Inst, Memory.OffsetImm);
3246 }
3247
3248 void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const {
3249 assert(N == 1 && "Invalid number of operands!");
3250 // This is container for the immediate that we will create the constant
3251 // pool from
3252 addExpr(Inst, getConstantPoolImm());
3253 }
3254
3255 void addMemTBBOperands(MCInst &Inst, unsigned N) const {
3256 assert(N == 2 && "Invalid number of operands!");
3257 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3258 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3259 }
3260
3261 void addMemTBHOperands(MCInst &Inst, unsigned N) const {
3262 assert(N == 2 && "Invalid number of operands!");
3263 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3264 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3265 }
3266
3267 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3268 assert(N == 3 && "Invalid number of operands!");
3269 unsigned Val =
3270 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3271 Memory.ShiftImm, Memory.ShiftType);
3272 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3273 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3275 }
3276
3277 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3278 assert(N == 3 && "Invalid number of operands!");
3279 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3280 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3281 Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
3282 }
3283
3284 void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
3285 assert(N == 2 && "Invalid number of operands!");
3286 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3287 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3288 }
3289
3290 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
3291 assert(N == 2 && "Invalid number of operands!");
3292 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3293 if (!Memory.OffsetImm)
3295 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3296 // The lower two bits are always zero and as such are not encoded.
3297 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3298 else
3299 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3300 }
3301
3302 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
3303 assert(N == 2 && "Invalid number of operands!");
3304 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3305 if (!Memory.OffsetImm)
3307 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3308 Inst.addOperand(MCOperand::createImm(CE->getValue() / 2));
3309 else
3310 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3311 }
3312
3313 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
3314 assert(N == 2 && "Invalid number of operands!");
3315 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3316 addExpr(Inst, Memory.OffsetImm);
3317 }
3318
3319 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
3320 assert(N == 2 && "Invalid number of operands!");
3321 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3322 if (!Memory.OffsetImm)
3324 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3325 // The lower two bits are always zero and as such are not encoded.
3326 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3327 else
3328 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3329 }
3330
3331 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
3332 assert(N == 1 && "Invalid number of operands!");
3333 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3334 assert(CE && "non-constant post-idx-imm8 operand!");
3335 int Imm = CE->getValue();
3336 bool isAdd = Imm >= 0;
3337 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3338 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
3340 }
3341
3342 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
3343 assert(N == 1 && "Invalid number of operands!");
3344 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3345 assert(CE && "non-constant post-idx-imm8s4 operand!");
3346 int Imm = CE->getValue();
3347 bool isAdd = Imm >= 0;
3348 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3349 // Immediate is scaled by 4.
3350 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
3352 }
3353
3354 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
3355 assert(N == 2 && "Invalid number of operands!");
3356 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3357 Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
3358 }
3359
3360 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
3361 assert(N == 2 && "Invalid number of operands!");
3362 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3363 // The sign, shift type, and shift amount are encoded in a single operand
3364 // using the AM2 encoding helpers.
3365 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
3366 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
3367 PostIdxReg.ShiftTy);
3369 }
3370
3371 void addPowerTwoOperands(MCInst &Inst, unsigned N) const {
3372 assert(N == 1 && "Invalid number of operands!");
3373 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3374 Inst.addOperand(MCOperand::createImm(CE->getValue()));
3375 }
3376
3377 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
3378 assert(N == 1 && "Invalid number of operands!");
3379 Inst.addOperand(MCOperand::createImm(getMSRMask()));
3380 }
3381
3382 void addBankedRegOperands(MCInst &Inst, unsigned N) const {
3383 assert(N == 1 && "Invalid number of operands!");
3384 Inst.addOperand(MCOperand::createImm(getBankedReg()));
3385 }
3386
3387 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
3388 assert(N == 1 && "Invalid number of operands!");
3389 Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
3390 }
3391
3392 void addVecListOperands(MCInst &Inst, unsigned N) const {
3393 assert(N == 1 && "Invalid number of operands!");
3394
3395 if (isAnyVectorList())
3396 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3397 else if (isDReg() && !Parser->hasMVE()) {
3398 Inst.addOperand(MCOperand::createReg(Reg.RegNum));
3399 } else if (isQReg() && !Parser->hasMVE()) {
3400 MCRegister DPair = Parser->getDRegFromQReg(Reg.RegNum);
3401 DPair = Parser->getMRI()->getMatchingSuperReg(
3402 DPair, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
3403 Inst.addOperand(MCOperand::createReg(DPair));
3404 } else {
3405 LLVM_DEBUG(dbgs() << "TYPE: " << Kind << "\n");
3407 "attempted to add a vector list register with wrong type!");
3408 }
3409 }
3410
3411 void addMVEVecListOperands(MCInst &Inst, unsigned N) const {
3412 assert(N == 1 && "Invalid number of operands!");
3413
3414 // When we come here, the VectorList field will identify a range
3415 // of q-registers by its base register and length, and it will
3416 // have already been error-checked to be the expected length of
3417 // range and contain only q-regs in the range q0-q7. So we can
3418 // count on the base register being in the range q0-q6 (for 2
3419 // regs) or q0-q4 (for 4)
3420 //
3421 // The MVE instructions taking a register range of this kind will
3422 // need an operand in the MQQPR or MQQQQPR class, representing the
3423 // entire range as a unit. So we must translate into that class,
3424 // by finding the index of the base register in the MQPR reg
3425 // class, and returning the super-register at the corresponding
3426 // index in the target class.
3427
3428 const MCRegisterClass *RC_in = &getARMMCRegisterClass(ARM::MQPRRegClassID);
3429 const MCRegisterClass *RC_out =
3430 (VectorList.Count == 2)
3431 ? &getARMMCRegisterClass(ARM::MQQPRRegClassID)
3432 : &getARMMCRegisterClass(ARM::MQQQQPRRegClassID);
3433
3434 unsigned I, E = RC_out->getNumRegs();
3435 for (I = 0; I < E; I++)
3436 if (RC_in->getRegister(I) == VectorList.RegNum)
3437 break;
3438 assert(I < E && "Invalid vector list start register!");
3439
3441 }
3442
3443 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
3444 assert(N == 2 && "Invalid number of operands!");
3445 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3446 Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
3447 }
3448
3449 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
3450 assert(N == 1 && "Invalid number of operands!");
3451 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3452 }
3453
3454 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
3455 assert(N == 1 && "Invalid number of operands!");
3456 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3457 }
3458
3459 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
3460 assert(N == 1 && "Invalid number of operands!");
3461 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3462 }
3463
3464 void addVectorIndex64Operands(MCInst &Inst, unsigned N) const {
3465 assert(N == 1 && "Invalid number of operands!");
3466 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3467 }
3468
3469 void addMVEVectorIndexOperands(MCInst &Inst, unsigned N) const {
3470 assert(N == 1 && "Invalid number of operands!");
3471 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3472 }
3473
3474 void addMVEPairVectorIndexOperands(MCInst &Inst, unsigned N) const {
3475 assert(N == 1 && "Invalid number of operands!");
3476 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3477 }
3478
3479 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
3480 assert(N == 1 && "Invalid number of operands!");
3481 // The immediate encodes the type of constant as well as the value.
3482 // Mask in that this is an i8 splat.
3483 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3484 Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
3485 }
3486
3487 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
3488 assert(N == 1 && "Invalid number of operands!");
3489 // The immediate encodes the type of constant as well as the value.
3490 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3491 unsigned Value = CE->getValue();
3494 }
3495
3496 void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
3497 assert(N == 1 && "Invalid number of operands!");
3498 // The immediate encodes the type of constant as well as the value.
3499 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3500 unsigned Value = CE->getValue();
3503 }
3504
3505 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
3506 assert(N == 1 && "Invalid number of operands!");
3507 // The immediate encodes the type of constant as well as the value.
3508 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3509 unsigned Value = CE->getValue();
3512 }
3513
3514 void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
3515 assert(N == 1 && "Invalid number of operands!");
3516 // The immediate encodes the type of constant as well as the value.
3517 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3518 unsigned Value = CE->getValue();
3521 }
3522
3523 void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
3524 // The immediate encodes the type of constant as well as the value.
3525 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3526 assert((Inst.getOpcode() == ARM::VMOVv8i8 ||
3527 Inst.getOpcode() == ARM::VMOVv16i8) &&
3528 "All instructions that wants to replicate non-zero byte "
3529 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3530 unsigned Value = CE->getValue();
3531 if (Inv)
3532 Value = ~Value;
3533 unsigned B = Value & 0xff;
3534 B |= 0xe00; // cmode = 0b1110
3536 }
3537
3538 void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3539 assert(N == 1 && "Invalid number of operands!");
3540 addNEONi8ReplicateOperands(Inst, true);
3541 }
3542
3543 static unsigned encodeNeonVMOVImmediate(unsigned Value) {
3544 if (Value >= 256 && Value <= 0xffff)
3545 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
3546 else if (Value > 0xffff && Value <= 0xffffff)
3547 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
3548 else if (Value > 0xffffff)
3549 Value = (Value >> 24) | 0x600;
3550 return Value;
3551 }
3552
3553 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
3554 assert(N == 1 && "Invalid number of operands!");
3555 // The immediate encodes the type of constant as well as the value.
3556 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3557 unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
3559 }
3560
3561 void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3562 assert(N == 1 && "Invalid number of operands!");
3563 addNEONi8ReplicateOperands(Inst, false);
3564 }
3565
3566 void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
3567 assert(N == 1 && "Invalid number of operands!");
3568 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3569 assert((Inst.getOpcode() == ARM::VMOVv4i16 ||
3570 Inst.getOpcode() == ARM::VMOVv8i16 ||
3571 Inst.getOpcode() == ARM::VMVNv4i16 ||
3572 Inst.getOpcode() == ARM::VMVNv8i16) &&
3573 "All instructions that want to replicate non-zero half-word "
3574 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3575 uint64_t Value = CE->getValue();
3576 unsigned Elem = Value & 0xffff;
3577 if (Elem >= 256)
3578 Elem = (Elem >> 8) | 0x200;
3579 Inst.addOperand(MCOperand::createImm(Elem));
3580 }
3581
3582 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
3583 assert(N == 1 && "Invalid number of operands!");
3584 // The immediate encodes the type of constant as well as the value.
3585 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3586 unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
3588 }
3589
3590 void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
3591 assert(N == 1 && "Invalid number of operands!");
3592 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3593 assert((Inst.getOpcode() == ARM::VMOVv2i32 ||
3594 Inst.getOpcode() == ARM::VMOVv4i32 ||
3595 Inst.getOpcode() == ARM::VMVNv2i32 ||
3596 Inst.getOpcode() == ARM::VMVNv4i32) &&
3597 "All instructions that want to replicate non-zero word "
3598 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3599 uint64_t Value = CE->getValue();
3600 unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
3601 Inst.addOperand(MCOperand::createImm(Elem));
3602 }
3603
3604 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
3605 assert(N == 1 && "Invalid number of operands!");
3606 // The immediate encodes the type of constant as well as the value.
3607 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3608 uint64_t Value = CE->getValue();
3609 unsigned Imm = 0;
3610 for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
3611 Imm |= (Value & 1) << i;
3612 }
3613 Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
3614 }
3615
3616 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
3617 assert(N == 1 && "Invalid number of operands!");
3618 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3619 Inst.addOperand(MCOperand::createImm(CE->getValue() / 90));
3620 }
3621
3622 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
3623 assert(N == 1 && "Invalid number of operands!");
3624 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3625 Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
3626 }
3627
3628 void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
3629 assert(N == 1 && "Invalid number of operands!");
3630 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3631 unsigned Imm = CE->getValue();
3632 assert((Imm == 48 || Imm == 64) && "Invalid saturate operand");
3633 Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0));
3634 }
3635
3636 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;
3637
3638 static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S,
3639 ARMAsmParser &Parser) {
3640 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3641 Op->ITMask.Mask = Mask;
3642 Op->StartLoc = S;
3643 Op->EndLoc = S;
3644 return Op;
3645 }
3646
3647 static std::unique_ptr<ARMOperand>
3648 CreateCondCode(ARMCC::CondCodes CC, SMLoc S, ARMAsmParser &Parser) {
3649 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3650 Op->CC.Val = CC;
3651 Op->StartLoc = S;
3652 Op->EndLoc = S;
3653 return Op;
3654 }
3655
3656 static std::unique_ptr<ARMOperand> CreateVPTPred(ARMVCC::VPTCodes CC, SMLoc S,
3657 ARMAsmParser &Parser) {
3658 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3659 Op->VCC.Val = CC;
3660 Op->StartLoc = S;
3661 Op->EndLoc = S;
3662 return Op;
3663 }
3664
3665 static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S,
3666 ARMAsmParser &Parser) {
3667 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3668 Op->Cop.Val = CopVal;
3669 Op->StartLoc = S;
3670 Op->EndLoc = S;
3671 return Op;
3672 }
3673
3674 static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S,
3675 ARMAsmParser &Parser) {
3676 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3677 Op->Cop.Val = CopVal;
3678 Op->StartLoc = S;
3679 Op->EndLoc = S;
3680 return Op;
3681 }
3682
3683 static std::unique_ptr<ARMOperand>
3684 CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3685 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3686 Op->Cop.Val = Val;
3687 Op->StartLoc = S;
3688 Op->EndLoc = E;
3689 return Op;
3690 }
3691
3692 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister Reg, SMLoc S,
3693 ARMAsmParser &Parser) {
3694 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3695 Op->Reg.RegNum = Reg;
3696 Op->StartLoc = S;
3697 Op->EndLoc = S;
3698 return Op;
3699 }
3700
3701 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3702 ARMAsmParser &Parser) {
3703 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3704 Op->Tok.Data = Str.data();
3705 Op->Tok.Length = Str.size();
3706 Op->StartLoc = S;
3707 Op->EndLoc = S;
3708 return Op;
3709 }
3710
3711 static std::unique_ptr<ARMOperand> CreateReg(MCRegister Reg, SMLoc S, SMLoc E,
3712 ARMAsmParser &Parser) {
3713 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3714 Op->Reg.RegNum = Reg;
3715 Op->StartLoc = S;
3716 Op->EndLoc = E;
3717 return Op;
3718 }
3719
3720 static std::unique_ptr<ARMOperand>
3721 CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, MCRegister SrcReg,
3722 MCRegister ShiftReg, unsigned ShiftImm, SMLoc S,
3723 SMLoc E, ARMAsmParser &Parser) {
3724 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3725 Op->RegShiftedReg.ShiftTy = ShTy;
3726 Op->RegShiftedReg.SrcReg = SrcReg;
3727 Op->RegShiftedReg.ShiftReg = ShiftReg;
3728 Op->RegShiftedReg.ShiftImm = ShiftImm;
3729 Op->StartLoc = S;
3730 Op->EndLoc = E;
3731 return Op;
3732 }
3733
3734 static std::unique_ptr<ARMOperand>
3735 CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, MCRegister SrcReg,
3736 unsigned ShiftImm, SMLoc S, SMLoc E,
3737 ARMAsmParser &Parser) {
3738 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3739 Op->RegShiftedImm.ShiftTy = ShTy;
3740 Op->RegShiftedImm.SrcReg = SrcReg;
3741 Op->RegShiftedImm.ShiftImm = ShiftImm;
3742 Op->StartLoc = S;
3743 Op->EndLoc = E;
3744 return Op;
3745 }
3746
3747 static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm,
3748 SMLoc S, SMLoc E,
3749 ARMAsmParser &Parser) {
3750 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3751 Op->ShifterImm.isASR = isASR;
3752 Op->ShifterImm.Imm = Imm;
3753 Op->StartLoc = S;
3754 Op->EndLoc = E;
3755 return Op;
3756 }
3757
3758 static std::unique_ptr<ARMOperand>
3759 CreateRotImm(unsigned Imm, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3760 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3761 Op->RotImm.Imm = Imm;
3762 Op->StartLoc = S;
3763 Op->EndLoc = E;
3764 return Op;
3765 }
3766
3767 static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
3768 SMLoc S, SMLoc E,
3769 ARMAsmParser &Parser) {
3770 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3771 Op->ModImm.Bits = Bits;
3772 Op->ModImm.Rot = Rot;
3773 Op->StartLoc = S;
3774 Op->EndLoc = E;
3775 return Op;
3776 }
3777
3778 static std::unique_ptr<ARMOperand>
3779 CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E,
3780 ARMAsmParser &Parser) {
3781 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3782 Op->Imm.Val = Val;
3783 Op->StartLoc = S;
3784 Op->EndLoc = E;
3785 return Op;
3786 }
3787
3788 static std::unique_ptr<ARMOperand> CreateBitfield(unsigned LSB,
3789 unsigned Width, SMLoc S,
3790 SMLoc E,
3791 ARMAsmParser &Parser) {
3792 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3793 Op->Bitfield.LSB = LSB;
3794 Op->Bitfield.Width = Width;
3795 Op->StartLoc = S;
3796 Op->EndLoc = E;
3797 return Op;
3798 }
3799
3800 static std::unique_ptr<ARMOperand>
3801 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3802 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3803 assert(Regs.size() > 0 && "RegList contains no registers?");
3804 KindTy Kind = k_RegisterList;
3805
3806 if (getARMMCRegisterClass(ARM::DPRRegClassID)
3807 .contains(Regs.front().second)) {
3808 if (Regs.back().second == ARM::VPR)
3809 Kind = k_FPDRegisterListWithVPR;
3810 else
3811 Kind = k_DPRRegisterList;
3812 } else if (getARMMCRegisterClass(ARM::SPRRegClassID)
3813 .contains(Regs.front().second)) {
3814 if (Regs.back().second == ARM::VPR)
3815 Kind = k_FPSRegisterListWithVPR;
3816 else
3817 Kind = k_SPRRegisterList;
3818 } else if (Regs.front().second == ARM::VPR) {
3819 assert(Regs.size() == 1 &&
3820 "Register list starting with VPR expected to only contain VPR");
3821 Kind = k_FPSRegisterListWithVPR;
3822 }
3823
3824 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3825 Kind = k_RegisterListWithAPSR;
3826
3827 assert(llvm::is_sorted(Regs) && "Register list must be sorted by encoding");
3828
3829 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3830 for (const auto &P : Regs)
3831 Op->Registers.push_back(P.second);
3832
3833 Op->StartLoc = StartLoc;
3834 Op->EndLoc = EndLoc;
3835 return Op;
3836 }
3837
3838 static std::unique_ptr<ARMOperand>
3839 CreateVectorList(MCRegister Reg, unsigned Count, bool isDoubleSpaced, SMLoc S,
3840 SMLoc E, ARMAsmParser &Parser) {
3841 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3842 Op->VectorList.RegNum = Reg;
3843 Op->VectorList.Count = Count;
3844 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3845 Op->StartLoc = S;
3846 Op->EndLoc = E;
3847 return Op;
3848 }
3849
3850 static std::unique_ptr<ARMOperand>
3851 CreateVectorListAllLanes(MCRegister Reg, unsigned Count, bool isDoubleSpaced,
3852 SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3853 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3854 Op->VectorList.RegNum = Reg;
3855 Op->VectorList.Count = Count;
3856 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3857 Op->StartLoc = S;
3858 Op->EndLoc = E;
3859 return Op;
3860 }
3861
3862 static std::unique_ptr<ARMOperand>
3863 CreateVectorListIndexed(MCRegister Reg, unsigned Count, unsigned Index,
3864 bool isDoubleSpaced, SMLoc S, SMLoc E,
3865 ARMAsmParser &Parser) {
3866 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3867 Op->VectorList.RegNum = Reg;
3868 Op->VectorList.Count = Count;
3869 Op->VectorList.LaneIndex = Index;
3870 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3871 Op->StartLoc = S;
3872 Op->EndLoc = E;
3873 return Op;
3874 }
3875
3876 static std::unique_ptr<ARMOperand> CreateVectorIndex(unsigned Idx, SMLoc S,
3877 SMLoc E, MCContext &Ctx,
3878 ARMAsmParser &Parser) {
3879 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3880 Op->VectorIndex.Val = Idx;
3881 Op->StartLoc = S;
3882 Op->EndLoc = E;
3883 return Op;
3884 }
3885
3886 static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S,
3887 SMLoc E, ARMAsmParser &Parser) {
3888 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3889 Op->Imm.Val = Val;
3890 Op->StartLoc = S;
3891 Op->EndLoc = E;
3892 return Op;
3893 }
3894
3895 static std::unique_ptr<ARMOperand>
3896 CreateMem(MCRegister BaseReg, const MCExpr *OffsetImm, MCRegister OffsetReg,
3897 ARM_AM::ShiftOpc ShiftType, unsigned ShiftImm, unsigned Alignment,
3898 bool isNegative, SMLoc S, SMLoc E, ARMAsmParser &Parser,
3899 SMLoc AlignmentLoc = SMLoc()) {
3900 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3901 Op->Memory.BaseRegNum = BaseReg;
3902 Op->Memory.OffsetImm = OffsetImm;
3903 Op->Memory.OffsetRegNum = OffsetReg;
3904 Op->Memory.ShiftType = ShiftType;
3905 Op->Memory.ShiftImm = ShiftImm;
3906 Op->Memory.Alignment = Alignment;
3907 Op->Memory.isNegative = isNegative;
3908 Op->StartLoc = S;
3909 Op->EndLoc = E;
3910 Op->AlignmentLoc = AlignmentLoc;
3911 return Op;
3912 }
3913
3914 static std::unique_ptr<ARMOperand>
3915 CreatePostIdxReg(MCRegister Reg, bool isAdd, ARM_AM::ShiftOpc ShiftTy,
3916 unsigned ShiftImm, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3917 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3918 Op->PostIdxReg.RegNum = Reg;
3919 Op->PostIdxReg.isAdd = isAdd;
3920 Op->PostIdxReg.ShiftTy = ShiftTy;
3921 Op->PostIdxReg.ShiftImm = ShiftImm;
3922 Op->StartLoc = S;
3923 Op->EndLoc = E;
3924 return Op;
3925 }
3926
3927 static std::unique_ptr<ARMOperand>
3928 CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3929 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3930 Op->MBOpt.Val = Opt;
3931 Op->StartLoc = S;
3932 Op->EndLoc = S;
3933 return Op;
3934 }
3935
3936 static std::unique_ptr<ARMOperand>
3937 CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S,
3938 ARMAsmParser &Parser) {
3939 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3940 Op->ISBOpt.Val = Opt;
3941 Op->StartLoc = S;
3942 Op->EndLoc = S;
3943 return Op;
3944 }
3945
3946 static std::unique_ptr<ARMOperand>
3947 CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S,
3948 ARMAsmParser &Parser) {
3949 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3950 Op->TSBOpt.Val = Opt;
3951 Op->StartLoc = S;
3952 Op->EndLoc = S;
3953 return Op;
3954 }
3955
3956 static std::unique_ptr<ARMOperand>
3957 CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S, ARMAsmParser &Parser) {
3958 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3959 Op->IFlags.Val = IFlags;
3960 Op->StartLoc = S;
3961 Op->EndLoc = S;
3962 return Op;
3963 }
3964
3965 static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S,
3966 ARMAsmParser &Parser) {
3967 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3968 Op->MMask.Val = MMask;
3969 Op->StartLoc = S;
3970 Op->EndLoc = S;
3971 return Op;
3972 }
3973
3974 static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S,
3975 ARMAsmParser &Parser) {
3976 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3977 Op->BankedReg.Val = Reg;
3978 Op->StartLoc = S;
3979 Op->EndLoc = S;
3980 return Op;
3981 }
3982};
3983
3984} // end anonymous namespace.
3985
3986void ARMOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
3987 auto RegName = [](MCRegister Reg) {
3988 if (Reg)
3990 else
3991 return "noreg";
3992 };
3993
3994 switch (Kind) {
3995 case k_CondCode:
3996 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
3997 break;
3998 case k_VPTPred:
3999 OS << "<ARMVCC::" << ARMVPTPredToString(getVPTPred()) << ">";
4000 break;
4001 case k_CCOut:
4002 OS << "<ccout " << RegName(getReg()) << ">";
4003 break;
4004 case k_ITCondMask: {
4005 static const char *const MaskStr[] = {
4006 "(invalid)", "(tttt)", "(ttt)", "(ttte)",
4007 "(tt)", "(ttet)", "(tte)", "(ttee)",
4008 "(t)", "(tett)", "(tet)", "(tete)",
4009 "(te)", "(teet)", "(tee)", "(teee)",
4010 };
4011 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4012 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
4013 break;
4014 }
4015 case k_CoprocNum:
4016 OS << "<coprocessor number: " << getCoproc() << ">";
4017 break;
4018 case k_CoprocReg:
4019 OS << "<coprocessor register: " << getCoproc() << ">";
4020 break;
4021 case k_CoprocOption:
4022 OS << "<coprocessor option: " << CoprocOption.Val << ">";
4023 break;
4024 case k_MSRMask:
4025 OS << "<mask: " << getMSRMask() << ">";
4026 break;
4027 case k_BankedReg:
4028 OS << "<banked reg: " << getBankedReg() << ">";
4029 break;
4030 case k_Immediate:
4031 MAI.printExpr(OS, *getImm());
4032 break;
4033 case k_MemBarrierOpt:
4034 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
4035 break;
4036 case k_InstSyncBarrierOpt:
4037 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
4038 break;
4039 case k_TraceSyncBarrierOpt:
4040 OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
4041 break;
4042 case k_Memory:
4043 OS << "<memory";
4044 if (Memory.BaseRegNum)
4045 OS << " base:" << RegName(Memory.BaseRegNum);
4046 if (Memory.OffsetImm) {
4047 OS << " offset-imm:";
4048 MAI.printExpr(OS, *Memory.OffsetImm);
4049 }
4050 if (Memory.OffsetRegNum)
4051 OS << " offset-reg:" << (Memory.isNegative ? "-" : "")
4052 << RegName(Memory.OffsetRegNum);
4053 if (Memory.ShiftType != ARM_AM::no_shift) {
4054 OS << " shift-type:" << ARM_AM::getShiftOpcStr(Memory.ShiftType);
4055 OS << " shift-imm:" << Memory.ShiftImm;
4056 }
4057 if (Memory.Alignment)
4058 OS << " alignment:" << Memory.Alignment;
4059 OS << ">";
4060 break;
4061 case k_PostIndexRegister:
4062 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
4063 << RegName(PostIdxReg.RegNum);
4064 if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
4065 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
4066 << PostIdxReg.ShiftImm;
4067 OS << ">";
4068 break;
4069 case k_ProcIFlags: {
4070 OS << "<ARM_PROC::";
4071 unsigned IFlags = getProcIFlags();
4072 for (int i=2; i >= 0; --i)
4073 if (IFlags & (1 << i))
4074 OS << ARM_PROC::IFlagsToString(1 << i);
4075 OS << ">";
4076 break;
4077 }
4078 case k_Register:
4079 OS << "<register " << RegName(getReg()) << ">";
4080 break;
4081 case k_ShifterImmediate:
4082 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
4083 << " #" << ShifterImm.Imm << ">";
4084 break;
4085 case k_ShiftedRegister:
4086 OS << "<so_reg_reg " << RegName(RegShiftedReg.SrcReg) << " "
4087 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) << " "
4088 << RegName(RegShiftedReg.ShiftReg) << ">";
4089 break;
4090 case k_ShiftedImmediate:
4091 OS << "<so_reg_imm " << RegName(RegShiftedImm.SrcReg) << " "
4092 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) << " #"
4093 << RegShiftedImm.ShiftImm << ">";
4094 break;
4095 case k_RotateImmediate:
4096 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
4097 break;
4098 case k_ModifiedImmediate:
4099 OS << "<mod_imm #" << ModImm.Bits << ", #"
4100 << ModImm.Rot << ")>";
4101 break;
4102 case k_ConstantPoolImmediate:
4103 OS << "<constant_pool_imm #";
4104 MAI.printExpr(OS, *getConstantPoolImm());
4105 break;
4106 case k_BitfieldDescriptor:
4107 OS << "<bitfield " << "lsb: " << Bitfield.LSB
4108 << ", width: " << Bitfield.Width << ">";
4109 break;
4110 case k_RegisterList:
4111 case k_RegisterListWithAPSR:
4112 case k_DPRRegisterList:
4113 case k_SPRRegisterList:
4114 case k_FPSRegisterListWithVPR:
4115 case k_FPDRegisterListWithVPR: {
4116 OS << "<register_list ";
4117
4118 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4119 for (auto I = RegList.begin(), E = RegList.end(); I != E;) {
4120 OS << RegName(*I);
4121 if (++I < E) OS << ", ";
4122 }
4123
4124 OS << ">";
4125 break;
4126 }
4127 case k_VectorList:
4128 OS << "<vector_list " << VectorList.Count << " * "
4129 << RegName(VectorList.RegNum) << ">";
4130 break;
4131 case k_VectorListAllLanes:
4132 OS << "<vector_list(all lanes) " << VectorList.Count << " * "
4133 << RegName(VectorList.RegNum) << ">";
4134 break;
4135 case k_VectorListIndexed:
4136 OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
4137 << VectorList.Count << " * " << RegName(VectorList.RegNum) << ">";
4138 break;
4139 case k_Token:
4140 OS << "'" << getToken() << "'";
4141 break;
4142 case k_VectorIndex:
4143 OS << "<vectorindex " << getVectorIndex() << ">";
4144 break;
4145 }
4146}
4147
4148/// @name Auto-generated Match Functions
4149/// {
4150
4152
4153/// }
4154
4155static bool isDataTypeToken(StringRef Tok) {
4156 static const DenseSet<StringRef> DataTypes{
4157 ".8", ".16", ".32", ".64", ".i8", ".i16", ".i32", ".i64",
4158 ".u8", ".u16", ".u32", ".u64", ".s8", ".s16", ".s32", ".s64",
4159 ".p8", ".p16", ".f32", ".f64", ".f", ".d"};
4160 return DataTypes.contains(Tok);
4161}
4162
4164 unsigned MnemonicOpsEndInd = 1;
4165 // Special case for CPS which has a Mnemonic side token for possibly storing
4166 // ie/id variant
4167 if (Operands[0]->isToken() &&
4168 static_cast<ARMOperand &>(*Operands[0]).getToken() == "cps") {
4169 if (Operands.size() > 1 && Operands[1]->isImm() &&
4170 static_cast<ARMOperand &>(*Operands[1]).getImm()->getKind() ==
4173 static_cast<ARMOperand &>(*Operands[1]).getImm())
4174 ->getValue() == ARM_PROC::IE ||
4176 static_cast<ARMOperand &>(*Operands[1]).getImm())
4177 ->getValue() == ARM_PROC::ID))
4178 ++MnemonicOpsEndInd;
4179 }
4180
4181 // In some circumstances the condition code moves to the right
4182 bool RHSCondCode = false;
4183 while (MnemonicOpsEndInd < Operands.size()) {
4184 auto Op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
4185 // Special case for it instructions which have a condition code on the RHS
4186 if (Op.isITMask()) {
4187 RHSCondCode = true;
4188 MnemonicOpsEndInd++;
4189 } else if (Op.isToken() &&
4190 (
4191 // There are several special cases not covered by
4192 // isDataTypeToken
4193 Op.getToken() == ".w" || Op.getToken() == ".bf16" ||
4194 Op.getToken() == ".p64" || Op.getToken() == ".f16" ||
4195 isDataTypeToken(Op.getToken()))) {
4196 // In the mnemonic operators the cond code must always precede the data
4197 // type. So we can now safely assume any subsequent cond code is on the
4198 // RHS. As is the case for VCMP and VPT.
4199 RHSCondCode = true;
4200 MnemonicOpsEndInd++;
4201 }
4202 // Skip all mnemonic operator types
4203 else if (Op.isCCOut() || (Op.isCondCode() && !RHSCondCode) ||
4204 Op.isVPTPred() || (Op.isToken() && Op.getToken() == ".w"))
4205 MnemonicOpsEndInd++;
4206 else
4207 break;
4208 }
4209 return MnemonicOpsEndInd;
4210}
4211
4212bool ARMAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
4213 SMLoc &EndLoc) {
4214 const AsmToken &Tok = getParser().getTok();
4215 StartLoc = Tok.getLoc();
4216 EndLoc = Tok.getEndLoc();
4217 Reg = tryParseRegister();
4218
4219 return !Reg;
4220}
4221
4222ParseStatus ARMAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
4223 SMLoc &EndLoc) {
4224 if (parseRegister(Reg, StartLoc, EndLoc))
4225 return ParseStatus::NoMatch;
4226 return ParseStatus::Success;
4227}
4228
4229/// Try to parse a register name. The token must be an Identifier when called,
4230/// and if it is a register name the token is eaten and the register is
4231/// returned. Otherwise return an invalid MCRegister.
4232MCRegister ARMAsmParser::tryParseRegister(bool AllowOutOfBoundReg) {
4233 MCAsmParser &Parser = getParser();
4234 const AsmToken &Tok = Parser.getTok();
4235 if (Tok.isNot(AsmToken::Identifier))
4236 return MCRegister();
4237
4238 std::string lowerCase = Tok.getString().lower();
4239 MCRegister Reg = MatchRegisterName(lowerCase);
4240 if (!Reg) {
4241 Reg = StringSwitch<MCRegister>(lowerCase)
4242 .Case("r13", ARM::SP)
4243 .Case("r14", ARM::LR)
4244 .Case("r15", ARM::PC)
4245 .Case("ip", ARM::R12)
4246 // Additional register name aliases for 'gas' compatibility.
4247 .Case("a1", ARM::R0)
4248 .Case("a2", ARM::R1)
4249 .Case("a3", ARM::R2)
4250 .Case("a4", ARM::R3)
4251 .Case("v1", ARM::R4)
4252 .Case("v2", ARM::R5)
4253 .Case("v3", ARM::R6)
4254 .Case("v4", ARM::R7)
4255 .Case("v5", ARM::R8)
4256 .Case("v6", ARM::R9)
4257 .Case("v7", ARM::R10)
4258 .Case("v8", ARM::R11)
4259 .Case("sb", ARM::R9)
4260 .Case("sl", ARM::R10)
4261 .Case("fp", ARM::R11)
4262 .Default(MCRegister());
4263 }
4264 if (!Reg) {
4265 // Check for aliases registered via .req. Canonicalize to lower case.
4266 // That's more consistent since register names are case insensitive, and
4267 // it's how the original entry was passed in from MC/MCParser/AsmParser.
4268 auto Entry = RegisterReqs.find(lowerCase);
4269 // If no match, return failure.
4270 if (Entry == RegisterReqs.end())
4271 return MCRegister();
4272 Parser.Lex(); // Eat identifier token.
4273 return Entry->getValue();
4274 }
4275
4276 // Some FPUs only have 16 D registers, so D16-D31 are invalid
4277 if (!AllowOutOfBoundReg && !hasD32() && Reg >= ARM::D16 && Reg <= ARM::D31)
4278 return MCRegister();
4279
4280 Parser.Lex(); // Eat identifier token.
4281
4282 return Reg;
4283}
4284
4285std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4286 MCAsmParser &Parser = getParser();
4287 const AsmToken &Tok = Parser.getTok();
4288 if (Tok.isNot(AsmToken::Identifier))
4289 return std::nullopt;
4290
4291 std::string lowerCase = Tok.getString().lower();
4292 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4293 .Case("asl", ARM_AM::lsl)
4294 .Case("lsl", ARM_AM::lsl)
4295 .Case("lsr", ARM_AM::lsr)
4296 .Case("asr", ARM_AM::asr)
4297 .Case("ror", ARM_AM::ror)
4298 .Case("rrx", ARM_AM::rrx)
4299 .Default(std::nullopt);
4300}
4301
4302// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0.
4303// If a recoverable error occurs, return 1. If an irrecoverable error
4304// occurs, return -1. An irrecoverable error is one where tokens have been
4305// consumed in the process of trying to parse the shifter (i.e., when it is
4306// indeed a shifter operand, but malformed).
4307int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
4308 MCAsmParser &Parser = getParser();
4309 SMLoc S = Parser.getTok().getLoc();
4310
4311 auto ShiftTyOpt = tryParseShiftToken();
4312 if (ShiftTyOpt == std::nullopt)
4313 return 1;
4314 auto ShiftTy = ShiftTyOpt.value();
4315
4316 Parser.Lex(); // Eat the operator.
4317
4318 // The source register for the shift has already been added to the
4319 // operand list, so we need to pop it off and combine it into the shifted
4320 // register operand instead.
4321 std::unique_ptr<ARMOperand> PrevOp(
4322 (ARMOperand *)Operands.pop_back_val().release());
4323 if (!PrevOp->isReg())
4324 return Error(PrevOp->getStartLoc(), "shift must be of a register");
4325 MCRegister SrcReg = PrevOp->getReg();
4326
4327 SMLoc EndLoc;
4328 int64_t Imm = 0;
4329 MCRegister ShiftReg;
4330 if (ShiftTy == ARM_AM::rrx) {
4331 // RRX Doesn't have an explicit shift amount. The encoder expects
4332 // the shift register to be the same as the source register. Seems odd,
4333 // but OK.
4334 ShiftReg = SrcReg;
4335 } else {
4336 // Figure out if this is shifted by a constant or a register (for non-RRX).
4337 if (Parser.getTok().is(AsmToken::Hash) ||
4338 Parser.getTok().is(AsmToken::Dollar)) {
4339 Parser.Lex(); // Eat hash.
4340 SMLoc ImmLoc = Parser.getTok().getLoc();
4341 const MCExpr *ShiftExpr = nullptr;
4342 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4343 Error(ImmLoc, "invalid immediate shift value");
4344 return -1;
4345 }
4346 // The expression must be evaluatable as an immediate.
4347 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
4348 if (!CE) {
4349 Error(ImmLoc, "invalid immediate shift value");
4350 return -1;
4351 }
4352 // Range check the immediate.
4353 // lsl, ror: 0 <= imm <= 31
4354 // lsr, asr: 0 <= imm <= 32
4355 Imm = CE->getValue();
4356 if (Imm < 0 ||
4357 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
4358 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
4359 Error(ImmLoc, "immediate shift value out of range");
4360 return -1;
4361 }
4362 // shift by zero is a nop. Always send it through as lsl.
4363 // ('as' compatibility)
4364 if (Imm == 0)
4365 ShiftTy = ARM_AM::lsl;
4366 } else if (Parser.getTok().is(AsmToken::Identifier)) {
4367 SMLoc L = Parser.getTok().getLoc();
4368 EndLoc = Parser.getTok().getEndLoc();
4369 ShiftReg = tryParseRegister();
4370 if (!ShiftReg) {
4371 Error(L, "expected immediate or register in shift operand");
4372 return -1;
4373 }
4374 } else {
4375 Error(Parser.getTok().getLoc(),
4376 "expected immediate or register in shift operand");
4377 return -1;
4378 }
4379 }
4380
4381 if (ShiftReg && ShiftTy != ARM_AM::rrx)
4382 Operands.push_back(ARMOperand::CreateShiftedRegister(
4383 ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *this));
4384 else
4385 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4386 S, EndLoc, *this));
4387
4388 return 0;
4389}
4390
4391/// Try to parse a register name. The token must be an Identifier when called.
4392/// If it's a register, an AsmOperand is created. Another AsmOperand is created
4393/// if there is a "writeback". 'true' if it's not a register.
4394///
4395/// TODO this is likely to change to allow different register types and or to
4396/// parse for a specific register type.
4397bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) {
4398 MCAsmParser &Parser = getParser();
4399 SMLoc RegStartLoc = Parser.getTok().getLoc();
4400 SMLoc RegEndLoc = Parser.getTok().getEndLoc();
4401 MCRegister Reg = tryParseRegister();
4402 if (!Reg)
4403 return true;
4404
4405 Operands.push_back(ARMOperand::CreateReg(Reg, RegStartLoc, RegEndLoc, *this));
4406
4407 const AsmToken &ExclaimTok = Parser.getTok();
4408 if (ExclaimTok.is(AsmToken::Exclaim)) {
4409 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
4410 ExclaimTok.getLoc(), *this));
4411 Parser.Lex(); // Eat exclaim token
4412 return false;
4413 }
4414
4415 // Also check for an index operand. This is only legal for vector registers,
4416 // but that'll get caught OK in operand matching, so we don't need to
4417 // explicitly filter everything else out here.
4418 if (Parser.getTok().is(AsmToken::LBrac)) {
4419 SMLoc SIdx = Parser.getTok().getLoc();
4420 Parser.Lex(); // Eat left bracket token.
4421
4422 const MCExpr *ImmVal;
4423 if (getParser().parseExpression(ImmVal))
4424 return true;
4425 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
4426 if (!MCE)
4427 return TokError("immediate value expected for vector index");
4428
4429 if (Parser.getTok().isNot(AsmToken::RBrac))
4430 return Error(Parser.getTok().getLoc(), "']' expected");
4431
4432 SMLoc E = Parser.getTok().getEndLoc();
4433 Parser.Lex(); // Eat right bracket token.
4434
4435 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), SIdx, E,
4436 getContext(), *this));
4437 }
4438
4439 return false;
4440}
4441
4442/// MatchCoprocessorOperandName - Try to parse an coprocessor related
4443/// instruction with a symbolic operand name.
4444/// We accept "crN" syntax for GAS compatibility.
4445/// <operand-name> ::= <prefix><number>
4446/// If CoprocOp is 'c', then:
4447/// <prefix> ::= c | cr
4448/// If CoprocOp is 'p', then :
4449/// <prefix> ::= p
4450/// <number> ::= integer in range [0, 15]
4451static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
4452 // Use the same layout as the tablegen'erated register name matcher. Ugly,
4453 // but efficient.
4454 if (Name.size() < 2 || Name[0] != CoprocOp)
4455 return -1;
4456 Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front();
4457
4458 switch (Name.size()) {
4459 default: return -1;
4460 case 1:
4461 switch (Name[0]) {
4462 default: return -1;
4463 case '0': return 0;
4464 case '1': return 1;
4465 case '2': return 2;
4466 case '3': return 3;
4467 case '4': return 4;
4468 case '5': return 5;
4469 case '6': return 6;
4470 case '7': return 7;
4471 case '8': return 8;
4472 case '9': return 9;
4473 }
4474 case 2:
4475 if (Name[0] != '1')
4476 return -1;
4477 switch (Name[1]) {
4478 default: return -1;
4479 // CP10 and CP11 are VFP/NEON and so vector instructions should be used.
4480 // However, old cores (v5/v6) did use them in that way.
4481 case '0': return 10;
4482 case '1': return 11;
4483 case '2': return 12;
4484 case '3': return 13;
4485 case '4': return 14;
4486 case '5': return 15;
4487 }
4488 }
4489}
4490
4491/// parseITCondCode - Try to parse a condition code for an IT instruction.
4492ParseStatus ARMAsmParser::parseITCondCode(OperandVector &Operands) {
4493 MCAsmParser &Parser = getParser();
4494 SMLoc S = Parser.getTok().getLoc();
4495 const AsmToken &Tok = Parser.getTok();
4496 if (!Tok.is(AsmToken::Identifier))
4497 return ParseStatus::NoMatch;
4498 unsigned CC = ARMCondCodeFromString(Tok.getString());
4499 if (CC == ~0U)
4500 return ParseStatus::NoMatch;
4501 Parser.Lex(); // Eat the token.
4502
4503 Operands.push_back(
4504 ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S, *this));
4505
4506 return ParseStatus::Success;
4507}
4508
4509/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
4510/// token must be an Identifier when called, and if it is a coprocessor
4511/// number, the token is eaten and the operand is added to the operand list.
4512ParseStatus ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
4513 MCAsmParser &Parser = getParser();
4514 SMLoc S = Parser.getTok().getLoc();
4515 const AsmToken &Tok = Parser.getTok();
4516 if (Tok.isNot(AsmToken::Identifier))
4517 return ParseStatus::NoMatch;
4518
4519 int Num = MatchCoprocessorOperandName(Tok.getString().lower(), 'p');
4520 if (Num == -1)
4521 return ParseStatus::NoMatch;
4522 if (!isValidCoprocessorNumber(Num, getSTI().getFeatureBits()))
4523 return ParseStatus::NoMatch;
4524
4525 Parser.Lex(); // Eat identifier token.
4526 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *this));
4527 return ParseStatus::Success;
4528}
4529
4530/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
4531/// token must be an Identifier when called, and if it is a coprocessor
4532/// number, the token is eaten and the operand is added to the operand list.
4533ParseStatus ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) {
4534 MCAsmParser &Parser = getParser();
4535 SMLoc S = Parser.getTok().getLoc();
4536 const AsmToken &Tok = Parser.getTok();
4537 if (Tok.isNot(AsmToken::Identifier))
4538 return ParseStatus::NoMatch;
4539
4540 int Reg = MatchCoprocessorOperandName(Tok.getString().lower(), 'c');
4541 if (Reg == -1)
4542 return ParseStatus::NoMatch;
4543
4544 Parser.Lex(); // Eat identifier token.
4545 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S, *this));
4546 return ParseStatus::Success;
4547}
4548
4549/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
4550/// coproc_option : '{' imm0_255 '}'
4551ParseStatus ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) {
4552 MCAsmParser &Parser = getParser();
4553 SMLoc S = Parser.getTok().getLoc();
4554
4555 // If this isn't a '{', this isn't a coprocessor immediate operand.
4556 if (Parser.getTok().isNot(AsmToken::LCurly))
4557 return ParseStatus::NoMatch;
4558 Parser.Lex(); // Eat the '{'
4559
4560 const MCExpr *Expr;
4561 SMLoc Loc = Parser.getTok().getLoc();
4562 if (getParser().parseExpression(Expr))
4563 return Error(Loc, "illegal expression");
4564 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
4565 if (!CE || CE->getValue() < 0 || CE->getValue() > 255)
4566 return Error(Loc,
4567 "coprocessor option must be an immediate in range [0, 255]");
4568 int Val = CE->getValue();
4569
4570 // Check for and consume the closing '}'
4571 if (Parser.getTok().isNot(AsmToken::RCurly))
4572 return ParseStatus::Failure;
4573 SMLoc E = Parser.getTok().getEndLoc();
4574 Parser.Lex(); // Eat the '}'
4575
4576 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E, *this));
4577 return ParseStatus::Success;
4578}
4579
4580// For register list parsing, we need to map from raw GPR register numbering
4581// to the enumeration values. The enumeration values aren't sorted by
4582// register number due to our using "sp", "lr" and "pc" as canonical names.
4584 // If this is a GPR, we need to do it manually, otherwise we can rely
4585 // on the sort ordering of the enumeration since the other reg-classes
4586 // are sane.
4587 if (!getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4588 return Reg + 1;
4589 switch (Reg.id()) {
4590 default: llvm_unreachable("Invalid GPR number!");
4591 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2;
4592 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4;
4593 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6;
4594 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8;
4595 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10;
4596 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
4597 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR;
4598 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0;
4599 }
4600}
4601
4602// Insert an <Encoding, Register> pair in an ordered vector. Return true on
4603// success, or false, if duplicate encoding found.
4604static bool
4605insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
4606 unsigned Enc, MCRegister Reg) {
4607 Regs.emplace_back(Enc, Reg);
4608 for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
4609 if (J->first == Enc) {
4610 Regs.erase(J.base());
4611 return false;
4612 }
4613 if (J->first < Enc)
4614 break;
4615 std::swap(*I, *J);
4616 }
4617 return true;
4618}
4619
4620/// Parse a register list.
4621bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
4622 bool AllowRAAC, bool IsLazyLoadStore,
4623 bool IsVSCCLRM) {
4624 MCAsmParser &Parser = getParser();
4625 if (Parser.getTok().isNot(AsmToken::LCurly))
4626 return TokError("Token is not a Left Curly Brace");
4627 SMLoc S = Parser.getTok().getLoc();
4628 Parser.Lex(); // Eat '{' token.
4629 SMLoc RegLoc = Parser.getTok().getLoc();
4630
4631 // Check the first register in the list to see what register class
4632 // this is a list of.
4633 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4634 MCRegister Reg = tryParseRegister(AllowOutOfBoundReg);
4635 if (!Reg)
4636 return Error(RegLoc, "register expected");
4637 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
4638 return Error(RegLoc, "pseudo-register not allowed");
4639 // The reglist instructions have at most 32 registers, so reserve
4640 // space for that many.
4641 int EReg = 0;
4643
4644 // Single-precision VSCCLRM can have double-precision registers in the
4645 // register list. When VSCCLRMAdjustEncoding is true then we've switched from
4646 // single-precision to double-precision and we pretend that these registers
4647 // are encoded as S32 onwards, which we can do by adding 16 to the encoding
4648 // value.
4649 bool VSCCLRMAdjustEncoding = false;
4650
4651 // Allow Q regs and just interpret them as the two D sub-registers.
4652 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4653 Reg = getDRegFromQReg(Reg);
4654 EReg = MRI->getEncodingValue(Reg);
4655 Registers.emplace_back(EReg, Reg);
4656 Reg = Reg + 1;
4657 }
4658 const MCRegisterClass *RC;
4659 if (Reg == ARM::RA_AUTH_CODE ||
4660 getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4661 RC = &getARMMCRegisterClass(ARM::GPRRegClassID);
4662 else if (getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg))
4663 RC = &getARMMCRegisterClass(ARM::DPRRegClassID);
4664 else if (getARMMCRegisterClass(ARM::SPRRegClassID).contains(Reg))
4665 RC = &getARMMCRegisterClass(ARM::SPRRegClassID);
4666 else if (getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).contains(Reg))
4667 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4668 else if (Reg == ARM::VPR)
4669 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4670 else
4671 return Error(RegLoc, "invalid register in register list");
4672
4673 // Store the register.
4674 EReg = MRI->getEncodingValue(Reg);
4675 Registers.emplace_back(EReg, Reg);
4676
4677 // This starts immediately after the first register token in the list,
4678 // so we can see either a comma or a minus (range separator) as a legal
4679 // next token.
4680 while (Parser.getTok().is(AsmToken::Comma) ||
4681 Parser.getTok().is(AsmToken::Minus)) {
4682 if (Parser.getTok().is(AsmToken::Minus)) {
4683 if (Reg == ARM::RA_AUTH_CODE)
4684 return Error(RegLoc, "pseudo-register not allowed");
4685 Parser.Lex(); // Eat the minus.
4686 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4687 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4688 if (!EndReg)
4689 return Error(AfterMinusLoc, "register expected");
4690 if (EndReg == ARM::RA_AUTH_CODE)
4691 return Error(AfterMinusLoc, "pseudo-register not allowed");
4692 // Allow Q regs and just interpret them as the two D sub-registers.
4693 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(EndReg))
4694 EndReg = getDRegFromQReg(EndReg) + 1;
4695 // If the register is the same as the start reg, there's nothing
4696 // more to do.
4697 if (Reg == EndReg)
4698 continue;
4699 // The register must be in the same register class as the first.
4700 if (!RC->contains(Reg))
4701 return Error(AfterMinusLoc, "invalid register in register list");
4702 // Ranges must go from low to high.
4703 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
4704 return Error(AfterMinusLoc, "bad range in register list");
4705
4706 // Add all the registers in the range to the register list.
4707 while (Reg != EndReg) {
4709 EReg = MRI->getEncodingValue(Reg);
4710 if (VSCCLRMAdjustEncoding)
4711 EReg += 16;
4712 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4713 Warning(AfterMinusLoc, StringRef("duplicated register (") +
4715 ") in register list");
4716 }
4717 }
4718 continue;
4719 }
4720 Parser.Lex(); // Eat the comma.
4721 RegLoc = Parser.getTok().getLoc();
4722 MCRegister OldReg = Reg;
4723 int EOldReg = EReg;
4724 const AsmToken RegTok = Parser.getTok();
4725 Reg = tryParseRegister(AllowOutOfBoundReg);
4726 if (!Reg)
4727 return Error(RegLoc, "register expected");
4728 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
4729 return Error(RegLoc, "pseudo-register not allowed");
4730 // Allow Q regs and just interpret them as the two D sub-registers.
4731 bool isQReg = false;
4732 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4733 Reg = getDRegFromQReg(Reg);
4734 isQReg = true;
4735 }
4736 if (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg) &&
4737 RC->getID() == getARMMCRegisterClass(ARM::GPRRegClassID).getID() &&
4738 getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).contains(Reg)) {
4739 // switch the register classes, as GPRwithAPSRnospRegClassID is a partial
4740 // subset of GPRRegClassId except it contains APSR as well.
4741 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4742 }
4743 if (Reg == ARM::VPR &&
4744 (RC == &getARMMCRegisterClass(ARM::SPRRegClassID) ||
4745 RC == &getARMMCRegisterClass(ARM::DPRRegClassID) ||
4746 RC == &getARMMCRegisterClass(ARM::FPWithVPRRegClassID))) {
4747 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4748 EReg = MRI->getEncodingValue(Reg);
4749 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4750 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4751 ") in register list");
4752 }
4753 continue;
4754 }
4755 // VSCCLRM can switch from single-precision to double-precision only when
4756 // S31 is followed by D16.
4757 if (IsVSCCLRM && OldReg == ARM::S31 && Reg == ARM::D16) {
4758 VSCCLRMAdjustEncoding = true;
4759 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4760 }
4761 // The register must be in the same register class as the first.
4762 if ((Reg == ARM::RA_AUTH_CODE &&
4763 RC != &getARMMCRegisterClass(ARM::GPRRegClassID)) ||
4764 (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg)))
4765 return Error(RegLoc, "invalid register in register list");
4766 // In most cases, the list must be monotonically increasing. An
4767 // exception is CLRM, which is order-independent anyway, so
4768 // there's no potential for confusion if you write clrm {r2,r1}
4769 // instead of clrm {r1,r2}.
4770 EReg = MRI->getEncodingValue(Reg);
4771 if (VSCCLRMAdjustEncoding)
4772 EReg += 16;
4773 if (EnforceOrder && EReg < EOldReg) {
4774 if (getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4775 Warning(RegLoc, "register list not in ascending order");
4776 else if (!getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
4777 .contains(Reg))
4778 return Error(RegLoc, "register list not in ascending order");
4779 }
4780 // VFP register lists must also be contiguous.
4781 if (RC != &getARMMCRegisterClass(ARM::GPRRegClassID) &&
4782 RC != &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID) &&
4783 EReg != EOldReg + 1)
4784 return Error(RegLoc, "non-contiguous register range");
4785
4786 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4787 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4788 ") in register list");
4789 }
4790 if (isQReg) {
4791 Reg = Reg + 1;
4792 EReg = MRI->getEncodingValue(Reg);
4793 Registers.emplace_back(EReg, Reg);
4794 }
4795 }
4796
4797 if (Parser.getTok().isNot(AsmToken::RCurly))
4798 return Error(Parser.getTok().getLoc(), "'}' expected");
4799 SMLoc E = Parser.getTok().getEndLoc();
4800 Parser.Lex(); // Eat '}' token.
4801
4802 // Push the register list operand.
4803 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E, *this));
4804
4805 // The ARM system instruction variants for LDM/STM have a '^' token here.
4806 if (Parser.getTok().is(AsmToken::Caret)) {
4807 Operands.push_back(
4808 ARMOperand::CreateToken("^", Parser.getTok().getLoc(), *this));
4809 Parser.Lex(); // Eat '^' token.
4810 }
4811
4812 return false;
4813}
4814
4815// Helper function to parse the lane index for vector lists.
4816ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4817 unsigned &Index, SMLoc &EndLoc) {
4818 MCAsmParser &Parser = getParser();
4819 Index = 0; // Always return a defined index value.
4820 if (Parser.getTok().is(AsmToken::LBrac)) {
4821 Parser.Lex(); // Eat the '['.
4822 if (Parser.getTok().is(AsmToken::RBrac)) {
4823 // "Dn[]" is the 'all lanes' syntax.
4824 LaneKind = AllLanes;
4825 EndLoc = Parser.getTok().getEndLoc();
4826 Parser.Lex(); // Eat the ']'.
4827 return ParseStatus::Success;
4828 }
4829
4830 // There's an optional '#' token here. Normally there wouldn't be, but
4831 // inline assemble puts one in, and it's friendly to accept that.
4832 if (Parser.getTok().is(AsmToken::Hash))
4833 Parser.Lex(); // Eat '#' or '$'.
4834
4835 const MCExpr *LaneIndex;
4836 SMLoc Loc = Parser.getTok().getLoc();
4837 if (getParser().parseExpression(LaneIndex))
4838 return Error(Loc, "illegal expression");
4839 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
4840 if (!CE)
4841 return Error(Loc, "lane index must be empty or an integer");
4842 if (Parser.getTok().isNot(AsmToken::RBrac))
4843 return Error(Parser.getTok().getLoc(), "']' expected");
4844 EndLoc = Parser.getTok().getEndLoc();
4845 Parser.Lex(); // Eat the ']'.
4846 int64_t Val = CE->getValue();
4847
4848 // FIXME: Make this range check context sensitive for .8, .16, .32.
4849 if (Val < 0 || Val > 7)
4850 return Error(Parser.getTok().getLoc(), "lane index out of range");
4851 Index = Val;
4852 LaneKind = IndexedLane;
4853 return ParseStatus::Success;
4854 }
4855 LaneKind = NoLanes;
4856 return ParseStatus::Success;
4857}
4858
4859// parse a vector register list
4860ParseStatus ARMAsmParser::parseVectorList(OperandVector &Operands) {
4861 MCAsmParser &Parser = getParser();
4862 VectorLaneTy LaneKind;
4863 unsigned LaneIndex;
4864 SMLoc S = Parser.getTok().getLoc();
4865 // As an extension (to match gas), support a plain D register or Q register
4866 // (without encosing curly braces) as a single or double entry list,
4867 // respectively.
4868 // If there is no lane supplied, just parse as a register and
4869 // use the custom matcher to convert to list if necessary
4870 if (!hasMVE() && Parser.getTok().is(AsmToken::Identifier)) {
4871 SMLoc E = Parser.getTok().getEndLoc();
4872 MCRegister Reg = tryParseRegister();
4873 if (!Reg)
4874 return ParseStatus::NoMatch;
4875 if (getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg)) {
4876 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex, E);
4877 if (!Res.isSuccess())
4878 return Res;
4879 switch (LaneKind) {
4880 case NoLanes:
4881 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4882 break;
4883 case AllLanes:
4884 Operands.push_back(
4885 ARMOperand::CreateVectorListAllLanes(Reg, 1, false, S, E, *this));
4886 break;
4887 case IndexedLane:
4888 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4889 Reg, 1, LaneIndex, false, S, E, *this));
4890 break;
4891 }
4892 return ParseStatus::Success;
4893 }
4894 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4895 Reg = getDRegFromQReg(Reg);
4896 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex, E);
4897 if (!Res.isSuccess())
4898 return Res;
4899 switch (LaneKind) {
4900 case NoLanes:
4901 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4902 break;
4903 case AllLanes:
4904 Reg = MRI->getMatchingSuperReg(
4905 Reg, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
4906 Operands.push_back(
4907 ARMOperand::CreateVectorListAllLanes(Reg, 2, false, S, E, *this));
4908 break;
4909 case IndexedLane:
4910 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4911 Reg, 2, LaneIndex, false, S, E, *this));
4912 break;
4913 }
4914 return ParseStatus::Success;
4915 }
4916 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4917 return ParseStatus::Success;
4918 }
4919
4920 if (Parser.getTok().isNot(AsmToken::LCurly))
4921 return ParseStatus::NoMatch;
4922
4923 Parser.Lex(); // Eat '{' token.
4924 SMLoc RegLoc = Parser.getTok().getLoc();
4925
4926 MCRegister Reg = tryParseRegister();
4927 if (!Reg)
4928 return Error(RegLoc, "register expected");
4929 unsigned Count = 1;
4930 int Spacing = 0;
4931 MCRegister FirstReg = Reg;
4932
4933 if (hasMVE() && !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Reg))
4934 return Error(Parser.getTok().getLoc(),
4935 "vector register in range Q0-Q7 expected");
4936 // The list is of D registers, but we also allow Q regs and just interpret
4937 // them as the two D sub-registers.
4938 else if (!hasMVE() &&
4939 getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4940 FirstReg = Reg = getDRegFromQReg(Reg);
4941 Spacing = 1; // double-spacing requires explicit D registers, otherwise
4942 // it's ambiguous with four-register single spaced.
4943 Reg = Reg + 1;
4944 ++Count;
4945 }
4946
4947 SMLoc E;
4948 if (!parseVectorLane(LaneKind, LaneIndex, E).isSuccess())
4949 return ParseStatus::Failure;
4950
4951 while (Parser.getTok().is(AsmToken::Comma) ||
4952 Parser.getTok().is(AsmToken::Minus)) {
4953 if (Parser.getTok().is(AsmToken::Minus)) {
4954 if (!Spacing)
4955 Spacing = 1; // Register range implies a single spaced list.
4956 else if (Spacing == 2)
4957 return Error(Parser.getTok().getLoc(),
4958 "sequential registers in double spaced list");
4959 Parser.Lex(); // Eat the minus.
4960 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4961 MCRegister EndReg = tryParseRegister();
4962 if (!EndReg)
4963 return Error(AfterMinusLoc, "register expected");
4964 // Allow Q regs and just interpret them as the two D sub-registers.
4965 if (!hasMVE() &&
4966 getARMMCRegisterClass(ARM::QPRRegClassID).contains(EndReg))
4967 EndReg = getDRegFromQReg(EndReg) + 1;
4968 // If the register is the same as the start reg, there's nothing
4969 // more to do.
4970 if (Reg == EndReg)
4971 continue;
4972 // The register must be in the same register class as the first.
4973 if ((hasMVE() &&
4974 !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(EndReg)) ||
4975 (!hasMVE() &&
4976 !getARMMCRegisterClass(ARM::DPRRegClassID).contains(EndReg)))
4977 return Error(AfterMinusLoc, "invalid register in register list");
4978 // Ranges must go from low to high.
4979 if (Reg > EndReg)
4980 return Error(AfterMinusLoc, "bad range in register list");
4981 // Parse the lane specifier if present.
4982 VectorLaneTy NextLaneKind;
4983 unsigned NextLaneIndex;
4984 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
4985 return ParseStatus::Failure;
4986 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4987 return Error(AfterMinusLoc, "mismatched lane index in register list");
4988
4989 // Add all the registers in the range to the register list.
4990 Count += EndReg - Reg;
4991 Reg = EndReg;
4992 continue;
4993 }
4994 Parser.Lex(); // Eat the comma.
4995 RegLoc = Parser.getTok().getLoc();
4996 MCRegister OldReg = Reg;
4997 Reg = tryParseRegister();
4998 if (!Reg)
4999 return Error(RegLoc, "register expected");
5000
5001 if (hasMVE()) {
5002 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Reg))
5003 return Error(RegLoc, "vector register in range Q0-Q7 expected");
5004 Spacing = 1;
5005 }
5006 // vector register lists must be contiguous.
5007 // It's OK to use the enumeration values directly here rather, as the
5008 // VFP register classes have the enum sorted properly.
5009 //
5010 // The list is of D registers, but we also allow Q regs and just interpret
5011 // them as the two D sub-registers.
5012 else if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
5013 if (!Spacing)
5014 Spacing = 1; // Register range implies a single spaced list.
5015 else if (Spacing == 2)
5016 return Error(
5017 RegLoc,
5018 "invalid register in double-spaced list (must be 'D' register')");
5019 Reg = getDRegFromQReg(Reg);
5020 if (Reg != OldReg + 1)
5021 return Error(RegLoc, "non-contiguous register range");
5022 Reg = Reg + 1;
5023 Count += 2;
5024 // Parse the lane specifier if present.
5025 VectorLaneTy NextLaneKind;
5026 unsigned NextLaneIndex;
5027 SMLoc LaneLoc = Parser.getTok().getLoc();
5028 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
5029 return ParseStatus::Failure;
5030 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5031 return Error(LaneLoc, "mismatched lane index in register list");
5032 continue;
5033 }
5034 // Normal D register.
5035 // Figure out the register spacing (single or double) of the list if
5036 // we don't know it already.
5037 if (!Spacing)
5038 Spacing = 1 + (Reg == OldReg + 2);
5039
5040 // Just check that it's contiguous and keep going.
5041 if (Reg != OldReg + Spacing)
5042 return Error(RegLoc, "non-contiguous register range");
5043 ++Count;
5044 // Parse the lane specifier if present.
5045 VectorLaneTy NextLaneKind;
5046 unsigned NextLaneIndex;
5047 SMLoc EndLoc = Parser.getTok().getLoc();
5048 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
5049 return ParseStatus::Failure;
5050 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5051 return Error(EndLoc, "mismatched lane index in register list");
5052 }
5053
5054 if (Parser.getTok().isNot(AsmToken::RCurly))
5055 return Error(Parser.getTok().getLoc(), "'}' expected");
5056 E = Parser.getTok().getEndLoc();
5057 Parser.Lex(); // Eat '}' token.
5058
5059 switch (LaneKind) {
5060 case NoLanes:
5061 case AllLanes: {
5062 // Two-register operands have been converted to the
5063 // composite register classes.
5064 if (Count == 2 && !hasMVE()) {
5065 const MCRegisterClass *RC =
5066 (Spacing == 1) ? &getARMMCRegisterClass(ARM::DPairRegClassID)
5067 : &getARMMCRegisterClass(ARM::DPairSpcRegClassID);
5068 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
5069 }
5070 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5071 ARMOperand::CreateVectorListAllLanes);
5072 Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E, *this));
5073 break;
5074 }
5075 case IndexedLane:
5076 Operands.push_back(ARMOperand::CreateVectorListIndexed(
5077 FirstReg, Count, LaneIndex, (Spacing == 2), S, E, *this));
5078 break;
5079 }
5080 return ParseStatus::Success;
5081}
5082
5083/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
5084ParseStatus ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
5085 MCAsmParser &Parser = getParser();
5086 SMLoc S = Parser.getTok().getLoc();
5087 const AsmToken &Tok = Parser.getTok();
5088 unsigned Opt;
5089
5090 if (Tok.is(AsmToken::Identifier)) {
5091 StringRef OptStr = Tok.getString();
5092
5093 Opt = StringSwitch<unsigned>(OptStr.lower())
5094 .Case("sy", ARM_MB::SY)
5095 .Case("st", ARM_MB::ST)
5096 .Case("ld", ARM_MB::LD)
5097 .Case("sh", ARM_MB::ISH)
5098 .Case("ish", ARM_MB::ISH)
5099 .Case("shst", ARM_MB::ISHST)
5100 .Case("ishst", ARM_MB::ISHST)
5101 .Case("ishld", ARM_MB::ISHLD)
5102 .Case("nsh", ARM_MB::NSH)
5103 .Case("un", ARM_MB::NSH)
5104 .Case("nshst", ARM_MB::NSHST)
5105 .Case("nshld", ARM_MB::NSHLD)
5106 .Case("unst", ARM_MB::NSHST)
5107 .Case("osh", ARM_MB::OSH)
5108 .Case("oshst", ARM_MB::OSHST)
5109 .Case("oshld", ARM_MB::OSHLD)
5110 .Default(~0U);
5111
5112 // ishld, oshld, nshld and ld are only available from ARMv8.
5113 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD ||
5114 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD))
5115 Opt = ~0U;
5116
5117 if (Opt == ~0U)
5118 return ParseStatus::NoMatch;
5119
5120 Parser.Lex(); // Eat identifier token.
5121 } else if (Tok.is(AsmToken::Hash) ||
5122 Tok.is(AsmToken::Dollar) ||
5123 Tok.is(AsmToken::Integer)) {
5124 if (Parser.getTok().isNot(AsmToken::Integer))
5125 Parser.Lex(); // Eat '#' or '$'.
5126 SMLoc Loc = Parser.getTok().getLoc();
5127
5128 const MCExpr *MemBarrierID;
5129 if (getParser().parseExpression(MemBarrierID))
5130 return Error(Loc, "illegal expression");
5131
5132 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
5133 if (!CE)
5134 return Error(Loc, "constant expression expected");
5135
5136 int Val = CE->getValue();
5137 if (Val & ~0xf)
5138 return Error(Loc, "immediate value out of range");
5139
5140 Opt = ARM_MB::RESERVED_0 + Val;
5141 } else
5142 return Error(Parser.getTok().getLoc(),
5143 "expected an immediate or barrier type");
5144
5145 Operands.push_back(
5146 ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S, *this));
5147 return ParseStatus::Success;
5148}
5149
5150ParseStatus
5151ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) {
5152 MCAsmParser &Parser = getParser();
5153 SMLoc S = Parser.getTok().getLoc();
5154 const AsmToken &Tok = Parser.getTok();
5155
5156 if (Tok.isNot(AsmToken::Identifier))
5157 return ParseStatus::NoMatch;
5158
5159 if (!Tok.getString().equals_insensitive("csync"))
5160 return ParseStatus::NoMatch;
5161
5162 Parser.Lex(); // Eat identifier token.
5163
5164 Operands.push_back(
5165 ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S, *this));
5166 return ParseStatus::Success;
5167}
5168
5169/// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
5170ParseStatus
5171ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
5172 MCAsmParser &Parser = getParser();
5173 SMLoc S = Parser.getTok().getLoc();
5174 const AsmToken &Tok = Parser.getTok();
5175 unsigned Opt;
5176
5177 if (Tok.is(AsmToken::Identifier)) {
5178 StringRef OptStr = Tok.getString();
5179
5180 if (OptStr.equals_insensitive("sy"))
5181 Opt = ARM_ISB::SY;
5182 else
5183 return ParseStatus::NoMatch;
5184
5185 Parser.Lex(); // Eat identifier token.
5186 } else if (Tok.is(AsmToken::Hash) ||
5187 Tok.is(AsmToken::Dollar) ||
5188 Tok.is(AsmToken::Integer)) {
5189 if (Parser.getTok().isNot(AsmToken::Integer))
5190 Parser.Lex(); // Eat '#' or '$'.
5191 SMLoc Loc = Parser.getTok().getLoc();
5192
5193 const MCExpr *ISBarrierID;
5194 if (getParser().parseExpression(ISBarrierID))
5195 return Error(Loc, "illegal expression");
5196
5197 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID);
5198 if (!CE)
5199 return Error(Loc, "constant expression expected");
5200
5201 int Val = CE->getValue();
5202 if (Val & ~0xf)
5203 return Error(Loc, "immediate value out of range");
5204
5205 Opt = ARM_ISB::RESERVED_0 + Val;
5206 } else
5207 return Error(Parser.getTok().getLoc(),
5208 "expected an immediate or barrier type");
5209
5210 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
5211 (ARM_ISB::InstSyncBOpt)Opt, S, *this));
5212 return ParseStatus::Success;
5213}
5214
5215/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
5216ParseStatus ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {
5217 MCAsmParser &Parser = getParser();
5218 SMLoc S = Parser.getTok().getLoc();
5219 const AsmToken &Tok = Parser.getTok();
5220 if (!Tok.is(AsmToken::Identifier))
5221 return ParseStatus::NoMatch;
5222 StringRef IFlagsStr = Tok.getString();
5223
5224 // An iflags string of "none" is interpreted to mean that none of the AIF
5225 // bits are set. Not a terribly useful instruction, but a valid encoding.
5226 unsigned IFlags = 0;
5227 if (IFlagsStr != "none") {
5228 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
5229 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1).lower())
5230 .Case("a", ARM_PROC::A)
5231 .Case("i", ARM_PROC::I)
5232 .Case("f", ARM_PROC::F)
5233 .Default(~0U);
5234
5235 // If some specific iflag is already set, it means that some letter is
5236 // present more than once, this is not acceptable.
5237 if (Flag == ~0U || (IFlags & Flag))
5238 return ParseStatus::NoMatch;
5239
5240 IFlags |= Flag;
5241 }
5242 }
5243
5244 Parser.Lex(); // Eat identifier token.
5245 Operands.push_back(
5246 ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S, *this));
5247 return ParseStatus::Success;
5248}
5249
5250/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
5251ParseStatus ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {
5252 // Don't parse two MSR registers in a row
5253 if (static_cast<ARMOperand &>(*Operands.back()).isMSRMask() ||
5254 static_cast<ARMOperand &>(*Operands.back()).isBankedReg())
5255 return ParseStatus::NoMatch;
5256 MCAsmParser &Parser = getParser();
5257 SMLoc S = Parser.getTok().getLoc();
5258 const AsmToken &Tok = Parser.getTok();
5259
5260 if (Tok.is(AsmToken::Integer)) {
5261 int64_t Val = Tok.getIntVal();
5262 if (Val > 255 || Val < 0) {
5263 return ParseStatus::NoMatch;
5264 }
5265 unsigned SYSmvalue = Val & 0xFF;
5266 Parser.Lex();
5267 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this));
5268 return ParseStatus::Success;
5269 }
5270
5271 if (!Tok.is(AsmToken::Identifier))
5272 return ParseStatus::NoMatch;
5273 StringRef Mask = Tok.getString();
5274
5275 if (isMClass()) {
5276 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower());
5277 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5278 return ParseStatus::NoMatch;
5279
5280 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5281
5282 Parser.Lex(); // Eat identifier token.
5283 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this));
5284 return ParseStatus::Success;
5285 }
5286
5287 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
5288 size_t Start = 0, Next = Mask.find('_');
5289 StringRef Flags = "";
5290 std::string SpecReg = Mask.slice(Start, Next).lower();
5291 if (Next != StringRef::npos)
5292 Flags = Mask.substr(Next + 1);
5293
5294 // FlagsVal contains the complete mask:
5295 // 3-0: Mask
5296 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5297 unsigned FlagsVal = 0;
5298
5299 if (SpecReg == "apsr") {
5300 FlagsVal = StringSwitch<unsigned>(Flags)
5301 .Case("nzcvq", 0x8) // same as CPSR_f
5302 .Case("g", 0x4) // same as CPSR_s
5303 .Case("nzcvqg", 0xc) // same as CPSR_fs
5304 .Default(~0U);
5305
5306 if (FlagsVal == ~0U) {
5307 if (!Flags.empty())
5308 return ParseStatus::NoMatch;
5309 else
5310 FlagsVal = 8; // No flag
5311 }
5312 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
5313 // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
5314 if (Flags == "all" || Flags == "")
5315 Flags = "fc";
5316 for (int i = 0, e = Flags.size(); i != e; ++i) {
5317 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
5318 .Case("c", 1)
5319 .Case("x", 2)
5320 .Case("s", 4)
5321 .Case("f", 8)
5322 .Default(~0U);
5323
5324 // If some specific flag is already set, it means that some letter is
5325 // present more than once, this is not acceptable.
5326 if (Flag == ~0U || (FlagsVal & Flag))
5327 return ParseStatus::NoMatch;
5328 FlagsVal |= Flag;
5329 }
5330 } else // No match for special register.
5331 return ParseStatus::NoMatch;
5332
5333 // Special register without flags is NOT equivalent to "fc" flags.
5334 // NOTE: This is a divergence from gas' behavior. Uncommenting the following
5335 // two lines would enable gas compatibility at the expense of breaking
5336 // round-tripping.
5337 //
5338 // if (!FlagsVal)
5339 // FlagsVal = 0x9;
5340
5341 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5342 if (SpecReg == "spsr")
5343 FlagsVal |= 16;
5344
5345 Parser.Lex(); // Eat identifier token.
5346 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *this));
5347 return ParseStatus::Success;
5348}
5349
5350/// parseBankedRegOperand - Try to parse a banked register (e.g. "lr_irq") for
5351/// use in the MRS/MSR instructions added to support virtualization.
5352ParseStatus ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
5353 // Don't parse two Banked registers in a row
5354 if (static_cast<ARMOperand &>(*Operands.back()).isBankedReg() ||
5355 static_cast<ARMOperand &>(*Operands.back()).isMSRMask())
5356 return ParseStatus::NoMatch;
5357 MCAsmParser &Parser = getParser();
5358 SMLoc S = Parser.getTok().getLoc();
5359 const AsmToken &Tok = Parser.getTok();
5360 if (!Tok.is(AsmToken::Identifier))
5361 return ParseStatus::NoMatch;
5362 StringRef RegName = Tok.getString();
5363
5364 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.lower());
5365 if (!TheReg)
5366 return ParseStatus::NoMatch;
5367 unsigned Encoding = TheReg->Encoding;
5368
5369 Parser.Lex(); // Eat identifier token.
5370 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S, *this));
5371 return ParseStatus::Success;
5372}
5373
5374// FIXME: Unify the different methods for handling shift operators
5375// and use TableGen matching mechanisms to do the validation rather than
5376// separate parsing paths.
5377ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands,
5378 ARM_AM::ShiftOpc Op, int Low, int High) {
5379 MCAsmParser &Parser = getParser();
5380 auto ShiftCodeOpt = tryParseShiftToken();
5381
5382 if (!ShiftCodeOpt.has_value())
5383 return ParseStatus::NoMatch;
5384 auto ShiftCode = ShiftCodeOpt.value();
5385
5386 // The wrong shift code has been provided. Can error here as has matched the
5387 // correct operand in this case.
5388 if (ShiftCode != Op)
5389 return Error(Parser.getTok().getLoc(),
5390 ARM_AM::getShiftOpcStr(Op) + " operand expected.");
5391
5392 Parser.Lex(); // Eat shift type token.
5393
5394 // There must be a '#' and a shift amount.
5395 if (Parser.getTok().isNot(AsmToken::Hash) &&
5396 Parser.getTok().isNot(AsmToken::Dollar))
5397 return ParseStatus::NoMatch;
5398 Parser.Lex(); // Eat hash token.
5399
5400 const MCExpr *ShiftAmount;
5401 SMLoc Loc = Parser.getTok().getLoc();
5402 SMLoc EndLoc;
5403 if (getParser().parseExpression(ShiftAmount, EndLoc))
5404 return Error(Loc, "illegal expression");
5405 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5406 if (!CE)
5407 return Error(Loc, "constant expression expected");
5408 int Val = CE->getValue();
5409 if (Val < Low || Val > High)
5410 return Error(Loc, "immediate value out of range");
5411
5412 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *this));
5413
5414 return ParseStatus::Success;
5415}
5416
5417ParseStatus ARMAsmParser::parseSetEndImm(OperandVector &Operands) {
5418 MCAsmParser &Parser = getParser();
5419 const AsmToken &Tok = Parser.getTok();
5420 SMLoc S = Tok.getLoc();
5421 if (Tok.isNot(AsmToken::Identifier))
5422 return Error(S, "'be' or 'le' operand expected");
5423 int Val = StringSwitch<int>(Tok.getString().lower())
5424 .Case("be", 1)
5425 .Case("le", 0)
5426 .Default(-1);
5427 Parser.Lex(); // Eat the token.
5428
5429 if (Val == -1)
5430 return Error(S, "'be' or 'le' operand expected");
5431 Operands.push_back(ARMOperand::CreateImm(
5432 MCConstantExpr::create(Val, getContext()), S, Tok.getEndLoc(), *this));
5433 return ParseStatus::Success;
5434}
5435
5436/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
5437/// instructions. Legal values are:
5438/// lsl #n 'n' in [0,31]
5439/// asr #n 'n' in [1,32]
5440/// n == 32 encoded as n == 0.
5441ParseStatus ARMAsmParser::parseShifterImm(OperandVector &Operands) {
5442 MCAsmParser &Parser = getParser();
5443 const AsmToken &Tok = Parser.getTok();
5444 SMLoc S = Tok.getLoc();
5445 if (Tok.isNot(AsmToken::Identifier))
5446 return ParseStatus::NoMatch;
5447 StringRef ShiftName = Tok.getString();
5448 bool isASR;
5449 if (ShiftName == "lsl" || ShiftName == "LSL")
5450 isASR = false;
5451 else if (ShiftName == "asr" || ShiftName == "ASR")
5452 isASR = true;
5453 else
5454 return ParseStatus::NoMatch;
5455 Parser.Lex(); // Eat the operator.
5456
5457 // A '#' and a shift amount.
5458 if (Parser.getTok().isNot(AsmToken::Hash) &&
5459 Parser.getTok().isNot(AsmToken::Dollar))
5460 return Error(Parser.getTok().getLoc(), "'#' expected");
5461 Parser.Lex(); // Eat hash token.
5462 SMLoc ExLoc = Parser.getTok().getLoc();
5463
5464 const MCExpr *ShiftAmount;
5465 SMLoc EndLoc;
5466 if (getParser().parseExpression(ShiftAmount, EndLoc))
5467 return Error(ExLoc, "malformed shift expression");
5468 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5469 if (!CE)
5470 return Error(ExLoc, "shift amount must be an immediate");
5471
5472 int64_t Val = CE->getValue();
5473 if (isASR) {
5474 // Shift amount must be in [1,32]
5475 if (Val < 1 || Val > 32)
5476 return Error(ExLoc, "'asr' shift amount must be in range [1,32]");
5477 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
5478 if (isThumb() && Val == 32)
5479 return Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode");
5480 if (Val == 32) Val = 0;
5481 } else {
5482 // Shift amount must be in [1,32]
5483 if (Val < 0 || Val > 31)
5484 return Error(ExLoc, "'lsr' shift amount must be in range [0,31]");
5485 }
5486
5487 Operands.push_back(
5488 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *this));
5489
5490 return ParseStatus::Success;
5491}
5492
5493/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
5494/// of instructions. Legal values are:
5495/// ror #n 'n' in {0, 8, 16, 24}
5496ParseStatus ARMAsmParser::parseRotImm(OperandVector &Operands) {
5497 MCAsmParser &Parser = getParser();
5498 const AsmToken &Tok = Parser.getTok();
5499 SMLoc S = Tok.getLoc();
5500 if (Tok.isNot(AsmToken::Identifier))
5501 return ParseStatus::NoMatch;
5502 StringRef ShiftName = Tok.getString();
5503 if (ShiftName != "ror" && ShiftName != "ROR")
5504 return ParseStatus::NoMatch;
5505 Parser.Lex(); // Eat the operator.
5506
5507 // A '#' and a rotate amount.
5508 if (Parser.getTok().isNot(AsmToken::Hash) &&
5509 Parser.getTok().isNot(AsmToken::Dollar))
5510 return Error(Parser.getTok().getLoc(), "'#' expected");
5511 Parser.Lex(); // Eat hash token.
5512 SMLoc ExLoc = Parser.getTok().getLoc();
5513
5514 const MCExpr *ShiftAmount;
5515 SMLoc EndLoc;
5516 if (getParser().parseExpression(ShiftAmount, EndLoc))
5517 return Error(ExLoc, "malformed rotate expression");
5518 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5519 if (!CE)
5520 return Error(ExLoc, "rotate amount must be an immediate");
5521
5522 int64_t Val = CE->getValue();
5523 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
5524 // normally, zero is represented in asm by omitting the rotate operand
5525 // entirely.
5526 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5527 return Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24");
5528
5529 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *this));
5530
5531 return ParseStatus::Success;
5532}
5533
5534ParseStatus ARMAsmParser::parseModImm(OperandVector &Operands) {
5535 MCAsmParser &Parser = getParser();
5536 AsmLexer &Lexer = getLexer();
5537 int64_t Imm1, Imm2;
5538
5539 SMLoc S = Parser.getTok().getLoc();
5540
5541 // 1) A mod_imm operand can appear in the place of a register name:
5542 // add r0, #mod_imm
5543 // add r0, r0, #mod_imm
5544 // to correctly handle the latter, we bail out as soon as we see an
5545 // identifier.
5546 //
5547 // 2) Similarly, we do not want to parse into complex operands:
5548 // mov r0, #mod_imm
5549 // mov r0, :lower16:(_foo)
5550 if (Parser.getTok().is(AsmToken::Identifier) ||
5551 Parser.getTok().is(AsmToken::Colon))
5552 return ParseStatus::NoMatch;
5553
5554 // Hash (dollar) is optional as per the ARMARM
5555 if (Parser.getTok().is(AsmToken::Hash) ||
5556 Parser.getTok().is(AsmToken::Dollar)) {
5557 // Avoid parsing into complex operands (#:)
5558 if (Lexer.peekTok().is(AsmToken::Colon))
5559 return ParseStatus::NoMatch;
5560
5561 // Eat the hash (dollar)
5562 Parser.Lex();
5563 }
5564
5565 SMLoc Sx1, Ex1;
5566 Sx1 = Parser.getTok().getLoc();
5567 const MCExpr *Imm1Exp;
5568 if (getParser().parseExpression(Imm1Exp, Ex1))
5569 return Error(Sx1, "malformed expression");
5570
5571 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
5572
5573 if (CE) {
5574 // Immediate must fit within 32-bits
5575 Imm1 = CE->getValue();
5576 int Enc = ARM_AM::getSOImmVal(Imm1);
5577 if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) {
5578 // We have a match!
5579 Operands.push_back(ARMOperand::CreateModImm(
5580 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *this));
5581 return ParseStatus::Success;
5582 }
5583
5584 // We have parsed an immediate which is not for us, fallback to a plain
5585 // immediate. This can happen for instruction aliases. For an example,
5586 // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
5587 // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
5588 // instruction with a mod_imm operand. The alias is defined such that the
5589 // parser method is shared, that's why we have to do this here.
5590 if (Parser.getTok().is(AsmToken::EndOfStatement)) {
5591 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this));
5592 return ParseStatus::Success;
5593 }
5594 } else {
5595 // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
5596 // MCFixup). Fallback to a plain immediate.
5597 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this));
5598 return ParseStatus::Success;
5599 }
5600
5601 // From this point onward, we expect the input to be a (#bits, #rot) pair
5602 if (Parser.getTok().isNot(AsmToken::Comma))
5603 return Error(Sx1,
5604 "expected modified immediate operand: #[0, 255], #even[0-30]");
5605
5606 if (Imm1 & ~0xFF)
5607 return Error(Sx1, "immediate operand must a number in the range [0, 255]");
5608
5609 // Eat the comma
5610 Parser.Lex();
5611
5612 // Repeat for #rot
5613 SMLoc Sx2, Ex2;
5614 Sx2 = Parser.getTok().getLoc();
5615
5616 // Eat the optional hash (dollar)
5617 if (Parser.getTok().is(AsmToken::Hash) ||
5618 Parser.getTok().is(AsmToken::Dollar))
5619 Parser.Lex();
5620
5621 const MCExpr *Imm2Exp;
5622 if (getParser().parseExpression(Imm2Exp, Ex2))
5623 return Error(Sx2, "malformed expression");
5624
5625 CE = dyn_cast<MCConstantExpr>(Imm2Exp);
5626
5627 if (CE) {
5628 Imm2 = CE->getValue();
5629 if (!(Imm2 & ~0x1E)) {
5630 // We have a match!
5631 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *this));
5632 return ParseStatus::Success;
5633 }
5634 return Error(Sx2,
5635 "immediate operand must an even number in the range [0, 30]");
5636 } else {
5637 return Error(Sx2, "constant expression expected");
5638 }
5639}
5640
5641ParseStatus ARMAsmParser::parseBitfield(OperandVector &Operands) {
5642 MCAsmParser &Parser = getParser();
5643 SMLoc S = Parser.getTok().getLoc();
5644 // The bitfield descriptor is really two operands, the LSB and the width.
5645 if (Parser.getTok().isNot(AsmToken::Hash) &&
5646 Parser.getTok().isNot(AsmToken::Dollar))
5647 return ParseStatus::NoMatch;
5648 Parser.Lex(); // Eat hash token.
5649
5650 const MCExpr *LSBExpr;
5651 SMLoc E = Parser.getTok().getLoc();
5652 if (getParser().parseExpression(LSBExpr))
5653 return Error(E, "malformed immediate expression");
5654 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
5655 if (!CE)
5656 return Error(E, "'lsb' operand must be an immediate");
5657
5658 int64_t LSB = CE->getValue();
5659 // The LSB must be in the range [0,31]
5660 if (LSB < 0 || LSB > 31)
5661 return Error(E, "'lsb' operand must be in the range [0,31]");
5662 E = Parser.getTok().getLoc();
5663
5664 // Expect another immediate operand.
5665 if (Parser.getTok().isNot(AsmToken::Comma))
5666 return Error(Parser.getTok().getLoc(), "too few operands");
5667 Parser.Lex(); // Eat hash token.
5668 if (Parser.getTok().isNot(AsmToken::Hash) &&
5669 Parser.getTok().isNot(AsmToken::Dollar))
5670 return Error(Parser.getTok().getLoc(), "'#' expected");
5671 Parser.Lex(); // Eat hash token.
5672
5673 const MCExpr *WidthExpr;
5674 SMLoc EndLoc;
5675 if (getParser().parseExpression(WidthExpr, EndLoc))
5676 return Error(E, "malformed immediate expression");
5677 CE = dyn_cast<MCConstantExpr>(WidthExpr);
5678 if (!CE)
5679 return Error(E, "'width' operand must be an immediate");
5680
5681 int64_t Width = CE->getValue();
5682 // The LSB must be in the range [1,32-lsb]
5683 if (Width < 1 || Width > 32 - LSB)
5684 return Error(E, "'width' operand must be in the range [1,32-lsb]");
5685
5686 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *this));
5687
5688 return ParseStatus::Success;
5689}
5690
5691ParseStatus ARMAsmParser::parsePostIdxReg(OperandVector &Operands) {
5692 // Check for a post-index addressing register operand. Specifically:
5693 // postidx_reg := '+' register {, shift}
5694 // | '-' register {, shift}
5695 // | register {, shift}
5696
5697 // This method must return ParseStatus::NoMatch without consuming any tokens
5698 // in the case where there is no match, as other alternatives take other
5699 // parse methods.
5700 MCAsmParser &Parser = getParser();
5701 AsmToken Tok = Parser.getTok();
5702 SMLoc S = Tok.getLoc();
5703 bool haveEaten = false;
5704 bool isAdd = true;
5705 if (Tok.is(AsmToken::Plus)) {
5706 Parser.Lex(); // Eat the '+' token.
5707 haveEaten = true;
5708 } else if (Tok.is(AsmToken::Minus)) {
5709 Parser.Lex(); // Eat the '-' token.
5710 isAdd = false;
5711 haveEaten = true;
5712 }
5713
5714 SMLoc E = Parser.getTok().getEndLoc();
5715 MCRegister Reg = tryParseRegister();
5716 if (!Reg) {
5717 if (!haveEaten)
5718 return ParseStatus::NoMatch;
5719 return Error(Parser.getTok().getLoc(), "register expected");
5720 }
5721
5723 unsigned ShiftImm = 0;
5724 if (Parser.getTok().is(AsmToken::Comma)) {
5725 Parser.Lex(); // Eat the ','.
5726 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5727 return ParseStatus::Failure;
5728
5729 // FIXME: Only approximates end...may include intervening whitespace.
5730 E = Parser.getTok().getLoc();
5731 }
5732
5733 Operands.push_back(
5734 ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, ShiftImm, S, E, *this));
5735
5736 return ParseStatus::Success;
5737}
5738
5739ParseStatus ARMAsmParser::parseAM3Offset(OperandVector &Operands) {
5740 // Check for a post-index addressing register operand. Specifically:
5741 // am3offset := '+' register
5742 // | '-' register
5743 // | register
5744 // | # imm
5745 // | # + imm
5746 // | # - imm
5747
5748 // This method must return ParseStatus::NoMatch without consuming any tokens
5749 // in the case where there is no match, as other alternatives take other
5750 // parse methods.
5751 MCAsmParser &Parser = getParser();
5752 AsmToken Tok = Parser.getTok();
5753 SMLoc S = Tok.getLoc();
5754
5755 // Do immediates first, as we always parse those if we have a '#'.
5756 if (Parser.getTok().is(AsmToken::Hash) ||
5757 Parser.getTok().is(AsmToken::Dollar)) {
5758 Parser.Lex(); // Eat '#' or '$'.
5759 // Explicitly look for a '-', as we need to encode negative zero
5760 // differently.
5761 bool isNegative = Parser.getTok().is(AsmToken::Minus);
5762 const MCExpr *Offset;
5763 SMLoc E;
5764 if (getParser().parseExpression(Offset, E))
5765 return ParseStatus::Failure;
5766 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
5767 if (!CE)
5768 return Error(S, "constant expression expected");
5769 // Negative zero is encoded as the flag value
5770 // std::numeric_limits<int32_t>::min().
5771 int32_t Val = CE->getValue();
5772 if (isNegative && Val == 0)
5773 Val = std::numeric_limits<int32_t>::min();
5774
5775 Operands.push_back(ARMOperand::CreateImm(
5776 MCConstantExpr::create(Val, getContext()), S, E, *this));
5777
5778 return ParseStatus::Success;
5779 }
5780
5781 bool haveEaten = false;
5782 bool isAdd = true;
5783 if (Tok.is(AsmToken::Plus)) {
5784 Parser.Lex(); // Eat the '+' token.
5785 haveEaten = true;
5786 } else if (Tok.is(AsmToken::Minus)) {
5787 Parser.Lex(); // Eat the '-' token.
5788 isAdd = false;
5789 haveEaten = true;
5790 }
5791
5792 Tok = Parser.getTok();
5793 MCRegister Reg = tryParseRegister();
5794 if (!Reg) {
5795 if (!haveEaten)
5796 return ParseStatus::NoMatch;
5797 return Error(Tok.getLoc(), "register expected");
5798 }
5799
5800 Operands.push_back(ARMOperand::CreatePostIdxReg(
5801 Reg, isAdd, ARM_AM::no_shift, 0, S, Tok.getEndLoc(), *this));
5802
5803 return ParseStatus::Success;
5804}
5805
5806// Finds the index of the first CondCode operator, if there is none returns 0
5808 unsigned MnemonicOpsEndInd) {
5809 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
5810 auto Op = static_cast<ARMOperand &>(*Operands[I]);
5811 if (Op.isCondCode())
5812 return I;
5813 }
5814 return 0;
5815}
5816
5818 unsigned MnemonicOpsEndInd) {
5819 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
5820 auto Op = static_cast<ARMOperand &>(*Operands[I]);
5821 if (Op.isCCOut())
5822 return I;
5823 }
5824 return 0;
5825}
5826
5827/// Convert parsed operands to MCInst. Needed here because this instruction
5828/// only has two register operands, but multiplication is commutative so
5829/// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN".
5830void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5831 const OperandVector &Operands) {
5832 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5833 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5834 unsigned CondOutI = findCCOutInd(Operands, MnemonicOpsEndInd);
5835
5836 // 2 operand form
5837 unsigned RegRd = MnemonicOpsEndInd;
5838 unsigned RegRn = MnemonicOpsEndInd + 1;
5839 unsigned RegRm = MnemonicOpsEndInd;
5840
5841 if (Operands.size() == MnemonicOpsEndInd + 3) {
5842 // If we have a three-operand form, make sure to set Rn to be the operand
5843 // that isn't the same as Rd.
5844 if (((ARMOperand &)*Operands[RegRd]).getReg() ==
5845 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1]).getReg()) {
5846 RegRn = MnemonicOpsEndInd + 2;
5847 RegRm = MnemonicOpsEndInd + 1;
5848 } else {
5849 RegRn = MnemonicOpsEndInd + 1;
5850 RegRm = MnemonicOpsEndInd + 2;
5851 }
5852 }
5853
5854 // Rd
5855 ((ARMOperand &)*Operands[RegRd]).addRegOperands(Inst, 1);
5856 // CCOut
5857 if (CondOutI != 0) {
5858 ((ARMOperand &)*Operands[CondOutI]).addCCOutOperands(Inst, 1);
5859 } else {
5860 ARMOperand Op =
5861 *ARMOperand::CreateCCOut(0, Operands[0]->getEndLoc(), *this);
5862 Op.addCCOutOperands(Inst, 1);
5863 }
5864 // Rn
5865 ((ARMOperand &)*Operands[RegRn]).addRegOperands(Inst, 1);
5866 // Rm
5867 ((ARMOperand &)*Operands[RegRm]).addRegOperands(Inst, 1);
5868
5869 // Cond code
5870 if (CondI != 0) {
5871 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5872 } else {
5873 ARMOperand Op = *ARMOperand::CreateCondCode(
5874 llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this);
5875 Op.addCondCodeOperands(Inst, 2);
5876 }
5877}
5878
5879void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5880 const OperandVector &Operands) {
5881 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5882 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5883 unsigned Cond =
5884 (CondI == 0 ? ARMCC::AL
5885 : static_cast<ARMOperand &>(*Operands[CondI]).getCondCode());
5886
5887 // first decide whether or not the branch should be conditional
5888 // by looking at it's location relative to an IT block
5889 if(inITBlock()) {
5890 // inside an IT block we cannot have any conditional branches. any
5891 // such instructions needs to be converted to unconditional form
5892 switch(Inst.getOpcode()) {
5893 case ARM::tBcc: Inst.setOpcode(ARM::tB); break;
5894 case ARM::t2Bcc: Inst.setOpcode(ARM::t2B); break;
5895 }
5896 } else {
5897 switch(Inst.getOpcode()) {
5898 case ARM::tB:
5899 case ARM::tBcc:
5900 Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc);
5901 break;
5902 case ARM::t2B:
5903 case ARM::t2Bcc:
5904 Inst.setOpcode(Cond == ARMCC::AL ? ARM::t2B : ARM::t2Bcc);
5905 break;
5906 }
5907 }
5908
5909 // now decide on encoding size based on branch target range
5910 switch(Inst.getOpcode()) {
5911 // classify tB as either t2B or t1B based on range of immediate operand
5912 case ARM::tB: {
5913 ARMOperand &op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
5914 if (!op.isSignedOffset<11, 1>() && isThumb() && hasV8MBaseline())
5915 Inst.setOpcode(ARM::t2B);
5916 break;
5917 }
5918 // classify tBcc as either t2Bcc or t1Bcc based on range of immediate operand
5919 case ARM::tBcc: {
5920 ARMOperand &op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
5921 if (!op.isSignedOffset<8, 1>() && isThumb() && hasV8MBaseline())
5922 Inst.setOpcode(ARM::t2Bcc);
5923 break;
5924 }
5925 }
5926 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5927 if (CondI != 0) {
5928 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5929 } else {
5930 ARMOperand Op = *ARMOperand::CreateCondCode(
5931 llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this);
5932 Op.addCondCodeOperands(Inst, 2);
5933 }
5934}
5935
5936void ARMAsmParser::cvtMVEVMOVQtoDReg(
5937 MCInst &Inst, const OperandVector &Operands) {
5938
5939 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5940 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5941
5942 // mnemonic, condition code, Rt, Rt2, Qd, idx, Qd again, idx2
5943 assert(Operands.size() == MnemonicOpsEndInd + 6);
5944
5945 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1); // Rt
5946 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1])
5947 .addRegOperands(Inst, 1); // Rt2
5948 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 2])
5949 .addRegOperands(Inst, 1); // Qd
5950 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 3])
5951 .addMVEPairVectorIndexOperands(Inst, 1); // idx
5952 // skip second copy of Qd in Operands[6]
5953 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 5])
5954 .addMVEPairVectorIndexOperands(Inst, 1); // idx2
5955 if (CondI != 0) {
5956 ((ARMOperand &)*Operands[CondI])
5957 .addCondCodeOperands(Inst, 2); // condition code
5958 } else {
5959 ARMOperand Op =
5960 *ARMOperand::CreateCondCode(ARMCC::AL, Operands[0]->getEndLoc(), *this);
5961 Op.addCondCodeOperands(Inst, 2);
5962 }
5963}
5964
5965/// Parse an ARM memory expression, return false if successful else return true
5966/// or an error. The first token must be a '[' when called.
5967bool ARMAsmParser::parseMemory(OperandVector &Operands) {
5968 MCAsmParser &Parser = getParser();
5969 SMLoc S, E;
5970 if (Parser.getTok().isNot(AsmToken::LBrac))
5971 return TokError("Token is not a Left Bracket");
5972 S = Parser.getTok().getLoc();
5973 Parser.Lex(); // Eat left bracket token.
5974
5975 const AsmToken &BaseRegTok = Parser.getTok();
5976 MCRegister BaseReg = tryParseRegister();
5977 if (!BaseReg)
5978 return Error(BaseRegTok.getLoc(), "register expected");
5979
5980 // The next token must either be a comma, a colon or a closing bracket.
5981 const AsmToken &Tok = Parser.getTok();
5982 if (!Tok.is(AsmToken::Colon) && !Tok.is(AsmToken::Comma) &&
5983 !Tok.is(AsmToken::RBrac))
5984 return Error(Tok.getLoc(), "malformed memory operand");
5985
5986 if (Tok.is(AsmToken::RBrac)) {
5987 E = Tok.getEndLoc();
5988 Parser.Lex(); // Eat right bracket token.
5989
5990 Operands.push_back(ARMOperand::CreateMem(
5991 BaseReg, nullptr, 0, ARM_AM::no_shift, 0, 0, false, S, E, *this));
5992
5993 // If there's a pre-indexing writeback marker, '!', just add it as a token
5994 // operand. It's rather odd, but syntactically valid.
5995 if (Parser.getTok().is(AsmToken::Exclaim)) {
5996 Operands.push_back(
5997 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
5998 Parser.Lex(); // Eat the '!'.
5999 }
6000
6001 return false;
6002 }
6003
6004 assert((Tok.is(AsmToken::Colon) || Tok.is(AsmToken::Comma)) &&
6005 "Lost colon or comma in memory operand?!");
6006 if (Tok.is(AsmToken::Comma)) {
6007 Parser.Lex(); // Eat the comma.
6008 }
6009
6010 // If we have a ':', it's an alignment specifier.
6011 if (Parser.getTok().is(AsmToken::Colon)) {
6012 Parser.Lex(); // Eat the ':'.
6013 E = Parser.getTok().getLoc();
6014 SMLoc AlignmentLoc = Tok.getLoc();
6015
6016 const MCExpr *Expr;
6017 if (getParser().parseExpression(Expr))
6018 return true;
6019
6020 // The expression has to be a constant. Memory references with relocations
6021 // don't come through here, as they use the <label> forms of the relevant
6022 // instructions.
6023 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
6024 if (!CE)
6025 return Error (E, "constant expression expected");
6026
6027 unsigned Align = 0;
6028 switch (CE->getValue()) {
6029 default:
6030 return Error(E,
6031 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6032 case 16: Align = 2; break;
6033 case 32: Align = 4; break;
6034 case 64: Align = 8; break;
6035 case 128: Align = 16; break;
6036 case 256: Align = 32; break;
6037 }
6038
6039 // Now we should have the closing ']'
6040 if (Parser.getTok().isNot(AsmToken::RBrac))
6041 return Error(Parser.getTok().getLoc(), "']' expected");
6042 E = Parser.getTok().getEndLoc();
6043 Parser.Lex(); // Eat right bracket token.
6044
6045 // Don't worry about range checking the value here. That's handled by
6046 // the is*() predicates.
6047 Operands.push_back(ARMOperand::CreateMem(BaseReg, nullptr, 0,
6048 ARM_AM::no_shift, 0, Align, false,
6049 S, E, *this, AlignmentLoc));
6050
6051 // If there's a pre-indexing writeback marker, '!', just add it as a token
6052 // operand.
6053 if (Parser.getTok().is(AsmToken::Exclaim)) {
6054 Operands.push_back(
6055 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6056 Parser.Lex(); // Eat the '!'.
6057 }
6058
6059 return false;
6060 }
6061
6062 // If we have a '#' or '$', it's an immediate offset, else assume it's a
6063 // register offset. Be friendly and also accept a plain integer or expression
6064 // (without a leading hash) for gas compatibility.
6065 if (Parser.getTok().is(AsmToken::Hash) ||
6066 Parser.getTok().is(AsmToken::Dollar) ||
6067 Parser.getTok().is(AsmToken::LParen) ||
6068 Parser.getTok().is(AsmToken::Integer)) {
6069 if (Parser.getTok().is(AsmToken::Hash) ||
6070 Parser.getTok().is(AsmToken::Dollar))
6071 Parser.Lex(); // Eat '#' or '$'
6072 E = Parser.getTok().getLoc();
6073
6074 bool isNegative = getParser().getTok().is(AsmToken::Minus);
6075 const MCExpr *Offset, *AdjustedOffset;
6076 if (getParser().parseExpression(Offset))
6077 return true;
6078
6079 if (const auto *CE = dyn_cast<MCConstantExpr>(Offset)) {
6080 // If the constant was #-0, represent it as
6081 // std::numeric_limits<int32_t>::min().
6082 int32_t Val = CE->getValue();
6083 if (isNegative && Val == 0)
6084 CE = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
6085 getContext());
6086 // Don't worry about range checking the value here. That's handled by
6087 // the is*() predicates.
6088 AdjustedOffset = CE;
6089 } else
6090 AdjustedOffset = Offset;
6091 Operands.push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6092 ARM_AM::no_shift, 0, 0, false, S,
6093 E, *this));
6094
6095 // Now we should have the closing ']'
6096 if (Parser.getTok().isNot(AsmToken::RBrac))
6097 return Error(Parser.getTok().getLoc(), "']' expected");
6098 E = Parser.getTok().getEndLoc();
6099 Parser.Lex(); // Eat right bracket token.
6100
6101 // If there's a pre-indexing writeback marker, '!', just add it as a token
6102 // operand.
6103 if (Parser.getTok().is(AsmToken::Exclaim)) {
6104 Operands.push_back(
6105 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6106 Parser.Lex(); // Eat the '!'.
6107 }
6108
6109 return false;
6110 }
6111
6112 // The register offset is optionally preceded by a '+' or '-'
6113 bool isNegative = false;
6114 if (Parser.getTok().is(AsmToken::Minus)) {
6115 isNegative = true;
6116 Parser.Lex(); // Eat the '-'.
6117 } else if (Parser.getTok().is(AsmToken::Plus)) {
6118 // Nothing to do.
6119 Parser.Lex(); // Eat the '+'.
6120 }
6121
6122 E = Parser.getTok().getLoc();
6123 MCRegister OffsetReg = tryParseRegister();
6124 if (!OffsetReg)
6125 return Error(E, "register expected");
6126
6127 // If there's a shift operator, handle it.
6129 unsigned ShiftImm = 0;
6130 if (Parser.getTok().is(AsmToken::Comma)) {
6131 Parser.Lex(); // Eat the ','.
6132 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6133 return true;
6134 }
6135
6136 // Now we should have the closing ']'
6137 if (Parser.getTok().isNot(AsmToken::RBrac))
6138 return Error(Parser.getTok().getLoc(), "']' expected");
6139 E = Parser.getTok().getEndLoc();
6140 Parser.Lex(); // Eat right bracket token.
6141
6142 Operands.push_back(ARMOperand::CreateMem(BaseReg, nullptr, OffsetReg,
6143 ShiftType, ShiftImm, 0, isNegative,
6144 S, E, *this));
6145
6146 // If there's a pre-indexing writeback marker, '!', just add it as a token
6147 // operand.
6148 if (Parser.getTok().is(AsmToken::Exclaim)) {
6149 Operands.push_back(
6150 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6151 Parser.Lex(); // Eat the '!'.
6152 }
6153
6154 return false;
6155}
6156
6157/// parseMemRegOffsetShift - one of these two:
6158/// ( lsl | lsr | asr | ror ) , # shift_amount
6159/// rrx
6160/// return true if it parses a shift otherwise it returns false.
6161bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
6162 unsigned &Amount) {
6163 MCAsmParser &Parser = getParser();
6164 SMLoc Loc = Parser.getTok().getLoc();
6165 const AsmToken &Tok = Parser.getTok();
6166 if (Tok.isNot(AsmToken::Identifier))
6167 return Error(Loc, "illegal shift operator");
6168 StringRef ShiftName = Tok.getString();
6169 if (ShiftName == "lsl" || ShiftName == "LSL" ||
6170 ShiftName == "asl" || ShiftName == "ASL")
6171 St = ARM_AM::lsl;
6172 else if (ShiftName == "lsr" || ShiftName == "LSR")
6173 St = ARM_AM::lsr;
6174 else if (ShiftName == "asr" || ShiftName == "ASR")
6175 St = ARM_AM::asr;
6176 else if (ShiftName == "ror" || ShiftName == "ROR")
6177 St = ARM_AM::ror;
6178 else if (ShiftName == "rrx" || ShiftName == "RRX")
6179 St = ARM_AM::rrx;
6180 else if (ShiftName == "uxtw" || ShiftName == "UXTW")
6181 St = ARM_AM::uxtw;
6182 else
6183 return Error(Loc, "illegal shift operator");
6184 Parser.Lex(); // Eat shift type token.
6185
6186 // rrx stands alone.
6187 Amount = 0;
6188 if (St != ARM_AM::rrx) {
6189 Loc = Parser.getTok().getLoc();
6190 // A '#' and a shift amount.
6191 const AsmToken &HashTok = Parser.getTok();
6192 if (HashTok.isNot(AsmToken::Hash) &&
6193 HashTok.isNot(AsmToken::Dollar))
6194 return Error(HashTok.getLoc(), "'#' expected");
6195 Parser.Lex(); // Eat hash token.
6196
6197 const MCExpr *Expr;
6198 if (getParser().parseExpression(Expr))
6199 return true;
6200 // Range check the immediate.
6201 // lsl, ror: 0 <= imm <= 31
6202 // lsr, asr: 0 <= imm <= 32
6203 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
6204 if (!CE)
6205 return Error(Loc, "shift amount must be an immediate");
6206 int64_t Imm = CE->getValue();
6207 if (Imm < 0 ||
6208 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
6209 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
6210 return Error(Loc, "immediate shift value out of range");
6211 // If <ShiftTy> #0, turn it into a no_shift.
6212 if (Imm == 0)
6213 St = ARM_AM::lsl;
6214 // For consistency, treat lsr #32 and asr #32 as having immediate value 0.
6215 if (Imm == 32)
6216 Imm = 0;
6217 Amount = Imm;
6218 }
6219
6220 return false;
6221}
6222
6223/// parseFPImm - A floating point immediate expression operand.
6224ParseStatus ARMAsmParser::parseFPImm(OperandVector &Operands) {
6225 LLVM_DEBUG(dbgs() << "PARSE FPImm, Ops: " << Operands.size());
6226
6227 MCAsmParser &Parser = getParser();
6228 // Anything that can accept a floating point constant as an operand
6229 // needs to go through here, as the regular parseExpression is
6230 // integer only.
6231 //
6232 // This routine still creates a generic Immediate operand, containing
6233 // a bitcast of the 64-bit floating point value. The various operands
6234 // that accept floats can check whether the value is valid for them
6235 // via the standard is*() predicates.
6236
6237 SMLoc S = Parser.getTok().getLoc();
6238
6239 if (Parser.getTok().isNot(AsmToken::Hash) &&
6240 Parser.getTok().isNot(AsmToken::Dollar))
6241 return ParseStatus::NoMatch;
6242
6243 // Disambiguate the VMOV forms that can accept an FP immediate.
6244 // vmov.f32 <sreg>, #imm
6245 // vmov.f64 <dreg>, #imm
6246 // vmov.f32 <dreg>, #imm @ vector f32x2
6247 // vmov.f32 <qreg>, #imm @ vector f32x4
6248 //
6249 // There are also the NEON VMOV instructions which expect an
6250 // integer constant. Make sure we don't try to parse an FPImm
6251 // for these:
6252 // vmov.i{8|16|32|64} <dreg|qreg>, #imm
6253
6254 bool isVmovf = false;
6255 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
6256 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
6257 ARMOperand &TyOp = static_cast<ARMOperand &>(*Operands[I]);
6258 if (TyOp.isToken() &&
6259 (TyOp.getToken() == ".f32" || TyOp.getToken() == ".f64" ||
6260 TyOp.getToken() == ".f16")) {
6261 isVmovf = true;
6262 break;
6263 }
6264 }
6265
6266 ARMOperand &Mnemonic = static_cast<ARMOperand &>(*Operands[0]);
6267 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() == "fconstd" ||
6268 Mnemonic.getToken() == "fconsts");
6269 if (!(isVmovf || isFconst))
6270 return ParseStatus::NoMatch;
6271
6272 Parser.Lex(); // Eat '#' or '$'.
6273
6274 // Handle negation, as that still comes through as a separate token.
6275 bool isNegative = false;
6276 if (Parser.getTok().is(AsmToken::Minus)) {
6277 isNegative = true;
6278 Parser.Lex();
6279 }
6280 const AsmToken &Tok = Parser.getTok();
6281 SMLoc Loc = Tok.getLoc();
6282 if (Tok.is(AsmToken::Real) && isVmovf) {
6283 APFloat RealVal(APFloat::IEEEsingle(), Tok.getString());
6284 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
6285 // If we had a '-' in front, toggle the sign bit.
6286 IntVal ^= (uint64_t)isNegative << 31;
6287 Parser.Lex(); // Eat the token.
6288 Operands.push_back(
6289 ARMOperand::CreateImm(MCConstantExpr::create(IntVal, getContext()), S,
6290 Parser.getTok().getLoc(), *this));
6291 return ParseStatus::Success;
6292 }
6293 // Also handle plain integers. Instructions which allow floating point
6294 // immediates also allow a raw encoded 8-bit value.
6295 if (Tok.is(AsmToken::Integer) && isFconst) {
6296 int64_t Val = Tok.getIntVal();
6297 Parser.Lex(); // Eat the token.
6298 if (Val > 255 || Val < 0)
6299 return Error(Loc, "encoded floating point value out of range");
6300 float RealVal = ARM_AM::getFPImmFloat(Val);
6301 Val = APFloat(RealVal).bitcastToAPInt().getZExtValue();
6302
6303 Operands.push_back(
6304 ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S,
6305 Parser.getTok().getLoc(), *this));
6306 return ParseStatus::Success;
6307 }
6308
6309 return Error(Loc, "invalid floating point immediate");
6310}
6311
6312/// Parse a arm instruction operand. For now this parses the operand regardless
6313/// of the mnemonic.
6314bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6315 MCAsmParser &Parser = getParser();
6316 SMLoc S, E;
6317
6318 // Check if the current operand has a custom associated parser, if so, try to
6319 // custom parse the operand, or fallback to the general approach.
6320 ParseStatus ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6321 if (ResTy.isSuccess())
6322 return false;
6323 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6324 // there was a match, but an error occurred, in which case, just return that
6325 // the operand parsing failed.
6326 if (ResTy.isFailure())
6327 return true;
6328
6329 switch (getLexer().getKind()) {
6330 default:
6331 Error(Parser.getTok().getLoc(), "unexpected token in operand");
6332 return true;
6333 case AsmToken::Identifier: {
6334 // If we've seen a branch mnemonic, the next operand must be a label. This
6335 // is true even if the label is a register name. So "br r1" means branch to
6336 // label "r1".
6337 bool ExpectLabel = Mnemonic == "b" || Mnemonic == "bl";
6338 if (!ExpectLabel) {
6339 if (!tryParseRegisterWithWriteBack(Operands))
6340 return false;
6341 int Res = tryParseShiftRegister(Operands);
6342 if (Res == 0) // success
6343 return false;
6344 else if (Res == -1) // irrecoverable error
6345 return true;
6346 // If this is VMRS, check for the apsr_nzcv operand.
6347 if (Mnemonic == "vmrs" &&
6348 Parser.getTok().getString().equals_insensitive("apsr_nzcv")) {
6349 S = Parser.getTok().getLoc();
6350 Parser.Lex();
6351 Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S, *this));
6352 return false;
6353 }
6354 }
6355
6356 // Fall though for the Identifier case that is not a register or a
6357 // special name.
6358 [[fallthrough]];
6359 }
6360 case AsmToken::LParen: // parenthesized expressions like (_strcmp-4)
6361 case AsmToken::Integer: // things like 1f and 2b as a branch targets
6362 case AsmToken::String: // quoted label names.
6363 case AsmToken::Dot: { // . as a branch target
6364 // This was not a register so parse other operands that start with an
6365 // identifier (like labels) as expressions and create them as immediates.
6366 const MCExpr *IdVal;
6367 S = Parser.getTok().getLoc();
6368 if (getParser().parseExpression(IdVal))
6369 return true;
6370 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6371 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E, *this));
6372 return false;
6373 }
6374 case AsmToken::LBrac:
6375 return parseMemory(Operands);
6376 case AsmToken::LCurly: {
6377 bool IsLazyLoadStore = Mnemonic == "vlldm" || Mnemonic == "vlstm";
6378 bool IsVSCCLRM = Mnemonic == "vscclrm";
6379 return parseRegisterList(Operands, !Mnemonic.starts_with("clr"), false,
6380 IsLazyLoadStore, IsVSCCLRM);
6381 }
6382 case AsmToken::Dollar:
6383 case AsmToken::Hash: {
6384 // #42 -> immediate
6385 // $ 42 -> immediate
6386 // $foo -> symbol name
6387 // $42 -> symbol name
6388 S = Parser.getTok().getLoc();
6389
6390 // Favor the interpretation of $-prefixed operands as symbol names.
6391 // Cases where immediates are explicitly expected are handled by their
6392 // specific ParseMethod implementations.
6393 auto AdjacentToken = getLexer().peekTok(/*ShouldSkipSpace=*/false);
6394 bool ExpectIdentifier = Parser.getTok().is(AsmToken::Dollar) &&
6395 (AdjacentToken.is(AsmToken::Identifier) ||
6396 AdjacentToken.is(AsmToken::Integer));
6397 if (!ExpectIdentifier) {
6398 // Token is not part of identifier. Drop leading $ or # before parsing
6399 // expression.
6400 Parser.Lex();
6401 }
6402
6403 if (Parser.getTok().isNot(AsmToken::Colon)) {
6404 bool IsNegative = Parser.getTok().is(AsmToken::Minus);
6405 const MCExpr *ImmVal;
6406 if (getParser().parseExpression(ImmVal))
6407 return true;
6408 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
6409 if (CE) {
6410 int32_t Val = CE->getValue();
6411 if (IsNegative && Val == 0)
6412 ImmVal = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
6413 getContext());
6414 }
6415 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6416 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E, *this));
6417
6418 // There can be a trailing '!' on operands that we want as a separate
6419 // '!' Token operand. Handle that here. For example, the compatibility
6420 // alias for 'srsdb sp!, #imm' is 'srsdb #imm!'.
6421 if (Parser.getTok().is(AsmToken::Exclaim)) {
6422 Operands.push_back(ARMOperand::CreateToken(
6423 Parser.getTok().getString(), Parser.getTok().getLoc(), *this));
6424 Parser.Lex(); // Eat exclaim token
6425 }
6426 return false;
6427 }
6428 // w/ a ':' after the '#', it's just like a plain ':'.
6429 [[fallthrough]];
6430 }
6431 case AsmToken::Colon: {
6432 S = Parser.getTok().getLoc();
6433 // ":lower16:", ":upper16:", ":lower0_7:", ":lower8_15:", ":upper0_7:" and
6434 // ":upper8_15:", expression prefixes
6435 // FIXME: Check it's an expression prefix,
6436 // e.g. (FOO - :lower16:BAR) isn't legal.
6437 ARM::Specifier Spec;
6438 if (parsePrefix(Spec))
6439 return true;
6440
6441 const MCExpr *SubExprVal;
6442 if (getParser().parseExpression(SubExprVal))
6443 return true;
6444
6445 const auto *ExprVal =
6446 MCSpecifierExpr::create(SubExprVal, Spec, getContext(), S);
6447 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6448 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E, *this));
6449 return false;
6450 }
6451 case AsmToken::Equal: {
6452 S = Parser.getTok().getLoc();
6453 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
6454 return Error(S, "unexpected token in operand");
6455 Parser.Lex(); // Eat '='
6456 const MCExpr *SubExprVal;
6457 if (getParser().parseExpression(SubExprVal))
6458 return true;
6459 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6460
6461 // execute-only: we assume that assembly programmers know what they are
6462 // doing and allow literal pool creation here
6463 Operands.push_back(
6464 ARMOperand::CreateConstantPoolImm(SubExprVal, S, E, *this));
6465 return false;
6466 }
6467 }
6468}
6469
6470bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6471 const MCExpr *Expr = nullptr;
6472 SMLoc L = getParser().getTok().getLoc();
6473 if (check(getParser().parseExpression(Expr), L, "expected expression"))
6474 return true;
6475 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
6476 if (check(!Value, L, "expected constant expression"))
6477 return true;
6478 Out = Value->getValue();
6479 return false;
6480}
6481
6482// parsePrefix - Parse ARM 16-bit relocations expression prefixes, i.e.
6483// :lower16: and :upper16: and Thumb 8-bit relocation expression prefixes, i.e.
6484// :upper8_15:, :upper0_7:, :lower8_15: and :lower0_7:
6485bool ARMAsmParser::parsePrefix(ARM::Specifier &Spec) {
6486 MCAsmParser &Parser = getParser();
6487 Spec = ARM::S_None;
6488
6489 // consume an optional '#' (GNU compatibility)
6490 if (getLexer().is(AsmToken::Hash))
6491 Parser.Lex();
6492
6493 assert(getLexer().is(AsmToken::Colon) && "expected a :");
6494 Parser.Lex(); // Eat ':'
6495
6496 if (getLexer().isNot(AsmToken::Identifier)) {
6497 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
6498 return true;
6499 }
6500
6501 enum {
6502 COFF = (1 << MCContext::IsCOFF),
6503 ELF = (1 << MCContext::IsELF),
6504 MACHO = (1 << MCContext::IsMachO),
6505 WASM = (1 << MCContext::IsWasm),
6506 };
6507 static const struct PrefixEntry {
6508 const char *Spelling;
6509 ARM::Specifier Spec;
6510 uint8_t SupportedFormats;
6511 } PrefixEntries[] = {
6512 {"upper16", ARM::S_HI16, COFF | ELF | MACHO},
6513 {"lower16", ARM::S_LO16, COFF | ELF | MACHO},
6514 {"upper8_15", ARM::S_HI_8_15, ELF},
6515 {"upper0_7", ARM::S_HI_0_7, ELF},
6516 {"lower8_15", ARM::S_LO_8_15, ELF},
6517 {"lower0_7", ARM::S_LO_0_7, ELF},
6518 };
6519
6520 StringRef IDVal = Parser.getTok().getIdentifier();
6521
6522 const auto &Prefix =
6523 llvm::find_if(PrefixEntries, [&IDVal](const PrefixEntry &PE) {
6524 return PE.Spelling == IDVal;
6525 });
6526 if (Prefix == std::end(PrefixEntries)) {
6527 Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
6528 return true;
6529 }
6530
6531 uint8_t CurrentFormat;
6532 switch (getContext().getObjectFileType()) {
6533 case MCContext::IsMachO:
6534 CurrentFormat = MACHO;
6535 break;
6536 case MCContext::IsELF:
6537 CurrentFormat = ELF;
6538 break;
6539 case MCContext::IsCOFF:
6540 CurrentFormat = COFF;
6541 break;
6542 case MCContext::IsWasm:
6543 CurrentFormat = WASM;
6544 break;
6545 case MCContext::IsGOFF:
6546 case MCContext::IsSPIRV:
6547 case MCContext::IsXCOFF:
6549 llvm_unreachable("unexpected object format");
6550 break;
6551 }
6552
6553 if (~Prefix->SupportedFormats & CurrentFormat) {
6554 Error(Parser.getTok().getLoc(),
6555 "cannot represent relocation in the current file format");
6556 return true;
6557 }
6558
6559 Spec = Prefix->Spec;
6560 Parser.Lex();
6561
6562 if (getLexer().isNot(AsmToken::Colon)) {
6563 Error(Parser.getTok().getLoc(), "unexpected token after prefix");
6564 return true;
6565 }
6566 Parser.Lex(); // Eat the last ':'
6567
6568 // consume an optional trailing '#' (GNU compatibility) bla
6569 parseOptionalToken(AsmToken::Hash);
6570
6571 return false;
6572}
6573
6574/// Given a mnemonic, split out possible predication code and carry
6575/// setting letters to form a canonical mnemonic and flags.
6576//
6577// FIXME: Would be nice to autogen this.
6578// FIXME: This is a bit of a maze of special cases.
6579StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6580 ARMCC::CondCodes &PredicationCode,
6581 ARMVCC::VPTCodes &VPTPredicationCode,
6582 bool &CarrySetting,
6583 unsigned &ProcessorIMod,
6584 StringRef &ITMask) {
6585 PredicationCode = ARMCC::AL;
6586 VPTPredicationCode = ARMVCC::None;
6587 CarrySetting = false;
6588 ProcessorIMod = 0;
6589
6590 // Ignore some mnemonics we know aren't predicated forms.
6591 //
6592 // FIXME: Would be nice to autogen this.
6593 if ((Mnemonic == "movs" && isThumb()) || Mnemonic == "teq" ||
6594 Mnemonic == "vceq" || Mnemonic == "svc" || Mnemonic == "mls" ||
6595 Mnemonic == "smmls" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
6596 Mnemonic == "vnmls" || Mnemonic == "vacge" || Mnemonic == "vcge" ||
6597 Mnemonic == "vclt" || Mnemonic == "vacgt" || Mnemonic == "vaclt" ||
6598 Mnemonic == "vacle" || Mnemonic == "hlt" || Mnemonic == "vcgt" ||
6599 Mnemonic == "vcle" || Mnemonic == "smlal" || Mnemonic == "umaal" ||
6600 Mnemonic == "umlal" || Mnemonic == "vabal" || Mnemonic == "vmlal" ||
6601 Mnemonic == "vpadal" || Mnemonic == "vqdmlal" || Mnemonic == "fmuls" ||
6602 Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" ||
6603 Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" ||
6604 Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" ||
6605 Mnemonic == "vrintm" || Mnemonic == "hvc" ||
6606 Mnemonic.starts_with("vsel") || Mnemonic == "vins" ||
6607 Mnemonic == "vmovx" || Mnemonic == "bxns" || Mnemonic == "blxns" ||
6608 Mnemonic == "vdot" || Mnemonic == "vmmla" || Mnemonic == "vudot" ||
6609 Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
6610 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || Mnemonic == "wls" ||
6611 Mnemonic == "le" || Mnemonic == "dls" || Mnemonic == "csel" ||
6612 Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" ||
6613 Mnemonic == "cinc" || Mnemonic == "cinv" || Mnemonic == "cneg" ||
6614 Mnemonic == "cset" || Mnemonic == "csetm" || Mnemonic == "aut" ||
6615 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "bti")
6616 return Mnemonic;
6617
6618 // First, split out any predication code. Ignore mnemonics we know aren't
6619 // predicated but do have a carry-set and so weren't caught above.
6620 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
6621 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
6622 Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
6623 Mnemonic != "sbcs" && Mnemonic != "rscs" &&
6624 !(hasMVE() &&
6625 (Mnemonic == "vmine" || Mnemonic == "vshle" || Mnemonic == "vshlt" ||
6626 Mnemonic == "vshllt" || Mnemonic == "vrshle" || Mnemonic == "vrshlt" ||
6627 Mnemonic == "vmvne" || Mnemonic == "vorne" || Mnemonic == "vnege" ||
6628 Mnemonic == "vnegt" || Mnemonic == "vmule" || Mnemonic == "vmult" ||
6629 Mnemonic == "vrintne" || Mnemonic == "vcmult" ||
6630 Mnemonic == "vcmule" || Mnemonic == "vpsele" || Mnemonic == "vpselt" ||
6631 Mnemonic.starts_with("vq")))) {
6632 unsigned CC = ARMCondCodeFromString(Mnemonic.substr(Mnemonic.size()-2));
6633 if (CC != ~0U) {
6634 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
6635 PredicationCode = static_cast<ARMCC::CondCodes>(CC);
6636 }
6637 }
6638
6639 // Next, determine if we have a carry setting bit. We explicitly ignore all
6640 // the instructions we know end in 's'.
6641 if (Mnemonic.ends_with("s") &&
6642 !(Mnemonic == "cps" || Mnemonic == "mls" || Mnemonic == "mrs" ||
6643 Mnemonic == "smmls" || Mnemonic == "vabs" || Mnemonic == "vcls" ||
6644 Mnemonic == "vmls" || Mnemonic == "vmrs" || Mnemonic == "vnmls" ||
6645 Mnemonic == "vqabs" || Mnemonic == "vrecps" || Mnemonic == "vrsqrts" ||
6646 Mnemonic == "srs" || Mnemonic == "flds" || Mnemonic == "fmrs" ||
6647 Mnemonic == "fsqrts" || Mnemonic == "fsubs" || Mnemonic == "fsts" ||
6648 Mnemonic == "fcpys" || Mnemonic == "fdivs" || Mnemonic == "fmuls" ||
6649 Mnemonic == "fcmps" || Mnemonic == "fcmpzs" || Mnemonic == "vfms" ||
6650 Mnemonic == "vfnms" || Mnemonic == "fconsts" || Mnemonic == "bxns" ||
6651 Mnemonic == "blxns" || Mnemonic == "vfmas" || Mnemonic == "vmlas" ||
6652 (Mnemonic == "movs" && isThumb()))) {
6653 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
6654 CarrySetting = true;
6655 }
6656
6657 // The "cps" instruction can have a interrupt mode operand which is glued into
6658 // the mnemonic. Check if this is the case, split it and parse the imod op
6659 if (Mnemonic.starts_with("cps")) {
6660 // Split out any imod code.
6661 unsigned IMod =
6662 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
6663 .Case("ie", ARM_PROC::IE)
6664 .Case("id", ARM_PROC::ID)
6665 .Default(~0U);
6666 if (IMod != ~0U) {
6667 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
6668 ProcessorIMod = IMod;
6669 }
6670 }
6671
6672 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic != "vmovlt" &&
6673 Mnemonic != "vshllt" && Mnemonic != "vrshrnt" && Mnemonic != "vshrnt" &&
6674 Mnemonic != "vqrshrunt" && Mnemonic != "vqshrunt" &&
6675 Mnemonic != "vqrshrnt" && Mnemonic != "vqshrnt" && Mnemonic != "vmullt" &&
6676 Mnemonic != "vqmovnt" && Mnemonic != "vqmovunt" && Mnemonic != "vmovnt" &&
6677 Mnemonic != "vqdmullt" && Mnemonic != "vpnot" && Mnemonic != "vcvtt" &&
6678 Mnemonic != "vcvt") {
6679 unsigned VCC =
6680 ARMVectorCondCodeFromString(Mnemonic.substr(Mnemonic.size() - 1));
6681 if (VCC != ~0U) {
6682 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-1);
6683 VPTPredicationCode = static_cast<ARMVCC::VPTCodes>(VCC);
6684 }
6685 return Mnemonic;
6686 }
6687
6688 // The "it" instruction has the condition mask on the end of the mnemonic.
6689 if (Mnemonic.starts_with("it")) {
6690 ITMask = Mnemonic.substr(2);
6691 Mnemonic = Mnemonic.slice(0, 2);
6692 }
6693
6694 if (Mnemonic.starts_with("vpst")) {
6695 ITMask = Mnemonic.substr(4);
6696 Mnemonic = Mnemonic.slice(0, 4);
6697 } else if (Mnemonic.starts_with("vpt")) {
6698 ITMask = Mnemonic.substr(3);
6699 Mnemonic = Mnemonic.slice(0, 3);
6700 }
6701
6702 return Mnemonic;
6703}
6704
6705/// Given a canonical mnemonic, determine if the instruction ever allows
6706/// inclusion of carry set or predication code operands.
6707//
6708// FIXME: It would be nice to autogen this.
6709void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6710 StringRef ExtraToken,
6711 StringRef FullInst,
6712 bool &CanAcceptCarrySet,
6713 bool &CanAcceptPredicationCode,
6714 bool &CanAcceptVPTPredicationCode) {
6715 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6716
6717 CanAcceptCarrySet =
6718 Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
6719 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
6720 Mnemonic == "add" || Mnemonic == "adc" || Mnemonic == "mul" ||
6721 Mnemonic == "bic" || Mnemonic == "asr" || Mnemonic == "orr" ||
6722 Mnemonic == "mvn" || Mnemonic == "rsb" || Mnemonic == "rsc" ||
6723 Mnemonic == "orn" || Mnemonic == "sbc" || Mnemonic == "eor" ||
6724 Mnemonic == "neg" || Mnemonic == "vfm" || Mnemonic == "vfnm" ||
6725 (!isThumb() &&
6726 (Mnemonic == "smull" || Mnemonic == "mov" || Mnemonic == "mla" ||
6727 Mnemonic == "smlal" || Mnemonic == "umlal" || Mnemonic == "umull"));
6728
6729 if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
6730 Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
6731 Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic == "udf" ||
6732 Mnemonic.starts_with("crc32") || Mnemonic.starts_with("cps") ||
6733 Mnemonic.starts_with("vsel") || Mnemonic == "vmaxnm" ||
6734 Mnemonic == "vminnm" || Mnemonic == "vcvta" || Mnemonic == "vcvtn" ||
6735 Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || Mnemonic == "vrinta" ||
6736 Mnemonic == "vrintn" || Mnemonic == "vrintp" || Mnemonic == "vrintm" ||
6737 Mnemonic.starts_with("aes") || Mnemonic == "hvc" ||
6738 Mnemonic == "setpan" || Mnemonic.starts_with("sha1") ||
6739 Mnemonic.starts_with("sha256") ||
6740 (FullInst.starts_with("vmull") && FullInst.ends_with(".p64")) ||
6741 Mnemonic == "vmovx" || Mnemonic == "vins" || Mnemonic == "vudot" ||
6742 Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
6743 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || Mnemonic == "vfmat" ||
6744 Mnemonic == "vfmab" || Mnemonic == "vdot" || Mnemonic == "vmmla" ||
6745 Mnemonic == "sb" || Mnemonic == "ssbb" || Mnemonic == "pssbb" ||
6746 Mnemonic == "vsmmla" || Mnemonic == "vummla" || Mnemonic == "vusmmla" ||
6747 Mnemonic == "vusdot" || Mnemonic == "vsudot" || Mnemonic == "bfcsel" ||
6748 Mnemonic == "wls" || Mnemonic == "dls" || Mnemonic == "le" ||
6749 Mnemonic == "csel" || Mnemonic == "csinc" || Mnemonic == "csinv" ||
6750 Mnemonic == "csneg" || Mnemonic == "cinc" || Mnemonic == "cinv" ||
6751 Mnemonic == "cneg" || Mnemonic == "cset" || Mnemonic == "csetm" ||
6752 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6753 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6754 Mnemonic.starts_with("vpt") || Mnemonic.starts_with("vpst") ||
6755 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "aut" ||
6756 Mnemonic == "bti" ||
6757 (hasMVE() &&
6758 (Mnemonic.starts_with("vst2") || Mnemonic.starts_with("vld2") ||
6759 Mnemonic.starts_with("vst4") || Mnemonic.starts_with("vld4") ||
6760 Mnemonic.starts_with("wlstp") || Mnemonic.starts_with("dlstp") ||
6761 Mnemonic.starts_with("letp")))) {
6762 // These mnemonics are never predicable
6763 CanAcceptPredicationCode = false;
6764 } else if (!isThumb()) {
6765 // Some instructions are only predicable in Thumb mode
6766 CanAcceptPredicationCode =
6767 Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" &&
6768 Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" &&
6769 Mnemonic != "dmb" && Mnemonic != "dfb" && Mnemonic != "dsb" &&
6770 Mnemonic != "isb" && Mnemonic != "pld" && Mnemonic != "pli" &&
6771 Mnemonic != "pldw" && Mnemonic != "ldc2" && Mnemonic != "ldc2l" &&
6772 Mnemonic != "stc2" && Mnemonic != "stc2l" && Mnemonic != "tsb" &&
6773 !Mnemonic.starts_with("rfe") && !Mnemonic.starts_with("srs");
6774 } else if (isThumbOne()) {
6775 if (hasV6MOps())
6776 CanAcceptPredicationCode = Mnemonic != "movs";
6777 else
6778 CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs";
6779 } else
6780 CanAcceptPredicationCode = true;
6781}
6782
6783bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6784 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I) {
6785 auto &Op = static_cast<ARMOperand &>(*Operands[I]);
6786 if (Op.isToken() && Op.getToken() == ".w")
6787 return true;
6788 }
6789 return false;
6790}
6791
6792// Some Thumb instructions have two operand forms that are not
6793// available as three operand, convert to two operand form if possible.
6794//
6795// FIXME: We would really like to be able to tablegen'erate this.
6796void ARMAsmParser::tryConvertingToTwoOperandForm(
6797 StringRef Mnemonic, ARMCC::CondCodes PredicationCode, bool CarrySetting,
6798 OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6799
6800 if (operandsContainWide(Operands, MnemonicOpsEndInd))
6801 return;
6802 if (Operands.size() != MnemonicOpsEndInd + 3)
6803 return;
6804
6805 const auto &Op3 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
6806 auto &Op4 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
6807 if (!Op3.isReg() || !Op4.isReg())
6808 return;
6809
6810 auto Op3Reg = Op3.getReg();
6811 auto Op4Reg = Op4.getReg();
6812
6813 // For most Thumb2 cases we just generate the 3 operand form and reduce
6814 // it in processInstruction(), but the 3 operand form of ADD (t2ADDrr)
6815 // won't accept SP or PC so we do the transformation here taking care
6816 // with immediate range in the 'add sp, sp #imm' case.
6817 auto &Op5 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 2]);
6818 if (isThumbTwo()) {
6819 if (Mnemonic != "add")
6820 return;
6821 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6822 (Op5.isReg() && Op5.getReg() == ARM::PC);
6823 if (!TryTransform) {
6824 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6825 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6826 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6827 Op5.isImm() && !Op5.isImm0_508s4());
6828 }
6829 if (!TryTransform)
6830 return;
6831 } else if (!isThumbOne())
6832 return;
6833
6834 if (!(Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
6835 Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
6836 Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
6837 Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic"))
6838 return;
6839
6840 // If first 2 operands of a 3 operand instruction are the same
6841 // then transform to 2 operand version of the same instruction
6842 // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
6843 bool Transform = Op3Reg == Op4Reg;
6844
6845 // For communtative operations, we might be able to transform if we swap
6846 // Op4 and Op5. The 'ADD Rdm, SP, Rdm' form is already handled specially
6847 // as tADDrsp.
6848 const ARMOperand *LastOp = &Op5;
6849 bool Swap = false;
6850 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6851 ((Mnemonic == "add" && Op4Reg != ARM::SP) ||
6852 Mnemonic == "and" || Mnemonic == "eor" ||
6853 Mnemonic == "adc" || Mnemonic == "orr")) {
6854 Swap = true;
6855 LastOp = &Op4;
6856 Transform = true;
6857 }
6858
6859 // If both registers are the same then remove one of them from
6860 // the operand list, with certain exceptions.
6861 if (Transform) {
6862 // Don't transform 'adds Rd, Rd, Rm' or 'sub{s} Rd, Rd, Rm' because the
6863 // 2 operand forms don't exist.
6864 if (((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub") &&
6865 LastOp->isReg())
6866 Transform = false;
6867
6868 // Don't transform 'add/sub{s} Rd, Rd, #imm' if the immediate fits into
6869 // 3-bits because the ARMARM says not to.
6870 if ((Mnemonic == "add" || Mnemonic == "sub") && LastOp->isImm0_7())
6871 Transform = false;
6872 }
6873
6874 if (Transform) {
6875 if (Swap)
6876 std::swap(Op4, Op5);
6877 Operands.erase(Operands.begin() + MnemonicOpsEndInd);
6878 }
6879}
6880
6881static bool isARMMCExpr(MCParsedAsmOperand &MCOp);
6882// this function returns true if the operand is one of the following
6883// relocations: :upper8_15:, :upper0_7:, :lower8_15: or :lower0_7:
6885 assert(isARMMCExpr(MCOp));
6886 ARMOperand &Op = static_cast<ARMOperand &>(MCOp);
6887 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(Op.getImm());
6888 if (ARM16Expr && (ARM16Expr->getSpecifier() == ARM::S_HI_8_15 ||
6889 ARM16Expr->getSpecifier() == ARM::S_HI_0_7 ||
6890 ARM16Expr->getSpecifier() == ARM::S_LO_8_15 ||
6891 ARM16Expr->getSpecifier() == ARM::S_LO_0_7))
6892 return true;
6893 return false;
6894}
6895
6896bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6897 StringRef Mnemonic, OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6898 if (!hasMVE() || Operands.size() <= MnemonicOpsEndInd)
6899 return true;
6900
6901 if (Mnemonic.starts_with("vld2") || Mnemonic.starts_with("vld4") ||
6902 Mnemonic.starts_with("vst2") || Mnemonic.starts_with("vst4"))
6903 return true;
6904
6905 if (Mnemonic.starts_with("vctp") || Mnemonic.starts_with("vpnot"))
6906 return false;
6907
6908 if (Mnemonic.starts_with("vmov") &&
6909 !(Mnemonic.starts_with("vmovl") || Mnemonic.starts_with("vmovn") ||
6910 Mnemonic.starts_with("vmovx"))) {
6911 for (auto &Operand : Operands) {
6912 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() ||
6913 ((*Operand).isReg() && (getARMMCRegisterClass(ARM::SPRRegClassID)
6914 .contains((*Operand).getReg()) ||
6915 getARMMCRegisterClass(ARM::DPRRegClassID)
6916 .contains((*Operand).getReg())))) {
6917 return true;
6918 }
6919 }
6920 return false;
6921 } else {
6922 for (auto &Operand : Operands) {
6923 // We check the larger class QPR instead of just the legal class
6924 // MQPR, to more accurately report errors when using Q registers
6925 // outside of the allowed range.
6926 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() ||
6927 static_cast<ARMOperand &>(*Operand).isQReg())
6928 return false;
6929 }
6930 return true;
6931 }
6932}
6933
6934// FIXME: This bit should probably be handled via an explicit match class
6935// in the .td files that matches the suffix instead of having it be
6936// a literal string token the way it is now.
6938 return Mnemonic.starts_with("vldm") || Mnemonic.starts_with("vstm");
6939}
6940
6941static void applyMnemonicAliases(StringRef &Mnemonic,
6942 const FeatureBitset &Features,
6943 unsigned VariantID);
6944
6945// The GNU assembler has aliases of ldrd, strd, ldrexd, strexd, ldaexd, and
6946// stlexd with the second register omitted. We don't have a way to do that in
6947// tablegen, so fix it up here.
6948//
6949// We have to be careful to not emit an invalid Rt2 here, because the rest of
6950// the assembly parser could then generate confusing diagnostics referring to
6951// it. If we do find anything that prevents us from doing the transformation we
6952// bail out, and let the assembly parser report an error on the instruction as
6953// it is written.
6954void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic,
6956 unsigned MnemonicOpsEndInd) {
6957 if (Mnemonic != "ldrd" && Mnemonic != "strd" && Mnemonic != "ldrexd" &&
6958 Mnemonic != "strexd" && Mnemonic != "ldaexd" && Mnemonic != "stlexd")
6959 return;
6960
6961 unsigned IdX = Mnemonic == "strexd" || Mnemonic == "stlexd"
6962 ? MnemonicOpsEndInd + 1
6963 : MnemonicOpsEndInd;
6964
6965 if (Operands.size() < IdX + 2)
6966 return;
6967
6968 ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[IdX]);
6969 ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[IdX + 1]);
6970
6971 if (!Op2.isReg())
6972 return;
6973 if (!Op3.isGPRMem())
6974 return;
6975
6976 const MCRegisterClass &GPR = MRI->getRegClass(ARM::GPRRegClassID);
6977 if (!GPR.contains(Op2.getReg()))
6978 return;
6979
6980 unsigned RtEncoding = MRI->getEncodingValue(Op2.getReg());
6981 if (!isThumb() && (RtEncoding & 1)) {
6982 // In ARM mode, the registers must be from an aligned pair, this
6983 // restriction does not apply in Thumb mode.
6984 return;
6985 }
6986 if (Op2.getReg() == ARM::PC)
6987 return;
6988 MCRegister PairedReg = GPR.getRegister(RtEncoding + 1);
6989 if (!PairedReg || PairedReg == ARM::PC ||
6990 (PairedReg == ARM::SP && !hasV8Ops()))
6991 return;
6992
6993 Operands.insert(Operands.begin() + IdX + 1,
6994 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(),
6995 Op2.getEndLoc(), *this));
6996}
6997
6998// Dual-register instruction have the following syntax:
6999// <mnemonic> <predicate>? <coproc>, <Rdest>, <Rdest+1>, <Rsrc>, ..., #imm
7000// This function tries to remove <Rdest+1> and replace <Rdest> with a pair
7001// operand. If the conversion fails an error is diagnosed, and the function
7002// returns true.
7003bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic,
7005 unsigned MnemonicOpsEndInd) {
7006 assert(MS.isCDEDualRegInstr(Mnemonic));
7007
7008 if (Operands.size() < 3 + MnemonicOpsEndInd)
7009 return false;
7010
7011 StringRef Op2Diag(
7012 "operand must be an even-numbered register in the range [r0, r10]");
7013
7014 const MCParsedAsmOperand &Op2 = *Operands[MnemonicOpsEndInd + 1];
7015 if (!Op2.isReg())
7016 return Error(Op2.getStartLoc(), Op2Diag);
7017
7018 MCRegister RNext;
7019 MCRegister RPair;
7020 switch (Op2.getReg().id()) {
7021 default:
7022 return Error(Op2.getStartLoc(), Op2Diag);
7023 case ARM::R0:
7024 RNext = ARM::R1;
7025 RPair = ARM::R0_R1;
7026 break;
7027 case ARM::R2:
7028 RNext = ARM::R3;
7029 RPair = ARM::R2_R3;
7030 break;
7031 case ARM::R4:
7032 RNext = ARM::R5;
7033 RPair = ARM::R4_R5;
7034 break;
7035 case ARM::R6:
7036 RNext = ARM::R7;
7037 RPair = ARM::R6_R7;
7038 break;
7039 case ARM::R8:
7040 RNext = ARM::R9;
7041 RPair = ARM::R8_R9;
7042 break;
7043 case ARM::R10:
7044 RNext = ARM::R11;
7045 RPair = ARM::R10_R11;
7046 break;
7047 }
7048
7049 const MCParsedAsmOperand &Op3 = *Operands[MnemonicOpsEndInd + 2];
7050 if (!Op3.isReg() || Op3.getReg() != RNext)
7051 return Error(Op3.getStartLoc(), "operand must be a consecutive register");
7052
7053 Operands.erase(Operands.begin() + MnemonicOpsEndInd + 2);
7054 Operands[MnemonicOpsEndInd + 1] =
7055 ARMOperand::CreateReg(RPair, Op2.getStartLoc(), Op2.getEndLoc(), *this);
7056 return false;
7057}
7058
7059void removeCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7060 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7061 if (static_cast<ARMOperand &>(*Operands[I]).isCondCode()) {
7062 Operands.erase(Operands.begin() + I);
7063 --MnemonicOpsEndInd;
7064 break;
7065 }
7066}
7067
7068void removeCCOut(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7069 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7070 if (static_cast<ARMOperand &>(*Operands[I]).isCCOut()) {
7071 Operands.erase(Operands.begin() + I);
7072 --MnemonicOpsEndInd;
7073 break;
7074 }
7075}
7076
7077void removeVPTCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7078 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7079 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred()) {
7080 Operands.erase(Operands.begin() + I);
7081 --MnemonicOpsEndInd;
7082 break;
7083 }
7084}
7085
7086/// Parse an arm instruction mnemonic followed by its operands.
7087bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7088 SMLoc NameLoc, OperandVector &Operands) {
7089 MCAsmParser &Parser = getParser();
7090
7091 // Apply mnemonic aliases before doing anything else, as the destination
7092 // mnemonic may include suffices and we want to handle them normally.
7093 // The generic tblgen'erated code does this later, at the start of
7094 // MatchInstructionImpl(), but that's too late for aliases that include
7095 // any sort of suffix.
7096 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
7097 unsigned AssemblerDialect = getParser().getAssemblerDialect();
7098 applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect);
7099
7100 // First check for the ARM-specific .req directive.
7101 if (Parser.getTok().is(AsmToken::Identifier) &&
7102 Parser.getTok().getIdentifier().lower() == ".req") {
7103 parseDirectiveReq(Name, NameLoc);
7104 // We always return 'error' for this, as we're done with this
7105 // statement and don't need to match the 'instruction."
7106 return true;
7107 }
7108
7109 // Create the leading tokens for the mnemonic, split by '.' characters.
7110 size_t Start = 0, Next = Name.find('.');
7111 StringRef Mnemonic = Name.slice(Start, Next);
7112 StringRef ExtraToken = Name.slice(Next, Name.find(' ', Next + 1));
7113
7114 // Split out the predication code and carry setting flag from the mnemonic.
7115 ARMCC::CondCodes PredicationCode;
7116 ARMVCC::VPTCodes VPTPredicationCode;
7117 unsigned ProcessorIMod;
7118 bool CarrySetting;
7119 StringRef ITMask;
7120 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode,
7121 CarrySetting, ProcessorIMod, ITMask);
7122
7123 // In Thumb1, only the branch (B) instruction can be predicated.
7124 if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
7125 return Error(NameLoc, "conditional execution not supported in Thumb1");
7126 }
7127
7128 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc, *this));
7129
7130 // Handle the mask for IT and VPT instructions. In ARMOperand and
7131 // MCOperand, this is stored in a format independent of the
7132 // condition code: the lowest set bit indicates the end of the
7133 // encoding, and above that, a 1 bit indicates 'else', and an 0
7134 // indicates 'then'. E.g.
7135 // IT -> 1000
7136 // ITx -> x100 (ITT -> 0100, ITE -> 1100)
7137 // ITxy -> xy10 (e.g. ITET -> 1010)
7138 // ITxyz -> xyz1 (e.g. ITEET -> 1101)
7139 // Note: See the ARM::PredBlockMask enum in
7140 // /lib/Target/ARM/Utils/ARMBaseInfo.h
7141 if (Mnemonic == "it" || Mnemonic.starts_with("vpt") ||
7142 Mnemonic.starts_with("vpst")) {
7143 SMLoc Loc = Mnemonic == "it" ? SMLoc::getFromPointer(NameLoc.getPointer() + 2) :
7144 Mnemonic == "vpt" ? SMLoc::getFromPointer(NameLoc.getPointer() + 3) :
7145 SMLoc::getFromPointer(NameLoc.getPointer() + 4);
7146 if (ITMask.size() > 3) {
7147 if (Mnemonic == "it")
7148 return Error(Loc, "too many conditions on IT instruction");
7149 return Error(Loc, "too many conditions on VPT instruction");
7150 }
7151 unsigned Mask = 8;
7152 for (char Pos : llvm::reverse(ITMask)) {
7153 if (Pos != 't' && Pos != 'e') {
7154 return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
7155 }
7156 Mask >>= 1;
7157 if (Pos == 'e')
7158 Mask |= 8;
7159 }
7160 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc, *this));
7161 }
7162
7163 // FIXME: This is all a pretty gross hack. We should automatically handle
7164 // optional operands like this via tblgen.
7165
7166 // Next, add the CCOut and ConditionCode operands, if needed.
7167 //
7168 // For mnemonics which can ever incorporate a carry setting bit or predication
7169 // code, our matching model involves us always generating CCOut and
7170 // ConditionCode operands to match the mnemonic "as written" and then we let
7171 // the matcher deal with finding the right instruction or generating an
7172 // appropriate error.
7173 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode;
7174 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet,
7175 CanAcceptPredicationCode, CanAcceptVPTPredicationCode);
7176
7177 // If we had a carry-set on an instruction that can't do that, issue an
7178 // error.
7179 if (!CanAcceptCarrySet && CarrySetting) {
7180 return Error(NameLoc, "instruction '" + Mnemonic +
7181 "' can not set flags, but 's' suffix specified");
7182 }
7183 // If we had a predication code on an instruction that can't do that, issue an
7184 // error.
7185 if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
7186 return Error(NameLoc, "instruction '" + Mnemonic +
7187 "' is not predicable, but condition code specified");
7188 }
7189
7190 // If we had a VPT predication code on an instruction that can't do that, issue an
7191 // error.
7192 if (!CanAcceptVPTPredicationCode && VPTPredicationCode != ARMVCC::None) {
7193 return Error(NameLoc, "instruction '" + Mnemonic +
7194 "' is not VPT predicable, but VPT code T/E is specified");
7195 }
7196
7197 // Add the carry setting operand, if necessary.
7198 if (CanAcceptCarrySet && CarrySetting) {
7199 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
7200 Operands.push_back(ARMOperand::CreateCCOut(
7201 CarrySetting ? ARM::CPSR : ARM::NoRegister, Loc, *this));
7202 }
7203
7204 // Add the predication code operand, if necessary.
7205 if (CanAcceptPredicationCode && PredicationCode != llvm::ARMCC::AL) {
7206 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
7207 CarrySetting);
7208 Operands.push_back(ARMOperand::CreateCondCode(
7209 ARMCC::CondCodes(PredicationCode), Loc, *this));
7210 }
7211
7212 // Add the VPT predication code operand, if necessary.
7213 // Dont add in certain cases of VCVT as this needs to be disambiguated
7214 // after operand parsing.
7215 if (CanAcceptVPTPredicationCode && VPTPredicationCode != llvm::ARMVCC::None &&
7216 !(Mnemonic.starts_with("vcvt") && Mnemonic != "vcvta" &&
7217 Mnemonic != "vcvtn" && Mnemonic != "vcvtp" && Mnemonic != "vcvtm")) {
7218 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
7219 CarrySetting);
7220 Operands.push_back(ARMOperand::CreateVPTPred(
7221 ARMVCC::VPTCodes(VPTPredicationCode), Loc, *this));
7222 }
7223
7224 // Add the processor imod operand, if necessary.
7225 if (ProcessorIMod) {
7226 Operands.push_back(ARMOperand::CreateImm(
7227 MCConstantExpr::create(ProcessorIMod, getContext()), NameLoc, NameLoc,
7228 *this));
7229 } else if (Mnemonic == "cps" && isMClass()) {
7230 return Error(NameLoc, "instruction 'cps' requires effect for M-class");
7231 }
7232
7233 // Add the remaining tokens in the mnemonic.
7234 while (Next != StringRef::npos) {
7235 Start = Next;
7236 Next = Name.find('.', Start + 1);
7237 ExtraToken = Name.slice(Start, Next);
7238
7239 // Some NEON instructions have an optional datatype suffix that is
7240 // completely ignored. Check for that.
7241 if (isDataTypeToken(ExtraToken) &&
7242 doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
7243 continue;
7244
7245 // For for ARM mode generate an error if the .n qualifier is used.
7246 if (ExtraToken == ".n" && !isThumb()) {
7247 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
7248 return Error(Loc, "instruction with .n (narrow) qualifier not allowed in "
7249 "arm mode");
7250 }
7251
7252 // The .n qualifier is always discarded as that is what the tables
7253 // and matcher expect. In ARM mode the .w qualifier has no effect,
7254 // so discard it to avoid errors that can be caused by the matcher.
7255 if (ExtraToken != ".n" && (isThumb() || ExtraToken != ".w")) {
7256 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
7257 Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc, *this));
7258 }
7259 }
7260
7261 // This marks the end of the LHS Mnemonic operators.
7262 // This is used for indexing into the non-mnemonic operators as some of the
7263 // mnemonic operators are optional and therefore indexes can differ.
7264 unsigned MnemonicOpsEndInd = Operands.size();
7265
7266 // Read the remaining operands.
7267 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7268 // Read the first operand.
7269 if (parseOperand(Operands, Mnemonic)) {
7270 return true;
7271 }
7272
7273 while (parseOptionalToken(AsmToken::Comma)) {
7274 // Parse and remember the operand.
7275 if (parseOperand(Operands, Mnemonic)) {
7276 return true;
7277 }
7278 }
7279 }
7280
7281 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
7282 return true;
7283
7284 tryConvertingToTwoOperandForm(Mnemonic, PredicationCode, CarrySetting,
7285 Operands, MnemonicOpsEndInd);
7286
7287 if (hasCDE() && MS.isCDEInstr(Mnemonic)) {
7288 // Dual-register instructions use even-odd register pairs as their
7289 // destination operand, in assembly such pair is spelled as two
7290 // consecutive registers, without any special syntax. ConvertDualRegOperand
7291 // tries to convert such operand into register pair, e.g. r2, r3 -> r2_r3.
7292 // It returns true, if an error message has been emitted. If the function
7293 // returns false, the function either succeeded or an error (e.g. missing
7294 // operand) will be diagnosed elsewhere.
7295 if (MS.isCDEDualRegInstr(Mnemonic)) {
7296 bool GotError =
7297 CDEConvertDualRegOperand(Mnemonic, Operands, MnemonicOpsEndInd);
7298 if (GotError)
7299 return GotError;
7300 }
7301 }
7302
7303 if (hasMVE()) {
7304 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7305 MnemonicOpsEndInd) &&
7306 Mnemonic == "vmov" && PredicationCode == ARMCC::LT) {
7307 // Very nasty hack to deal with the vector predicated variant of vmovlt
7308 // the scalar predicated vmov with condition 'lt'. We can not tell them
7309 // apart until we have parsed their operands.
7310 Operands.erase(Operands.begin() + 1);
7311 Operands.erase(Operands.begin());
7312 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7313 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7314 Mnemonic.size() - 1 + CarrySetting);
7315 Operands.insert(Operands.begin(),
7316 ARMOperand::CreateVPTPred(ARMVCC::None, PLoc, *this));
7317 Operands.insert(Operands.begin(), ARMOperand::CreateToken(
7318 StringRef("vmovlt"), MLoc, *this));
7319 } else if (Mnemonic == "vcvt" && PredicationCode == ARMCC::NE &&
7320 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7321 MnemonicOpsEndInd)) {
7322 // Another nasty hack to deal with the ambiguity between vcvt with scalar
7323 // predication 'ne' and vcvtn with vector predication 'e'. As above we
7324 // can only distinguish between the two after we have parsed their
7325 // operands.
7326 Operands.erase(Operands.begin() + 1);
7327 Operands.erase(Operands.begin());
7328 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7329 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7330 Mnemonic.size() - 1 + CarrySetting);
7331 Operands.insert(Operands.begin(),
7332 ARMOperand::CreateVPTPred(ARMVCC::Else, PLoc, *this));
7333 Operands.insert(Operands.begin(),
7334 ARMOperand::CreateToken(StringRef("vcvtn"), MLoc, *this));
7335 } else if (Mnemonic == "vmul" && PredicationCode == ARMCC::LT &&
7336 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7337 MnemonicOpsEndInd)) {
7338 // Another hack, this time to distinguish between scalar predicated vmul
7339 // with 'lt' predication code and the vector instruction vmullt with
7340 // vector predication code "none"
7341 removeCondCode(Operands, MnemonicOpsEndInd);
7342 Operands.erase(Operands.begin());
7343 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7344 Operands.insert(Operands.begin(), ARMOperand::CreateToken(
7345 StringRef("vmullt"), MLoc, *this));
7346 } else if (Mnemonic.starts_with("vcvt") && !Mnemonic.starts_with("vcvta") &&
7347 !Mnemonic.starts_with("vcvtn") &&
7348 !Mnemonic.starts_with("vcvtp") &&
7349 !Mnemonic.starts_with("vcvtm")) {
7350 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7351 MnemonicOpsEndInd)) {
7352 // We could not split the vector predicate off vcvt because it might
7353 // have been the scalar vcvtt instruction. Now we know its a vector
7354 // instruction, we still need to check whether its the vector
7355 // predicated vcvt with 'Then' predication or the vector vcvtt. We can
7356 // distinguish the two based on the suffixes, if it is any of
7357 // ".f16.f32", ".f32.f16", ".f16.f64" or ".f64.f16" then it is the vcvtt.
7358 if (Mnemonic.starts_with("vcvtt") && MnemonicOpsEndInd > 2) {
7359 auto Sz1 =
7360 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd - 2]);
7361 auto Sz2 =
7362 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd - 1]);
7363 if (!(Sz1.isToken() && Sz1.getToken().starts_with(".f") &&
7364 Sz2.isToken() && Sz2.getToken().starts_with(".f"))) {
7365 Operands.erase(Operands.begin());
7366 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7367 VPTPredicationCode = ARMVCC::Then;
7368
7369 Mnemonic = Mnemonic.substr(0, 4);
7370 Operands.insert(Operands.begin(),
7371 ARMOperand::CreateToken(Mnemonic, MLoc, *this));
7372 }
7373 }
7374 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7375 Mnemonic.size() + CarrySetting);
7376 // Add VPTPred
7377 Operands.insert(Operands.begin() + 1,
7378 ARMOperand::CreateVPTPred(
7379 ARMVCC::VPTCodes(VPTPredicationCode), PLoc, *this));
7380 ++MnemonicOpsEndInd;
7381 }
7382 } else if (CanAcceptVPTPredicationCode) {
7383 // For all other instructions, make sure only one of the two
7384 // predication operands is left behind, depending on whether we should
7385 // use the vector predication.
7386 if (shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7387 MnemonicOpsEndInd)) {
7388 removeVPTCondCode(Operands, MnemonicOpsEndInd);
7389 }
7390 }
7391 }
7392
7393 if (VPTPredicationCode != ARMVCC::None) {
7394 bool usedVPTPredicationCode = false;
7395 for (unsigned I = 1; I < Operands.size(); ++I)
7396 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred())
7397 usedVPTPredicationCode = true;
7398 if (!usedVPTPredicationCode) {
7399 // If we have a VPT predication code and we haven't just turned it
7400 // into an operand, then it was a mistake for splitMnemonic to
7401 // separate it from the rest of the mnemonic in the first place,
7402 // and this may lead to wrong disassembly (e.g. scalar floating
7403 // point VCMPE is actually a different instruction from VCMP, so
7404 // we mustn't treat them the same). In that situation, glue it
7405 // back on.
7406 Mnemonic = Name.slice(0, Mnemonic.size() + 1);
7407 Operands.erase(Operands.begin());
7408 Operands.insert(Operands.begin(),
7409 ARMOperand::CreateToken(Mnemonic, NameLoc, *this));
7410 }
7411 }
7412
7413 // ARM mode 'blx' need special handling, as the register operand version
7414 // is predicable, but the label operand version is not. So, we can't rely
7415 // on the Mnemonic based checking to correctly figure out when to put
7416 // a k_CondCode operand in the list. If we're trying to match the label
7417 // version, remove the k_CondCode operand here.
7418 if (!isThumb() && Mnemonic == "blx" &&
7419 Operands.size() == MnemonicOpsEndInd + 1 &&
7420 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).isImm())
7421 removeCondCode(Operands, MnemonicOpsEndInd);
7422
7423 // GNU Assembler extension (compatibility).
7424 fixupGNULDRDAlias(Mnemonic, Operands, MnemonicOpsEndInd);
7425
7426 // Adjust operands of ldrexd/strexd to MCK_GPRPair.
7427 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
7428 // a single GPRPair reg operand is used in the .td file to replace the two
7429 // GPRs. However, when parsing from asm, the two GRPs cannot be
7430 // automatically
7431 // expressed as a GPRPair, so we have to manually merge them.
7432 // FIXME: We would really like to be able to tablegen'erate this.
7433 bool IsLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd");
7434 if (!isThumb() && Operands.size() > MnemonicOpsEndInd + 1 + (!IsLoad) &&
7435 (Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" ||
7436 Mnemonic == "stlexd")) {
7437 unsigned Idx = IsLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
7438 ARMOperand &Op1 = static_cast<ARMOperand &>(*Operands[Idx]);
7439 ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[Idx + 1]);
7440
7441 const MCRegisterClass &MRC = MRI->getRegClass(ARM::GPRRegClassID);
7442 // Adjust only if Op1 is a GPR.
7443 if (Op1.isReg() && MRC.contains(Op1.getReg())) {
7444 MCRegister Reg1 = Op1.getReg();
7445 unsigned Rt = MRI->getEncodingValue(Reg1);
7446 MCRegister Reg2 = Op2.getReg();
7447 unsigned Rt2 = MRI->getEncodingValue(Reg2);
7448 // Rt2 must be Rt + 1.
7449 if (Rt + 1 != Rt2)
7450 return Error(Op2.getStartLoc(),
7451 IsLoad ? "destination operands must be sequential"
7452 : "source operands must be sequential");
7453
7454 // Rt must be even
7455 if (Rt & 1)
7456 return Error(
7457 Op1.getStartLoc(),
7458 IsLoad ? "destination operands must start start at an even register"
7459 : "source operands must start start at an even register");
7460
7461 MCRegister NewReg = MRI->getMatchingSuperReg(
7462 Reg1, ARM::gsub_0, &(MRI->getRegClass(ARM::GPRPairRegClassID)));
7463 Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7464 Op2.getEndLoc(), *this);
7465 Operands.erase(Operands.begin() + Idx + 1);
7466 }
7467 }
7468
7469 // FIXME: As said above, this is all a pretty gross hack. This instruction
7470 // does not fit with other "subs" and tblgen.
7471 // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
7472 // so the Mnemonic is "subs" and delete the CCOut operand so it will match
7473 // the table entry.
7474 if (isThumbTwo() && Mnemonic == "sub" && CarrySetting &&
7475 Operands.size() == MnemonicOpsEndInd + 3 &&
7476 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).isReg() &&
7477 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).getReg() ==
7478 ARM::PC &&
7479 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]).isReg() &&
7480 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]).getReg() ==
7481 ARM::LR &&
7482 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 2]).isImm()) {
7483 Operands.front() = ARMOperand::CreateToken("subs", NameLoc, *this);
7484 removeCCOut(Operands, MnemonicOpsEndInd);
7485 }
7486 return false;
7487}
7488
7489// Validate context-sensitive operand constraints.
7490
7491// return 'true' if register list contains non-low GPR registers,
7492// 'false' otherwise. If Reg is in the register list or is HiReg, set
7493// 'containsReg' to true.
7494static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo,
7495 MCRegister Reg, MCRegister HiReg,
7496 bool &containsReg) {
7497 containsReg = false;
7498 for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
7499 MCRegister OpReg = Inst.getOperand(i).getReg();
7500 if (OpReg == Reg)
7501 containsReg = true;
7502 // Anything other than a low register isn't legal here.
7503 if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
7504 return true;
7505 }
7506 return false;
7507}
7508
7509// Check if the specified regisgter is in the register list of the inst,
7510// starting at the indicated operand number.
7511static bool listContainsReg(const MCInst &Inst, unsigned OpNo, MCRegister Reg) {
7512 for (unsigned i = OpNo, e = Inst.getNumOperands(); i < e; ++i) {
7513 MCRegister OpReg = Inst.getOperand(i).getReg();
7514 if (OpReg == Reg)
7515 return true;
7516 }
7517 return false;
7518}
7519
7520// Return true if instruction has the interesting property of being
7521// allowed in IT blocks, but not being predicable.
7522static bool instIsBreakpoint(const MCInst &Inst) {
7523 return Inst.getOpcode() == ARM::tBKPT ||
7524 Inst.getOpcode() == ARM::BKPT ||
7525 Inst.getOpcode() == ARM::tHLT ||
7526 Inst.getOpcode() == ARM::HLT;
7527}
7528
7530 unsigned MnemonicOpsEndInd) {
7531 for (unsigned I = MnemonicOpsEndInd; I < Operands.size(); ++I) {
7532 const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[I]);
7533 if (Op.isRegList()) {
7534 return I;
7535 }
7536 }
7537 return 0;
7538}
7539
7540bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst,
7541 const OperandVector &Operands,
7542 unsigned MnemonicOpsEndInd,
7543 unsigned ListIndex, bool IsARPop) {
7544 bool ListContainsSP = listContainsReg(Inst, ListIndex, ARM::SP);
7545 bool ListContainsLR = listContainsReg(Inst, ListIndex, ARM::LR);
7546 bool ListContainsPC = listContainsReg(Inst, ListIndex, ARM::PC);
7547
7548 if (!IsARPop && ListContainsSP)
7549 return Error(
7550 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7551 "SP may not be in the register list");
7552 if (ListContainsPC && ListContainsLR)
7553 return Error(
7554 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7555 "PC and LR may not be in the register list simultaneously");
7556 return false;
7557}
7558
7559bool ARMAsmParser::validatetSTMRegList(const MCInst &Inst,
7560 const OperandVector &Operands,
7561 unsigned MnemonicOpsEndInd,
7562 unsigned ListIndex) {
7563 bool ListContainsSP = listContainsReg(Inst, ListIndex, ARM::SP);
7564 bool ListContainsPC = listContainsReg(Inst, ListIndex, ARM::PC);
7565
7566 if (ListContainsSP && ListContainsPC)
7567 return Error(
7568 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7569 "SP and PC may not be in the register list");
7570 if (ListContainsSP)
7571 return Error(
7572 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7573 "SP may not be in the register list");
7574 if (ListContainsPC)
7575 return Error(
7576 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7577 "PC may not be in the register list");
7578 return false;
7579}
7580
7581bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
7582 bool Load, bool ARMMode, bool Writeback,
7583 unsigned MnemonicOpsEndInd) {
7584 unsigned RtIndex = Load || !Writeback ? 0 : 1;
7585 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(RtIndex).getReg());
7586 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(RtIndex + 1).getReg());
7587
7588 if (ARMMode) {
7589 // Rt can't be R14.
7590 if (Rt == 14)
7591 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7592 "Rt can't be R14");
7593
7594 // Rt must be even-numbered.
7595 if ((Rt & 1) == 1)
7596 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7597 "Rt must be even-numbered");
7598
7599 // Rt2 must be Rt + 1.
7600 if (Rt2 != Rt + 1) {
7601 if (Load)
7602 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7603 "destination operands must be sequential");
7604 else
7605 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7606 "source operands must be sequential");
7607 }
7608
7609 // FIXME: Diagnose m == 15
7610 // FIXME: Diagnose ldrd with m == t || m == t2.
7611 }
7612
7613 if (!ARMMode && Load) {
7614 if (Rt2 == Rt)
7615 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7616 "destination operands can't be identical");
7617 }
7618
7619 if (Writeback) {
7620 unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg());
7621
7622 if (Rn == Rt || Rn == Rt2) {
7623 if (Load)
7624 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7625 "base register needs to be different from destination "
7626 "registers");
7627 else
7628 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7629 "source register and base register can't be identical");
7630 }
7631
7632 // FIXME: Diagnose ldrd/strd with writeback and n == 15.
7633 // (Except the immediate form of ldrd?)
7634 }
7635
7636 return false;
7637}
7638
7640 for (unsigned i = 0; i < MCID.NumOperands; ++i) {
7641 if (ARM::isVpred(MCID.operands()[i].OperandType))
7642 return i;
7643 }
7644 return -1;
7645}
7646
7648 return findFirstVectorPredOperandIdx(MCID) != -1;
7649}
7650
7652 ARMOperand &Op = static_cast<ARMOperand &>(MCOp);
7653 if (!Op.isImm())
7654 return false;
7655 return !isa<MCConstantExpr>(Op.getImm());
7656}
7657
7658// FIXME: We would really like to be able to tablegen'erate this.
7659bool ARMAsmParser::validateInstruction(MCInst &Inst,
7660 const OperandVector &Operands,
7661 unsigned MnemonicOpsEndInd) {
7662 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
7663 SMLoc Loc = Operands[0]->getStartLoc();
7664
7665 // Check the IT block state first.
7666 // NOTE: BKPT and HLT instructions have the interesting property of being
7667 // allowed in IT blocks, but not being predicable. They just always execute.
7668 if (inITBlock() && !instIsBreakpoint(Inst)) {
7669 // The instruction must be predicable.
7670 if (!MCID.isPredicable())
7671 return Error(Loc, "instructions in IT block must be predicable");
7674 if (Cond != currentITCond()) {
7675 // Find the condition code Operand to get its SMLoc information.
7676 SMLoc CondLoc = Operands[0]->getEndLoc();
7677 for (unsigned I = 1; I < Operands.size(); ++I)
7678 if (static_cast<ARMOperand &>(*Operands[I]).isCondCode())
7679 CondLoc = Operands[I]->getStartLoc();
7680 return Error(CondLoc, "incorrect condition in IT block; got '" +
7681 StringRef(ARMCondCodeToString(Cond)) +
7682 "', but expected '" +
7683 ARMCondCodeToString(currentITCond()) + "'");
7684 }
7685 // Check for non-'al' condition codes outside of the IT block.
7686 } else if (isThumbTwo() && MCID.isPredicable() &&
7687 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
7688 ARMCC::AL && Inst.getOpcode() != ARM::tBcc &&
7689 Inst.getOpcode() != ARM::t2Bcc &&
7690 Inst.getOpcode() != ARM::t2BFic) {
7691 return Error(Loc, "predicated instructions must be in IT block");
7692 } else if (!isThumb() && !useImplicitITARM() && MCID.isPredicable() &&
7693 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
7694 ARMCC::AL) {
7695 return Warning(Loc, "predicated instructions should be in IT block");
7696 } else if (!MCID.isPredicable()) {
7697 // Check the instruction doesn't have a predicate operand anyway
7698 // that it's not allowed to use. Sometimes this happens in order
7699 // to keep instructions the same shape even though one cannot
7700 // legally be predicated, e.g. vmul.f16 vs vmul.f32.
7701 for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i) {
7702 if (MCID.operands()[i].isPredicate()) {
7703 if (Inst.getOperand(i).getImm() != ARMCC::AL)
7704 return Error(Loc, "instruction is not predicable");
7705 break;
7706 }
7707 }
7708 }
7709
7710 // PC-setting instructions in an IT block, but not the last instruction of
7711 // the block, are UNPREDICTABLE.
7712 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
7713 return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block");
7714 }
7715
7716 if (inVPTBlock() && !instIsBreakpoint(Inst)) {
7717 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
7718 if (!isVectorPredicable(MCID))
7719 return Error(Loc, "instruction in VPT block must be predicable");
7720 unsigned Pred = Inst.getOperand(findFirstVectorPredOperandIdx(MCID)).getImm();
7721 unsigned VPTPred = Bit ? ARMVCC::Else : ARMVCC::Then;
7722 if (Pred != VPTPred) {
7723 SMLoc PredLoc;
7724 for (unsigned I = 1; I < Operands.size(); ++I)
7725 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred())
7726 PredLoc = Operands[I]->getStartLoc();
7727 return Error(PredLoc, "incorrect predication in VPT block; got '" +
7728 StringRef(ARMVPTPredToString(ARMVCC::VPTCodes(Pred))) +
7729 "', but expected '" +
7730 ARMVPTPredToString(ARMVCC::VPTCodes(VPTPred)) + "'");
7731 }
7732 }
7733 else if (isVectorPredicable(MCID) &&
7736 return Error(Loc, "VPT predicated instructions must be in VPT block");
7737
7738 const unsigned Opcode = Inst.getOpcode();
7739 switch (Opcode) {
7740 case ARM::VLLDM:
7741 case ARM::VLLDM_T2:
7742 case ARM::VLSTM:
7743 case ARM::VLSTM_T2: {
7744 // Since in some cases both T1 and T2 are valid, tablegen can not always
7745 // pick the correct instruction.
7746 if (Operands.size() ==
7747 MnemonicOpsEndInd + 2) { // a register list has been provided
7748 ARMOperand &Op = static_cast<ARMOperand &>(
7749 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
7750 assert(Op.isDPRRegList());
7751 auto &RegList = Op.getRegList();
7752 // T2 requires v8.1-M.Main (cannot be handled by tablegen)
7753 if (RegList.size() == 32 && !hasV8_1MMainline()) {
7754 return Error(Op.getEndLoc(), "T2 version requires v8.1-M.Main");
7755 }
7756 // When target has 32 D registers, T1 is undefined.
7757 if (hasD32() && RegList.size() != 32) {
7758 return Error(Op.getEndLoc(), "operand must be exactly {d0-d31}");
7759 }
7760 // When target has 16 D registers, both T1 and T2 are valid.
7761 if (!hasD32() && (RegList.size() != 16 && RegList.size() != 32)) {
7762 return Error(Op.getEndLoc(),
7763 "operand must be exactly {d0-d15} (T1) or {d0-d31} (T2)");
7764 }
7765 }
7766 return false;
7767 }
7768 case ARM::t2IT: {
7769 // Encoding is unpredictable if it ever results in a notional 'NV'
7770 // predicate. Since we don't parse 'NV' directly this means an 'AL'
7771 // predicate with an "else" mask bit.
7772 unsigned Cond = Inst.getOperand(0).getImm();
7773 unsigned Mask = Inst.getOperand(1).getImm();
7774
7775 // Conditions only allowing a 't' are those with no set bit except
7776 // the lowest-order one that indicates the end of the sequence. In
7777 // other words, powers of 2.
7778 if (Cond == ARMCC::AL && llvm::popcount(Mask) != 1)
7779 return Error(Loc, "unpredictable IT predicate sequence");
7780 break;
7781 }
7782 case ARM::LDRD:
7783 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ true,
7784 /*Writeback*/ false, MnemonicOpsEndInd))
7785 return true;
7786 break;
7787 case ARM::LDRD_PRE:
7788 case ARM::LDRD_POST:
7789 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ true,
7790 /*Writeback*/ true, MnemonicOpsEndInd))
7791 return true;
7792 break;
7793 case ARM::t2LDRDi8:
7794 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ false,
7795 /*Writeback*/ false, MnemonicOpsEndInd))
7796 return true;
7797 break;
7798 case ARM::t2LDRD_PRE:
7799 case ARM::t2LDRD_POST:
7800 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ false,
7801 /*Writeback*/ true, MnemonicOpsEndInd))
7802 return true;
7803 break;
7804 case ARM::t2BXJ: {
7805 const MCRegister RmReg = Inst.getOperand(0).getReg();
7806 // Rm = SP is no longer unpredictable in v8-A
7807 if (RmReg == ARM::SP && !hasV8Ops())
7808 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7809 "r13 (SP) is an unpredictable operand to BXJ");
7810 return false;
7811 }
7812 case ARM::STRD:
7813 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ true,
7814 /*Writeback*/ false, MnemonicOpsEndInd))
7815 return true;
7816 break;
7817 case ARM::STRD_PRE:
7818 case ARM::STRD_POST:
7819 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ true,
7820 /*Writeback*/ true, MnemonicOpsEndInd))
7821 return true;
7822 break;
7823 case ARM::t2STRD_PRE:
7824 case ARM::t2STRD_POST:
7825 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ false,
7826 /*Writeback*/ true, MnemonicOpsEndInd))
7827 return true;
7828 break;
7829 case ARM::STR_PRE_IMM:
7830 case ARM::STR_PRE_REG:
7831 case ARM::t2STR_PRE:
7832 case ARM::STR_POST_IMM:
7833 case ARM::STR_POST_REG:
7834 case ARM::t2STR_POST:
7835 case ARM::STRH_PRE:
7836 case ARM::t2STRH_PRE:
7837 case ARM::STRH_POST:
7838 case ARM::t2STRH_POST:
7839 case ARM::STRB_PRE_IMM:
7840 case ARM::STRB_PRE_REG:
7841 case ARM::t2STRB_PRE:
7842 case ARM::STRB_POST_IMM:
7843 case ARM::STRB_POST_REG:
7844 case ARM::t2STRB_POST: {
7845 // Rt must be different from Rn.
7846 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7847 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
7848
7849 if (Rt == Rn)
7850 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7851 "source register and base register can't be identical");
7852 return false;
7853 }
7854 case ARM::t2LDR_PRE_imm:
7855 case ARM::t2LDR_POST_imm:
7856 case ARM::t2STR_PRE_imm:
7857 case ARM::t2STR_POST_imm: {
7858 // Rt must be different from Rn.
7859 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
7860 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7861
7862 if (Rt == Rn)
7863 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7864 "destination register and base register can't be identical");
7865 if (Inst.getOpcode() == ARM::t2LDR_POST_imm ||
7866 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7867 int Imm = Inst.getOperand(2).getImm();
7868 if (Imm > 255 || Imm < -255)
7869 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7870 "operand must be in range [-255, 255]");
7871 }
7872 if (Inst.getOpcode() == ARM::t2STR_PRE_imm ||
7873 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7874 if (Inst.getOperand(0).getReg() == ARM::PC) {
7875 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7876 "operand must be a register in range [r0, r14]");
7877 }
7878 }
7879 return false;
7880 }
7881
7882 case ARM::t2LDRB_OFFSET_imm:
7883 case ARM::t2LDRB_PRE_imm:
7884 case ARM::t2LDRB_POST_imm:
7885 case ARM::t2STRB_OFFSET_imm:
7886 case ARM::t2STRB_PRE_imm:
7887 case ARM::t2STRB_POST_imm: {
7888 if (Inst.getOpcode() == ARM::t2LDRB_POST_imm ||
7889 Inst.getOpcode() == ARM::t2STRB_POST_imm ||
7890 Inst.getOpcode() == ARM::t2LDRB_PRE_imm ||
7891 Inst.getOpcode() == ARM::t2STRB_PRE_imm) {
7892 int Imm = Inst.getOperand(2).getImm();
7893 if (Imm > 255 || Imm < -255)
7894 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7895 "operand must be in range [-255, 255]");
7896 } else if (Inst.getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7897 Inst.getOpcode() == ARM::t2STRB_OFFSET_imm) {
7898 int Imm = Inst.getOperand(2).getImm();
7899 if (Imm > 0 || Imm < -255)
7900 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7901 "operand must be in range [0, 255] with a negative sign");
7902 }
7903 if (Inst.getOperand(0).getReg() == ARM::PC) {
7904 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7905 "if operand is PC, should call the LDRB (literal)");
7906 }
7907 return false;
7908 }
7909
7910 case ARM::t2LDRH_OFFSET_imm:
7911 case ARM::t2LDRH_PRE_imm:
7912 case ARM::t2LDRH_POST_imm:
7913 case ARM::t2STRH_OFFSET_imm:
7914 case ARM::t2STRH_PRE_imm:
7915 case ARM::t2STRH_POST_imm: {
7916 if (Inst.getOpcode() == ARM::t2LDRH_POST_imm ||
7917 Inst.getOpcode() == ARM::t2STRH_POST_imm ||
7918 Inst.getOpcode() == ARM::t2LDRH_PRE_imm ||
7919 Inst.getOpcode() == ARM::t2STRH_PRE_imm) {
7920 int Imm = Inst.getOperand(2).getImm();
7921 if (Imm > 255 || Imm < -255)
7922 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7923 "operand must be in range [-255, 255]");
7924 } else if (Inst.getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7925 Inst.getOpcode() == ARM::t2STRH_OFFSET_imm) {
7926 int Imm = Inst.getOperand(2).getImm();
7927 if (Imm > 0 || Imm < -255)
7928 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7929 "operand must be in range [0, 255] with a negative sign");
7930 }
7931 if (Inst.getOperand(0).getReg() == ARM::PC) {
7932 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7933 "if operand is PC, should call the LDRH (literal)");
7934 }
7935 return false;
7936 }
7937
7938 case ARM::t2LDRSB_OFFSET_imm:
7939 case ARM::t2LDRSB_PRE_imm:
7940 case ARM::t2LDRSB_POST_imm: {
7941 if (Inst.getOpcode() == ARM::t2LDRSB_POST_imm ||
7942 Inst.getOpcode() == ARM::t2LDRSB_PRE_imm) {
7943 int Imm = Inst.getOperand(2).getImm();
7944 if (Imm > 255 || Imm < -255)
7945 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7946 "operand must be in range [-255, 255]");
7947 } else if (Inst.getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7948 int Imm = Inst.getOperand(2).getImm();
7949 if (Imm > 0 || Imm < -255)
7950 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7951 "operand must be in range [0, 255] with a negative sign");
7952 }
7953 if (Inst.getOperand(0).getReg() == ARM::PC) {
7954 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7955 "if operand is PC, should call the LDRH (literal)");
7956 }
7957 return false;
7958 }
7959
7960 case ARM::t2LDRSH_OFFSET_imm:
7961 case ARM::t2LDRSH_PRE_imm:
7962 case ARM::t2LDRSH_POST_imm: {
7963 if (Inst.getOpcode() == ARM::t2LDRSH_POST_imm ||
7964 Inst.getOpcode() == ARM::t2LDRSH_PRE_imm) {
7965 int Imm = Inst.getOperand(2).getImm();
7966 if (Imm > 255 || Imm < -255)
7967 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7968 "operand must be in range [-255, 255]");
7969 } else if (Inst.getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7970 int Imm = Inst.getOperand(2).getImm();
7971 if (Imm > 0 || Imm < -255)
7972 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7973 "operand must be in range [0, 255] with a negative sign");
7974 }
7975 if (Inst.getOperand(0).getReg() == ARM::PC) {
7976 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7977 "if operand is PC, should call the LDRH (literal)");
7978 }
7979 return false;
7980 }
7981
7982 case ARM::LDR_PRE_IMM:
7983 case ARM::LDR_PRE_REG:
7984 case ARM::t2LDR_PRE:
7985 case ARM::LDR_POST_IMM:
7986 case ARM::LDR_POST_REG:
7987 case ARM::t2LDR_POST:
7988 case ARM::LDRH_PRE:
7989 case ARM::t2LDRH_PRE:
7990 case ARM::LDRH_POST:
7991 case ARM::t2LDRH_POST:
7992 case ARM::LDRSH_PRE:
7993 case ARM::t2LDRSH_PRE:
7994 case ARM::LDRSH_POST:
7995 case ARM::t2LDRSH_POST:
7996 case ARM::LDRB_PRE_IMM:
7997 case ARM::LDRB_PRE_REG:
7998 case ARM::t2LDRB_PRE:
7999 case ARM::LDRB_POST_IMM:
8000 case ARM::LDRB_POST_REG:
8001 case ARM::t2LDRB_POST:
8002 case ARM::LDRSB_PRE:
8003 case ARM::t2LDRSB_PRE:
8004 case ARM::LDRSB_POST:
8005 case ARM::t2LDRSB_POST: {
8006 // Rt must be different from Rn.
8007 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8008 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8009
8010 if (Rt == Rn)
8011 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8012 "destination register and base register can't be identical");
8013 return false;
8014 }
8015
8016 case ARM::MVE_VLDRBU8_rq:
8017 case ARM::MVE_VLDRBU16_rq:
8018 case ARM::MVE_VLDRBS16_rq:
8019 case ARM::MVE_VLDRBU32_rq:
8020 case ARM::MVE_VLDRBS32_rq:
8021 case ARM::MVE_VLDRHU16_rq:
8022 case ARM::MVE_VLDRHU16_rq_u:
8023 case ARM::MVE_VLDRHU32_rq:
8024 case ARM::MVE_VLDRHU32_rq_u:
8025 case ARM::MVE_VLDRHS32_rq:
8026 case ARM::MVE_VLDRHS32_rq_u:
8027 case ARM::MVE_VLDRWU32_rq:
8028 case ARM::MVE_VLDRWU32_rq_u:
8029 case ARM::MVE_VLDRDU64_rq:
8030 case ARM::MVE_VLDRDU64_rq_u:
8031 case ARM::MVE_VLDRWU32_qi:
8032 case ARM::MVE_VLDRWU32_qi_pre:
8033 case ARM::MVE_VLDRDU64_qi:
8034 case ARM::MVE_VLDRDU64_qi_pre: {
8035 // Qd must be different from Qm.
8036 unsigned QdIdx = 0, QmIdx = 2;
8037 bool QmIsPointer = false;
8038 switch (Opcode) {
8039 case ARM::MVE_VLDRWU32_qi:
8040 case ARM::MVE_VLDRDU64_qi:
8041 QmIdx = 1;
8042 QmIsPointer = true;
8043 break;
8044 case ARM::MVE_VLDRWU32_qi_pre:
8045 case ARM::MVE_VLDRDU64_qi_pre:
8046 QdIdx = 1;
8047 QmIsPointer = true;
8048 break;
8049 }
8050
8051 const unsigned Qd = MRI->getEncodingValue(Inst.getOperand(QdIdx).getReg());
8052 const unsigned Qm = MRI->getEncodingValue(Inst.getOperand(QmIdx).getReg());
8053
8054 if (Qd == Qm) {
8055 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8056 Twine("destination vector register and vector ") +
8057 (QmIsPointer ? "pointer" : "offset") +
8058 " register can't be identical");
8059 }
8060 return false;
8061 }
8062
8063 case ARM::SBFX:
8064 case ARM::t2SBFX:
8065 case ARM::UBFX:
8066 case ARM::t2UBFX: {
8067 // Width must be in range [1, 32-lsb].
8068 unsigned LSB = Inst.getOperand(2).getImm();
8069 unsigned Widthm1 = Inst.getOperand(3).getImm();
8070 if (Widthm1 >= 32 - LSB)
8071 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8072 "bitfield width must be in range [1,32-lsb]");
8073 return false;
8074 }
8075 // Notionally handles ARM::tLDMIA_UPD too.
8076 case ARM::tLDMIA: {
8077 // If we're parsing Thumb2, the .w variant is available and handles
8078 // most cases that are normally illegal for a Thumb1 LDM instruction.
8079 // We'll make the transformation in processInstruction() if necessary.
8080 //
8081 // Thumb LDM instructions are writeback iff the base register is not
8082 // in the register list.
8083 MCRegister Rn = Inst.getOperand(0).getReg();
8084 bool HasWritebackToken =
8085 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8086 .isToken() &&
8087 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8088 .getToken() == "!");
8089
8090 bool ListContainsBase;
8091 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), ListContainsBase) &&
8092 !isThumbTwo())
8093 return Error(
8094 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8095 "registers must be in range r0-r7");
8096 // If we should have writeback, then there should be a '!' token.
8097 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8098 return Error(
8099 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8100 "writeback operator '!' expected");
8101 // If we should not have writeback, there must not be a '!'. This is
8102 // true even for the 32-bit wide encodings.
8103 if (ListContainsBase && HasWritebackToken)
8104 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8105 "writeback operator '!' not allowed when base register "
8106 "in register list");
8107
8108 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8109 return true;
8110 break;
8111 }
8112 case ARM::LDMIA_UPD:
8113 case ARM::LDMDB_UPD:
8114 case ARM::LDMIB_UPD:
8115 case ARM::LDMDA_UPD:
8116 // ARM variants loading and updating the same register are only officially
8117 // UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
8118 if (!hasV7Ops())
8119 break;
8120 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8121 return Error(Operands.back()->getStartLoc(),
8122 "writeback register not allowed in register list");
8123 break;
8124 case ARM::t2LDMIA:
8125 case ARM::t2LDMDB:
8126 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8127 return true;
8128 break;
8129 case ARM::t2STMIA:
8130 case ARM::t2STMDB:
8131 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8132 return true;
8133 break;
8134 case ARM::t2LDMIA_UPD:
8135 case ARM::t2LDMDB_UPD:
8136 case ARM::t2STMIA_UPD:
8137 case ARM::t2STMDB_UPD:
8138 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8139 return Error(Operands.back()->getStartLoc(),
8140 "writeback register not allowed in register list");
8141
8142 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8143 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8144 return true;
8145 } else {
8146 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8147 return true;
8148 }
8149 break;
8150
8151 case ARM::sysLDMIA_UPD:
8152 case ARM::sysLDMDA_UPD:
8153 case ARM::sysLDMDB_UPD:
8154 case ARM::sysLDMIB_UPD:
8155 if (!listContainsReg(Inst, 3, ARM::PC))
8156 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8157 "writeback register only allowed on system LDM "
8158 "if PC in register-list");
8159 break;
8160 case ARM::sysSTMIA_UPD:
8161 case ARM::sysSTMDA_UPD:
8162 case ARM::sysSTMDB_UPD:
8163 case ARM::sysSTMIB_UPD:
8164 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8165 "system STM cannot have writeback register");
8166 // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
8167 // so only issue a diagnostic for thumb1. The instructions will be
8168 // switched to the t2 encodings in processInstruction() if necessary.
8169 case ARM::tPOP: {
8170 bool ListContainsBase;
8171 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC,
8172 ListContainsBase) &&
8173 !isThumbTwo())
8174 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8175 "registers must be in range r0-r7 or pc");
8176 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 2, !isMClass()))
8177 return true;
8178 break;
8179 }
8180 case ARM::tPUSH: {
8181 bool ListContainsBase;
8182 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR,
8183 ListContainsBase) &&
8184 !isThumbTwo())
8185 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8186 "registers must be in range r0-r7 or lr");
8187 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 2))
8188 return true;
8189 break;
8190 }
8191 case ARM::tSTMIA_UPD: {
8192 bool ListContainsBase, InvalidLowList;
8193 InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(),
8194 0, ListContainsBase);
8195 if (InvalidLowList && !isThumbTwo())
8196 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8197 "registers must be in range r0-r7");
8198
8199 // This would be converted to a 32-bit stm, but that's not valid if the
8200 // writeback register is in the list.
8201 if (InvalidLowList && ListContainsBase)
8202 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8203 "writeback operator '!' not allowed when base register "
8204 "in register list");
8205
8206 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 4))
8207 return true;
8208 break;
8209 }
8210 case ARM::tADDrSP:
8211 // If the non-SP source operand and the destination operand are not the
8212 // same, we need thumb2 (for the wide encoding), or we have an error.
8213 if (!isThumbTwo() &&
8214 Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
8215 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8216 "source register must be the same as destination");
8217 }
8218 break;
8219
8220 case ARM::t2ADDrr:
8221 case ARM::t2ADDrs:
8222 case ARM::t2SUBrr:
8223 case ARM::t2SUBrs:
8224 if (Inst.getOperand(0).getReg() == ARM::SP &&
8225 Inst.getOperand(1).getReg() != ARM::SP)
8226 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8227 "source register must be sp if destination is sp");
8228 break;
8229
8230 // Final range checking for Thumb unconditional branch instructions.
8231 case ARM::tB:
8232 if (!(static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]))
8233 .isSignedOffset<11, 1>())
8234 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8235 "branch target out of range");
8236 break;
8237 case ARM::t2B: {
8238 int op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8239 : MnemonicOpsEndInd + 1;
8240 ARMOperand &Operand = static_cast<ARMOperand &>(*Operands[op]);
8241 // Delay the checks of symbolic expressions until they are resolved.
8242 if (!isa<MCBinaryExpr>(Operand.getImm()) &&
8243 !Operand.isSignedOffset<24, 1>())
8244 return Error(Operands[op]->getStartLoc(), "branch target out of range");
8245 break;
8246 }
8247 // Final range checking for Thumb conditional branch instructions.
8248 case ARM::tBcc:
8249 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8250 .isSignedOffset<8, 1>())
8251 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8252 "branch target out of range");
8253 break;
8254 case ARM::t2Bcc: {
8255 int Op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8256 : MnemonicOpsEndInd + 1;
8257 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
8258 return Error(Operands[Op]->getStartLoc(), "branch target out of range");
8259 break;
8260 }
8261 case ARM::tCBZ:
8262 case ARM::tCBNZ: {
8263 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8264 .isUnsignedOffset<6, 1>())
8265 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8266 "branch target out of range");
8267 break;
8268 }
8269 case ARM::MOVi16:
8270 case ARM::MOVTi16:
8271 case ARM::t2MOVi16:
8272 case ARM::t2MOVTi16:
8273 {
8274 // We want to avoid misleadingly allowing something like "mov r0, <symbol>"
8275 // especially when we turn it into a movw and the expression <symbol> does
8276 // not have a :lower16: or :upper16 as part of the expression. We don't
8277 // want the behavior of silently truncating, which can be unexpected and
8278 // lead to bugs that are difficult to find since this is an easy mistake
8279 // to make.
8280 int i = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8281 : MnemonicOpsEndInd + 1;
8282 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[i]);
8283 const MCExpr *E = Op.getImm();
8285 break;
8286 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(E);
8287 if (!ARM16Expr || (ARM16Expr->getSpecifier() != ARM::S_HI16 &&
8288 ARM16Expr->getSpecifier() != ARM::S_LO16))
8289 return Error(
8290 Op.getStartLoc(),
8291 "immediate expression for mov requires :lower16: or :upper16");
8292 break;
8293 }
8294 case ARM::tADDi8: {
8295 int i = (Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8296 : MnemonicOpsEndInd + 2;
8297 MCParsedAsmOperand &Op = *Operands[i];
8299 return Error(Op.getStartLoc(),
8300 "Immediate expression for Thumb adds requires :lower0_7:,"
8301 " :lower8_15:, :upper0_7: or :upper8_15:");
8302 break;
8303 }
8304 case ARM::tMOVi8: {
8305 MCParsedAsmOperand &Op = *Operands[MnemonicOpsEndInd + 1];
8307 return Error(Op.getStartLoc(),
8308 "Immediate expression for Thumb movs requires :lower0_7:,"
8309 " :lower8_15:, :upper0_7: or :upper8_15:");
8310 break;
8311 }
8312 case ARM::HINT:
8313 case ARM::t2HINT: {
8314 unsigned Imm8 = Inst.getOperand(0).getImm();
8315 unsigned Pred = Inst.getOperand(1).getImm();
8316 // ESB is not predicable (pred must be AL). Without the RAS extension, this
8317 // behaves as any other unallocated hint.
8318 if (Imm8 == 0x10 && Pred != ARMCC::AL && hasRAS())
8319 return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not "
8320 "predicable, but condition "
8321 "code specified");
8322 if (Imm8 == 0x14 && Pred != ARMCC::AL)
8323 return Error(Operands[1]->getStartLoc(), "instruction 'csdb' is not "
8324 "predicable, but condition "
8325 "code specified");
8326 break;
8327 }
8328 case ARM::t2BFi:
8329 case ARM::t2BFr:
8330 case ARM::t2BFLi:
8331 case ARM::t2BFLr: {
8332 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8333 .isUnsignedOffset<4, 1>() ||
8334 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0)) {
8335 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8336 "branch location out of range or not a multiple of 2");
8337 }
8338
8339 if (Opcode == ARM::t2BFi) {
8340 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8341 .isSignedOffset<16, 1>())
8342 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8343 "branch target out of range or not a multiple of 2");
8344 } else if (Opcode == ARM::t2BFLi) {
8345 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8346 .isSignedOffset<18, 1>())
8347 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8348 "branch target out of range or not a multiple of 2");
8349 }
8350 break;
8351 }
8352 case ARM::t2BFic: {
8353 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8354 .isUnsignedOffset<4, 1>() ||
8355 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0))
8356 return Error(Operands[1]->getStartLoc(),
8357 "branch location out of range or not a multiple of 2");
8358
8359 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8360 .isSignedOffset<16, 1>())
8361 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8362 "branch target out of range or not a multiple of 2");
8363
8364 assert(Inst.getOperand(0).isImm() == Inst.getOperand(2).isImm() &&
8365 "branch location and else branch target should either both be "
8366 "immediates or both labels");
8367
8368 if (Inst.getOperand(0).isImm() && Inst.getOperand(2).isImm()) {
8369 int Diff = Inst.getOperand(2).getImm() - Inst.getOperand(0).getImm();
8370 if (Diff != 4 && Diff != 2)
8371 return Error(
8372 Operands[3]->getStartLoc(),
8373 "else branch target must be 2 or 4 greater than the branch location");
8374 }
8375 break;
8376 }
8377 case ARM::t2CLRM: {
8378 for (unsigned i = 2; i < Inst.getNumOperands(); i++) {
8379 if (Inst.getOperand(i).isReg() &&
8380 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8381 .contains(Inst.getOperand(i).getReg())) {
8382 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8383 "invalid register in register list. Valid registers are "
8384 "r0-r12, lr/r14 and APSR.");
8385 }
8386 }
8387 break;
8388 }
8389 case ARM::DSB:
8390 case ARM::t2DSB: {
8391
8392 if (Inst.getNumOperands() < 2)
8393 break;
8394
8395 unsigned Option = Inst.getOperand(0).getImm();
8396 unsigned Pred = Inst.getOperand(1).getImm();
8397
8398 // SSBB and PSSBB (DSB #0|#4) are not predicable (pred must be AL).
8399 if (Option == 0 && Pred != ARMCC::AL)
8400 return Error(Operands[1]->getStartLoc(),
8401 "instruction 'ssbb' is not predicable, but condition code "
8402 "specified");
8403 if (Option == 4 && Pred != ARMCC::AL)
8404 return Error(Operands[1]->getStartLoc(),
8405 "instruction 'pssbb' is not predicable, but condition code "
8406 "specified");
8407 break;
8408 }
8409 case ARM::VMOVRRS: {
8410 // Source registers must be sequential.
8411 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8412 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(3).getReg());
8413 if (Sm1 != Sm + 1)
8414 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8415 "source operands must be sequential");
8416 break;
8417 }
8418 case ARM::VMOVSRR: {
8419 // Destination registers must be sequential.
8420 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8421 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
8422 if (Sm1 != Sm + 1)
8423 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8424 "destination operands must be sequential");
8425 break;
8426 }
8427 case ARM::VLDMDIA:
8428 case ARM::VSTMDIA: {
8429 ARMOperand &Op =
8430 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
8431 auto &RegList = Op.getRegList();
8432 if (RegList.size() < 1 || RegList.size() > 16)
8433 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8434 "list of registers must be at least 1 and at most 16");
8435 break;
8436 }
8437 case ARM::MVE_VQDMULLs32bh:
8438 case ARM::MVE_VQDMULLs32th:
8439 case ARM::MVE_VCMULf32:
8440 case ARM::MVE_VMULLBs32:
8441 case ARM::MVE_VMULLTs32:
8442 case ARM::MVE_VMULLBu32:
8443 case ARM::MVE_VMULLTu32: {
8444 if (Operands[MnemonicOpsEndInd]->getReg() ==
8445 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8446 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8447 "Qd register and Qn register can't be identical");
8448 }
8449 if (Operands[MnemonicOpsEndInd]->getReg() ==
8450 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8451 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8452 "Qd register and Qm register can't be identical");
8453 }
8454 break;
8455 }
8456 case ARM::MVE_VREV64_8:
8457 case ARM::MVE_VREV64_16:
8458 case ARM::MVE_VREV64_32:
8459 case ARM::MVE_VQDMULL_qr_s32bh:
8460 case ARM::MVE_VQDMULL_qr_s32th: {
8461 if (Operands[MnemonicOpsEndInd]->getReg() ==
8462 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8463 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8464 "Qd register and Qn register can't be identical");
8465 }
8466 break;
8467 }
8468 case ARM::MVE_VCADDi32:
8469 case ARM::MVE_VCADDf32:
8470 case ARM::MVE_VHCADDs32: {
8471 if (Operands[MnemonicOpsEndInd]->getReg() ==
8472 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8473 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8474 "Qd register and Qm register can't be identical");
8475 }
8476 break;
8477 }
8478 case ARM::MVE_VMOV_rr_q: {
8479 if (Operands[MnemonicOpsEndInd + 2]->getReg() !=
8480 Operands[MnemonicOpsEndInd + 4]->getReg())
8481 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8482 "Q-registers must be the same");
8483 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8484 .getVectorIndex() !=
8485 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 5])
8486 .getVectorIndex() +
8487 2)
8488 return Error(Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8489 "Q-register indexes must be 2 and 0 or 3 and 1");
8490 break;
8491 }
8492 case ARM::MVE_VMOV_q_rr: {
8493 if (Operands[MnemonicOpsEndInd]->getReg() !=
8494 Operands[MnemonicOpsEndInd + 2]->getReg())
8495 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8496 "Q-registers must be the same");
8497 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8498 .getVectorIndex() !=
8499 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8500 .getVectorIndex() +
8501 2)
8502 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8503 "Q-register indexes must be 2 and 0 or 3 and 1");
8504 break;
8505 }
8506 case ARM::MVE_SQRSHR:
8507 case ARM::MVE_UQRSHL: {
8508 if (Operands[MnemonicOpsEndInd]->getReg() ==
8509 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8510 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8511 "Rda register and Rm register can't be identical");
8512 }
8513 break;
8514 }
8515 case ARM::UMAAL:
8516 case ARM::UMLAL:
8517 case ARM::UMULL:
8518 case ARM::t2UMAAL:
8519 case ARM::t2UMLAL:
8520 case ARM::t2UMULL:
8521 case ARM::SMLAL:
8522 case ARM::SMLALBB:
8523 case ARM::SMLALBT:
8524 case ARM::SMLALD:
8525 case ARM::SMLALDX:
8526 case ARM::SMLALTB:
8527 case ARM::SMLALTT:
8528 case ARM::SMLSLD:
8529 case ARM::SMLSLDX:
8530 case ARM::SMULL:
8531 case ARM::t2SMLAL:
8532 case ARM::t2SMLALBB:
8533 case ARM::t2SMLALBT:
8534 case ARM::t2SMLALD:
8535 case ARM::t2SMLALDX:
8536 case ARM::t2SMLALTB:
8537 case ARM::t2SMLALTT:
8538 case ARM::t2SMLSLD:
8539 case ARM::t2SMLSLDX:
8540 case ARM::t2SMULL: {
8541 MCRegister RdHi = Inst.getOperand(0).getReg();
8542 MCRegister RdLo = Inst.getOperand(1).getReg();
8543 if(RdHi == RdLo) {
8544 return Error(Loc,
8545 "unpredictable instruction, RdHi and RdLo must be different");
8546 }
8547 break;
8548 }
8549
8550 case ARM::CDE_CX1:
8551 case ARM::CDE_CX1A:
8552 case ARM::CDE_CX1D:
8553 case ARM::CDE_CX1DA:
8554 case ARM::CDE_CX2:
8555 case ARM::CDE_CX2A:
8556 case ARM::CDE_CX2D:
8557 case ARM::CDE_CX2DA:
8558 case ARM::CDE_CX3:
8559 case ARM::CDE_CX3A:
8560 case ARM::CDE_CX3D:
8561 case ARM::CDE_CX3DA:
8562 case ARM::CDE_VCX1_vec:
8563 case ARM::CDE_VCX1_fpsp:
8564 case ARM::CDE_VCX1_fpdp:
8565 case ARM::CDE_VCX1A_vec:
8566 case ARM::CDE_VCX1A_fpsp:
8567 case ARM::CDE_VCX1A_fpdp:
8568 case ARM::CDE_VCX2_vec:
8569 case ARM::CDE_VCX2_fpsp:
8570 case ARM::CDE_VCX2_fpdp:
8571 case ARM::CDE_VCX2A_vec:
8572 case ARM::CDE_VCX2A_fpsp:
8573 case ARM::CDE_VCX2A_fpdp:
8574 case ARM::CDE_VCX3_vec:
8575 case ARM::CDE_VCX3_fpsp:
8576 case ARM::CDE_VCX3_fpdp:
8577 case ARM::CDE_VCX3A_vec:
8578 case ARM::CDE_VCX3A_fpsp:
8579 case ARM::CDE_VCX3A_fpdp: {
8580 assert(Inst.getOperand(1).isImm() &&
8581 "CDE operand 1 must be a coprocessor ID");
8582 int64_t Coproc = Inst.getOperand(1).getImm();
8583 if (Coproc < 8 && !ARM::isCDECoproc(Coproc, *STI))
8584 return Error(Operands[1]->getStartLoc(),
8585 "coprocessor must be configured as CDE");
8586 else if (Coproc >= 8)
8587 return Error(Operands[1]->getStartLoc(),
8588 "coprocessor must be in the range [p0, p7]");
8589 break;
8590 }
8591
8592 case ARM::t2CDP:
8593 case ARM::t2CDP2:
8594 case ARM::t2LDC2L_OFFSET:
8595 case ARM::t2LDC2L_OPTION:
8596 case ARM::t2LDC2L_POST:
8597 case ARM::t2LDC2L_PRE:
8598 case ARM::t2LDC2_OFFSET:
8599 case ARM::t2LDC2_OPTION:
8600 case ARM::t2LDC2_POST:
8601 case ARM::t2LDC2_PRE:
8602 case ARM::t2LDCL_OFFSET:
8603 case ARM::t2LDCL_OPTION:
8604 case ARM::t2LDCL_POST:
8605 case ARM::t2LDCL_PRE:
8606 case ARM::t2LDC_OFFSET:
8607 case ARM::t2LDC_OPTION:
8608 case ARM::t2LDC_POST:
8609 case ARM::t2LDC_PRE:
8610 case ARM::t2MCR:
8611 case ARM::t2MCR2:
8612 case ARM::t2MCRR:
8613 case ARM::t2MCRR2:
8614 case ARM::t2MRC:
8615 case ARM::t2MRC2:
8616 case ARM::t2MRRC:
8617 case ARM::t2MRRC2:
8618 case ARM::t2STC2L_OFFSET:
8619 case ARM::t2STC2L_OPTION:
8620 case ARM::t2STC2L_POST:
8621 case ARM::t2STC2L_PRE:
8622 case ARM::t2STC2_OFFSET:
8623 case ARM::t2STC2_OPTION:
8624 case ARM::t2STC2_POST:
8625 case ARM::t2STC2_PRE:
8626 case ARM::t2STCL_OFFSET:
8627 case ARM::t2STCL_OPTION:
8628 case ARM::t2STCL_POST:
8629 case ARM::t2STCL_PRE:
8630 case ARM::t2STC_OFFSET:
8631 case ARM::t2STC_OPTION:
8632 case ARM::t2STC_POST:
8633 case ARM::t2STC_PRE: {
8634 unsigned Opcode = Inst.getOpcode();
8635 // Inst.getOperand indexes operands in the (oops ...) and (iops ...) dags,
8636 // CopInd is the index of the coprocessor operand.
8637 size_t CopInd = 0;
8638 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8639 CopInd = 2;
8640 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8641 CopInd = 1;
8642 assert(Inst.getOperand(CopInd).isImm() &&
8643 "Operand must be a coprocessor ID");
8644 int64_t Coproc = Inst.getOperand(CopInd).getImm();
8645 // Operands[2] is the coprocessor operand at syntactic level
8646 if (ARM::isCDECoproc(Coproc, *STI))
8647 return Error(Operands[2]->getStartLoc(),
8648 "coprocessor must be configured as GCP");
8649 break;
8650 }
8651
8652 case ARM::VTOSHH:
8653 case ARM::VTOUHH:
8654 case ARM::VTOSLH:
8655 case ARM::VTOULH:
8656 case ARM::VTOSHS:
8657 case ARM::VTOUHS:
8658 case ARM::VTOSLS:
8659 case ARM::VTOULS:
8660 case ARM::VTOSHD:
8661 case ARM::VTOUHD:
8662 case ARM::VTOSLD:
8663 case ARM::VTOULD:
8664 case ARM::VSHTOH:
8665 case ARM::VUHTOH:
8666 case ARM::VSLTOH:
8667 case ARM::VULTOH:
8668 case ARM::VSHTOS:
8669 case ARM::VUHTOS:
8670 case ARM::VSLTOS:
8671 case ARM::VULTOS:
8672 case ARM::VSHTOD:
8673 case ARM::VUHTOD:
8674 case ARM::VSLTOD:
8675 case ARM::VULTOD: {
8676 if (Operands[MnemonicOpsEndInd]->getReg() !=
8677 Operands[MnemonicOpsEndInd + 1]->getReg())
8678 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8679 "source and destination registers must be the same");
8680 break;
8681 }
8682 }
8683
8684 return false;
8685}
8686
8687static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
8688 switch(Opc) {
8689 default: llvm_unreachable("unexpected opcode!");
8690 // VST1LN
8691 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8693 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8694 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8695 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8696 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8697 case ARM::VST1LNdAsm_8: Spacing = 1; return ARM::VST1LNd8;
8698 case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
8699 case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
8700
8701 // VST2LN
8702 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8704 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8706 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8707
8708 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8709 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8710 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8711 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8712 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8713
8714 case ARM::VST2LNdAsm_8: Spacing = 1; return ARM::VST2LNd8;
8715 case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
8716 case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
8717 case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
8718 case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
8719
8720 // VST3LN
8721 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8723 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
8725 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8726 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8727 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8728 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8729 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
8730 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8731 case ARM::VST3LNdAsm_8: Spacing = 1; return ARM::VST3LNd8;
8732 case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
8733 case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
8734 case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
8735 case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
8736
8737 // VST3
8738 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8739 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8740 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8741 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8742 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8743 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8744 case ARM::VST3dWB_register_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8745 case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8746 case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8747 case ARM::VST3qWB_register_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8748 case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8749 case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8750 case ARM::VST3dAsm_8: Spacing = 1; return ARM::VST3d8;
8751 case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
8752 case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
8753 case ARM::VST3qAsm_8: Spacing = 2; return ARM::VST3q8;
8754 case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
8755 case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
8756
8757 // VST4LN
8758 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8760 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
8762 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8763 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8764 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8765 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8766 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
8767 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8768 case ARM::VST4LNdAsm_8: Spacing = 1; return ARM::VST4LNd8;
8769 case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
8770 case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
8771 case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
8772 case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
8773
8774 // VST4
8775 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8776 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8777 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8778 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8779 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8780 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8781 case ARM::VST4dWB_register_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8782 case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8783 case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8784 case ARM::VST4qWB_register_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8785 case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8786 case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8787 case ARM::VST4dAsm_8: Spacing = 1; return ARM::VST4d8;
8788 case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
8789 case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
8790 case ARM::VST4qAsm_8: Spacing = 2; return ARM::VST4q8;
8791 case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
8792 case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
8793 }
8794}
8795
8796static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
8797 switch(Opc) {
8798 default: llvm_unreachable("unexpected opcode!");
8799 // VLD1LN
8800 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8802 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8805 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8806 case ARM::VLD1LNdAsm_8: Spacing = 1; return ARM::VLD1LNd8;
8807 case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
8808 case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
8809
8810 // VLD2LN
8811 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8813 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
8815 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8818 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
8820 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8821 case ARM::VLD2LNdAsm_8: Spacing = 1; return ARM::VLD2LNd8;
8822 case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
8823 case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
8824 case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
8825 case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
8826
8827 // VLD3DUP
8828 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8830 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8833 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8836 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8839 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8840 case ARM::VLD3DUPdAsm_8: Spacing = 1; return ARM::VLD3DUPd8;
8841 case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
8842 case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
8843 case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
8844 case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
8845 case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
8846
8847 // VLD3LN
8848 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8850 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
8852 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8855 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
8857 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8858 case ARM::VLD3LNdAsm_8: Spacing = 1; return ARM::VLD3LNd8;
8859 case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
8860 case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
8861 case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
8862 case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
8863
8864 // VLD3
8865 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8867 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8870 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8871 case ARM::VLD3dWB_register_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8872 case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8873 case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8874 case ARM::VLD3qWB_register_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8875 case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8876 case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8877 case ARM::VLD3dAsm_8: Spacing = 1; return ARM::VLD3d8;
8878 case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
8879 case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
8880 case ARM::VLD3qAsm_8: Spacing = 2; return ARM::VLD3q8;
8881 case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
8882 case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
8883
8884 // VLD4LN
8885 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8887 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8889 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8892 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8894 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8895 case ARM::VLD4LNdAsm_8: Spacing = 1; return ARM::VLD4LNd8;
8896 case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
8897 case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
8898 case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
8899 case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
8900
8901 // VLD4DUP
8902 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8904 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
8907 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8910 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
8913 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8914 case ARM::VLD4DUPdAsm_8: Spacing = 1; return ARM::VLD4DUPd8;
8915 case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
8916 case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
8917 case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
8918 case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
8919 case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
8920
8921 // VLD4
8922 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8924 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8927 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8928 case ARM::VLD4dWB_register_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8929 case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8930 case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8931 case ARM::VLD4qWB_register_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8932 case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8933 case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8934 case ARM::VLD4dAsm_8: Spacing = 1; return ARM::VLD4d8;
8935 case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
8936 case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
8937 case ARM::VLD4qAsm_8: Spacing = 2; return ARM::VLD4q8;
8938 case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
8939 case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
8940 }
8941}
8942
8943bool ARMAsmParser::processInstruction(MCInst &Inst,
8944 const OperandVector &Operands,
8945 unsigned MnemonicOpsEndInd,
8946 MCStreamer &Out) {
8947 // Check if we have the wide qualifier, because if it's present we
8948 // must avoid selecting a 16-bit thumb instruction.
8949 bool HasWideQualifier = false;
8950 for (auto &Op : Operands) {
8951 ARMOperand &ARMOp = static_cast<ARMOperand&>(*Op);
8952 if (ARMOp.isToken() && ARMOp.getToken() == ".w") {
8953 HasWideQualifier = true;
8954 break;
8955 }
8956 }
8957
8958 switch (Inst.getOpcode()) {
8959 case ARM::VLLDM:
8960 case ARM::VLSTM: {
8961 // In some cases both T1 and T2 are valid, causing tablegen pick T1 instead
8962 // of T2
8963 if (Operands.size() ==
8964 MnemonicOpsEndInd + 2) { // a register list has been provided
8965 ARMOperand &Op = static_cast<ARMOperand &>(
8966 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
8967 assert(Op.isDPRRegList());
8968 auto &RegList = Op.getRegList();
8969 // When the register list is {d0-d31} the instruction has to be the T2
8970 // variant
8971 if (RegList.size() == 32) {
8972 const unsigned Opcode =
8973 (Inst.getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8974 MCInst TmpInst;
8975 TmpInst.setOpcode(Opcode);
8976 TmpInst.addOperand(Inst.getOperand(0));
8977 TmpInst.addOperand(Inst.getOperand(1));
8978 TmpInst.addOperand(Inst.getOperand(2));
8979 TmpInst.addOperand(Inst.getOperand(3));
8980 Inst = TmpInst;
8981 return true;
8982 }
8983 }
8984 return false;
8985 }
8986 // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
8987 case ARM::LDRT_POST:
8988 case ARM::LDRBT_POST: {
8989 const unsigned Opcode =
8990 (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8991 : ARM::LDRBT_POST_IMM;
8992 MCInst TmpInst;
8993 TmpInst.setOpcode(Opcode);
8994 TmpInst.addOperand(Inst.getOperand(0));
8995 TmpInst.addOperand(Inst.getOperand(1));
8996 TmpInst.addOperand(Inst.getOperand(1));
8997 TmpInst.addOperand(MCOperand::createReg(0));
8998 TmpInst.addOperand(MCOperand::createImm(0));
8999 TmpInst.addOperand(Inst.getOperand(2));
9000 TmpInst.addOperand(Inst.getOperand(3));
9001 Inst = TmpInst;
9002 return true;
9003 }
9004 // Alias for 'ldr{sb,h,sh}t Rt, [Rn] {, #imm}' for omitted immediate.
9005 case ARM::LDRSBTii:
9006 case ARM::LDRHTii:
9007 case ARM::LDRSHTii: {
9008 MCInst TmpInst;
9009
9010 if (Inst.getOpcode() == ARM::LDRSBTii)
9011 TmpInst.setOpcode(ARM::LDRSBTi);
9012 else if (Inst.getOpcode() == ARM::LDRHTii)
9013 TmpInst.setOpcode(ARM::LDRHTi);
9014 else if (Inst.getOpcode() == ARM::LDRSHTii)
9015 TmpInst.setOpcode(ARM::LDRSHTi);
9016 TmpInst.addOperand(Inst.getOperand(0));
9017 TmpInst.addOperand(Inst.getOperand(1));
9018 TmpInst.addOperand(Inst.getOperand(1));
9019 TmpInst.addOperand(MCOperand::createImm(256));
9020 TmpInst.addOperand(Inst.getOperand(2));
9021 Inst = TmpInst;
9022 return true;
9023 }
9024 // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction.
9025 case ARM::STRT_POST:
9026 case ARM::STRBT_POST: {
9027 const unsigned Opcode =
9028 (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9029 : ARM::STRBT_POST_IMM;
9030 MCInst TmpInst;
9031 TmpInst.setOpcode(Opcode);
9032 TmpInst.addOperand(Inst.getOperand(1));
9033 TmpInst.addOperand(Inst.getOperand(0));
9034 TmpInst.addOperand(Inst.getOperand(1));
9035 TmpInst.addOperand(MCOperand::createReg(0));
9036 TmpInst.addOperand(MCOperand::createImm(0));
9037 TmpInst.addOperand(Inst.getOperand(2));
9038 TmpInst.addOperand(Inst.getOperand(3));
9039 Inst = TmpInst;
9040 return true;
9041 }
9042 // Alias for alternate form of 'ADR Rd, #imm' instruction.
9043 case ARM::ADDri: {
9044 if (Inst.getOperand(1).getReg() != ARM::PC || Inst.getOperand(5).getReg() ||
9045 !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
9046 return false;
9047 MCInst TmpInst;
9048 TmpInst.setOpcode(ARM::ADR);
9049 TmpInst.addOperand(Inst.getOperand(0));
9050 if (Inst.getOperand(2).isImm()) {
9051 // Immediate (mod_imm) will be in its encoded form, we must unencode it
9052 // before passing it to the ADR instruction.
9053 unsigned Enc = Inst.getOperand(2).getImm();
9055 llvm::rotr<uint32_t>(Enc & 0xFF, (Enc & 0xF00) >> 7)));
9056 } else {
9057 // Turn PC-relative expression into absolute expression.
9058 // Reading PC provides the start of the current instruction + 8 and
9059 // the transform to adr is biased by that.
9060 MCSymbol *Dot = getContext().createTempSymbol();
9061 Out.emitLabel(Dot);
9062 const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
9063 const MCExpr *InstPC = MCSymbolRefExpr::create(Dot,
9064 getContext());
9065 const MCExpr *Const8 = MCConstantExpr::create(8, getContext());
9066 const MCExpr *ReadPC = MCBinaryExpr::createAdd(InstPC, Const8,
9067 getContext());
9068 const MCExpr *FixupAddr = MCBinaryExpr::createAdd(ReadPC, OpExpr,
9069 getContext());
9070 TmpInst.addOperand(MCOperand::createExpr(FixupAddr));
9071 }
9072 TmpInst.addOperand(Inst.getOperand(3));
9073 TmpInst.addOperand(Inst.getOperand(4));
9074 Inst = TmpInst;
9075 return true;
9076 }
9077 // Aliases for imm syntax of LDR instructions.
9078 case ARM::t2LDR_PRE_imm:
9079 case ARM::t2LDR_POST_imm: {
9080 MCInst TmpInst;
9081 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDR_PRE_imm ? ARM::t2LDR_PRE
9082 : ARM::t2LDR_POST);
9083 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9084 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9085 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9086 TmpInst.addOperand(Inst.getOperand(2)); // imm
9087 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9088 TmpInst.addOperand(Inst.getOperand(4));
9089 Inst = TmpInst;
9090 return true;
9091 }
9092 // Aliases for imm syntax of STR instructions.
9093 case ARM::t2STR_PRE_imm:
9094 case ARM::t2STR_POST_imm: {
9095 MCInst TmpInst;
9096 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STR_PRE_imm ? ARM::t2STR_PRE
9097 : ARM::t2STR_POST);
9098 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9099 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9100 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9101 TmpInst.addOperand(Inst.getOperand(2)); // imm
9102 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9103 TmpInst.addOperand(Inst.getOperand(4));
9104 Inst = TmpInst;
9105 return true;
9106 }
9107 // Aliases for imm syntax of LDRB instructions.
9108 case ARM::t2LDRB_OFFSET_imm: {
9109 MCInst TmpInst;
9110 TmpInst.setOpcode(ARM::t2LDRBi8);
9111 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9112 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9113 TmpInst.addOperand(Inst.getOperand(2)); // imm
9114 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9115 Inst = TmpInst;
9116 return true;
9117 }
9118 case ARM::t2LDRB_PRE_imm:
9119 case ARM::t2LDRB_POST_imm: {
9120 MCInst TmpInst;
9121 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRB_PRE_imm
9122 ? ARM::t2LDRB_PRE
9123 : ARM::t2LDRB_POST);
9124 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9125 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9126 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9127 TmpInst.addOperand(Inst.getOperand(2)); // imm
9128 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9129 TmpInst.addOperand(Inst.getOperand(4));
9130 Inst = TmpInst;
9131 return true;
9132 }
9133 // Aliases for imm syntax of STRB instructions.
9134 case ARM::t2STRB_OFFSET_imm: {
9135 MCInst TmpInst;
9136 TmpInst.setOpcode(ARM::t2STRBi8);
9137 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9138 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9139 TmpInst.addOperand(Inst.getOperand(2)); // imm
9140 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9141 Inst = TmpInst;
9142 return true;
9143 }
9144 case ARM::t2STRB_PRE_imm:
9145 case ARM::t2STRB_POST_imm: {
9146 MCInst TmpInst;
9147 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRB_PRE_imm
9148 ? ARM::t2STRB_PRE
9149 : ARM::t2STRB_POST);
9150 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9151 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9152 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9153 TmpInst.addOperand(Inst.getOperand(2)); // imm
9154 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9155 TmpInst.addOperand(Inst.getOperand(4));
9156 Inst = TmpInst;
9157 return true;
9158 }
9159 // Aliases for imm syntax of LDRH instructions.
9160 case ARM::t2LDRH_OFFSET_imm: {
9161 MCInst TmpInst;
9162 TmpInst.setOpcode(ARM::t2LDRHi8);
9163 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9164 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9165 TmpInst.addOperand(Inst.getOperand(2)); // imm
9166 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9167 Inst = TmpInst;
9168 return true;
9169 }
9170 case ARM::t2LDRH_PRE_imm:
9171 case ARM::t2LDRH_POST_imm: {
9172 MCInst TmpInst;
9173 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRH_PRE_imm
9174 ? ARM::t2LDRH_PRE
9175 : ARM::t2LDRH_POST);
9176 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9177 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9178 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9179 TmpInst.addOperand(Inst.getOperand(2)); // imm
9180 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9181 TmpInst.addOperand(Inst.getOperand(4));
9182 Inst = TmpInst;
9183 return true;
9184 }
9185 // Aliases for imm syntax of STRH instructions.
9186 case ARM::t2STRH_OFFSET_imm: {
9187 MCInst TmpInst;
9188 TmpInst.setOpcode(ARM::t2STRHi8);
9189 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9190 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9191 TmpInst.addOperand(Inst.getOperand(2)); // imm
9192 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9193 Inst = TmpInst;
9194 return true;
9195 }
9196 case ARM::t2STRH_PRE_imm:
9197 case ARM::t2STRH_POST_imm: {
9198 MCInst TmpInst;
9199 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRH_PRE_imm
9200 ? ARM::t2STRH_PRE
9201 : ARM::t2STRH_POST);
9202 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9203 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9204 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9205 TmpInst.addOperand(Inst.getOperand(2)); // imm
9206 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9207 TmpInst.addOperand(Inst.getOperand(4));
9208 Inst = TmpInst;
9209 return true;
9210 }
9211 // Aliases for imm syntax of LDRSB instructions.
9212 case ARM::t2LDRSB_OFFSET_imm: {
9213 MCInst TmpInst;
9214 TmpInst.setOpcode(ARM::t2LDRSBi8);
9215 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9216 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9217 TmpInst.addOperand(Inst.getOperand(2)); // imm
9218 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9219 Inst = TmpInst;
9220 return true;
9221 }
9222 case ARM::t2LDRSB_PRE_imm:
9223 case ARM::t2LDRSB_POST_imm: {
9224 MCInst TmpInst;
9225 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSB_PRE_imm
9226 ? ARM::t2LDRSB_PRE
9227 : ARM::t2LDRSB_POST);
9228 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9229 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9230 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9231 TmpInst.addOperand(Inst.getOperand(2)); // imm
9232 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9233 TmpInst.addOperand(Inst.getOperand(4));
9234 Inst = TmpInst;
9235 return true;
9236 }
9237 // Aliases for imm syntax of LDRSH instructions.
9238 case ARM::t2LDRSH_OFFSET_imm: {
9239 MCInst TmpInst;
9240 TmpInst.setOpcode(ARM::t2LDRSHi8);
9241 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9242 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9243 TmpInst.addOperand(Inst.getOperand(2)); // imm
9244 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9245 Inst = TmpInst;
9246 return true;
9247 }
9248 case ARM::t2LDRSH_PRE_imm:
9249 case ARM::t2LDRSH_POST_imm: {
9250 MCInst TmpInst;
9251 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSH_PRE_imm
9252 ? ARM::t2LDRSH_PRE
9253 : ARM::t2LDRSH_POST);
9254 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9255 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9256 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9257 TmpInst.addOperand(Inst.getOperand(2)); // imm
9258 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9259 TmpInst.addOperand(Inst.getOperand(4));
9260 Inst = TmpInst;
9261 return true;
9262 }
9263 // Aliases for alternate PC+imm syntax of LDR instructions.
9264 case ARM::t2LDRpcrel:
9265 // Select the narrow version if the immediate will fit.
9266 if (Inst.getOperand(1).getImm() > 0 &&
9267 Inst.getOperand(1).getImm() <= 0xff &&
9268 !HasWideQualifier)
9269 Inst.setOpcode(ARM::tLDRpci);
9270 else
9271 Inst.setOpcode(ARM::t2LDRpci);
9272 return true;
9273 case ARM::t2LDRBpcrel:
9274 Inst.setOpcode(ARM::t2LDRBpci);
9275 return true;
9276 case ARM::t2LDRHpcrel:
9277 Inst.setOpcode(ARM::t2LDRHpci);
9278 return true;
9279 case ARM::t2LDRSBpcrel:
9280 Inst.setOpcode(ARM::t2LDRSBpci);
9281 return true;
9282 case ARM::t2LDRSHpcrel:
9283 Inst.setOpcode(ARM::t2LDRSHpci);
9284 return true;
9285 case ARM::LDRConstPool:
9286 case ARM::tLDRConstPool:
9287 case ARM::t2LDRConstPool: {
9288 // Pseudo instruction ldr rt, =immediate is converted to a
9289 // MOV rt, immediate if immediate is known and representable
9290 // otherwise we create a constant pool entry that we load from.
9291 MCInst TmpInst;
9292 if (Inst.getOpcode() == ARM::LDRConstPool)
9293 TmpInst.setOpcode(ARM::LDRi12);
9294 else if (Inst.getOpcode() == ARM::tLDRConstPool)
9295 TmpInst.setOpcode(ARM::tLDRpci);
9296 else if (Inst.getOpcode() == ARM::t2LDRConstPool)
9297 TmpInst.setOpcode(ARM::t2LDRpci);
9298 const ARMOperand &PoolOperand =
9299 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
9300 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9301 // If SubExprVal is a constant we may be able to use a MOV
9302 if (isa<MCConstantExpr>(SubExprVal) &&
9303 Inst.getOperand(0).getReg() != ARM::PC &&
9304 Inst.getOperand(0).getReg() != ARM::SP) {
9305 int64_t Value =
9306 (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue();
9307 bool UseMov = true;
9308 bool MovHasS = true;
9309 if (Inst.getOpcode() == ARM::LDRConstPool) {
9310 // ARM Constant
9311 if (ARM_AM::getSOImmVal(Value) != -1) {
9313 TmpInst.setOpcode(ARM::MOVi);
9314 }
9315 else if (ARM_AM::getSOImmVal(~Value) != -1) {
9317 TmpInst.setOpcode(ARM::MVNi);
9318 }
9319 else if (hasV6T2Ops() &&
9320 Value >=0 && Value < 65536) {
9321 TmpInst.setOpcode(ARM::MOVi16);
9322 MovHasS = false;
9323 }
9324 else
9325 UseMov = false;
9326 }
9327 else {
9328 // Thumb/Thumb2 Constant
9329 if (hasThumb2() &&
9331 TmpInst.setOpcode(ARM::t2MOVi);
9332 else if (hasThumb2() &&
9333 ARM_AM::getT2SOImmVal(~Value) != -1) {
9334 TmpInst.setOpcode(ARM::t2MVNi);
9335 Value = ~Value;
9336 }
9337 else if (hasV8MBaseline() &&
9338 Value >=0 && Value < 65536) {
9339 TmpInst.setOpcode(ARM::t2MOVi16);
9340 MovHasS = false;
9341 }
9342 else
9343 UseMov = false;
9344 }
9345 if (UseMov) {
9346 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9347 TmpInst.addOperand(MCOperand::createImm(Value)); // Immediate
9348 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9349 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9350 if (MovHasS)
9351 TmpInst.addOperand(MCOperand::createReg(0)); // S
9352 Inst = TmpInst;
9353 return true;
9354 }
9355 }
9356 // No opportunity to use MOV/MVN create constant pool
9357 const MCExpr *CPLoc =
9358 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9359 PoolOperand.getStartLoc());
9360 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9361 TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool
9362 if (TmpInst.getOpcode() == ARM::LDRi12)
9363 TmpInst.addOperand(MCOperand::createImm(0)); // unused offset
9364 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9365 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9366 Inst = TmpInst;
9367 return true;
9368 }
9369 // Handle NEON VST complex aliases.
9370 case ARM::VST1LNdWB_register_Asm_8:
9371 case ARM::VST1LNdWB_register_Asm_16:
9372 case ARM::VST1LNdWB_register_Asm_32: {
9373 MCInst TmpInst;
9374 // Shuffle the operands around so the lane index operand is in the
9375 // right place.
9376 unsigned Spacing;
9377 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9378 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9379 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9380 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9381 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9382 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9383 TmpInst.addOperand(Inst.getOperand(1)); // lane
9384 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9385 TmpInst.addOperand(Inst.getOperand(6));
9386 Inst = TmpInst;
9387 return true;
9388 }
9389
9390 case ARM::VST2LNdWB_register_Asm_8:
9391 case ARM::VST2LNdWB_register_Asm_16:
9392 case ARM::VST2LNdWB_register_Asm_32:
9393 case ARM::VST2LNqWB_register_Asm_16:
9394 case ARM::VST2LNqWB_register_Asm_32: {
9395 MCInst TmpInst;
9396 // Shuffle the operands around so the lane index operand is in the
9397 // right place.
9398 unsigned Spacing;
9399 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9400 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9401 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9402 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9403 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9404 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9406 Spacing));
9407 TmpInst.addOperand(Inst.getOperand(1)); // lane
9408 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9409 TmpInst.addOperand(Inst.getOperand(6));
9410 Inst = TmpInst;
9411 return true;
9412 }
9413
9414 case ARM::VST3LNdWB_register_Asm_8:
9415 case ARM::VST3LNdWB_register_Asm_16:
9416 case ARM::VST3LNdWB_register_Asm_32:
9417 case ARM::VST3LNqWB_register_Asm_16:
9418 case ARM::VST3LNqWB_register_Asm_32: {
9419 MCInst TmpInst;
9420 // Shuffle the operands around so the lane index operand is in the
9421 // right place.
9422 unsigned Spacing;
9423 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9424 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9425 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9426 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9427 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9428 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9430 Spacing));
9432 Spacing * 2));
9433 TmpInst.addOperand(Inst.getOperand(1)); // lane
9434 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9435 TmpInst.addOperand(Inst.getOperand(6));
9436 Inst = TmpInst;
9437 return true;
9438 }
9439
9440 case ARM::VST4LNdWB_register_Asm_8:
9441 case ARM::VST4LNdWB_register_Asm_16:
9442 case ARM::VST4LNdWB_register_Asm_32:
9443 case ARM::VST4LNqWB_register_Asm_16:
9444 case ARM::VST4LNqWB_register_Asm_32: {
9445 MCInst TmpInst;
9446 // Shuffle the operands around so the lane index operand is in the
9447 // right place.
9448 unsigned Spacing;
9449 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9450 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9451 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9452 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9453 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9454 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9456 Spacing));
9458 Spacing * 2));
9460 Spacing * 3));
9461 TmpInst.addOperand(Inst.getOperand(1)); // lane
9462 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9463 TmpInst.addOperand(Inst.getOperand(6));
9464 Inst = TmpInst;
9465 return true;
9466 }
9467
9468 case ARM::VST1LNdWB_fixed_Asm_8:
9469 case ARM::VST1LNdWB_fixed_Asm_16:
9470 case ARM::VST1LNdWB_fixed_Asm_32: {
9471 MCInst TmpInst;
9472 // Shuffle the operands around so the lane index operand is in the
9473 // right place.
9474 unsigned Spacing;
9475 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9476 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9477 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9478 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9479 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9480 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9481 TmpInst.addOperand(Inst.getOperand(1)); // lane
9482 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9483 TmpInst.addOperand(Inst.getOperand(5));
9484 Inst = TmpInst;
9485 return true;
9486 }
9487
9488 case ARM::VST2LNdWB_fixed_Asm_8:
9489 case ARM::VST2LNdWB_fixed_Asm_16:
9490 case ARM::VST2LNdWB_fixed_Asm_32:
9491 case ARM::VST2LNqWB_fixed_Asm_16:
9492 case ARM::VST2LNqWB_fixed_Asm_32: {
9493 MCInst TmpInst;
9494 // Shuffle the operands around so the lane index operand is in the
9495 // right place.
9496 unsigned Spacing;
9497 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9498 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9499 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9500 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9501 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9502 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9504 Spacing));
9505 TmpInst.addOperand(Inst.getOperand(1)); // lane
9506 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9507 TmpInst.addOperand(Inst.getOperand(5));
9508 Inst = TmpInst;
9509 return true;
9510 }
9511
9512 case ARM::VST3LNdWB_fixed_Asm_8:
9513 case ARM::VST3LNdWB_fixed_Asm_16:
9514 case ARM::VST3LNdWB_fixed_Asm_32:
9515 case ARM::VST3LNqWB_fixed_Asm_16:
9516 case ARM::VST3LNqWB_fixed_Asm_32: {
9517 MCInst TmpInst;
9518 // Shuffle the operands around so the lane index operand is in the
9519 // right place.
9520 unsigned Spacing;
9521 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9522 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9523 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9524 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9525 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9526 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9528 Spacing));
9530 Spacing * 2));
9531 TmpInst.addOperand(Inst.getOperand(1)); // lane
9532 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9533 TmpInst.addOperand(Inst.getOperand(5));
9534 Inst = TmpInst;
9535 return true;
9536 }
9537
9538 case ARM::VST4LNdWB_fixed_Asm_8:
9539 case ARM::VST4LNdWB_fixed_Asm_16:
9540 case ARM::VST4LNdWB_fixed_Asm_32:
9541 case ARM::VST4LNqWB_fixed_Asm_16:
9542 case ARM::VST4LNqWB_fixed_Asm_32: {
9543 MCInst TmpInst;
9544 // Shuffle the operands around so the lane index operand is in the
9545 // right place.
9546 unsigned Spacing;
9547 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9548 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9549 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9550 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9551 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9552 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9554 Spacing));
9556 Spacing * 2));
9558 Spacing * 3));
9559 TmpInst.addOperand(Inst.getOperand(1)); // lane
9560 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9561 TmpInst.addOperand(Inst.getOperand(5));
9562 Inst = TmpInst;
9563 return true;
9564 }
9565
9566 case ARM::VST1LNdAsm_8:
9567 case ARM::VST1LNdAsm_16:
9568 case ARM::VST1LNdAsm_32: {
9569 MCInst TmpInst;
9570 // Shuffle the operands around so the lane index operand is in the
9571 // right place.
9572 unsigned Spacing;
9573 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9574 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9575 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9576 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9577 TmpInst.addOperand(Inst.getOperand(1)); // lane
9578 TmpInst.addOperand(Inst.getOperand(4));