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"
57#include <algorithm>
58#include <cassert>
59#include <cstddef>
60#include <cstdint>
61#include <iterator>
62#include <limits>
63#include <memory>
64#include <optional>
65#include <string>
66#include <utility>
67#include <vector>
68
69#define DEBUG_TYPE "asm-parser"
70
71using namespace llvm;
72
73namespace {
74class ARMOperand;
75
76enum class ImplicitItModeTy { Always, Never, ARMOnly, ThumbOnly };
77
78static cl::opt<ImplicitItModeTy> ImplicitItMode(
79 "arm-implicit-it", cl::init(ImplicitItModeTy::ARMOnly),
80 cl::desc("Allow conditional instructions outside of an IT block"),
81 cl::values(clEnumValN(ImplicitItModeTy::Always, "always",
82 "Accept in both ISAs, emit implicit ITs in Thumb"),
83 clEnumValN(ImplicitItModeTy::Never, "never",
84 "Warn in ARM, reject in Thumb"),
85 clEnumValN(ImplicitItModeTy::ARMOnly, "arm",
86 "Accept in ARM, reject in Thumb"),
87 clEnumValN(ImplicitItModeTy::ThumbOnly, "thumb",
88 "Warn in ARM, emit implicit ITs in Thumb")));
89
90static cl::opt<bool> AddBuildAttributes("arm-add-build-attributes",
91 cl::init(false));
92
93enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
94
95static inline unsigned extractITMaskBit(unsigned Mask, unsigned Position) {
96 // Position==0 means we're not in an IT block at all. Position==1
97 // means we want the first state bit, which is always 0 (Then).
98 // Position==2 means we want the second state bit, stored at bit 3
99 // of Mask, and so on downwards. So (5 - Position) will shift the
100 // right bit down to bit 0, including the always-0 bit at bit 4 for
101 // the mandatory initial Then.
102 return (Mask >> (5 - Position) & 1);
103}
104
105class UnwindContext {
106 using Locs = SmallVector<SMLoc, 4>;
107
108 MCAsmParser &Parser;
109 Locs FnStartLocs;
110 Locs CantUnwindLocs;
111 Locs PersonalityLocs;
112 Locs PersonalityIndexLocs;
113 Locs HandlerDataLocs;
115
116public:
117 UnwindContext(MCAsmParser &P) : Parser(P), FPReg(ARM::SP) {}
118
119 bool hasFnStart() const { return !FnStartLocs.empty(); }
120 bool cantUnwind() const { return !CantUnwindLocs.empty(); }
121 bool hasHandlerData() const { return !HandlerDataLocs.empty(); }
122
123 bool hasPersonality() const {
124 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
125 }
126
127 void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); }
128 void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); }
129 void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); }
130 void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); }
131 void recordPersonalityIndex(SMLoc L) { PersonalityIndexLocs.push_back(L); }
132
133 void saveFPReg(MCRegister Reg) { FPReg = Reg; }
134 MCRegister getFPReg() const { return FPReg; }
135
136 void emitFnStartLocNotes() const {
137 for (SMLoc Loc : FnStartLocs)
138 Parser.Note(Loc, ".fnstart was specified here");
139 }
140
141 void emitCantUnwindLocNotes() const {
142 for (SMLoc Loc : CantUnwindLocs)
143 Parser.Note(Loc, ".cantunwind was specified here");
144 }
145
146 void emitHandlerDataLocNotes() const {
147 for (SMLoc Loc : HandlerDataLocs)
148 Parser.Note(Loc, ".handlerdata was specified here");
149 }
150
151 void emitPersonalityLocNotes() const {
152 for (Locs::const_iterator PI = PersonalityLocs.begin(),
153 PE = PersonalityLocs.end(),
154 PII = PersonalityIndexLocs.begin(),
155 PIE = PersonalityIndexLocs.end();
156 PI != PE || PII != PIE;) {
157 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
158 Parser.Note(*PI++, ".personality was specified here");
159 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
160 Parser.Note(*PII++, ".personalityindex was specified here");
161 else
162 llvm_unreachable(".personality and .personalityindex cannot be "
163 "at the same location");
164 }
165 }
166
167 void reset() {
168 FnStartLocs = Locs();
169 CantUnwindLocs = Locs();
170 PersonalityLocs = Locs();
171 HandlerDataLocs = Locs();
172 PersonalityIndexLocs = Locs();
173 FPReg = ARM::SP;
174 }
175};
176
177// Various sets of ARM instruction mnemonics which are used by the asm parser
178class ARMMnemonicSets {
179 StringSet<> CDE;
180 StringSet<> CDEWithVPTSuffix;
181public:
182 ARMMnemonicSets(const MCSubtargetInfo &STI);
183
184 /// Returns true iff a given mnemonic is a CDE instruction
185 bool isCDEInstr(StringRef Mnemonic) {
186 // Quick check before searching the set
187 if (!Mnemonic.starts_with("cx") && !Mnemonic.starts_with("vcx"))
188 return false;
189 return CDE.count(Mnemonic);
190 }
191
192 /// Returns true iff a given mnemonic is a VPT-predicable CDE instruction
193 /// (possibly with a predication suffix "e" or "t")
194 bool isVPTPredicableCDEInstr(StringRef Mnemonic) {
195 if (!Mnemonic.starts_with("vcx"))
196 return false;
197 return CDEWithVPTSuffix.count(Mnemonic);
198 }
199
200 /// Returns true iff a given mnemonic is an IT-predicable CDE instruction
201 /// (possibly with a condition suffix)
202 bool isITPredicableCDEInstr(StringRef Mnemonic) {
203 if (!Mnemonic.starts_with("cx"))
204 return false;
205 return Mnemonic.starts_with("cx1a") || Mnemonic.starts_with("cx1da") ||
206 Mnemonic.starts_with("cx2a") || Mnemonic.starts_with("cx2da") ||
207 Mnemonic.starts_with("cx3a") || Mnemonic.starts_with("cx3da");
208 }
209
210 /// Return true iff a given mnemonic is an integer CDE instruction with
211 /// dual-register destination
212 bool isCDEDualRegInstr(StringRef Mnemonic) {
213 if (!Mnemonic.starts_with("cx"))
214 return false;
215 return Mnemonic == "cx1d" || Mnemonic == "cx1da" ||
216 Mnemonic == "cx2d" || Mnemonic == "cx2da" ||
217 Mnemonic == "cx3d" || Mnemonic == "cx3da";
218 }
219};
220
221ARMMnemonicSets::ARMMnemonicSets(const MCSubtargetInfo &STI) {
222 for (StringRef Mnemonic: { "cx1", "cx1a", "cx1d", "cx1da",
223 "cx2", "cx2a", "cx2d", "cx2da",
224 "cx3", "cx3a", "cx3d", "cx3da", })
225 CDE.insert(Mnemonic);
226 for (StringRef Mnemonic :
227 {"vcx1", "vcx1a", "vcx2", "vcx2a", "vcx3", "vcx3a"}) {
228 CDE.insert(Mnemonic);
229 CDEWithVPTSuffix.insert(Mnemonic);
230 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "t");
231 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "e");
232 }
233}
234
235class ARMAsmParser : public MCTargetAsmParser {
236 const MCRegisterInfo *MRI;
237 UnwindContext UC;
238 ARMMnemonicSets MS;
239
240 ARMTargetStreamer &getTargetStreamer() {
241 assert(getParser().getStreamer().getTargetStreamer() &&
242 "do not have a target streamer");
243 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
244 return static_cast<ARMTargetStreamer &>(TS);
245 }
246
247 // Map of register aliases registers via the .req directive.
248 StringMap<MCRegister> RegisterReqs;
249
250 bool NextSymbolIsThumb;
251
252 bool useImplicitITThumb() const {
253 return ImplicitItMode == ImplicitItModeTy::Always ||
254 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
255 }
256
257 bool useImplicitITARM() const {
258 return ImplicitItMode == ImplicitItModeTy::Always ||
259 ImplicitItMode == ImplicitItModeTy::ARMOnly;
260 }
261
262 struct {
263 ARMCC::CondCodes Cond; // Condition for IT block.
264 unsigned Mask:4; // Condition mask for instructions.
265 // Starting at first 1 (from lsb).
266 // '1' condition as indicated in IT.
267 // '0' inverse of condition (else).
268 // Count of instructions in IT block is
269 // 4 - trailingzeroes(mask)
270 // Note that this does not have the same encoding
271 // as in the IT instruction, which also depends
272 // on the low bit of the condition code.
273
274 unsigned CurPosition; // Current position in parsing of IT
275 // block. In range [0,4], with 0 being the IT
276 // instruction itself. Initialized according to
277 // count of instructions in block. ~0U if no
278 // active IT block.
279
280 bool IsExplicit; // true - The IT instruction was present in the
281 // input, we should not modify it.
282 // false - The IT instruction was added
283 // implicitly, we can extend it if that
284 // would be legal.
285 } ITState;
286
287 SmallVector<MCInst, 4> PendingConditionalInsts;
288
289 void onEndOfFile() override {
290 flushPendingInstructions(getParser().getStreamer());
291 }
292
293 void flushPendingInstructions(MCStreamer &Out) override {
294 if (!inImplicitITBlock()) {
295 assert(PendingConditionalInsts.size() == 0);
296 return;
297 }
298
299 // Emit the IT instruction
300 MCInst ITInst;
301 ITInst.setOpcode(ARM::t2IT);
302 ITInst.addOperand(MCOperand::createImm(ITState.Cond));
303 ITInst.addOperand(MCOperand::createImm(ITState.Mask));
304 Out.emitInstruction(ITInst, getSTI());
305
306 // Emit the conditional instructions
307 assert(PendingConditionalInsts.size() <= 4);
308 for (const MCInst &Inst : PendingConditionalInsts) {
309 Out.emitInstruction(Inst, getSTI());
310 }
311 PendingConditionalInsts.clear();
312
313 // Clear the IT state
314 ITState.Mask = 0;
315 ITState.CurPosition = ~0U;
316 }
317
318 bool inITBlock() { return ITState.CurPosition != ~0U; }
319 bool inExplicitITBlock() { return inITBlock() && ITState.IsExplicit; }
320 bool inImplicitITBlock() { return inITBlock() && !ITState.IsExplicit; }
321
322 bool lastInITBlock() {
323 return ITState.CurPosition == 4 - (unsigned)llvm::countr_zero(ITState.Mask);
324 }
325
326 void forwardITPosition() {
327 if (!inITBlock()) return;
328 // Move to the next instruction in the IT block, if there is one. If not,
329 // mark the block as done, except for implicit IT blocks, which we leave
330 // open until we find an instruction that can't be added to it.
331 unsigned TZ = llvm::countr_zero(ITState.Mask);
332 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
333 ITState.CurPosition = ~0U; // Done with the IT block after this.
334 }
335
336 // Rewind the state of the current IT block, removing the last slot from it.
337 void rewindImplicitITPosition() {
338 assert(inImplicitITBlock());
339 assert(ITState.CurPosition > 1);
340 ITState.CurPosition--;
341 unsigned TZ = llvm::countr_zero(ITState.Mask);
342 unsigned NewMask = 0;
343 NewMask |= ITState.Mask & (0xC << TZ);
344 NewMask |= 0x2 << TZ;
345 ITState.Mask = NewMask;
346 }
347
348 // Rewind the state of the current IT block, removing the last slot from it.
349 // If we were at the first slot, this closes the IT block.
350 void discardImplicitITBlock() {
351 assert(inImplicitITBlock());
352 assert(ITState.CurPosition == 1);
353 ITState.CurPosition = ~0U;
354 }
355
356 // Get the condition code corresponding to the current IT block slot.
357 ARMCC::CondCodes currentITCond() {
358 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
359 return MaskBit ? ARMCC::getOppositeCondition(ITState.Cond) : ITState.Cond;
360 }
361
362 // Invert the condition of the current IT block slot without changing any
363 // other slots in the same block.
364 void invertCurrentITCondition() {
365 if (ITState.CurPosition == 1) {
366 ITState.Cond = ARMCC::getOppositeCondition(ITState.Cond);
367 } else {
368 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
369 }
370 }
371
372 // Returns true if the current IT block is full (all 4 slots used).
373 bool isITBlockFull() {
374 return inITBlock() && (ITState.Mask & 1);
375 }
376
377 // Extend the current implicit IT block to have one more slot with the given
378 // condition code.
379 void extendImplicitITBlock(ARMCC::CondCodes Cond) {
380 assert(inImplicitITBlock());
381 assert(!isITBlockFull());
382 assert(Cond == ITState.Cond ||
383 Cond == ARMCC::getOppositeCondition(ITState.Cond));
384 unsigned TZ = llvm::countr_zero(ITState.Mask);
385 unsigned NewMask = 0;
386 // Keep any existing condition bits.
387 NewMask |= ITState.Mask & (0xE << TZ);
388 // Insert the new condition bit.
389 NewMask |= (Cond != ITState.Cond) << TZ;
390 // Move the trailing 1 down one bit.
391 NewMask |= 1 << (TZ - 1);
392 ITState.Mask = NewMask;
393 }
394
395 // Create a new implicit IT block with a dummy condition code.
396 void startImplicitITBlock() {
397 assert(!inITBlock());
398 ITState.Cond = ARMCC::AL;
399 ITState.Mask = 8;
400 ITState.CurPosition = 1;
401 ITState.IsExplicit = false;
402 }
403
404 // Create a new explicit IT block with the given condition and mask.
405 // The mask should be in the format used in ARMOperand and
406 // MCOperand, with a 1 implying 'e', regardless of the low bit of
407 // the condition.
408 void startExplicitITBlock(ARMCC::CondCodes Cond, unsigned Mask) {
409 assert(!inITBlock());
410 ITState.Cond = Cond;
411 ITState.Mask = Mask;
412 ITState.CurPosition = 0;
413 ITState.IsExplicit = true;
414 }
415
416 struct {
417 unsigned Mask : 4;
418 unsigned CurPosition;
419 } VPTState;
420 bool inVPTBlock() { return VPTState.CurPosition != ~0U; }
421 void forwardVPTPosition() {
422 if (!inVPTBlock()) return;
423 unsigned TZ = llvm::countr_zero(VPTState.Mask);
424 if (++VPTState.CurPosition == 5 - TZ)
425 VPTState.CurPosition = ~0U;
426 }
427
428 void Note(SMLoc L, const Twine &Msg, SMRange Range = {}) {
429 return getParser().Note(L, Msg, Range);
430 }
431
432 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = {}) {
433 return getParser().Warning(L, Msg, Range);
434 }
435
436 bool Error(SMLoc L, const Twine &Msg, SMRange Range = {}) {
437 return getParser().Error(L, Msg, Range);
438 }
439
440 bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
441 unsigned MnemonicOpsEndInd, unsigned ListIndex,
442 bool IsARPop = false);
443 bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands,
444 unsigned MnemonicOpsEndInd, unsigned ListIndex);
445
446 MCRegister tryParseRegister(bool AllowOutofBoundReg = false);
447 bool tryParseRegisterWithWriteBack(OperandVector &);
448 int tryParseShiftRegister(OperandVector &);
449 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
450 bool parseRegisterList(OperandVector &, bool EnforceOrder = true,
451 bool AllowRAAC = false, bool IsLazyLoadStore = false,
452 bool IsVSCCLRM = false);
453 bool parseMemory(OperandVector &);
454 bool parseOperand(OperandVector &, StringRef Mnemonic);
455 bool parseImmExpr(int64_t &Out);
456 bool parsePrefix(ARM::Specifier &);
457 bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
458 unsigned &ShiftAmount);
459 bool parseLiteralValues(unsigned Size, SMLoc L);
460 bool parseDirectiveThumb(SMLoc L);
461 bool parseDirectiveARM(SMLoc L);
462 bool parseDirectiveThumbFunc(SMLoc L);
463 bool parseDirectiveCode(SMLoc L);
464 bool parseDirectiveSyntax(SMLoc L);
465 bool parseDirectiveReq(StringRef Name, SMLoc L);
466 bool parseDirectiveUnreq(SMLoc L);
467 bool parseDirectiveArch(SMLoc L);
468 bool parseDirectiveEabiAttr(SMLoc L);
469 bool parseDirectiveCPU(SMLoc L);
470 bool parseDirectiveFPU(SMLoc L);
471 bool parseDirectiveFnStart(SMLoc L);
472 bool parseDirectiveFnEnd(SMLoc L);
473 bool parseDirectiveCantUnwind(SMLoc L);
474 bool parseDirectivePersonality(SMLoc L);
475 bool parseDirectiveHandlerData(SMLoc L);
476 bool parseDirectiveSetFP(SMLoc L);
477 bool parseDirectivePad(SMLoc L);
478 bool parseDirectiveRegSave(SMLoc L, bool IsVector);
479 bool parseDirectiveInst(SMLoc L, char Suffix = '\0');
480 bool parseDirectiveLtorg(SMLoc L);
481 bool parseDirectiveEven(SMLoc L);
482 bool parseDirectivePersonalityIndex(SMLoc L);
483 bool parseDirectiveUnwindRaw(SMLoc L);
484 bool parseDirectiveTLSDescSeq(SMLoc L);
485 bool parseDirectiveMovSP(SMLoc L);
486 bool parseDirectiveObjectArch(SMLoc L);
487 bool parseDirectiveArchExtension(SMLoc L);
488 bool parseDirectiveAlign(SMLoc L);
489 bool parseDirectiveThumbSet(SMLoc L);
490
491 bool parseDirectiveSEHAllocStack(SMLoc L, bool Wide);
492 bool parseDirectiveSEHSaveRegs(SMLoc L, bool Wide);
493 bool parseDirectiveSEHSaveSP(SMLoc L);
494 bool parseDirectiveSEHSaveFRegs(SMLoc L);
495 bool parseDirectiveSEHSaveLR(SMLoc L);
496 bool parseDirectiveSEHPrologEnd(SMLoc L, bool Fragment);
497 bool parseDirectiveSEHNop(SMLoc L, bool Wide);
498 bool parseDirectiveSEHEpilogStart(SMLoc L, bool Condition);
499 bool parseDirectiveSEHEpilogEnd(SMLoc L);
500 bool parseDirectiveSEHCustom(SMLoc L);
501
502 std::unique_ptr<ARMOperand> defaultCondCodeOp();
503 std::unique_ptr<ARMOperand> defaultCCOutOp();
504 std::unique_ptr<ARMOperand> defaultVPTPredOp();
505
506 bool isMnemonicVPTPredicable(StringRef Mnemonic, StringRef ExtraToken);
507 StringRef splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
508 ARMCC::CondCodes &PredicationCode,
509 ARMVCC::VPTCodes &VPTPredicationCode,
510 bool &CarrySetting, unsigned &ProcessorIMod,
511 StringRef &ITMask);
512 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef ExtraToken,
513 StringRef FullInst, bool &CanAcceptCarrySet,
514 bool &CanAcceptPredicationCode,
515 bool &CanAcceptVPTPredicationCode);
516 bool enableArchExtFeature(StringRef Name, SMLoc &ExtLoc);
517
518 void tryConvertingToTwoOperandForm(StringRef Mnemonic,
519 ARMCC::CondCodes PredicationCode,
520 bool CarrySetting, OperandVector &Operands,
521 unsigned MnemonicOpsEndInd);
522
523 bool CDEConvertDualRegOperand(StringRef Mnemonic, OperandVector &Operands,
524 unsigned MnemonicOpsEndInd);
525
526 bool isThumb() const {
527 // FIXME: Can tablegen auto-generate this?
528 return getSTI().hasFeature(ARM::ModeThumb);
529 }
530
531 bool isThumbOne() const {
532 return isThumb() && !getSTI().hasFeature(ARM::FeatureThumb2);
533 }
534
535 bool isThumbTwo() const {
536 return isThumb() && getSTI().hasFeature(ARM::FeatureThumb2);
537 }
538
539 bool hasThumb() const {
540 return getSTI().hasFeature(ARM::HasV4TOps);
541 }
542
543 bool hasThumb2() const {
544 return getSTI().hasFeature(ARM::FeatureThumb2);
545 }
546
547 bool hasV6Ops() const {
548 return getSTI().hasFeature(ARM::HasV6Ops);
549 }
550
551 bool hasV6T2Ops() const {
552 return getSTI().hasFeature(ARM::HasV6T2Ops);
553 }
554
555 bool hasV6MOps() const {
556 return getSTI().hasFeature(ARM::HasV6MOps);
557 }
558
559 bool hasV7Ops() const {
560 return getSTI().hasFeature(ARM::HasV7Ops);
561 }
562
563 bool hasV8Ops() const {
564 return getSTI().hasFeature(ARM::HasV8Ops);
565 }
566
567 bool hasV8MBaseline() const {
568 return getSTI().hasFeature(ARM::HasV8MBaselineOps);
569 }
570
571 bool hasV8MMainline() const {
572 return getSTI().hasFeature(ARM::HasV8MMainlineOps);
573 }
574 bool hasV8_1MMainline() const {
575 return getSTI().hasFeature(ARM::HasV8_1MMainlineOps);
576 }
577 bool hasMVEFloat() const {
578 return getSTI().hasFeature(ARM::HasMVEFloatOps);
579 }
580 bool hasCDE() const {
581 return getSTI().hasFeature(ARM::HasCDEOps);
582 }
583 bool has8MSecExt() const {
584 return getSTI().hasFeature(ARM::Feature8MSecExt);
585 }
586
587 bool hasARM() const {
588 return !getSTI().hasFeature(ARM::FeatureNoARM);
589 }
590
591 bool hasDSP() const {
592 return getSTI().hasFeature(ARM::FeatureDSP);
593 }
594
595 bool hasD32() const {
596 return getSTI().hasFeature(ARM::FeatureD32);
597 }
598
599 bool hasV8_1aOps() const {
600 return getSTI().hasFeature(ARM::HasV8_1aOps);
601 }
602
603 bool hasRAS() const {
604 return getSTI().hasFeature(ARM::FeatureRAS);
605 }
606
607 void SwitchMode() {
608 MCSubtargetInfo &STI = copySTI();
609 auto FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
610 setAvailableFeatures(FB);
611 }
612
613 void FixModeAfterArchChange(bool WasThumb, SMLoc Loc);
614
615 bool isMClass() const {
616 return getSTI().hasFeature(ARM::FeatureMClass);
617 }
618
619 /// @name Auto-generated Match Functions
620 /// {
621
622#define GET_ASSEMBLER_HEADER
623#include "ARMGenAsmMatcher.inc"
624
625 /// }
626
627 ParseStatus parseITCondCode(OperandVector &);
628 ParseStatus parseCoprocNumOperand(OperandVector &);
629 ParseStatus parseCoprocRegOperand(OperandVector &);
630 ParseStatus parseCoprocOptionOperand(OperandVector &);
631 ParseStatus parseMemBarrierOptOperand(OperandVector &);
632 ParseStatus parseTraceSyncBarrierOptOperand(OperandVector &);
633 ParseStatus parseInstSyncBarrierOptOperand(OperandVector &);
634 ParseStatus parseProcIFlagsOperand(OperandVector &);
635 ParseStatus parseMSRMaskOperand(OperandVector &);
636 ParseStatus parseBankedRegOperand(OperandVector &);
637 ParseStatus parsePKHImm(OperandVector &O, ARM_AM::ShiftOpc, int Low,
638 int High);
639 ParseStatus parsePKHLSLImm(OperandVector &O) {
640 return parsePKHImm(O, ARM_AM::lsl, 0, 31);
641 }
642 ParseStatus parsePKHASRImm(OperandVector &O) {
643 return parsePKHImm(O, ARM_AM::asr, 1, 32);
644 }
645 ParseStatus parseSetEndImm(OperandVector &);
646 ParseStatus parseShifterImm(OperandVector &);
647 ParseStatus parseRotImm(OperandVector &);
648 ParseStatus parseModImm(OperandVector &);
649 ParseStatus parseBitfield(OperandVector &);
650 ParseStatus parsePostIdxReg(OperandVector &);
651 ParseStatus parseAM3Offset(OperandVector &);
652 ParseStatus parseFPImm(OperandVector &);
653 ParseStatus parseVectorList(OperandVector &);
654 ParseStatus parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index,
655 SMLoc &EndLoc);
656
657 // Asm Match Converter Methods
658 void cvtThumbMultiply(MCInst &Inst, const OperandVector &);
659 void cvtThumbBranches(MCInst &Inst, const OperandVector &);
660 void cvtMVEVMOVQtoDReg(MCInst &Inst, const OperandVector &);
661
662 bool validateInstruction(MCInst &Inst, const OperandVector &Ops,
663 unsigned MnemonicOpsEndInd);
664 bool processInstruction(MCInst &Inst, const OperandVector &Ops,
665 unsigned MnemonicOpsEndInd, MCStreamer &Out);
666 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic,
668 unsigned MnemonicOpsEndInd);
669 bool isITBlockTerminator(MCInst &Inst) const;
670
671 void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands,
672 unsigned MnemonicOpsEndInd);
673 bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands, bool Load,
674 bool ARMMode, bool Writeback,
675 unsigned MnemonicOpsEndInd);
676
677public:
678 enum ARMMatchResultTy {
679 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
680 Match_RequiresNotITBlock,
681 Match_RequiresV6,
682 Match_RequiresThumb2,
683 Match_RequiresV8,
684 Match_RequiresFlagSetting,
685#define GET_OPERAND_DIAGNOSTIC_TYPES
686#include "ARMGenAsmMatcher.inc"
687
688 };
689
690 ARMAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
691 const MCInstrInfo &MII)
692 : MCTargetAsmParser(STI, MII), UC(Parser), MS(STI) {
694
695 // Cache the MCRegisterInfo.
696 MRI = getContext().getRegisterInfo();
697
698 // Initialize the set of available features.
699 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
700
701 // Add build attributes based on the selected target.
703 getTargetStreamer().emitTargetAttributes(STI);
704
705 // Not in an ITBlock to start with.
706 ITState.CurPosition = ~0U;
707
708 VPTState.CurPosition = ~0U;
709
710 NextSymbolIsThumb = false;
711 }
712
713 // Implementation of the MCTargetAsmParser interface:
714 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
715 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
716 SMLoc &EndLoc) override;
717 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
718 SMLoc NameLoc, OperandVector &Operands) override;
719 bool ParseDirective(AsmToken DirectiveID) override;
720
721 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
722 unsigned Kind) override;
723 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
724 unsigned
725 checkEarlyTargetMatchPredicate(MCInst &Inst,
726 const OperandVector &Operands) override;
727
728 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
729 OperandVector &Operands, MCStreamer &Out,
730 uint64_t &ErrorInfo,
731 bool MatchingInlineAsm) override;
732 unsigned MatchInstruction(OperandVector &Operands, MCInst &Inst,
733 SmallVectorImpl<NearMissInfo> &NearMisses,
734 bool MatchingInlineAsm, bool &EmitInITBlock,
735 MCStreamer &Out);
736
737 struct NearMissMessage {
738 SMLoc Loc;
739 SmallString<128> Message;
740 };
741
742 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
743
744 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
745 SmallVectorImpl<NearMissMessage> &NearMissesOut,
746 SMLoc IDLoc, OperandVector &Operands);
747 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
749
750 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) override;
751
752 void onLabelParsed(MCSymbol *Symbol) override;
753
754 const MCInstrDesc &getInstrDesc(unsigned int Opcode) const {
755 return MII.get(Opcode);
756 }
757
758 bool hasMVE() const { return getSTI().hasFeature(ARM::HasMVEIntegerOps); }
759
760 // Return the low-subreg of a given Q register.
761 MCRegister getDRegFromQReg(MCRegister QReg) const {
762 return MRI->getSubReg(QReg, ARM::dsub_0);
763 }
764
765 const MCRegisterInfo *getMRI() const { return MRI; }
766};
767
768/// ARMOperand - Instances of this class represent a parsed ARM machine
769/// operand.
770class ARMOperand : public MCParsedAsmOperand {
771 enum KindTy {
772 k_CondCode,
773 k_VPTPred,
774 k_CCOut,
775 k_ITCondMask,
776 k_CoprocNum,
777 k_CoprocReg,
778 k_CoprocOption,
779 k_Immediate,
780 k_MemBarrierOpt,
781 k_InstSyncBarrierOpt,
782 k_TraceSyncBarrierOpt,
783 k_Memory,
784 k_PostIndexRegister,
785 k_MSRMask,
786 k_BankedReg,
787 k_ProcIFlags,
788 k_VectorIndex,
789 k_Register,
790 k_RegisterList,
791 k_RegisterListWithAPSR,
792 k_DPRRegisterList,
793 k_SPRRegisterList,
794 k_FPSRegisterListWithVPR,
795 k_FPDRegisterListWithVPR,
796 k_VectorList,
797 k_VectorListAllLanes,
798 k_VectorListIndexed,
799 k_ShiftedRegister,
800 k_ShiftedImmediate,
801 k_ShifterImmediate,
802 k_RotateImmediate,
803 k_ModifiedImmediate,
804 k_ConstantPoolImmediate,
805 k_BitfieldDescriptor,
806 k_Token,
807 } Kind;
808
809 SMLoc StartLoc, EndLoc, AlignmentLoc;
811
812 ARMAsmParser *Parser;
813
814 struct CCOp {
816 };
817
818 struct VCCOp {
820 };
821
822 struct CopOp {
823 unsigned Val;
824 };
825
826 struct CoprocOptionOp {
827 unsigned Val;
828 };
829
830 struct ITMaskOp {
831 unsigned Mask:4;
832 };
833
834 struct MBOptOp {
835 ARM_MB::MemBOpt Val;
836 };
837
838 struct ISBOptOp {
840 };
841
842 struct TSBOptOp {
844 };
845
846 struct IFlagsOp {
848 };
849
850 struct MMaskOp {
851 unsigned Val;
852 };
853
854 struct BankedRegOp {
855 unsigned Val;
856 };
857
858 struct TokOp {
859 const char *Data;
860 unsigned Length;
861 };
862
863 struct RegOp {
864 MCRegister RegNum;
865 };
866
867 // A vector register list is a sequential list of 1 to 4 registers.
868 struct VectorListOp {
869 MCRegister RegNum;
870 unsigned Count;
871 unsigned LaneIndex;
872 bool isDoubleSpaced;
873 };
874
875 struct VectorIndexOp {
876 unsigned Val;
877 };
878
879 struct ImmOp {
880 const MCExpr *Val;
881 };
882
883 /// Combined record for all forms of ARM address expressions.
884 struct MemoryOp {
885 MCRegister BaseRegNum;
886 // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
887 // was specified.
888 const MCExpr *OffsetImm; // Offset immediate value
889 MCRegister OffsetRegNum; // Offset register num, when OffsetImm == NULL
890 ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
891 unsigned ShiftImm; // shift for OffsetReg.
892 unsigned Alignment; // 0 = no alignment specified
893 // n = alignment in bytes (2, 4, 8, 16, or 32)
894 unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit)
895 };
896
897 struct PostIdxRegOp {
898 MCRegister RegNum;
899 bool isAdd;
900 ARM_AM::ShiftOpc ShiftTy;
901 unsigned ShiftImm;
902 };
903
904 struct ShifterImmOp {
905 bool isASR;
906 unsigned Imm;
907 };
908
909 struct RegShiftedRegOp {
910 ARM_AM::ShiftOpc ShiftTy;
911 MCRegister SrcReg;
912 MCRegister ShiftReg;
913 unsigned ShiftImm;
914 };
915
916 struct RegShiftedImmOp {
917 ARM_AM::ShiftOpc ShiftTy;
918 MCRegister SrcReg;
919 unsigned ShiftImm;
920 };
921
922 struct RotImmOp {
923 unsigned Imm;
924 };
925
926 struct ModImmOp {
927 unsigned Bits;
928 unsigned Rot;
929 };
930
931 struct BitfieldOp {
932 unsigned LSB;
933 unsigned Width;
934 };
935
936 union {
937 struct CCOp CC;
938 struct VCCOp VCC;
939 struct CopOp Cop;
940 struct CoprocOptionOp CoprocOption;
941 struct MBOptOp MBOpt;
942 struct ISBOptOp ISBOpt;
943 struct TSBOptOp TSBOpt;
944 struct ITMaskOp ITMask;
945 struct IFlagsOp IFlags;
946 struct MMaskOp MMask;
947 struct BankedRegOp BankedReg;
948 struct TokOp Tok;
949 struct RegOp Reg;
950 struct VectorListOp VectorList;
951 struct VectorIndexOp VectorIndex;
952 struct ImmOp Imm;
953 struct MemoryOp Memory;
954 struct PostIdxRegOp PostIdxReg;
955 struct ShifterImmOp ShifterImm;
956 struct RegShiftedRegOp RegShiftedReg;
957 struct RegShiftedImmOp RegShiftedImm;
958 struct RotImmOp RotImm;
959 struct ModImmOp ModImm;
960 struct BitfieldOp Bitfield;
961 };
962
963public:
964 ARMOperand(KindTy K, ARMAsmParser &Parser) : Kind(K), Parser(&Parser) {}
965
966 /// getStartLoc - Get the location of the first token of this operand.
967 SMLoc getStartLoc() const override { return StartLoc; }
968
969 /// getEndLoc - Get the location of the last token of this operand.
970 SMLoc getEndLoc() const override { return EndLoc; }
971
972 /// getLocRange - Get the range between the first and last token of this
973 /// operand.
974 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
975
976 /// getAlignmentLoc - Get the location of the Alignment token of this operand.
977 SMLoc getAlignmentLoc() const {
978 assert(Kind == k_Memory && "Invalid access!");
979 return AlignmentLoc;
980 }
981
983 assert(Kind == k_CondCode && "Invalid access!");
984 return CC.Val;
985 }
986
987 ARMVCC::VPTCodes getVPTPred() const {
988 assert(isVPTPred() && "Invalid access!");
989 return VCC.Val;
990 }
991
992 unsigned getCoproc() const {
993 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
994 return Cop.Val;
995 }
996
997 StringRef getToken() const {
998 assert(Kind == k_Token && "Invalid access!");
999 return StringRef(Tok.Data, Tok.Length);
1000 }
1001
1002 MCRegister getReg() const override {
1003 assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
1004 return Reg.RegNum;
1005 }
1006
1007 const SmallVectorImpl<MCRegister> &getRegList() const {
1008 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
1009 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
1010 Kind == k_FPSRegisterListWithVPR ||
1011 Kind == k_FPDRegisterListWithVPR) &&
1012 "Invalid access!");
1013 return Registers;
1014 }
1015
1016 const MCExpr *getImm() const {
1017 assert(isImm() && "Invalid access!");
1018 return Imm.Val;
1019 }
1020
1021 const MCExpr *getConstantPoolImm() const {
1022 assert(isConstantPoolImm() && "Invalid access!");
1023 return Imm.Val;
1024 }
1025
1026 unsigned getVectorIndex() const {
1027 assert(Kind == k_VectorIndex && "Invalid access!");
1028 return VectorIndex.Val;
1029 }
1030
1031 ARM_MB::MemBOpt getMemBarrierOpt() const {
1032 assert(Kind == k_MemBarrierOpt && "Invalid access!");
1033 return MBOpt.Val;
1034 }
1035
1036 ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const {
1037 assert(Kind == k_InstSyncBarrierOpt && "Invalid access!");
1038 return ISBOpt.Val;
1039 }
1040
1041 ARM_TSB::TraceSyncBOpt getTraceSyncBarrierOpt() const {
1042 assert(Kind == k_TraceSyncBarrierOpt && "Invalid access!");
1043 return TSBOpt.Val;
1044 }
1045
1046 ARM_PROC::IFlags getProcIFlags() const {
1047 assert(Kind == k_ProcIFlags && "Invalid access!");
1048 return IFlags.Val;
1049 }
1050
1051 unsigned getMSRMask() const {
1052 assert(Kind == k_MSRMask && "Invalid access!");
1053 return MMask.Val;
1054 }
1055
1056 unsigned getBankedReg() const {
1057 assert(Kind == k_BankedReg && "Invalid access!");
1058 return BankedReg.Val;
1059 }
1060
1061 bool isCoprocNum() const { return Kind == k_CoprocNum; }
1062 bool isCoprocReg() const { return Kind == k_CoprocReg; }
1063 bool isCoprocOption() const { return Kind == k_CoprocOption; }
1064 bool isCondCode() const { return Kind == k_CondCode; }
1065 bool isVPTPred() const { return Kind == k_VPTPred; }
1066 bool isCCOut() const { return Kind == k_CCOut; }
1067 bool isITMask() const { return Kind == k_ITCondMask; }
1068 bool isITCondCode() const { return Kind == k_CondCode; }
1069 bool isImm() const override {
1070 return Kind == k_Immediate;
1071 }
1072
1073 bool isARMBranchTarget() const {
1074 if (!isImm()) return false;
1075
1076 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1077 return CE->getValue() % 4 == 0;
1078 return true;
1079 }
1080
1081
1082 bool isThumbBranchTarget() const {
1083 if (!isImm()) return false;
1084
1085 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1086 return CE->getValue() % 2 == 0;
1087 return true;
1088 }
1089
1090 // checks whether this operand is an unsigned offset which fits is a field
1091 // of specified width and scaled by a specific number of bits
1092 template<unsigned width, unsigned scale>
1093 bool isUnsignedOffset() const {
1094 if (!isImm()) return false;
1095 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1096 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1097 int64_t Val = CE->getValue();
1098 int64_t Align = 1LL << scale;
1099 int64_t Max = Align * ((1LL << width) - 1);
1100 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
1101 }
1102 return false;
1103 }
1104
1105 // checks whether this operand is an signed offset which fits is a field
1106 // of specified width and scaled by a specific number of bits
1107 template<unsigned width, unsigned scale>
1108 bool isSignedOffset() const {
1109 if (!isImm()) return false;
1110 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1111 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1112 int64_t Val = CE->getValue();
1113 int64_t Align = 1LL << scale;
1114 int64_t Max = Align * ((1LL << (width-1)) - 1);
1115 int64_t Min = -Align * (1LL << (width-1));
1116 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
1117 }
1118 return false;
1119 }
1120
1121 // checks whether this operand is an offset suitable for the LE /
1122 // LETP instructions in Arm v8.1M
1123 bool isLEOffset() const {
1124 if (!isImm()) return false;
1125 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1126 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1127 int64_t Val = CE->getValue();
1128 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1129 }
1130 return false;
1131 }
1132
1133 // checks whether this operand is a memory operand computed as an offset
1134 // applied to PC. the offset may have 8 bits of magnitude and is represented
1135 // with two bits of shift. textually it may be either [pc, #imm], #imm or
1136 // relocable expression...
1137 bool isThumbMemPC() const {
1138 int64_t Val = 0;
1139 if (isImm()) {
1140 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1141 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val);
1142 if (!CE) return false;
1143 Val = CE->getValue();
1144 }
1145 else if (isGPRMem()) {
1146 if(!Memory.OffsetImm || Memory.OffsetRegNum) return false;
1147 if(Memory.BaseRegNum != ARM::PC) return false;
1148 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
1149 Val = CE->getValue();
1150 else
1151 return false;
1152 }
1153 else return false;
1154 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1155 }
1156
1157 bool isFPImm() const {
1158 if (!isImm()) return false;
1159 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1160 if (!CE || !isUInt<32>(CE->getValue()))
1161 return false;
1162 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
1163 return Val != -1;
1164 }
1165
1166 template<int64_t N, int64_t M>
1167 bool isImmediate() const {
1168 if (!isImm()) return false;
1169 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1170 if (!CE) return false;
1171 int64_t Value = CE->getValue();
1172 return Value >= N && Value <= M;
1173 }
1174
1175 template<int64_t N, int64_t M>
1176 bool isImmediateS4() const {
1177 if (!isImm()) return false;
1178 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1179 if (!CE) return false;
1180 int64_t Value = CE->getValue();
1181 // ARM assembly uses #-0 to request the subtract-zero encoding,
1182 // which is distinct from the add-zero spelling even though both
1183 // have zero magnitude. The rather odd std::numeric_limits
1184 // invocation gives us this.
1185 return (((Value & 3) == 0) && Value >= N && Value <= M) ||
1186 Value == std::numeric_limits<int32_t>::min();
1187 }
1188 template<int64_t N, int64_t M>
1189 bool isImmediateS2() const {
1190 if (!isImm()) return false;
1191 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1192 if (!CE) return false;
1193 int64_t Value = CE->getValue();
1194 return ((Value & 1) == 0) && Value >= N && Value <= M;
1195 }
1196 bool isFBits16() const {
1197 return isImmediate<0, 17>();
1198 }
1199 bool isFBits32() const {
1200 return isImmediate<1, 33>();
1201 }
1202 bool isImm8s4() const {
1203 return isImmediateS4<-1020, 1020>();
1204 }
1205 bool isImm7s4() const {
1206 return isImmediateS4<-508, 508>();
1207 }
1208 bool isImm7Shift0() const {
1209 return isImmediate<-127, 127>();
1210 }
1211 bool isImm7Shift1() const {
1212 return isImmediateS2<-255, 255>();
1213 }
1214 bool isImm7Shift2() const {
1215 return isImmediateS4<-511, 511>();
1216 }
1217 bool isImm7() const {
1218 return isImmediate<-127, 127>();
1219 }
1220 bool isImm0_1020s4() const {
1221 return isImmediateS4<0, 1020>();
1222 }
1223 bool isImm0_508s4() const {
1224 return isImmediateS4<0, 508>();
1225 }
1226 bool isImm0_508s4Neg() const {
1227 if (!isImm()) return false;
1228 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1229 if (!CE) return false;
1230 int64_t Value = -CE->getValue();
1231 // explicitly exclude zero. we want that to use the normal 0_508 version.
1232 return ((Value & 3) == 0) && Value > 0 && Value <= 508;
1233 }
1234
1235 bool isImm0_4095Neg() const {
1236 if (!isImm()) return false;
1237 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1238 if (!CE) return false;
1239 // isImm0_4095Neg is used with 32-bit immediates only.
1240 // 32-bit immediates are zero extended to 64-bit when parsed,
1241 // thus simple -CE->getValue() results in a big negative number,
1242 // not a small positive number as intended
1243 if ((CE->getValue() >> 32) > 0) return false;
1244 uint32_t Value = -static_cast<uint32_t>(CE->getValue());
1245 return Value > 0 && Value < 4096;
1246 }
1247
1248 bool isImm0_7() const {
1249 return isImmediate<0, 7>();
1250 }
1251
1252 bool isImm1_16() const {
1253 return isImmediate<1, 16>();
1254 }
1255
1256 bool isImm1_32() const {
1257 return isImmediate<1, 32>();
1258 }
1259
1260 bool isImm8_255() const {
1261 return isImmediate<8, 255>();
1262 }
1263
1264 bool isImm0_255Expr() const {
1265 if (!isImm())
1266 return false;
1267 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1268 // If it's not a constant expression, it'll generate a fixup and be
1269 // handled later.
1270 if (!CE)
1271 return true;
1272 int64_t Value = CE->getValue();
1273 return isUInt<8>(Value);
1274 }
1275
1276 bool isImm256_65535Expr() const {
1277 if (!isImm()) return false;
1278 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1279 // If it's not a constant expression, it'll generate a fixup and be
1280 // handled later.
1281 if (!CE) return true;
1282 int64_t Value = CE->getValue();
1283 return Value >= 256 && Value < 65536;
1284 }
1285
1286 bool isImm0_65535Expr() const {
1287 if (!isImm()) return false;
1288 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1289 // If it's not a constant expression, it'll generate a fixup and be
1290 // handled later.
1291 if (!CE) return true;
1292 int64_t Value = CE->getValue();
1293 return Value >= 0 && Value < 65536;
1294 }
1295
1296 bool isImm24bit() const {
1297 return isImmediate<0, 0xffffff + 1>();
1298 }
1299
1300 bool isImmThumbSR() const {
1301 return isImmediate<1, 33>();
1302 }
1303
1304 bool isPKHLSLImm() const {
1305 return isImmediate<0, 32>();
1306 }
1307
1308 bool isPKHASRImm() const {
1309 return isImmediate<0, 33>();
1310 }
1311
1312 bool isAdrLabel() const {
1313 // If we have an immediate that's not a constant, treat it as a label
1314 // reference needing a fixup.
1315 if (isImm() && !isa<MCConstantExpr>(getImm()))
1316 return true;
1317
1318 // If it is a constant, it must fit into a modified immediate encoding.
1319 if (!isImm()) return false;
1320 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1321 if (!CE) return false;
1322 int64_t Value = CE->getValue();
1323 return (ARM_AM::getSOImmVal(Value) != -1 ||
1324 ARM_AM::getSOImmVal(-Value) != -1);
1325 }
1326
1327 bool isT2SOImm() const {
1328 // If we have an immediate that's not a constant, treat it as an expression
1329 // needing a fixup.
1330 if (isImm() && !isa<MCConstantExpr>(getImm())) {
1331 // We want to avoid matching :upper16: and :lower16: as we want these
1332 // expressions to match in isImm0_65535Expr()
1333 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(getImm());
1334 return (!ARM16Expr || (ARM16Expr->getSpecifier() != ARM::S_HI16 &&
1335 ARM16Expr->getSpecifier() != ARM::S_LO16));
1336 }
1337 if (!isImm()) return false;
1338 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1339 if (!CE) return false;
1340 int64_t Value = CE->getValue();
1341 return ARM_AM::getT2SOImmVal(Value) != -1;
1342 }
1343
1344 bool isT2SOImmNot() const {
1345 if (!isImm()) return false;
1346 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1347 if (!CE) return false;
1348 int64_t Value = CE->getValue();
1349 return ARM_AM::getT2SOImmVal(Value) == -1 &&
1351 }
1352
1353 bool isT2SOImmNeg() const {
1354 if (!isImm()) return false;
1355 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1356 if (!CE) return false;
1357 int64_t Value = CE->getValue();
1358 // Only use this when not representable as a plain so_imm.
1359 return ARM_AM::getT2SOImmVal(Value) == -1 &&
1361 }
1362
1363 bool isSetEndImm() const {
1364 if (!isImm()) return false;
1365 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1366 if (!CE) return false;
1367 int64_t Value = CE->getValue();
1368 return Value == 1 || Value == 0;
1369 }
1370
1371 bool isReg() const override { return Kind == k_Register; }
1372 bool isRegList() const { return Kind == k_RegisterList; }
1373 bool isRegListWithAPSR() const {
1374 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1375 }
1376 bool isDReg() const {
1377 return isReg() &&
1378 getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg.RegNum);
1379 }
1380 bool isQReg() const {
1381 return isReg() &&
1382 getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg.RegNum);
1383 }
1384 bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
1385 bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
1386 bool isFPSRegListWithVPR() const { return Kind == k_FPSRegisterListWithVPR; }
1387 bool isFPDRegListWithVPR() const { return Kind == k_FPDRegisterListWithVPR; }
1388 bool isToken() const override { return Kind == k_Token; }
1389 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
1390 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
1391 bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; }
1392 bool isMem() const override {
1393 return isGPRMem() || isMVEMem();
1394 }
1395 bool isMVEMem() const {
1396 if (Kind != k_Memory)
1397 return false;
1398 if (Memory.BaseRegNum &&
1399 !getARMMCRegisterClass(ARM::GPRRegClassID)
1400 .contains(Memory.BaseRegNum) &&
1401 !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Memory.BaseRegNum))
1402 return false;
1403 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::MQPRRegClassID)
1404 .contains(Memory.OffsetRegNum))
1405 return false;
1406 return true;
1407 }
1408 bool isGPRMem() const {
1409 if (Kind != k_Memory)
1410 return false;
1411 if (Memory.BaseRegNum &&
1412 !getARMMCRegisterClass(ARM::GPRRegClassID).contains(Memory.BaseRegNum))
1413 return false;
1414 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::GPRRegClassID)
1415 .contains(Memory.OffsetRegNum))
1416 return false;
1417 return true;
1418 }
1419 bool isShifterImm() const { return Kind == k_ShifterImmediate; }
1420 bool isRegShiftedReg() const {
1421 return Kind == k_ShiftedRegister &&
1422 getARMMCRegisterClass(ARM::GPRRegClassID)
1423 .contains(RegShiftedReg.SrcReg) &&
1424 getARMMCRegisterClass(ARM::GPRRegClassID)
1425 .contains(RegShiftedReg.ShiftReg);
1426 }
1427 bool isRegShiftedImm() const {
1428 return Kind == k_ShiftedImmediate &&
1429 getARMMCRegisterClass(ARM::GPRRegClassID)
1430 .contains(RegShiftedImm.SrcReg);
1431 }
1432 bool isRotImm() const { return Kind == k_RotateImmediate; }
1433
1434 template<unsigned Min, unsigned Max>
1435 bool isPowerTwoInRange() const {
1436 if (!isImm()) return false;
1437 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1438 if (!CE) return false;
1439 int64_t Value = CE->getValue();
1440 return Value > 0 && llvm::popcount((uint64_t)Value) == 1 && Value >= Min &&
1441 Value <= Max;
1442 }
1443 bool isModImm() const { return Kind == k_ModifiedImmediate; }
1444
1445 bool isModImmNot() const {
1446 if (!isImm()) return false;
1447 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1448 if (!CE) return false;
1449 int64_t Value = CE->getValue();
1450 return ARM_AM::getSOImmVal(~Value) != -1;
1451 }
1452
1453 bool isModImmNeg() const {
1454 if (!isImm()) return false;
1455 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1456 if (!CE) return false;
1457 int64_t Value = CE->getValue();
1458 return ARM_AM::getSOImmVal(Value) == -1 &&
1459 ARM_AM::getSOImmVal(-Value) != -1;
1460 }
1461
1462 bool isThumbModImmNeg1_7() const {
1463 if (!isImm()) return false;
1464 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1465 if (!CE) return false;
1466 int32_t Value = -(int32_t)CE->getValue();
1467 return 0 < Value && Value < 8;
1468 }
1469
1470 bool isThumbModImmNeg8_255() const {
1471 if (!isImm()) return false;
1472 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1473 if (!CE) return false;
1474 int32_t Value = -(int32_t)CE->getValue();
1475 return 7 < Value && Value < 256;
1476 }
1477
1478 bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
1479 bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
1480 bool isPostIdxRegShifted() const {
1481 return Kind == k_PostIndexRegister &&
1482 getARMMCRegisterClass(ARM::GPRRegClassID)
1483 .contains(PostIdxReg.RegNum);
1484 }
1485 bool isPostIdxReg() const {
1486 return isPostIdxRegShifted() && PostIdxReg.ShiftTy == ARM_AM::no_shift;
1487 }
1488 bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const {
1489 if (!isGPRMem())
1490 return false;
1491 // No offset of any kind.
1492 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1493 (alignOK || Memory.Alignment == Alignment);
1494 }
1495 bool isMemNoOffsetT2(bool alignOK = false, unsigned Alignment = 0) const {
1496 if (!isGPRMem())
1497 return false;
1498
1499 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1500 .contains(Memory.BaseRegNum))
1501 return false;
1502
1503 // No offset of any kind.
1504 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1505 (alignOK || Memory.Alignment == Alignment);
1506 }
1507 bool isMemNoOffsetT2NoSp(bool alignOK = false, unsigned Alignment = 0) const {
1508 if (!isGPRMem())
1509 return false;
1510
1511 if (!getARMMCRegisterClass(ARM::rGPRRegClassID).contains(Memory.BaseRegNum))
1512 return false;
1513
1514 // No offset of any kind.
1515 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1516 (alignOK || Memory.Alignment == Alignment);
1517 }
1518 bool isMemNoOffsetT(bool alignOK = false, unsigned Alignment = 0) const {
1519 if (!isGPRMem())
1520 return false;
1521
1522 if (!getARMMCRegisterClass(ARM::tGPRRegClassID).contains(Memory.BaseRegNum))
1523 return false;
1524
1525 // No offset of any kind.
1526 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1527 (alignOK || Memory.Alignment == Alignment);
1528 }
1529 bool isMemPCRelImm12() const {
1530 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1531 return false;
1532 // Base register must be PC.
1533 if (Memory.BaseRegNum != ARM::PC)
1534 return false;
1535 // Immediate offset in range [-4095, 4095].
1536 if (!Memory.OffsetImm) return true;
1537 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1538 int64_t Val = CE->getValue();
1539 return (Val > -4096 && Val < 4096) ||
1540 (Val == std::numeric_limits<int32_t>::min());
1541 }
1542 return false;
1543 }
1544
1545 bool isAlignedMemory() const {
1546 return isMemNoOffset(true);
1547 }
1548
1549 bool isAlignedMemoryNone() const {
1550 return isMemNoOffset(false, 0);
1551 }
1552
1553 bool isDupAlignedMemoryNone() const {
1554 return isMemNoOffset(false, 0);
1555 }
1556
1557 bool isAlignedMemory16() const {
1558 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1559 return true;
1560 return isMemNoOffset(false, 0);
1561 }
1562
1563 bool isDupAlignedMemory16() const {
1564 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1565 return true;
1566 return isMemNoOffset(false, 0);
1567 }
1568
1569 bool isAlignedMemory32() const {
1570 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1571 return true;
1572 return isMemNoOffset(false, 0);
1573 }
1574
1575 bool isDupAlignedMemory32() const {
1576 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1577 return true;
1578 return isMemNoOffset(false, 0);
1579 }
1580
1581 bool isAlignedMemory64() const {
1582 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1583 return true;
1584 return isMemNoOffset(false, 0);
1585 }
1586
1587 bool isDupAlignedMemory64() const {
1588 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1589 return true;
1590 return isMemNoOffset(false, 0);
1591 }
1592
1593 bool isAlignedMemory64or128() const {
1594 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1595 return true;
1596 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1597 return true;
1598 return isMemNoOffset(false, 0);
1599 }
1600
1601 bool isDupAlignedMemory64or128() const {
1602 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1603 return true;
1604 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1605 return true;
1606 return isMemNoOffset(false, 0);
1607 }
1608
1609 bool isAlignedMemory64or128or256() const {
1610 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1611 return true;
1612 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1613 return true;
1614 if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32.
1615 return true;
1616 return isMemNoOffset(false, 0);
1617 }
1618
1619 bool isAddrMode2() const {
1620 if (!isGPRMem() || Memory.Alignment != 0) return false;
1621 // Check for register offset.
1622 if (Memory.OffsetRegNum) return true;
1623 // Immediate offset in range [-4095, 4095].
1624 if (!Memory.OffsetImm) return true;
1625 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1626 int64_t Val = CE->getValue();
1627 return Val > -4096 && Val < 4096;
1628 }
1629 return false;
1630 }
1631
1632 bool isAM2OffsetImm() const {
1633 if (!isImm()) return false;
1634 // Immediate offset in range [-4095, 4095].
1635 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1636 if (!CE) return false;
1637 int64_t Val = CE->getValue();
1638 return (Val == std::numeric_limits<int32_t>::min()) ||
1639 (Val > -4096 && Val < 4096);
1640 }
1641
1642 bool isAddrMode3() const {
1643 // If we have an immediate that's not a constant, treat it as a label
1644 // reference needing a fixup. If it is a constant, it's something else
1645 // and we reject it.
1646 if (isImm() && !isa<MCConstantExpr>(getImm()))
1647 return true;
1648 if (!isGPRMem() || Memory.Alignment != 0) return false;
1649 // No shifts are legal for AM3.
1650 if (Memory.ShiftType != ARM_AM::no_shift) return false;
1651 // Check for register offset.
1652 if (Memory.OffsetRegNum) return true;
1653 // Immediate offset in range [-255, 255].
1654 if (!Memory.OffsetImm) return true;
1655 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1656 int64_t Val = CE->getValue();
1657 // The #-0 offset is encoded as std::numeric_limits<int32_t>::min(), and
1658 // we have to check for this too.
1659 return (Val > -256 && Val < 256) ||
1660 Val == std::numeric_limits<int32_t>::min();
1661 }
1662 return false;
1663 }
1664
1665 bool isAM3Offset() const {
1666 if (isPostIdxReg())
1667 return true;
1668 if (!isImm())
1669 return false;
1670 // Immediate offset in range [-255, 255].
1671 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1672 if (!CE) return false;
1673 int64_t Val = CE->getValue();
1674 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1675 return (Val > -256 && Val < 256) ||
1676 Val == std::numeric_limits<int32_t>::min();
1677 }
1678
1679 bool isAddrMode5() const {
1680 // If we have an immediate that's not a constant, treat it as a label
1681 // reference needing a fixup. If it is a constant, it's something else
1682 // and we reject it.
1683 if (isImm() && !isa<MCConstantExpr>(getImm()))
1684 return true;
1685 if (!isGPRMem() || Memory.Alignment != 0) return false;
1686 // Check for register offset.
1687 if (Memory.OffsetRegNum) return false;
1688 // Immediate offset in range [-1020, 1020] and a multiple of 4.
1689 if (!Memory.OffsetImm) return true;
1690 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1691 int64_t Val = CE->getValue();
1692 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1693 Val == std::numeric_limits<int32_t>::min();
1694 }
1695 return false;
1696 }
1697
1698 bool isAddrMode5FP16() const {
1699 // If we have an immediate that's not a constant, treat it as a label
1700 // reference needing a fixup. If it is a constant, it's something else
1701 // and we reject it.
1702 if (isImm() && !isa<MCConstantExpr>(getImm()))
1703 return true;
1704 if (!isGPRMem() || Memory.Alignment != 0) return false;
1705 // Check for register offset.
1706 if (Memory.OffsetRegNum) return false;
1707 // Immediate offset in range [-510, 510] and a multiple of 2.
1708 if (!Memory.OffsetImm) return true;
1709 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1710 int64_t Val = CE->getValue();
1711 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1712 Val == std::numeric_limits<int32_t>::min();
1713 }
1714 return false;
1715 }
1716
1717 bool isMemTBB() const {
1718 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1719 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1720 return false;
1721 return true;
1722 }
1723
1724 bool isMemTBH() const {
1725 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1726 Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
1727 Memory.Alignment != 0 )
1728 return false;
1729 return true;
1730 }
1731
1732 bool isMemRegOffset() const {
1733 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1734 return false;
1735 return true;
1736 }
1737
1738 bool isT2MemRegOffset() const {
1739 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1740 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1741 return false;
1742 // Only lsl #{0, 1, 2, 3} allowed.
1743 if (Memory.ShiftType == ARM_AM::no_shift)
1744 return true;
1745 if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
1746 return false;
1747 return true;
1748 }
1749
1750 bool isMemThumbRR() const {
1751 // Thumb reg+reg addressing is simple. Just two registers, a base and
1752 // an offset. No shifts, negations or any other complicating factors.
1753 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1754 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1755 return false;
1756 return isARMLowRegister(Memory.BaseRegNum) &&
1757 (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
1758 }
1759
1760 bool isMemThumbRIs4() const {
1761 if (!isGPRMem() || Memory.OffsetRegNum ||
1762 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1763 return false;
1764 // Immediate offset, multiple of 4 in range [0, 124].
1765 if (!Memory.OffsetImm) return true;
1766 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1767 int64_t Val = CE->getValue();
1768 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1769 }
1770 return false;
1771 }
1772
1773 bool isMemThumbRIs2() const {
1774 if (!isGPRMem() || Memory.OffsetRegNum ||
1775 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1776 return false;
1777 // Immediate offset, multiple of 4 in range [0, 62].
1778 if (!Memory.OffsetImm) return true;
1779 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1780 int64_t Val = CE->getValue();
1781 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1782 }
1783 return false;
1784 }
1785
1786 bool isMemThumbRIs1() const {
1787 if (!isGPRMem() || Memory.OffsetRegNum ||
1788 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1789 return false;
1790 // Immediate offset in range [0, 31].
1791 if (!Memory.OffsetImm) return true;
1792 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1793 int64_t Val = CE->getValue();
1794 return Val >= 0 && Val <= 31;
1795 }
1796 return false;
1797 }
1798
1799 bool isMemThumbSPI() const {
1800 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1801 Memory.Alignment != 0)
1802 return false;
1803 // Immediate offset, multiple of 4 in range [0, 1020].
1804 if (!Memory.OffsetImm) return true;
1805 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1806 int64_t Val = CE->getValue();
1807 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1808 }
1809 return false;
1810 }
1811
1812 bool isMemImm8s4Offset() const {
1813 // If we have an immediate that's not a constant, treat it as a label
1814 // reference needing a fixup. If it is a constant, it's something else
1815 // and we reject it.
1816 if (isImm() && !isa<MCConstantExpr>(getImm()))
1817 return true;
1818 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1819 return false;
1820 // Immediate offset a multiple of 4 in range [-1020, 1020].
1821 if (!Memory.OffsetImm) return true;
1822 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1823 int64_t Val = CE->getValue();
1824 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1825 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1826 Val == std::numeric_limits<int32_t>::min();
1827 }
1828 return false;
1829 }
1830
1831 bool isMemImm7s4Offset() const {
1832 // If we have an immediate that's not a constant, treat it as a label
1833 // reference needing a fixup. If it is a constant, it's something else
1834 // and we reject it.
1835 if (isImm() && !isa<MCConstantExpr>(getImm()))
1836 return true;
1837 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1838 !getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1839 .contains(Memory.BaseRegNum))
1840 return false;
1841 // Immediate offset a multiple of 4 in range [-508, 508].
1842 if (!Memory.OffsetImm) return true;
1843 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1844 int64_t Val = CE->getValue();
1845 // Special case, #-0 is INT32_MIN.
1846 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1847 }
1848 return false;
1849 }
1850
1851 bool isMemImm0_1020s4Offset() const {
1852 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1853 return false;
1854 // Immediate offset a multiple of 4 in range [0, 1020].
1855 if (!Memory.OffsetImm) return true;
1856 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1857 int64_t Val = CE->getValue();
1858 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1859 }
1860 return false;
1861 }
1862
1863 bool isMemImm8Offset() const {
1864 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1865 return false;
1866 // Base reg of PC isn't allowed for these encodings.
1867 if (Memory.BaseRegNum == ARM::PC) return false;
1868 // Immediate offset in range [-255, 255].
1869 if (!Memory.OffsetImm) return true;
1870 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1871 int64_t Val = CE->getValue();
1872 return (Val == std::numeric_limits<int32_t>::min()) ||
1873 (Val > -256 && Val < 256);
1874 }
1875 return false;
1876 }
1877
1878 template<unsigned Bits, unsigned RegClassID>
1879 bool isMemImm7ShiftedOffset() const {
1880 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1881 !getARMMCRegisterClass(RegClassID).contains(Memory.BaseRegNum))
1882 return false;
1883
1884 // Expect an immediate offset equal to an element of the range
1885 // [-127, 127], shifted left by Bits.
1886
1887 if (!Memory.OffsetImm) return true;
1888 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1889 int64_t Val = CE->getValue();
1890
1891 // INT32_MIN is a special-case value (indicating the encoding with
1892 // zero offset and the subtract bit set)
1893 if (Val == INT32_MIN)
1894 return true;
1895
1896 unsigned Divisor = 1U << Bits;
1897
1898 // Check that the low bits are zero
1899 if (Val % Divisor != 0)
1900 return false;
1901
1902 // Check that the remaining offset is within range.
1903 Val /= Divisor;
1904 return (Val >= -127 && Val <= 127);
1905 }
1906 return false;
1907 }
1908
1909 template <int shift> bool isMemRegRQOffset() const {
1910 if (!isMVEMem() || Memory.OffsetImm != nullptr || Memory.Alignment != 0)
1911 return false;
1912
1913 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1914 .contains(Memory.BaseRegNum))
1915 return false;
1916 if (!getARMMCRegisterClass(ARM::MQPRRegClassID)
1917 .contains(Memory.OffsetRegNum))
1918 return false;
1919
1920 if (shift == 0 && Memory.ShiftType != ARM_AM::no_shift)
1921 return false;
1922
1923 if (shift > 0 &&
1924 (Memory.ShiftType != ARM_AM::uxtw || Memory.ShiftImm != shift))
1925 return false;
1926
1927 return true;
1928 }
1929
1930 template <int shift> bool isMemRegQOffset() const {
1931 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1932 return false;
1933
1934 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Memory.BaseRegNum))
1935 return false;
1936
1937 if (!Memory.OffsetImm)
1938 return true;
1939 static_assert(shift < 56,
1940 "Such that we dont shift by a value higher than 62");
1941 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1942 int64_t Val = CE->getValue();
1943
1944 // The value must be a multiple of (1 << shift)
1945 if ((Val & ((1U << shift) - 1)) != 0)
1946 return false;
1947
1948 // And be in the right range, depending on the amount that it is shifted
1949 // by. Shift 0, is equal to 7 unsigned bits, the sign bit is set
1950 // separately.
1951 int64_t Range = (1U << (7 + shift)) - 1;
1952 return (Val == INT32_MIN) || (Val > -Range && Val < Range);
1953 }
1954 return false;
1955 }
1956
1957 bool isMemPosImm8Offset() const {
1958 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1959 return false;
1960 // Immediate offset in range [0, 255].
1961 if (!Memory.OffsetImm) return true;
1962 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1963 int64_t Val = CE->getValue();
1964 return Val >= 0 && Val < 256;
1965 }
1966 return false;
1967 }
1968
1969 bool isMemNegImm8Offset() const {
1970 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1971 return false;
1972 // Base reg of PC isn't allowed for these encodings.
1973 if (Memory.BaseRegNum == ARM::PC) return false;
1974 // Immediate offset in range [-255, -1].
1975 if (!Memory.OffsetImm) return false;
1976 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1977 int64_t Val = CE->getValue();
1978 return (Val == std::numeric_limits<int32_t>::min()) ||
1979 (Val > -256 && Val < 0);
1980 }
1981 return false;
1982 }
1983
1984 bool isMemUImm12Offset() const {
1985 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1986 return false;
1987 // Immediate offset in range [0, 4095].
1988 if (!Memory.OffsetImm) return true;
1989 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1990 int64_t Val = CE->getValue();
1991 return (Val >= 0 && Val < 4096);
1992 }
1993 return false;
1994 }
1995
1996 bool isMemImm12Offset() const {
1997 // If we have an immediate that's not a constant, treat it as a label
1998 // reference needing a fixup. If it is a constant, it's something else
1999 // and we reject it.
2000
2001 if (isImm() && !isa<MCConstantExpr>(getImm()))
2002 return true;
2003
2004 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2005 return false;
2006 // Immediate offset in range [-4095, 4095].
2007 if (!Memory.OffsetImm) return true;
2008 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
2009 int64_t Val = CE->getValue();
2010 return (Val > -4096 && Val < 4096) ||
2011 (Val == std::numeric_limits<int32_t>::min());
2012 }
2013 // If we have an immediate that's not a constant, treat it as a
2014 // symbolic expression needing a fixup.
2015 return true;
2016 }
2017
2018 bool isConstPoolAsmImm() const {
2019 // Delay processing of Constant Pool Immediate, this will turn into
2020 // a constant. Match no other operand
2021 return (isConstantPoolImm());
2022 }
2023
2024 bool isPostIdxImm8() const {
2025 if (!isImm()) return false;
2026 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2027 if (!CE) return false;
2028 int64_t Val = CE->getValue();
2029 return (Val > -256 && Val < 256) ||
2030 (Val == std::numeric_limits<int32_t>::min());
2031 }
2032
2033 bool isPostIdxImm8s4() const {
2034 if (!isImm()) return false;
2035 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2036 if (!CE) return false;
2037 int64_t Val = CE->getValue();
2038 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2039 (Val == std::numeric_limits<int32_t>::min());
2040 }
2041
2042 bool isMSRMask() const { return Kind == k_MSRMask; }
2043 bool isBankedReg() const { return Kind == k_BankedReg; }
2044 bool isProcIFlags() const { return Kind == k_ProcIFlags; }
2045
2046 // NEON operands.
2047 bool isAnyVectorList() const {
2048 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2049 Kind == k_VectorListIndexed;
2050 }
2051
2052 bool isVectorList() const { return Kind == k_VectorList; }
2053
2054 bool isSingleSpacedVectorList() const {
2055 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2056 }
2057
2058 bool isDoubleSpacedVectorList() const {
2059 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2060 }
2061
2062 bool isVecListOneD() const {
2063 // We convert a single D reg to a list containing a D reg
2064 if (isDReg() && !Parser->hasMVE())
2065 return true;
2066 if (!isSingleSpacedVectorList()) return false;
2067 return VectorList.Count == 1;
2068 }
2069
2070 bool isVecListTwoMQ() const {
2071 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2072 getARMMCRegisterClass(ARM::MQPRRegClassID)
2073 .contains(VectorList.RegNum);
2074 }
2075
2076 bool isVecListDPair() const {
2077 // We convert a single Q reg to a list with the two corresponding D
2078 // registers
2079 if (isQReg() && !Parser->hasMVE())
2080 return true;
2081 if (!isSingleSpacedVectorList()) return false;
2082 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2083 .contains(VectorList.RegNum));
2084 }
2085
2086 bool isVecListThreeD() const {
2087 if (!isSingleSpacedVectorList()) return false;
2088 return VectorList.Count == 3;
2089 }
2090
2091 bool isVecListFourD() const {
2092 if (!isSingleSpacedVectorList()) return false;
2093 return VectorList.Count == 4;
2094 }
2095
2096 bool isVecListDPairSpaced() const {
2097 if (Kind != k_VectorList) return false;
2098 if (isSingleSpacedVectorList()) return false;
2099 return (getARMMCRegisterClass(ARM::DPairSpcRegClassID)
2100 .contains(VectorList.RegNum));
2101 }
2102
2103 bool isVecListThreeQ() const {
2104 if (!isDoubleSpacedVectorList()) return false;
2105 return VectorList.Count == 3;
2106 }
2107
2108 bool isVecListFourQ() const {
2109 if (!isDoubleSpacedVectorList()) return false;
2110 return VectorList.Count == 4;
2111 }
2112
2113 bool isVecListFourMQ() const {
2114 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2115 getARMMCRegisterClass(ARM::MQPRRegClassID)
2116 .contains(VectorList.RegNum);
2117 }
2118
2119 bool isSingleSpacedVectorAllLanes() const {
2120 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2121 }
2122
2123 bool isDoubleSpacedVectorAllLanes() const {
2124 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2125 }
2126
2127 bool isVecListOneDAllLanes() const {
2128 if (!isSingleSpacedVectorAllLanes()) return false;
2129 return VectorList.Count == 1;
2130 }
2131
2132 bool isVecListDPairAllLanes() const {
2133 if (!isSingleSpacedVectorAllLanes()) return false;
2134 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2135 .contains(VectorList.RegNum));
2136 }
2137
2138 bool isVecListDPairSpacedAllLanes() const {
2139 if (!isDoubleSpacedVectorAllLanes()) return false;
2140 return VectorList.Count == 2;
2141 }
2142
2143 bool isVecListThreeDAllLanes() const {
2144 if (!isSingleSpacedVectorAllLanes()) return false;
2145 return VectorList.Count == 3;
2146 }
2147
2148 bool isVecListThreeQAllLanes() const {
2149 if (!isDoubleSpacedVectorAllLanes()) return false;
2150 return VectorList.Count == 3;
2151 }
2152
2153 bool isVecListFourDAllLanes() const {
2154 if (!isSingleSpacedVectorAllLanes()) return false;
2155 return VectorList.Count == 4;
2156 }
2157
2158 bool isVecListFourQAllLanes() const {
2159 if (!isDoubleSpacedVectorAllLanes()) return false;
2160 return VectorList.Count == 4;
2161 }
2162
2163 bool isSingleSpacedVectorIndexed() const {
2164 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2165 }
2166
2167 bool isDoubleSpacedVectorIndexed() const {
2168 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2169 }
2170
2171 bool isVecListOneDByteIndexed() const {
2172 if (!isSingleSpacedVectorIndexed()) return false;
2173 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2174 }
2175
2176 bool isVecListOneDHWordIndexed() const {
2177 if (!isSingleSpacedVectorIndexed()) return false;
2178 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2179 }
2180
2181 bool isVecListOneDWordIndexed() const {
2182 if (!isSingleSpacedVectorIndexed()) return false;
2183 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2184 }
2185
2186 bool isVecListTwoDByteIndexed() const {
2187 if (!isSingleSpacedVectorIndexed()) return false;
2188 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2189 }
2190
2191 bool isVecListTwoDHWordIndexed() const {
2192 if (!isSingleSpacedVectorIndexed()) return false;
2193 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2194 }
2195
2196 bool isVecListTwoQWordIndexed() const {
2197 if (!isDoubleSpacedVectorIndexed()) return false;
2198 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2199 }
2200
2201 bool isVecListTwoQHWordIndexed() const {
2202 if (!isDoubleSpacedVectorIndexed()) return false;
2203 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2204 }
2205
2206 bool isVecListTwoDWordIndexed() const {
2207 if (!isSingleSpacedVectorIndexed()) return false;
2208 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2209 }
2210
2211 bool isVecListThreeDByteIndexed() const {
2212 if (!isSingleSpacedVectorIndexed()) return false;
2213 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2214 }
2215
2216 bool isVecListThreeDHWordIndexed() const {
2217 if (!isSingleSpacedVectorIndexed()) return false;
2218 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2219 }
2220
2221 bool isVecListThreeQWordIndexed() const {
2222 if (!isDoubleSpacedVectorIndexed()) return false;
2223 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2224 }
2225
2226 bool isVecListThreeQHWordIndexed() const {
2227 if (!isDoubleSpacedVectorIndexed()) return false;
2228 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2229 }
2230
2231 bool isVecListThreeDWordIndexed() const {
2232 if (!isSingleSpacedVectorIndexed()) return false;
2233 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2234 }
2235
2236 bool isVecListFourDByteIndexed() const {
2237 if (!isSingleSpacedVectorIndexed()) return false;
2238 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2239 }
2240
2241 bool isVecListFourDHWordIndexed() const {
2242 if (!isSingleSpacedVectorIndexed()) return false;
2243 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2244 }
2245
2246 bool isVecListFourQWordIndexed() const {
2247 if (!isDoubleSpacedVectorIndexed()) return false;
2248 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2249 }
2250
2251 bool isVecListFourQHWordIndexed() const {
2252 if (!isDoubleSpacedVectorIndexed()) return false;
2253 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2254 }
2255
2256 bool isVecListFourDWordIndexed() const {
2257 if (!isSingleSpacedVectorIndexed()) return false;
2258 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2259 }
2260
2261 bool isVectorIndex() const { return Kind == k_VectorIndex; }
2262
2263 template <unsigned NumLanes>
2264 bool isVectorIndexInRange() const {
2265 if (Kind != k_VectorIndex) return false;
2266 return VectorIndex.Val < NumLanes;
2267 }
2268
2269 bool isVectorIndex8() const { return isVectorIndexInRange<8>(); }
2270 bool isVectorIndex16() const { return isVectorIndexInRange<4>(); }
2271 bool isVectorIndex32() const { return isVectorIndexInRange<2>(); }
2272 bool isVectorIndex64() const { return isVectorIndexInRange<1>(); }
2273
2274 template<int PermittedValue, int OtherPermittedValue>
2275 bool isMVEPairVectorIndex() const {
2276 if (Kind != k_VectorIndex) return false;
2277 return VectorIndex.Val == PermittedValue ||
2278 VectorIndex.Val == OtherPermittedValue;
2279 }
2280
2281 bool isNEONi8splat() const {
2282 if (!isImm()) return false;
2283 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2284 // Must be a constant.
2285 if (!CE) return false;
2286 int64_t Value = CE->getValue();
2287 // i8 value splatted across 8 bytes. The immediate is just the 8 byte
2288 // value.
2289 return Value >= 0 && Value < 256;
2290 }
2291
2292 bool isNEONi16splat() const {
2293 if (isNEONByteReplicate(2))
2294 return false; // Leave that for bytes replication and forbid by default.
2295 if (!isImm())
2296 return false;
2297 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2298 // Must be a constant.
2299 if (!CE) return false;
2300 unsigned Value = CE->getValue();
2302 }
2303
2304 bool isNEONi16splatNot() const {
2305 if (!isImm())
2306 return false;
2307 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2308 // Must be a constant.
2309 if (!CE) return false;
2310 unsigned Value = CE->getValue();
2311 return ARM_AM::isNEONi16splat(~Value & 0xffff);
2312 }
2313
2314 bool isNEONi32splat() const {
2315 if (isNEONByteReplicate(4))
2316 return false; // Leave that for bytes replication and forbid by default.
2317 if (!isImm())
2318 return false;
2319 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2320 // Must be a constant.
2321 if (!CE) return false;
2322 unsigned Value = CE->getValue();
2324 }
2325
2326 bool isNEONi32splatNot() const {
2327 if (!isImm())
2328 return false;
2329 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2330 // Must be a constant.
2331 if (!CE) return false;
2332 unsigned Value = CE->getValue();
2334 }
2335
2336 static bool isValidNEONi32vmovImm(int64_t Value) {
2337 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
2338 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
2339 return ((Value & 0xffffffffffffff00) == 0) ||
2340 ((Value & 0xffffffffffff00ff) == 0) ||
2341 ((Value & 0xffffffffff00ffff) == 0) ||
2342 ((Value & 0xffffffff00ffffff) == 0) ||
2343 ((Value & 0xffffffffffff00ff) == 0xff) ||
2344 ((Value & 0xffffffffff00ffff) == 0xffff);
2345 }
2346
2347 bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const {
2348 assert((Width == 8 || Width == 16 || Width == 32) &&
2349 "Invalid element width");
2350 assert(NumElems * Width <= 64 && "Invalid result width");
2351
2352 if (!isImm())
2353 return false;
2354 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2355 // Must be a constant.
2356 if (!CE)
2357 return false;
2358 int64_t Value = CE->getValue();
2359 if (!Value)
2360 return false; // Don't bother with zero.
2361 if (Inv)
2362 Value = ~Value;
2363
2364 uint64_t Mask = (1ull << Width) - 1;
2365 uint64_t Elem = Value & Mask;
2366 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2367 return false;
2368 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2369 return false;
2370
2371 for (unsigned i = 1; i < NumElems; ++i) {
2372 Value >>= Width;
2373 if ((Value & Mask) != Elem)
2374 return false;
2375 }
2376 return true;
2377 }
2378
2379 bool isNEONByteReplicate(unsigned NumBytes) const {
2380 return isNEONReplicate(8, NumBytes, false);
2381 }
2382
2383 static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
2384 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2385 "Invalid source width");
2386 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2387 "Invalid destination width");
2388 assert(FromW < ToW && "ToW is not less than FromW");
2389 }
2390
2391 template<unsigned FromW, unsigned ToW>
2392 bool isNEONmovReplicate() const {
2393 checkNeonReplicateArgs(FromW, ToW);
2394 if (ToW == 64 && isNEONi64splat())
2395 return false;
2396 return isNEONReplicate(FromW, ToW / FromW, false);
2397 }
2398
2399 template<unsigned FromW, unsigned ToW>
2400 bool isNEONinvReplicate() const {
2401 checkNeonReplicateArgs(FromW, ToW);
2402 return isNEONReplicate(FromW, ToW / FromW, true);
2403 }
2404
2405 bool isNEONi32vmov() const {
2406 if (isNEONByteReplicate(4))
2407 return false; // Let it to be classified as byte-replicate case.
2408 if (!isImm())
2409 return false;
2410 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2411 // Must be a constant.
2412 if (!CE)
2413 return false;
2414 return isValidNEONi32vmovImm(CE->getValue());
2415 }
2416
2417 bool isNEONi32vmovNeg() const {
2418 if (!isImm()) return false;
2419 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2420 // Must be a constant.
2421 if (!CE) return false;
2422 return isValidNEONi32vmovImm(~CE->getValue());
2423 }
2424
2425 bool isNEONi64splat() const {
2426 if (!isImm()) return false;
2427 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2428 // Must be a constant.
2429 if (!CE) return false;
2430 uint64_t Value = CE->getValue();
2431 // i64 value with each byte being either 0 or 0xff.
2432 for (unsigned i = 0; i < 8; ++i, Value >>= 8)
2433 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
2434 return true;
2435 }
2436
2437 template<int64_t Angle, int64_t Remainder>
2438 bool isComplexRotation() const {
2439 if (!isImm()) return false;
2440
2441 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2442 if (!CE) return false;
2443 uint64_t Value = CE->getValue();
2444
2445 return (Value % Angle == Remainder && Value <= 270);
2446 }
2447
2448 bool isMVELongShift() const {
2449 if (!isImm()) return false;
2450 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2451 // Must be a constant.
2452 if (!CE) return false;
2453 uint64_t Value = CE->getValue();
2454 return Value >= 1 && Value <= 32;
2455 }
2456
2457 bool isMveSaturateOp() const {
2458 if (!isImm()) return false;
2459 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2460 if (!CE) return false;
2461 uint64_t Value = CE->getValue();
2462 return Value == 48 || Value == 64;
2463 }
2464
2465 bool isITCondCodeNoAL() const {
2466 if (!isITCondCode()) return false;
2468 return CC != ARMCC::AL;
2469 }
2470
2471 bool isITCondCodeRestrictedI() const {
2472 if (!isITCondCode())
2473 return false;
2475 return CC == ARMCC::EQ || CC == ARMCC::NE;
2476 }
2477
2478 bool isITCondCodeRestrictedS() const {
2479 if (!isITCondCode())
2480 return false;
2482 return CC == ARMCC::LT || CC == ARMCC::GT || CC == ARMCC::LE ||
2483 CC == ARMCC::GE;
2484 }
2485
2486 bool isITCondCodeRestrictedU() const {
2487 if (!isITCondCode())
2488 return false;
2490 return CC == ARMCC::HS || CC == ARMCC::HI;
2491 }
2492
2493 bool isITCondCodeRestrictedFP() const {
2494 if (!isITCondCode())
2495 return false;
2497 return CC == ARMCC::EQ || CC == ARMCC::NE || CC == ARMCC::LT ||
2498 CC == ARMCC::GT || CC == ARMCC::LE || CC == ARMCC::GE;
2499 }
2500
2501 void setVecListDPair(unsigned int DPair) {
2502 Kind = k_VectorList;
2503 VectorList.RegNum = DPair;
2504 VectorList.Count = 2;
2505 VectorList.isDoubleSpaced = false;
2506 }
2507
2508 void setVecListOneD(unsigned int DReg) {
2509 Kind = k_VectorList;
2510 VectorList.RegNum = DReg;
2511 VectorList.Count = 1;
2512 VectorList.isDoubleSpaced = false;
2513 }
2514
2515 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2516 // Add as immediates when possible. Null MCExpr = 0.
2517 if (!Expr)
2519 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2520 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2521 else
2523 }
2524
2525 void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const {
2526 assert(N == 1 && "Invalid number of operands!");
2527 addExpr(Inst, getImm());
2528 }
2529
2530 void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const {
2531 assert(N == 1 && "Invalid number of operands!");
2532 addExpr(Inst, getImm());
2533 }
2534
2535 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
2536 assert(N == 2 && "Invalid number of operands!");
2537 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2538 unsigned RegNum = getCondCode() == ARMCC::AL ? ARM::NoRegister : ARM::CPSR;
2539 Inst.addOperand(MCOperand::createReg(RegNum));
2540 }
2541
2542 void addVPTPredNOperands(MCInst &Inst, unsigned N) const {
2543 assert(N == 3 && "Invalid number of operands!");
2544 Inst.addOperand(MCOperand::createImm(unsigned(getVPTPred())));
2545 unsigned RegNum = getVPTPred() == ARMVCC::None ? ARM::NoRegister : ARM::P0;
2546 Inst.addOperand(MCOperand::createReg(RegNum));
2548 }
2549
2550 void addVPTPredROperands(MCInst &Inst, unsigned N) const {
2551 assert(N == 4 && "Invalid number of operands!");
2552 addVPTPredNOperands(Inst, N-1);
2553 MCRegister RegNum;
2554 if (getVPTPred() == ARMVCC::None) {
2555 RegNum = ARM::NoRegister;
2556 } else {
2557 unsigned NextOpIndex = Inst.getNumOperands();
2558 auto &MCID = Parser->getInstrDesc(Inst.getOpcode());
2559 int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO);
2560 assert(TiedOp >= 0 &&
2561 "Inactive register in vpred_r is not tied to an output!");
2562 RegNum = Inst.getOperand(TiedOp).getReg();
2563 }
2564 Inst.addOperand(MCOperand::createReg(RegNum));
2565 }
2566
2567 void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
2568 assert(N == 1 && "Invalid number of operands!");
2569 Inst.addOperand(MCOperand::createImm(getCoproc()));
2570 }
2571
2572 void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
2573 assert(N == 1 && "Invalid number of operands!");
2574 Inst.addOperand(MCOperand::createImm(getCoproc()));
2575 }
2576
2577 void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
2578 assert(N == 1 && "Invalid number of operands!");
2579 Inst.addOperand(MCOperand::createImm(CoprocOption.Val));
2580 }
2581
2582 void addITMaskOperands(MCInst &Inst, unsigned N) const {
2583 assert(N == 1 && "Invalid number of operands!");
2584 Inst.addOperand(MCOperand::createImm(ITMask.Mask));
2585 }
2586
2587 void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
2588 assert(N == 1 && "Invalid number of operands!");
2589 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2590 }
2591
2592 void addITCondCodeInvOperands(MCInst &Inst, unsigned N) const {
2593 assert(N == 1 && "Invalid number of operands!");
2595 }
2596
2597 void addCCOutOperands(MCInst &Inst, unsigned N) const {
2598 assert(N == 1 && "Invalid number of operands!");
2600 }
2601
2602 void addRegOperands(MCInst &Inst, unsigned N) const {
2603 assert(N == 1 && "Invalid number of operands!");
2605 }
2606
2607 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
2608 assert(N == 3 && "Invalid number of operands!");
2609 assert(isRegShiftedReg() &&
2610 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2611 Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg));
2612 Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg));
2614 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
2615 }
2616
2617 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
2618 assert(N == 2 && "Invalid number of operands!");
2619 assert(isRegShiftedImm() &&
2620 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2621 Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg));
2622 // Shift of #32 is encoded as 0 where permitted
2623 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2625 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
2626 }
2627
2628 void addShifterImmOperands(MCInst &Inst, unsigned N) const {
2629 assert(N == 1 && "Invalid number of operands!");
2630 Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) |
2631 ShifterImm.Imm));
2632 }
2633
2634 void addRegListOperands(MCInst &Inst, unsigned N) const {
2635 assert(N == 1 && "Invalid number of operands!");
2636 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2637 for (MCRegister Reg : RegList)
2639 }
2640
2641 void addRegListWithAPSROperands(MCInst &Inst, unsigned N) const {
2642 assert(N == 1 && "Invalid number of operands!");
2643 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2644 for (MCRegister Reg : RegList)
2646 }
2647
2648 void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
2649 addRegListOperands(Inst, N);
2650 }
2651
2652 void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
2653 addRegListOperands(Inst, N);
2654 }
2655
2656 void addFPSRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2657 addRegListOperands(Inst, N);
2658 }
2659
2660 void addFPDRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2661 addRegListOperands(Inst, N);
2662 }
2663
2664 void addRotImmOperands(MCInst &Inst, unsigned N) const {
2665 assert(N == 1 && "Invalid number of operands!");
2666 // Encoded as val>>3. The printer handles display as 8, 16, 24.
2667 Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3));
2668 }
2669
2670 void addModImmOperands(MCInst &Inst, unsigned N) const {
2671 assert(N == 1 && "Invalid number of operands!");
2672
2673 // Support for fixups (MCFixup)
2674 if (isImm())
2675 return addImmOperands(Inst, N);
2676
2677 Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7)));
2678 }
2679
2680 void addModImmNotOperands(MCInst &Inst, unsigned N) const {
2681 assert(N == 1 && "Invalid number of operands!");
2682 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2683 uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue());
2685 }
2686
2687 void addModImmNegOperands(MCInst &Inst, unsigned N) const {
2688 assert(N == 1 && "Invalid number of operands!");
2689 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2690 uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue());
2692 }
2693
2694 void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const {
2695 assert(N == 1 && "Invalid number of operands!");
2696 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2697 uint32_t Val = -CE->getValue();
2699 }
2700
2701 void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const {
2702 assert(N == 1 && "Invalid number of operands!");
2703 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2704 uint32_t Val = -CE->getValue();
2706 }
2707
2708 void addBitfieldOperands(MCInst &Inst, unsigned N) const {
2709 assert(N == 1 && "Invalid number of operands!");
2710 // Munge the lsb/width into a bitfield mask.
2711 unsigned lsb = Bitfield.LSB;
2712 unsigned width = Bitfield.Width;
2713 // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
2714 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2715 (32 - (lsb + width)));
2716 Inst.addOperand(MCOperand::createImm(Mask));
2717 }
2718
2719 void addImmOperands(MCInst &Inst, unsigned N) const {
2720 assert(N == 1 && "Invalid number of operands!");
2721 addExpr(Inst, getImm());
2722 }
2723
2724 void addFBits16Operands(MCInst &Inst, unsigned N) const {
2725 assert(N == 1 && "Invalid number of operands!");
2726 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2727 Inst.addOperand(MCOperand::createImm(16 - CE->getValue()));
2728 }
2729
2730 void addFBits32Operands(MCInst &Inst, unsigned N) const {
2731 assert(N == 1 && "Invalid number of operands!");
2732 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2733 Inst.addOperand(MCOperand::createImm(32 - CE->getValue()));
2734 }
2735
2736 void addFPImmOperands(MCInst &Inst, unsigned N) const {
2737 assert(N == 1 && "Invalid number of operands!");
2738 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2739 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
2741 }
2742
2743 void addImm8s4Operands(MCInst &Inst, unsigned N) const {
2744 assert(N == 1 && "Invalid number of operands!");
2745 // FIXME: We really want to scale the value here, but the LDRD/STRD
2746 // instruction don't encode operands that way yet.
2747 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2748 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2749 }
2750
2751 void addImm7s4Operands(MCInst &Inst, unsigned N) const {
2752 assert(N == 1 && "Invalid number of operands!");
2753 // FIXME: We really want to scale the value here, but the VSTR/VLDR_VSYSR
2754 // instruction don't encode operands that way yet.
2755 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2756 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2757 }
2758
2759 void addImm7Shift0Operands(MCInst &Inst, unsigned N) const {
2760 assert(N == 1 && "Invalid number of operands!");
2761 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2762 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2763 }
2764
2765 void addImm7Shift1Operands(MCInst &Inst, unsigned N) const {
2766 assert(N == 1 && "Invalid number of operands!");
2767 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2768 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2769 }
2770
2771 void addImm7Shift2Operands(MCInst &Inst, unsigned N) const {
2772 assert(N == 1 && "Invalid number of operands!");
2773 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2774 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2775 }
2776
2777 void addImm7Operands(MCInst &Inst, unsigned N) const {
2778 assert(N == 1 && "Invalid number of operands!");
2779 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2780 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2781 }
2782
2783 void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
2784 assert(N == 1 && "Invalid number of operands!");
2785 // The immediate is scaled by four in the encoding and is stored
2786 // in the MCInst as such. Lop off the low two bits here.
2787 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2788 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2789 }
2790
2791 void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
2792 assert(N == 1 && "Invalid number of operands!");
2793 // The immediate is scaled by four in the encoding and is stored
2794 // in the MCInst as such. Lop off the low two bits here.
2795 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2796 Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4)));
2797 }
2798
2799 void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
2800 assert(N == 1 && "Invalid number of operands!");
2801 // The immediate is scaled by four in the encoding and is stored
2802 // in the MCInst as such. Lop off the low two bits here.
2803 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2804 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2805 }
2806
2807 void addImm1_16Operands(MCInst &Inst, unsigned N) const {
2808 assert(N == 1 && "Invalid number of operands!");
2809 // The constant encodes as the immediate-1, and we store in the instruction
2810 // the bits as encoded, so subtract off one here.
2811 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2812 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2813 }
2814
2815 void addImm1_32Operands(MCInst &Inst, unsigned N) const {
2816 assert(N == 1 && "Invalid number of operands!");
2817 // The constant encodes as the immediate-1, and we store in the instruction
2818 // the bits as encoded, so subtract off one here.
2819 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2820 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2821 }
2822
2823 void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
2824 assert(N == 1 && "Invalid number of operands!");
2825 // The constant encodes as the immediate, except for 32, which encodes as
2826 // zero.
2827 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2828 unsigned Imm = CE->getValue();
2829 Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm)));
2830 }
2831
2832 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
2833 assert(N == 1 && "Invalid number of operands!");
2834 // An ASR value of 32 encodes as 0, so that's how we want to add it to
2835 // the instruction as well.
2836 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2837 int Val = CE->getValue();
2838 Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val));
2839 }
2840
2841 void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
2842 assert(N == 1 && "Invalid number of operands!");
2843 // The operand is actually a t2_so_imm, but we have its bitwise
2844 // negation in the assembly source, so twiddle it here.
2845 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2846 Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue()));
2847 }
2848
2849 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
2850 assert(N == 1 && "Invalid number of operands!");
2851 // The operand is actually a t2_so_imm, but we have its
2852 // negation in the assembly source, so twiddle it here.
2853 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2854 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2855 }
2856
2857 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
2858 assert(N == 1 && "Invalid number of operands!");
2859 // The operand is actually an imm0_4095, but we have its
2860 // negation in the assembly source, so twiddle it here.
2861 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2862 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2863 }
2864
2865 void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
2866 if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2867 Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2));
2868 return;
2869 }
2870 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2872 }
2873
2874 void addThumbMemPCOperands(MCInst &Inst, unsigned N) const {
2875 assert(N == 1 && "Invalid number of operands!");
2876 if (isImm()) {
2877 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2878 if (CE) {
2879 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2880 return;
2881 }
2882 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2884 return;
2885 }
2886
2887 assert(isGPRMem() && "Unknown value type!");
2888 assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!");
2889 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
2890 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2891 else
2892 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
2893 }
2894
2895 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
2896 assert(N == 1 && "Invalid number of operands!");
2897 Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt())));
2898 }
2899
2900 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2901 assert(N == 1 && "Invalid number of operands!");
2902 Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
2903 }
2904
2905 void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2906 assert(N == 1 && "Invalid number of operands!");
2907 Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt())));
2908 }
2909
2910 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
2911 assert(N == 1 && "Invalid number of operands!");
2912 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2913 }
2914
2915 void addMemNoOffsetT2Operands(MCInst &Inst, unsigned N) const {
2916 assert(N == 1 && "Invalid number of operands!");
2917 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2918 }
2919
2920 void addMemNoOffsetT2NoSpOperands(MCInst &Inst, unsigned N) const {
2921 assert(N == 1 && "Invalid number of operands!");
2922 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2923 }
2924
2925 void addMemNoOffsetTOperands(MCInst &Inst, unsigned N) const {
2926 assert(N == 1 && "Invalid number of operands!");
2927 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2928 }
2929
2930 void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
2931 assert(N == 1 && "Invalid number of operands!");
2932 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
2933 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2934 else
2935 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
2936 }
2937
2938 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
2939 assert(N == 1 && "Invalid number of operands!");
2940 assert(isImm() && "Not an immediate!");
2941
2942 // If we have an immediate that's not a constant, treat it as a label
2943 // reference needing a fixup.
2944 if (!isa<MCConstantExpr>(getImm())) {
2946 return;
2947 }
2948
2949 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2950 int Val = CE->getValue();
2952 }
2953
2954 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
2955 assert(N == 2 && "Invalid number of operands!");
2956 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2957 Inst.addOperand(MCOperand::createImm(Memory.Alignment));
2958 }
2959
2960 void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2961 addAlignedMemoryOperands(Inst, N);
2962 }
2963
2964 void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2965 addAlignedMemoryOperands(Inst, N);
2966 }
2967
2968 void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2969 addAlignedMemoryOperands(Inst, N);
2970 }
2971
2972 void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2973 addAlignedMemoryOperands(Inst, N);
2974 }
2975
2976 void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2977 addAlignedMemoryOperands(Inst, N);
2978 }
2979
2980 void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2981 addAlignedMemoryOperands(Inst, N);
2982 }
2983
2984 void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2985 addAlignedMemoryOperands(Inst, N);
2986 }
2987
2988 void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2989 addAlignedMemoryOperands(Inst, N);
2990 }
2991
2992 void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2993 addAlignedMemoryOperands(Inst, N);
2994 }
2995
2996 void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2997 addAlignedMemoryOperands(Inst, N);
2998 }
2999
3000 void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const {
3001 addAlignedMemoryOperands(Inst, N);
3002 }
3003
3004 void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
3005 assert(N == 3 && "Invalid number of operands!");
3006 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3007 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3008 if (!Memory.OffsetRegNum) {
3009 if (!Memory.OffsetImm)
3011 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3012 int32_t Val = CE->getValue();
3014 // Special case for #-0
3015 if (Val == std::numeric_limits<int32_t>::min())
3016 Val = 0;
3017 if (Val < 0)
3018 Val = -Val;
3019 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
3021 } else
3022 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3023 } else {
3024 // For register offset, we encode the shift type and negation flag
3025 // here.
3026 int32_t Val =
3027 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3028 Memory.ShiftImm, Memory.ShiftType);
3030 }
3031 }
3032
3033 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
3034 assert(N == 2 && "Invalid number of operands!");
3035 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3036 assert(CE && "non-constant AM2OffsetImm operand!");
3037 int32_t Val = CE->getValue();
3039 // Special case for #-0
3040 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3041 if (Val < 0) Val = -Val;
3042 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
3045 }
3046
3047 void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
3048 assert(N == 3 && "Invalid number of operands!");
3049 // If we have an immediate that's not a constant, treat it as a label
3050 // reference needing a fixup. If it is a constant, it's something else
3051 // and we reject it.
3052 if (isImm()) {
3056 return;
3057 }
3058
3059 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3060 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3061 if (!Memory.OffsetRegNum) {
3062 if (!Memory.OffsetImm)
3064 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3065 int32_t Val = CE->getValue();
3067 // Special case for #-0
3068 if (Val == std::numeric_limits<int32_t>::min())
3069 Val = 0;
3070 if (Val < 0)
3071 Val = -Val;
3072 Val = ARM_AM::getAM3Opc(AddSub, Val);
3074 } else
3075 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3076 } else {
3077 // For register offset, we encode the shift type and negation flag
3078 // here.
3079 int32_t Val =
3080 ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
3082 }
3083 }
3084
3085 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
3086 assert(N == 2 && "Invalid number of operands!");
3087 if (Kind == k_PostIndexRegister) {
3088 int32_t Val =
3089 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
3090 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3092 return;
3093 }
3094
3095 // Constant offset.
3096 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
3097 int32_t Val = CE->getValue();
3099 // Special case for #-0
3100 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3101 if (Val < 0) Val = -Val;
3102 Val = ARM_AM::getAM3Opc(AddSub, Val);
3105 }
3106
3107 void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
3108 assert(N == 2 && "Invalid number of operands!");
3109 // If we have an immediate that's not a constant, treat it as a label
3110 // reference needing a fixup. If it is a constant, it's something else
3111 // and we reject it.
3112 if (isImm()) {
3115 return;
3116 }
3117
3118 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3119 if (!Memory.OffsetImm)
3121 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3122 // The lower two bits are always zero and as such are not encoded.
3123 int32_t Val = CE->getValue() / 4;
3125 // Special case for #-0
3126 if (Val == std::numeric_limits<int32_t>::min())
3127 Val = 0;
3128 if (Val < 0)
3129 Val = -Val;
3130 Val = ARM_AM::getAM5Opc(AddSub, Val);
3132 } else
3133 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3134 }
3135
3136 void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const {
3137 assert(N == 2 && "Invalid number of operands!");
3138 // If we have an immediate that's not a constant, treat it as a label
3139 // reference needing a fixup. If it is a constant, it's something else
3140 // and we reject it.
3141 if (isImm()) {
3144 return;
3145 }
3146
3147 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3148 // The lower bit is always zero and as such is not encoded.
3149 if (!Memory.OffsetImm)
3151 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3152 int32_t Val = CE->getValue() / 2;
3154 // Special case for #-0
3155 if (Val == std::numeric_limits<int32_t>::min())
3156 Val = 0;
3157 if (Val < 0)
3158 Val = -Val;
3159 Val = ARM_AM::getAM5FP16Opc(AddSub, Val);
3161 } else
3162 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3163 }
3164
3165 void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
3166 assert(N == 2 && "Invalid number of operands!");
3167 // If we have an immediate that's not a constant, treat it as a label
3168 // reference needing a fixup. If it is a constant, it's something else
3169 // and we reject it.
3170 if (isImm()) {
3173 return;
3174 }
3175
3176 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3177 addExpr(Inst, Memory.OffsetImm);
3178 }
3179
3180 void addMemImm7s4OffsetOperands(MCInst &Inst, unsigned N) const {
3181 assert(N == 2 && "Invalid number of operands!");
3182 // If we have an immediate that's not a constant, treat it as a label
3183 // reference needing a fixup. If it is a constant, it's something else
3184 // and we reject it.
3185 if (isImm()) {
3188 return;
3189 }
3190
3191 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3192 addExpr(Inst, Memory.OffsetImm);
3193 }
3194
3195 void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
3196 assert(N == 2 && "Invalid number of operands!");
3197 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3198 if (!Memory.OffsetImm)
3200 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3201 // The lower two bits are always zero and as such are not encoded.
3202 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3203 else
3204 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3205 }
3206
3207 void addMemImmOffsetOperands(MCInst &Inst, unsigned N) const {
3208 assert(N == 2 && "Invalid number of operands!");
3209 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3210 addExpr(Inst, Memory.OffsetImm);
3211 }
3212
3213 void addMemRegRQOffsetOperands(MCInst &Inst, unsigned N) const {
3214 assert(N == 2 && "Invalid number of operands!");
3215 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3216 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3217 }
3218
3219 void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3220 assert(N == 2 && "Invalid number of operands!");
3221 // If this is an immediate, it's a label reference.
3222 if (isImm()) {
3223 addExpr(Inst, getImm());
3225 return;
3226 }
3227
3228 // Otherwise, it's a normal memory reg+offset.
3229 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3230 addExpr(Inst, Memory.OffsetImm);
3231 }
3232
3233 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3234 assert(N == 2 && "Invalid number of operands!");
3235 // If this is an immediate, it's a label reference.
3236 if (isImm()) {
3237 addExpr(Inst, getImm());
3239 return;
3240 }
3241
3242 // Otherwise, it's a normal memory reg+offset.
3243 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3244 addExpr(Inst, Memory.OffsetImm);
3245 }
3246
3247 void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const {
3248 assert(N == 1 && "Invalid number of operands!");
3249 // This is container for the immediate that we will create the constant
3250 // pool from
3251 addExpr(Inst, getConstantPoolImm());
3252 }
3253
3254 void addMemTBBOperands(MCInst &Inst, unsigned N) const {
3255 assert(N == 2 && "Invalid number of operands!");
3256 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3257 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3258 }
3259
3260 void addMemTBHOperands(MCInst &Inst, unsigned N) const {
3261 assert(N == 2 && "Invalid number of operands!");
3262 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3263 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3264 }
3265
3266 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3267 assert(N == 3 && "Invalid number of operands!");
3268 unsigned Val =
3269 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3270 Memory.ShiftImm, Memory.ShiftType);
3271 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3272 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3274 }
3275
3276 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3277 assert(N == 3 && "Invalid number of operands!");
3278 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3279 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3280 Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
3281 }
3282
3283 void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
3284 assert(N == 2 && "Invalid number of operands!");
3285 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3286 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3287 }
3288
3289 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
3290 assert(N == 2 && "Invalid number of operands!");
3291 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3292 if (!Memory.OffsetImm)
3294 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3295 // The lower two bits are always zero and as such are not encoded.
3296 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3297 else
3298 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3299 }
3300
3301 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
3302 assert(N == 2 && "Invalid number of operands!");
3303 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3304 if (!Memory.OffsetImm)
3306 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3307 Inst.addOperand(MCOperand::createImm(CE->getValue() / 2));
3308 else
3309 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3310 }
3311
3312 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
3313 assert(N == 2 && "Invalid number of operands!");
3314 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3315 addExpr(Inst, Memory.OffsetImm);
3316 }
3317
3318 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
3319 assert(N == 2 && "Invalid number of operands!");
3320 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3321 if (!Memory.OffsetImm)
3323 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3324 // The lower two bits are always zero and as such are not encoded.
3325 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3326 else
3327 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3328 }
3329
3330 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
3331 assert(N == 1 && "Invalid number of operands!");
3332 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3333 assert(CE && "non-constant post-idx-imm8 operand!");
3334 int Imm = CE->getValue();
3335 bool isAdd = Imm >= 0;
3336 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3337 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
3339 }
3340
3341 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
3342 assert(N == 1 && "Invalid number of operands!");
3343 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3344 assert(CE && "non-constant post-idx-imm8s4 operand!");
3345 int Imm = CE->getValue();
3346 bool isAdd = Imm >= 0;
3347 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3348 // Immediate is scaled by 4.
3349 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
3351 }
3352
3353 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
3354 assert(N == 2 && "Invalid number of operands!");
3355 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3356 Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
3357 }
3358
3359 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
3360 assert(N == 2 && "Invalid number of operands!");
3361 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3362 // The sign, shift type, and shift amount are encoded in a single operand
3363 // using the AM2 encoding helpers.
3364 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
3365 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
3366 PostIdxReg.ShiftTy);
3368 }
3369
3370 void addPowerTwoOperands(MCInst &Inst, unsigned N) const {
3371 assert(N == 1 && "Invalid number of operands!");
3372 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3373 Inst.addOperand(MCOperand::createImm(CE->getValue()));
3374 }
3375
3376 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
3377 assert(N == 1 && "Invalid number of operands!");
3378 Inst.addOperand(MCOperand::createImm(getMSRMask()));
3379 }
3380
3381 void addBankedRegOperands(MCInst &Inst, unsigned N) const {
3382 assert(N == 1 && "Invalid number of operands!");
3383 Inst.addOperand(MCOperand::createImm(getBankedReg()));
3384 }
3385
3386 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
3387 assert(N == 1 && "Invalid number of operands!");
3388 Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
3389 }
3390
3391 void addVecListOperands(MCInst &Inst, unsigned N) const {
3392 assert(N == 1 && "Invalid number of operands!");
3393
3394 if (isAnyVectorList())
3395 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3396 else if (isDReg() && !Parser->hasMVE()) {
3397 Inst.addOperand(MCOperand::createReg(Reg.RegNum));
3398 } else if (isQReg() && !Parser->hasMVE()) {
3399 MCRegister DPair = Parser->getDRegFromQReg(Reg.RegNum);
3400 DPair = Parser->getMRI()->getMatchingSuperReg(
3401 DPair, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
3402 Inst.addOperand(MCOperand::createReg(DPair));
3403 } else {
3404 LLVM_DEBUG(dbgs() << "TYPE: " << Kind << "\n");
3406 "attempted to add a vector list register with wrong type!");
3407 }
3408 }
3409
3410 void addMVEVecListOperands(MCInst &Inst, unsigned N) const {
3411 assert(N == 1 && "Invalid number of operands!");
3412
3413 // When we come here, the VectorList field will identify a range
3414 // of q-registers by its base register and length, and it will
3415 // have already been error-checked to be the expected length of
3416 // range and contain only q-regs in the range q0-q7. So we can
3417 // count on the base register being in the range q0-q6 (for 2
3418 // regs) or q0-q4 (for 4)
3419 //
3420 // The MVE instructions taking a register range of this kind will
3421 // need an operand in the MQQPR or MQQQQPR class, representing the
3422 // entire range as a unit. So we must translate into that class,
3423 // by finding the index of the base register in the MQPR reg
3424 // class, and returning the super-register at the corresponding
3425 // index in the target class.
3426
3427 const MCRegisterClass *RC_in = &getARMMCRegisterClass(ARM::MQPRRegClassID);
3428 const MCRegisterClass *RC_out =
3429 (VectorList.Count == 2)
3430 ? &getARMMCRegisterClass(ARM::MQQPRRegClassID)
3431 : &getARMMCRegisterClass(ARM::MQQQQPRRegClassID);
3432
3433 unsigned I, E = RC_out->getNumRegs();
3434 for (I = 0; I < E; I++)
3435 if (RC_in->getRegister(I) == VectorList.RegNum)
3436 break;
3437 assert(I < E && "Invalid vector list start register!");
3438
3440 }
3441
3442 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
3443 assert(N == 2 && "Invalid number of operands!");
3444 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3445 Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
3446 }
3447
3448 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
3449 assert(N == 1 && "Invalid number of operands!");
3450 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3451 }
3452
3453 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
3454 assert(N == 1 && "Invalid number of operands!");
3455 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3456 }
3457
3458 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
3459 assert(N == 1 && "Invalid number of operands!");
3460 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3461 }
3462
3463 void addVectorIndex64Operands(MCInst &Inst, unsigned N) const {
3464 assert(N == 1 && "Invalid number of operands!");
3465 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3466 }
3467
3468 void addMVEVectorIndexOperands(MCInst &Inst, unsigned N) const {
3469 assert(N == 1 && "Invalid number of operands!");
3470 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3471 }
3472
3473 void addMVEPairVectorIndexOperands(MCInst &Inst, unsigned N) const {
3474 assert(N == 1 && "Invalid number of operands!");
3475 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3476 }
3477
3478 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
3479 assert(N == 1 && "Invalid number of operands!");
3480 // The immediate encodes the type of constant as well as the value.
3481 // Mask in that this is an i8 splat.
3482 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3483 Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
3484 }
3485
3486 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
3487 assert(N == 1 && "Invalid number of operands!");
3488 // The immediate encodes the type of constant as well as the value.
3489 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3490 unsigned Value = CE->getValue();
3493 }
3494
3495 void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
3496 assert(N == 1 && "Invalid number of operands!");
3497 // The immediate encodes the type of constant as well as the value.
3498 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3499 unsigned Value = CE->getValue();
3502 }
3503
3504 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
3505 assert(N == 1 && "Invalid number of operands!");
3506 // The immediate encodes the type of constant as well as the value.
3507 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3508 unsigned Value = CE->getValue();
3511 }
3512
3513 void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
3514 assert(N == 1 && "Invalid number of operands!");
3515 // The immediate encodes the type of constant as well as the value.
3516 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3517 unsigned Value = CE->getValue();
3520 }
3521
3522 void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
3523 // The immediate encodes the type of constant as well as the value.
3524 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3525 assert((Inst.getOpcode() == ARM::VMOVv8i8 ||
3526 Inst.getOpcode() == ARM::VMOVv16i8) &&
3527 "All instructions that wants to replicate non-zero byte "
3528 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3529 unsigned Value = CE->getValue();
3530 if (Inv)
3531 Value = ~Value;
3532 unsigned B = Value & 0xff;
3533 B |= 0xe00; // cmode = 0b1110
3535 }
3536
3537 void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3538 assert(N == 1 && "Invalid number of operands!");
3539 addNEONi8ReplicateOperands(Inst, true);
3540 }
3541
3542 static unsigned encodeNeonVMOVImmediate(unsigned Value) {
3543 if (Value >= 256 && Value <= 0xffff)
3544 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
3545 else if (Value > 0xffff && Value <= 0xffffff)
3546 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
3547 else if (Value > 0xffffff)
3548 Value = (Value >> 24) | 0x600;
3549 return Value;
3550 }
3551
3552 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
3553 assert(N == 1 && "Invalid number of operands!");
3554 // The immediate encodes the type of constant as well as the value.
3555 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3556 unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
3558 }
3559
3560 void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3561 assert(N == 1 && "Invalid number of operands!");
3562 addNEONi8ReplicateOperands(Inst, false);
3563 }
3564
3565 void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
3566 assert(N == 1 && "Invalid number of operands!");
3567 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3568 assert((Inst.getOpcode() == ARM::VMOVv4i16 ||
3569 Inst.getOpcode() == ARM::VMOVv8i16 ||
3570 Inst.getOpcode() == ARM::VMVNv4i16 ||
3571 Inst.getOpcode() == ARM::VMVNv8i16) &&
3572 "All instructions that want to replicate non-zero half-word "
3573 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3574 uint64_t Value = CE->getValue();
3575 unsigned Elem = Value & 0xffff;
3576 if (Elem >= 256)
3577 Elem = (Elem >> 8) | 0x200;
3578 Inst.addOperand(MCOperand::createImm(Elem));
3579 }
3580
3581 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
3582 assert(N == 1 && "Invalid number of operands!");
3583 // The immediate encodes the type of constant as well as the value.
3584 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3585 unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
3587 }
3588
3589 void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
3590 assert(N == 1 && "Invalid number of operands!");
3591 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3592 assert((Inst.getOpcode() == ARM::VMOVv2i32 ||
3593 Inst.getOpcode() == ARM::VMOVv4i32 ||
3594 Inst.getOpcode() == ARM::VMVNv2i32 ||
3595 Inst.getOpcode() == ARM::VMVNv4i32) &&
3596 "All instructions that want to replicate non-zero word "
3597 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3598 uint64_t Value = CE->getValue();
3599 unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
3600 Inst.addOperand(MCOperand::createImm(Elem));
3601 }
3602
3603 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
3604 assert(N == 1 && "Invalid number of operands!");
3605 // The immediate encodes the type of constant as well as the value.
3606 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3607 uint64_t Value = CE->getValue();
3608 unsigned Imm = 0;
3609 for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
3610 Imm |= (Value & 1) << i;
3611 }
3612 Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
3613 }
3614
3615 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
3616 assert(N == 1 && "Invalid number of operands!");
3617 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3618 Inst.addOperand(MCOperand::createImm(CE->getValue() / 90));
3619 }
3620
3621 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
3622 assert(N == 1 && "Invalid number of operands!");
3623 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3624 Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
3625 }
3626
3627 void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
3628 assert(N == 1 && "Invalid number of operands!");
3629 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3630 unsigned Imm = CE->getValue();
3631 assert((Imm == 48 || Imm == 64) && "Invalid saturate operand");
3632 Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0));
3633 }
3634
3635 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;
3636
3637 static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S,
3638 ARMAsmParser &Parser) {
3639 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3640 Op->ITMask.Mask = Mask;
3641 Op->StartLoc = S;
3642 Op->EndLoc = S;
3643 return Op;
3644 }
3645
3646 static std::unique_ptr<ARMOperand>
3647 CreateCondCode(ARMCC::CondCodes CC, SMLoc S, ARMAsmParser &Parser) {
3648 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3649 Op->CC.Val = CC;
3650 Op->StartLoc = S;
3651 Op->EndLoc = S;
3652 return Op;
3653 }
3654
3655 static std::unique_ptr<ARMOperand> CreateVPTPred(ARMVCC::VPTCodes CC, SMLoc S,
3656 ARMAsmParser &Parser) {
3657 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3658 Op->VCC.Val = CC;
3659 Op->StartLoc = S;
3660 Op->EndLoc = S;
3661 return Op;
3662 }
3663
3664 static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S,
3665 ARMAsmParser &Parser) {
3666 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3667 Op->Cop.Val = CopVal;
3668 Op->StartLoc = S;
3669 Op->EndLoc = S;
3670 return Op;
3671 }
3672
3673 static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S,
3674 ARMAsmParser &Parser) {
3675 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3676 Op->Cop.Val = CopVal;
3677 Op->StartLoc = S;
3678 Op->EndLoc = S;
3679 return Op;
3680 }
3681
3682 static std::unique_ptr<ARMOperand>
3683 CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3684 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3685 Op->Cop.Val = Val;
3686 Op->StartLoc = S;
3687 Op->EndLoc = E;
3688 return Op;
3689 }
3690
3691 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister Reg, SMLoc S,
3692 ARMAsmParser &Parser) {
3693 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3694 Op->Reg.RegNum = Reg;
3695 Op->StartLoc = S;
3696 Op->EndLoc = S;
3697 return Op;
3698 }
3699
3700 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3701 ARMAsmParser &Parser) {
3702 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3703 Op->Tok.Data = Str.data();
3704 Op->Tok.Length = Str.size();
3705 Op->StartLoc = S;
3706 Op->EndLoc = S;
3707 return Op;
3708 }
3709
3710 static std::unique_ptr<ARMOperand> CreateReg(MCRegister Reg, SMLoc S, SMLoc E,
3711 ARMAsmParser &Parser) {
3712 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3713 Op->Reg.RegNum = Reg;
3714 Op->StartLoc = S;
3715 Op->EndLoc = E;
3716 return Op;
3717 }
3718
3719 static std::unique_ptr<ARMOperand>
3720 CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, MCRegister SrcReg,
3721 MCRegister ShiftReg, unsigned ShiftImm, SMLoc S,
3722 SMLoc E, ARMAsmParser &Parser) {
3723 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3724 Op->RegShiftedReg.ShiftTy = ShTy;
3725 Op->RegShiftedReg.SrcReg = SrcReg;
3726 Op->RegShiftedReg.ShiftReg = ShiftReg;
3727 Op->RegShiftedReg.ShiftImm = ShiftImm;
3728 Op->StartLoc = S;
3729 Op->EndLoc = E;
3730 return Op;
3731 }
3732
3733 static std::unique_ptr<ARMOperand>
3734 CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, MCRegister SrcReg,
3735 unsigned ShiftImm, SMLoc S, SMLoc E,
3736 ARMAsmParser &Parser) {
3737 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3738 Op->RegShiftedImm.ShiftTy = ShTy;
3739 Op->RegShiftedImm.SrcReg = SrcReg;
3740 Op->RegShiftedImm.ShiftImm = ShiftImm;
3741 Op->StartLoc = S;
3742 Op->EndLoc = E;
3743 return Op;
3744 }
3745
3746 static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm,
3747 SMLoc S, SMLoc E,
3748 ARMAsmParser &Parser) {
3749 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3750 Op->ShifterImm.isASR = isASR;
3751 Op->ShifterImm.Imm = Imm;
3752 Op->StartLoc = S;
3753 Op->EndLoc = E;
3754 return Op;
3755 }
3756
3757 static std::unique_ptr<ARMOperand>
3758 CreateRotImm(unsigned Imm, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3759 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3760 Op->RotImm.Imm = Imm;
3761 Op->StartLoc = S;
3762 Op->EndLoc = E;
3763 return Op;
3764 }
3765
3766 static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
3767 SMLoc S, SMLoc E,
3768 ARMAsmParser &Parser) {
3769 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3770 Op->ModImm.Bits = Bits;
3771 Op->ModImm.Rot = Rot;
3772 Op->StartLoc = S;
3773 Op->EndLoc = E;
3774 return Op;
3775 }
3776
3777 static std::unique_ptr<ARMOperand>
3778 CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E,
3779 ARMAsmParser &Parser) {
3780 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3781 Op->Imm.Val = Val;
3782 Op->StartLoc = S;
3783 Op->EndLoc = E;
3784 return Op;
3785 }
3786
3787 static std::unique_ptr<ARMOperand> CreateBitfield(unsigned LSB,
3788 unsigned Width, SMLoc S,
3789 SMLoc E,
3790 ARMAsmParser &Parser) {
3791 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3792 Op->Bitfield.LSB = LSB;
3793 Op->Bitfield.Width = Width;
3794 Op->StartLoc = S;
3795 Op->EndLoc = E;
3796 return Op;
3797 }
3798
3799 static std::unique_ptr<ARMOperand>
3800 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3801 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3802 assert(Regs.size() > 0 && "RegList contains no registers?");
3803 KindTy Kind = k_RegisterList;
3804
3805 if (getARMMCRegisterClass(ARM::DPRRegClassID)
3806 .contains(Regs.front().second)) {
3807 if (Regs.back().second == ARM::VPR)
3808 Kind = k_FPDRegisterListWithVPR;
3809 else
3810 Kind = k_DPRRegisterList;
3811 } else if (getARMMCRegisterClass(ARM::SPRRegClassID)
3812 .contains(Regs.front().second)) {
3813 if (Regs.back().second == ARM::VPR)
3814 Kind = k_FPSRegisterListWithVPR;
3815 else
3816 Kind = k_SPRRegisterList;
3817 } else if (Regs.front().second == ARM::VPR) {
3818 assert(Regs.size() == 1 &&
3819 "Register list starting with VPR expected to only contain VPR");
3820 Kind = k_FPSRegisterListWithVPR;
3821 }
3822
3823 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3824 Kind = k_RegisterListWithAPSR;
3825
3826 assert(llvm::is_sorted(Regs) && "Register list must be sorted by encoding");
3827
3828 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3829 for (const auto &P : Regs)
3830 Op->Registers.push_back(P.second);
3831
3832 Op->StartLoc = StartLoc;
3833 Op->EndLoc = EndLoc;
3834 return Op;
3835 }
3836
3837 static std::unique_ptr<ARMOperand>
3838 CreateVectorList(MCRegister Reg, unsigned Count, bool isDoubleSpaced, SMLoc S,
3839 SMLoc E, ARMAsmParser &Parser) {
3840 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3841 Op->VectorList.RegNum = Reg;
3842 Op->VectorList.Count = Count;
3843 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3844 Op->StartLoc = S;
3845 Op->EndLoc = E;
3846 return Op;
3847 }
3848
3849 static std::unique_ptr<ARMOperand>
3850 CreateVectorListAllLanes(MCRegister Reg, unsigned Count, bool isDoubleSpaced,
3851 SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3852 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3853 Op->VectorList.RegNum = Reg;
3854 Op->VectorList.Count = Count;
3855 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3856 Op->StartLoc = S;
3857 Op->EndLoc = E;
3858 return Op;
3859 }
3860
3861 static std::unique_ptr<ARMOperand>
3862 CreateVectorListIndexed(MCRegister Reg, unsigned Count, unsigned Index,
3863 bool isDoubleSpaced, SMLoc S, SMLoc E,
3864 ARMAsmParser &Parser) {
3865 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3866 Op->VectorList.RegNum = Reg;
3867 Op->VectorList.Count = Count;
3868 Op->VectorList.LaneIndex = Index;
3869 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3870 Op->StartLoc = S;
3871 Op->EndLoc = E;
3872 return Op;
3873 }
3874
3875 static std::unique_ptr<ARMOperand> CreateVectorIndex(unsigned Idx, SMLoc S,
3876 SMLoc E, MCContext &Ctx,
3877 ARMAsmParser &Parser) {
3878 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3879 Op->VectorIndex.Val = Idx;
3880 Op->StartLoc = S;
3881 Op->EndLoc = E;
3882 return Op;
3883 }
3884
3885 static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S,
3886 SMLoc E, ARMAsmParser &Parser) {
3887 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3888 Op->Imm.Val = Val;
3889 Op->StartLoc = S;
3890 Op->EndLoc = E;
3891 return Op;
3892 }
3893
3894 static std::unique_ptr<ARMOperand>
3895 CreateMem(MCRegister BaseReg, const MCExpr *OffsetImm, MCRegister OffsetReg,
3896 ARM_AM::ShiftOpc ShiftType, unsigned ShiftImm, unsigned Alignment,
3897 bool isNegative, SMLoc S, SMLoc E, ARMAsmParser &Parser,
3898 SMLoc AlignmentLoc = SMLoc()) {
3899 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3900 Op->Memory.BaseRegNum = BaseReg;
3901 Op->Memory.OffsetImm = OffsetImm;
3902 Op->Memory.OffsetRegNum = OffsetReg;
3903 Op->Memory.ShiftType = ShiftType;
3904 Op->Memory.ShiftImm = ShiftImm;
3905 Op->Memory.Alignment = Alignment;
3906 Op->Memory.isNegative = isNegative;
3907 Op->StartLoc = S;
3908 Op->EndLoc = E;
3909 Op->AlignmentLoc = AlignmentLoc;
3910 return Op;
3911 }
3912
3913 static std::unique_ptr<ARMOperand>
3914 CreatePostIdxReg(MCRegister Reg, bool isAdd, ARM_AM::ShiftOpc ShiftTy,
3915 unsigned ShiftImm, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3916 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3917 Op->PostIdxReg.RegNum = Reg;
3918 Op->PostIdxReg.isAdd = isAdd;
3919 Op->PostIdxReg.ShiftTy = ShiftTy;
3920 Op->PostIdxReg.ShiftImm = ShiftImm;
3921 Op->StartLoc = S;
3922 Op->EndLoc = E;
3923 return Op;
3924 }
3925
3926 static std::unique_ptr<ARMOperand>
3927 CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3928 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3929 Op->MBOpt.Val = Opt;
3930 Op->StartLoc = S;
3931 Op->EndLoc = S;
3932 return Op;
3933 }
3934
3935 static std::unique_ptr<ARMOperand>
3936 CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S,
3937 ARMAsmParser &Parser) {
3938 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3939 Op->ISBOpt.Val = Opt;
3940 Op->StartLoc = S;
3941 Op->EndLoc = S;
3942 return Op;
3943 }
3944
3945 static std::unique_ptr<ARMOperand>
3946 CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S,
3947 ARMAsmParser &Parser) {
3948 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3949 Op->TSBOpt.Val = Opt;
3950 Op->StartLoc = S;
3951 Op->EndLoc = S;
3952 return Op;
3953 }
3954
3955 static std::unique_ptr<ARMOperand>
3956 CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S, ARMAsmParser &Parser) {
3957 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3958 Op->IFlags.Val = IFlags;
3959 Op->StartLoc = S;
3960 Op->EndLoc = S;
3961 return Op;
3962 }
3963
3964 static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S,
3965 ARMAsmParser &Parser) {
3966 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3967 Op->MMask.Val = MMask;
3968 Op->StartLoc = S;
3969 Op->EndLoc = S;
3970 return Op;
3971 }
3972
3973 static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S,
3974 ARMAsmParser &Parser) {
3975 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3976 Op->BankedReg.Val = Reg;
3977 Op->StartLoc = S;
3978 Op->EndLoc = S;
3979 return Op;
3980 }
3981};
3982
3983} // end anonymous namespace.
3984
3985void ARMOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
3986 auto RegName = [](MCRegister Reg) {
3987 if (Reg)
3989 else
3990 return "noreg";
3991 };
3992
3993 switch (Kind) {
3994 case k_CondCode:
3995 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
3996 break;
3997 case k_VPTPred:
3998 OS << "<ARMVCC::" << ARMVPTPredToString(getVPTPred()) << ">";
3999 break;
4000 case k_CCOut:
4001 OS << "<ccout " << RegName(getReg()) << ">";
4002 break;
4003 case k_ITCondMask: {
4004 static const char *const MaskStr[] = {
4005 "(invalid)", "(tttt)", "(ttt)", "(ttte)",
4006 "(tt)", "(ttet)", "(tte)", "(ttee)",
4007 "(t)", "(tett)", "(tet)", "(tete)",
4008 "(te)", "(teet)", "(tee)", "(teee)",
4009 };
4010 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4011 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
4012 break;
4013 }
4014 case k_CoprocNum:
4015 OS << "<coprocessor number: " << getCoproc() << ">";
4016 break;
4017 case k_CoprocReg:
4018 OS << "<coprocessor register: " << getCoproc() << ">";
4019 break;
4020 case k_CoprocOption:
4021 OS << "<coprocessor option: " << CoprocOption.Val << ">";
4022 break;
4023 case k_MSRMask:
4024 OS << "<mask: " << getMSRMask() << ">";
4025 break;
4026 case k_BankedReg:
4027 OS << "<banked reg: " << getBankedReg() << ">";
4028 break;
4029 case k_Immediate:
4030 MAI.printExpr(OS, *getImm());
4031 break;
4032 case k_MemBarrierOpt:
4033 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
4034 break;
4035 case k_InstSyncBarrierOpt:
4036 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
4037 break;
4038 case k_TraceSyncBarrierOpt:
4039 OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
4040 break;
4041 case k_Memory:
4042 OS << "<memory";
4043 if (Memory.BaseRegNum)
4044 OS << " base:" << RegName(Memory.BaseRegNum);
4045 if (Memory.OffsetImm) {
4046 OS << " offset-imm:";
4047 MAI.printExpr(OS, *Memory.OffsetImm);
4048 }
4049 if (Memory.OffsetRegNum)
4050 OS << " offset-reg:" << (Memory.isNegative ? "-" : "")
4051 << RegName(Memory.OffsetRegNum);
4052 if (Memory.ShiftType != ARM_AM::no_shift) {
4053 OS << " shift-type:" << ARM_AM::getShiftOpcStr(Memory.ShiftType);
4054 OS << " shift-imm:" << Memory.ShiftImm;
4055 }
4056 if (Memory.Alignment)
4057 OS << " alignment:" << Memory.Alignment;
4058 OS << ">";
4059 break;
4060 case k_PostIndexRegister:
4061 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
4062 << RegName(PostIdxReg.RegNum);
4063 if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
4064 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
4065 << PostIdxReg.ShiftImm;
4066 OS << ">";
4067 break;
4068 case k_ProcIFlags: {
4069 OS << "<ARM_PROC::";
4070 unsigned IFlags = getProcIFlags();
4071 for (int i=2; i >= 0; --i)
4072 if (IFlags & (1 << i))
4073 OS << ARM_PROC::IFlagsToString(1 << i);
4074 OS << ">";
4075 break;
4076 }
4077 case k_Register:
4078 OS << "<register " << RegName(getReg()) << ">";
4079 break;
4080 case k_ShifterImmediate:
4081 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
4082 << " #" << ShifterImm.Imm << ">";
4083 break;
4084 case k_ShiftedRegister:
4085 OS << "<so_reg_reg " << RegName(RegShiftedReg.SrcReg) << " "
4086 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) << " "
4087 << RegName(RegShiftedReg.ShiftReg) << ">";
4088 break;
4089 case k_ShiftedImmediate:
4090 OS << "<so_reg_imm " << RegName(RegShiftedImm.SrcReg) << " "
4091 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) << " #"
4092 << RegShiftedImm.ShiftImm << ">";
4093 break;
4094 case k_RotateImmediate:
4095 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
4096 break;
4097 case k_ModifiedImmediate:
4098 OS << "<mod_imm #" << ModImm.Bits << ", #"
4099 << ModImm.Rot << ")>";
4100 break;
4101 case k_ConstantPoolImmediate:
4102 OS << "<constant_pool_imm #";
4103 MAI.printExpr(OS, *getConstantPoolImm());
4104 break;
4105 case k_BitfieldDescriptor:
4106 OS << "<bitfield " << "lsb: " << Bitfield.LSB
4107 << ", width: " << Bitfield.Width << ">";
4108 break;
4109 case k_RegisterList:
4110 case k_RegisterListWithAPSR:
4111 case k_DPRRegisterList:
4112 case k_SPRRegisterList:
4113 case k_FPSRegisterListWithVPR:
4114 case k_FPDRegisterListWithVPR: {
4115 OS << "<register_list ";
4116
4117 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4118 for (auto I = RegList.begin(), E = RegList.end(); I != E;) {
4119 OS << RegName(*I);
4120 if (++I < E) OS << ", ";
4121 }
4122
4123 OS << ">";
4124 break;
4125 }
4126 case k_VectorList:
4127 OS << "<vector_list " << VectorList.Count << " * "
4128 << RegName(VectorList.RegNum) << ">";
4129 break;
4130 case k_VectorListAllLanes:
4131 OS << "<vector_list(all lanes) " << VectorList.Count << " * "
4132 << RegName(VectorList.RegNum) << ">";
4133 break;
4134 case k_VectorListIndexed:
4135 OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
4136 << VectorList.Count << " * " << RegName(VectorList.RegNum) << ">";
4137 break;
4138 case k_Token:
4139 OS << "'" << getToken() << "'";
4140 break;
4141 case k_VectorIndex:
4142 OS << "<vectorindex " << getVectorIndex() << ">";
4143 break;
4144 }
4145}
4146
4147/// @name Auto-generated Match Functions
4148/// {
4149
4151
4152/// }
4153
4154static bool isDataTypeToken(StringRef Tok) {
4155 static const DenseSet<StringRef> DataTypes{
4156 ".8", ".16", ".32", ".64", ".i8", ".i16", ".i32", ".i64",
4157 ".u8", ".u16", ".u32", ".u64", ".s8", ".s16", ".s32", ".s64",
4158 ".p8", ".p16", ".f32", ".f64", ".f", ".d"};
4159 return DataTypes.contains(Tok);
4160}
4161
4163 unsigned MnemonicOpsEndInd = 1;
4164 // Special case for CPS which has a Mnemonic side token for possibly storing
4165 // ie/id variant
4166 if (Operands[0]->isToken() &&
4167 static_cast<ARMOperand &>(*Operands[0]).getToken() == "cps") {
4168 if (Operands.size() > 1 && Operands[1]->isImm() &&
4169 static_cast<ARMOperand &>(*Operands[1]).getImm()->getKind() ==
4172 static_cast<ARMOperand &>(*Operands[1]).getImm())
4173 ->getValue() == ARM_PROC::IE ||
4175 static_cast<ARMOperand &>(*Operands[1]).getImm())
4176 ->getValue() == ARM_PROC::ID))
4177 ++MnemonicOpsEndInd;
4178 }
4179
4180 // In some circumstances the condition code moves to the right
4181 bool RHSCondCode = false;
4182 while (MnemonicOpsEndInd < Operands.size()) {
4183 auto Op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
4184 // Special case for it instructions which have a condition code on the RHS
4185 if (Op.isITMask()) {
4186 RHSCondCode = true;
4187 MnemonicOpsEndInd++;
4188 } else if (Op.isToken() &&
4189 (
4190 // There are several special cases not covered by
4191 // isDataTypeToken
4192 Op.getToken() == ".w" || Op.getToken() == ".bf16" ||
4193 Op.getToken() == ".p64" || Op.getToken() == ".f16" ||
4194 isDataTypeToken(Op.getToken()))) {
4195 // In the mnemonic operators the cond code must always precede the data
4196 // type. So we can now safely assume any subsequent cond code is on the
4197 // RHS. As is the case for VCMP and VPT.
4198 RHSCondCode = true;
4199 MnemonicOpsEndInd++;
4200 }
4201 // Skip all mnemonic operator types
4202 else if (Op.isCCOut() || (Op.isCondCode() && !RHSCondCode) ||
4203 Op.isVPTPred() || (Op.isToken() && Op.getToken() == ".w"))
4204 MnemonicOpsEndInd++;
4205 else
4206 break;
4207 }
4208 return MnemonicOpsEndInd;
4209}
4210
4211bool ARMAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
4212 SMLoc &EndLoc) {
4213 const AsmToken &Tok = getParser().getTok();
4214 StartLoc = Tok.getLoc();
4215 EndLoc = Tok.getEndLoc();
4216 Reg = tryParseRegister();
4217
4218 return !Reg;
4219}
4220
4221ParseStatus ARMAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
4222 SMLoc &EndLoc) {
4223 if (parseRegister(Reg, StartLoc, EndLoc))
4224 return ParseStatus::NoMatch;
4225 return ParseStatus::Success;
4226}
4227
4228/// Try to parse a register name. The token must be an Identifier when called,
4229/// and if it is a register name the token is eaten and the register is
4230/// returned. Otherwise return an invalid MCRegister.
4231MCRegister ARMAsmParser::tryParseRegister(bool AllowOutOfBoundReg) {
4232 MCAsmParser &Parser = getParser();
4233 const AsmToken &Tok = Parser.getTok();
4234 if (Tok.isNot(AsmToken::Identifier))
4235 return MCRegister();
4236
4237 std::string lowerCase = Tok.getString().lower();
4238 MCRegister Reg = MatchRegisterName(lowerCase);
4239 if (!Reg) {
4240 Reg = StringSwitch<MCRegister>(lowerCase)
4241 .Case("r13", ARM::SP)
4242 .Case("r14", ARM::LR)
4243 .Case("r15", ARM::PC)
4244 .Case("ip", ARM::R12)
4245 // Additional register name aliases for 'gas' compatibility.
4246 .Case("a1", ARM::R0)
4247 .Case("a2", ARM::R1)
4248 .Case("a3", ARM::R2)
4249 .Case("a4", ARM::R3)
4250 .Case("v1", ARM::R4)
4251 .Case("v2", ARM::R5)
4252 .Case("v3", ARM::R6)
4253 .Case("v4", ARM::R7)
4254 .Case("v5", ARM::R8)
4255 .Case("v6", ARM::R9)
4256 .Case("v7", ARM::R10)
4257 .Case("v8", ARM::R11)
4258 .Case("sb", ARM::R9)
4259 .Case("sl", ARM::R10)
4260 .Case("fp", ARM::R11)
4261 .Default(MCRegister());
4262 }
4263 if (!Reg) {
4264 // Check for aliases registered via .req. Canonicalize to lower case.
4265 // That's more consistent since register names are case insensitive, and
4266 // it's how the original entry was passed in from MC/MCParser/AsmParser.
4267 auto Entry = RegisterReqs.find(lowerCase);
4268 // If no match, return failure.
4269 if (Entry == RegisterReqs.end())
4270 return MCRegister();
4271 Parser.Lex(); // Eat identifier token.
4272 return Entry->getValue();
4273 }
4274
4275 // Some FPUs only have 16 D registers, so D16-D31 are invalid
4276 if (!AllowOutOfBoundReg && !hasD32() && Reg >= ARM::D16 && Reg <= ARM::D31)
4277 return MCRegister();
4278
4279 Parser.Lex(); // Eat identifier token.
4280
4281 return Reg;
4282}
4283
4284std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4285 MCAsmParser &Parser = getParser();
4286 const AsmToken &Tok = Parser.getTok();
4287 if (Tok.isNot(AsmToken::Identifier))
4288 return std::nullopt;
4289
4290 std::string lowerCase = Tok.getString().lower();
4291 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4292 .Case("asl", ARM_AM::lsl)
4293 .Case("lsl", ARM_AM::lsl)
4294 .Case("lsr", ARM_AM::lsr)
4295 .Case("asr", ARM_AM::asr)
4296 .Case("ror", ARM_AM::ror)
4297 .Case("rrx", ARM_AM::rrx)
4298 .Default(std::nullopt);
4299}
4300
4301// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0.
4302// If a recoverable error occurs, return 1. If an irrecoverable error
4303// occurs, return -1. An irrecoverable error is one where tokens have been
4304// consumed in the process of trying to parse the shifter (i.e., when it is
4305// indeed a shifter operand, but malformed).
4306int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
4307 MCAsmParser &Parser = getParser();
4308 SMLoc S = Parser.getTok().getLoc();
4309
4310 auto ShiftTyOpt = tryParseShiftToken();
4311 if (ShiftTyOpt == std::nullopt)
4312 return 1;
4313 auto ShiftTy = ShiftTyOpt.value();
4314
4315 Parser.Lex(); // Eat the operator.
4316
4317 // The source register for the shift has already been added to the
4318 // operand list, so we need to pop it off and combine it into the shifted
4319 // register operand instead.
4320 std::unique_ptr<ARMOperand> PrevOp(
4321 (ARMOperand *)Operands.pop_back_val().release());
4322 if (!PrevOp->isReg())
4323 return Error(PrevOp->getStartLoc(), "shift must be of a register");
4324 MCRegister SrcReg = PrevOp->getReg();
4325
4326 SMLoc EndLoc;
4327 int64_t Imm = 0;
4328 MCRegister ShiftReg;
4329 if (ShiftTy == ARM_AM::rrx) {
4330 // RRX Doesn't have an explicit shift amount. The encoder expects
4331 // the shift register to be the same as the source register. Seems odd,
4332 // but OK.
4333 ShiftReg = SrcReg;
4334 } else {
4335 // Figure out if this is shifted by a constant or a register (for non-RRX).
4336 if (Parser.getTok().is(AsmToken::Hash) ||
4337 Parser.getTok().is(AsmToken::Dollar)) {
4338 Parser.Lex(); // Eat hash.
4339 SMLoc ImmLoc = Parser.getTok().getLoc();
4340 const MCExpr *ShiftExpr = nullptr;
4341 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4342 Error(ImmLoc, "invalid immediate shift value");
4343 return -1;
4344 }
4345 // The expression must be evaluatable as an immediate.
4346 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
4347 if (!CE) {
4348 Error(ImmLoc, "invalid immediate shift value");
4349 return -1;
4350 }
4351 // Range check the immediate.
4352 // lsl, ror: 0 <= imm <= 31
4353 // lsr, asr: 0 <= imm <= 32
4354 Imm = CE->getValue();
4355 if (Imm < 0 ||
4356 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
4357 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
4358 Error(ImmLoc, "immediate shift value out of range");
4359 return -1;
4360 }
4361 // shift by zero is a nop. Always send it through as lsl.
4362 // ('as' compatibility)
4363 if (Imm == 0)
4364 ShiftTy = ARM_AM::lsl;
4365 } else if (Parser.getTok().is(AsmToken::Identifier)) {
4366 SMLoc L = Parser.getTok().getLoc();
4367 EndLoc = Parser.getTok().getEndLoc();
4368 ShiftReg = tryParseRegister();
4369 if (!ShiftReg) {
4370 Error(L, "expected immediate or register in shift operand");
4371 return -1;
4372 }
4373 } else {
4374 Error(Parser.getTok().getLoc(),
4375 "expected immediate or register in shift operand");
4376 return -1;
4377 }
4378 }
4379
4380 if (ShiftReg && ShiftTy != ARM_AM::rrx)
4381 Operands.push_back(ARMOperand::CreateShiftedRegister(
4382 ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *this));
4383 else
4384 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4385 S, EndLoc, *this));
4386
4387 return 0;
4388}
4389
4390/// Try to parse a register name. The token must be an Identifier when called.
4391/// If it's a register, an AsmOperand is created. Another AsmOperand is created
4392/// if there is a "writeback". 'true' if it's not a register.
4393///
4394/// TODO this is likely to change to allow different register types and or to
4395/// parse for a specific register type.
4396bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) {
4397 MCAsmParser &Parser = getParser();
4398 SMLoc RegStartLoc = Parser.getTok().getLoc();
4399 SMLoc RegEndLoc = Parser.getTok().getEndLoc();
4400 MCRegister Reg = tryParseRegister();
4401 if (!Reg)
4402 return true;
4403
4404 Operands.push_back(ARMOperand::CreateReg(Reg, RegStartLoc, RegEndLoc, *this));
4405
4406 const AsmToken &ExclaimTok = Parser.getTok();
4407 if (ExclaimTok.is(AsmToken::Exclaim)) {
4408 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
4409 ExclaimTok.getLoc(), *this));
4410 Parser.Lex(); // Eat exclaim token
4411 return false;
4412 }
4413
4414 // Also check for an index operand. This is only legal for vector registers,
4415 // but that'll get caught OK in operand matching, so we don't need to
4416 // explicitly filter everything else out here.
4417 if (Parser.getTok().is(AsmToken::LBrac)) {
4418 SMLoc SIdx = Parser.getTok().getLoc();
4419 Parser.Lex(); // Eat left bracket token.
4420
4421 const MCExpr *ImmVal;
4422 if (getParser().parseExpression(ImmVal))
4423 return true;
4424 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
4425 if (!MCE)
4426 return TokError("immediate value expected for vector index");
4427
4428 if (Parser.getTok().isNot(AsmToken::RBrac))
4429 return Error(Parser.getTok().getLoc(), "']' expected");
4430
4431 SMLoc E = Parser.getTok().getEndLoc();
4432 Parser.Lex(); // Eat right bracket token.
4433
4434 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), SIdx, E,
4435 getContext(), *this));
4436 }
4437
4438 return false;
4439}
4440
4441/// MatchCoprocessorOperandName - Try to parse an coprocessor related
4442/// instruction with a symbolic operand name.
4443/// We accept "crN" syntax for GAS compatibility.
4444/// <operand-name> ::= <prefix><number>
4445/// If CoprocOp is 'c', then:
4446/// <prefix> ::= c | cr
4447/// If CoprocOp is 'p', then :
4448/// <prefix> ::= p
4449/// <number> ::= integer in range [0, 15]
4450static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
4451 // Use the same layout as the tablegen'erated register name matcher. Ugly,
4452 // but efficient.
4453 if (Name.size() < 2 || Name[0] != CoprocOp)
4454 return -1;
4455 Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front();
4456
4457 switch (Name.size()) {
4458 default: return -1;
4459 case 1:
4460 switch (Name[0]) {
4461 default: return -1;
4462 case '0': return 0;
4463 case '1': return 1;
4464 case '2': return 2;
4465 case '3': return 3;
4466 case '4': return 4;
4467 case '5': return 5;
4468 case '6': return 6;
4469 case '7': return 7;
4470 case '8': return 8;
4471 case '9': return 9;
4472 }
4473 case 2:
4474 if (Name[0] != '1')
4475 return -1;
4476 switch (Name[1]) {
4477 default: return -1;
4478 // CP10 and CP11 are VFP/NEON and so vector instructions should be used.
4479 // However, old cores (v5/v6) did use them in that way.
4480 case '0': return 10;
4481 case '1': return 11;
4482 case '2': return 12;
4483 case '3': return 13;
4484 case '4': return 14;
4485 case '5': return 15;
4486 }
4487 }
4488}
4489
4490/// parseITCondCode - Try to parse a condition code for an IT instruction.
4491ParseStatus ARMAsmParser::parseITCondCode(OperandVector &Operands) {
4492 MCAsmParser &Parser = getParser();
4493 SMLoc S = Parser.getTok().getLoc();
4494 const AsmToken &Tok = Parser.getTok();
4495 if (!Tok.is(AsmToken::Identifier))
4496 return ParseStatus::NoMatch;
4497 unsigned CC = ARMCondCodeFromString(Tok.getString());
4498 if (CC == ~0U)
4499 return ParseStatus::NoMatch;
4500 Parser.Lex(); // Eat the token.
4501
4502 Operands.push_back(
4503 ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S, *this));
4504
4505 return ParseStatus::Success;
4506}
4507
4508/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
4509/// token must be an Identifier when called, and if it is a coprocessor
4510/// number, the token is eaten and the operand is added to the operand list.
4511ParseStatus ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
4512 MCAsmParser &Parser = getParser();
4513 SMLoc S = Parser.getTok().getLoc();
4514 const AsmToken &Tok = Parser.getTok();
4515 if (Tok.isNot(AsmToken::Identifier))
4516 return ParseStatus::NoMatch;
4517
4518 int Num = MatchCoprocessorOperandName(Tok.getString().lower(), 'p');
4519 if (Num == -1)
4520 return ParseStatus::NoMatch;
4521 if (!isValidCoprocessorNumber(Num, getSTI().getFeatureBits()))
4522 return ParseStatus::NoMatch;
4523
4524 Parser.Lex(); // Eat identifier token.
4525 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *this));
4526 return ParseStatus::Success;
4527}
4528
4529/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
4530/// token must be an Identifier when called, and if it is a coprocessor
4531/// number, the token is eaten and the operand is added to the operand list.
4532ParseStatus ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) {
4533 MCAsmParser &Parser = getParser();
4534 SMLoc S = Parser.getTok().getLoc();
4535 const AsmToken &Tok = Parser.getTok();
4536 if (Tok.isNot(AsmToken::Identifier))
4537 return ParseStatus::NoMatch;
4538
4539 int Reg = MatchCoprocessorOperandName(Tok.getString().lower(), 'c');
4540 if (Reg == -1)
4541 return ParseStatus::NoMatch;
4542
4543 Parser.Lex(); // Eat identifier token.
4544 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S, *this));
4545 return ParseStatus::Success;
4546}
4547
4548/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
4549/// coproc_option : '{' imm0_255 '}'
4550ParseStatus ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) {
4551 MCAsmParser &Parser = getParser();
4552 SMLoc S = Parser.getTok().getLoc();
4553
4554 // If this isn't a '{', this isn't a coprocessor immediate operand.
4555 if (Parser.getTok().isNot(AsmToken::LCurly))
4556 return ParseStatus::NoMatch;
4557 Parser.Lex(); // Eat the '{'
4558
4559 const MCExpr *Expr;
4560 SMLoc Loc = Parser.getTok().getLoc();
4561 if (getParser().parseExpression(Expr))
4562 return Error(Loc, "illegal expression");
4563 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
4564 if (!CE || CE->getValue() < 0 || CE->getValue() > 255)
4565 return Error(Loc,
4566 "coprocessor option must be an immediate in range [0, 255]");
4567 int Val = CE->getValue();
4568
4569 // Check for and consume the closing '}'
4570 if (Parser.getTok().isNot(AsmToken::RCurly))
4571 return ParseStatus::Failure;
4572 SMLoc E = Parser.getTok().getEndLoc();
4573 Parser.Lex(); // Eat the '}'
4574
4575 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E, *this));
4576 return ParseStatus::Success;
4577}
4578
4579// For register list parsing, we need to map from raw GPR register numbering
4580// to the enumeration values. The enumeration values aren't sorted by
4581// register number due to our using "sp", "lr" and "pc" as canonical names.
4583 // If this is a GPR, we need to do it manually, otherwise we can rely
4584 // on the sort ordering of the enumeration since the other reg-classes
4585 // are sane.
4586 if (!getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4587 return Reg + 1;
4588 switch (Reg.id()) {
4589 default: llvm_unreachable("Invalid GPR number!");
4590 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2;
4591 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4;
4592 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6;
4593 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8;
4594 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10;
4595 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
4596 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR;
4597 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0;
4598 }
4599}
4600
4601// Insert an <Encoding, Register> pair in an ordered vector. Return true on
4602// success, or false, if duplicate encoding found.
4603static bool
4604insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
4605 unsigned Enc, MCRegister Reg) {
4606 Regs.emplace_back(Enc, Reg);
4607 for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
4608 if (J->first == Enc) {
4609 Regs.erase(J.base());
4610 return false;
4611 }
4612 if (J->first < Enc)
4613 break;
4614 std::swap(*I, *J);
4615 }
4616 return true;
4617}
4618
4619/// Parse a register list.
4620bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
4621 bool AllowRAAC, bool IsLazyLoadStore,
4622 bool IsVSCCLRM) {
4623 MCAsmParser &Parser = getParser();
4624 if (Parser.getTok().isNot(AsmToken::LCurly))
4625 return TokError("Token is not a Left Curly Brace");
4626 SMLoc S = Parser.getTok().getLoc();
4627 Parser.Lex(); // Eat '{' token.
4628 SMLoc RegLoc = Parser.getTok().getLoc();
4629
4630 // Check the first register in the list to see what register class
4631 // this is a list of.
4632 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4633 MCRegister Reg = tryParseRegister(AllowOutOfBoundReg);
4634 if (!Reg)
4635 return Error(RegLoc, "register expected");
4636 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
4637 return Error(RegLoc, "pseudo-register not allowed");
4638 // The reglist instructions have at most 32 registers, so reserve
4639 // space for that many.
4640 int EReg = 0;
4642
4643 // Single-precision VSCCLRM can have double-precision registers in the
4644 // register list. When VSCCLRMAdjustEncoding is true then we've switched from
4645 // single-precision to double-precision and we pretend that these registers
4646 // are encoded as S32 onwards, which we can do by adding 16 to the encoding
4647 // value.
4648 bool VSCCLRMAdjustEncoding = false;
4649
4650 // Allow Q regs and just interpret them as the two D sub-registers.
4651 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4652 Reg = getDRegFromQReg(Reg);
4653 EReg = MRI->getEncodingValue(Reg);
4654 Registers.emplace_back(EReg, Reg);
4655 Reg = Reg + 1;
4656 }
4657 const MCRegisterClass *RC;
4658 if (Reg == ARM::RA_AUTH_CODE ||
4659 getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4660 RC = &getARMMCRegisterClass(ARM::GPRRegClassID);
4661 else if (getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg))
4662 RC = &getARMMCRegisterClass(ARM::DPRRegClassID);
4663 else if (getARMMCRegisterClass(ARM::SPRRegClassID).contains(Reg))
4664 RC = &getARMMCRegisterClass(ARM::SPRRegClassID);
4665 else if (getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).contains(Reg))
4666 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4667 else if (Reg == ARM::VPR)
4668 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4669 else
4670 return Error(RegLoc, "invalid register in register list");
4671
4672 // Store the register.
4673 EReg = MRI->getEncodingValue(Reg);
4674 Registers.emplace_back(EReg, Reg);
4675
4676 // This starts immediately after the first register token in the list,
4677 // so we can see either a comma or a minus (range separator) as a legal
4678 // next token.
4679 while (Parser.getTok().is(AsmToken::Comma) ||
4680 Parser.getTok().is(AsmToken::Minus)) {
4681 if (Parser.getTok().is(AsmToken::Minus)) {
4682 if (Reg == ARM::RA_AUTH_CODE)
4683 return Error(RegLoc, "pseudo-register not allowed");
4684 Parser.Lex(); // Eat the minus.
4685 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4686 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4687 if (!EndReg)
4688 return Error(AfterMinusLoc, "register expected");
4689 if (EndReg == ARM::RA_AUTH_CODE)
4690 return Error(AfterMinusLoc, "pseudo-register not allowed");
4691 // Allow Q regs and just interpret them as the two D sub-registers.
4692 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(EndReg))
4693 EndReg = getDRegFromQReg(EndReg) + 1;
4694 // If the register is the same as the start reg, there's nothing
4695 // more to do.
4696 if (Reg == EndReg)
4697 continue;
4698 // The register must be in the same register class as the first.
4699 if (!RC->contains(Reg))
4700 return Error(AfterMinusLoc, "invalid register in register list");
4701 // Ranges must go from low to high.
4702 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
4703 return Error(AfterMinusLoc, "bad range in register list");
4704
4705 // Add all the registers in the range to the register list.
4706 while (Reg != EndReg) {
4708 EReg = MRI->getEncodingValue(Reg);
4709 if (VSCCLRMAdjustEncoding)
4710 EReg += 16;
4711 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4712 Warning(AfterMinusLoc, StringRef("duplicated register (") +
4714 ") in register list");
4715 }
4716 }
4717 continue;
4718 }
4719 Parser.Lex(); // Eat the comma.
4720 RegLoc = Parser.getTok().getLoc();
4721 MCRegister OldReg = Reg;
4722 int EOldReg = EReg;
4723 const AsmToken RegTok = Parser.getTok();
4724 Reg = tryParseRegister(AllowOutOfBoundReg);
4725 if (!Reg)
4726 return Error(RegLoc, "register expected");
4727 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
4728 return Error(RegLoc, "pseudo-register not allowed");
4729 // Allow Q regs and just interpret them as the two D sub-registers.
4730 bool isQReg = false;
4731 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4732 Reg = getDRegFromQReg(Reg);
4733 isQReg = true;
4734 }
4735 if (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg) &&
4736 RC->getID() == getARMMCRegisterClass(ARM::GPRRegClassID).getID() &&
4737 getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).contains(Reg)) {
4738 // switch the register classes, as GPRwithAPSRnospRegClassID is a partial
4739 // subset of GPRRegClassId except it contains APSR as well.
4740 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4741 }
4742 if (Reg == ARM::VPR &&
4743 (RC == &getARMMCRegisterClass(ARM::SPRRegClassID) ||
4744 RC == &getARMMCRegisterClass(ARM::DPRRegClassID) ||
4745 RC == &getARMMCRegisterClass(ARM::FPWithVPRRegClassID))) {
4746 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4747 EReg = MRI->getEncodingValue(Reg);
4748 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4749 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4750 ") in register list");
4751 }
4752 continue;
4753 }
4754 // VSCCLRM can switch from single-precision to double-precision only when
4755 // S31 is followed by D16.
4756 if (IsVSCCLRM && OldReg == ARM::S31 && Reg == ARM::D16) {
4757 VSCCLRMAdjustEncoding = true;
4758 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4759 }
4760 // The register must be in the same register class as the first.
4761 if ((Reg == ARM::RA_AUTH_CODE &&
4762 RC != &getARMMCRegisterClass(ARM::GPRRegClassID)) ||
4763 (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg)))
4764 return Error(RegLoc, "invalid register in register list");
4765 // In most cases, the list must be monotonically increasing. An
4766 // exception is CLRM, which is order-independent anyway, so
4767 // there's no potential for confusion if you write clrm {r2,r1}
4768 // instead of clrm {r1,r2}.
4769 EReg = MRI->getEncodingValue(Reg);
4770 if (VSCCLRMAdjustEncoding)
4771 EReg += 16;
4772 if (EnforceOrder && EReg < EOldReg) {
4773 if (getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4774 Warning(RegLoc, "register list not in ascending order");
4775 else if (!getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
4776 .contains(Reg))
4777 return Error(RegLoc, "register list not in ascending order");
4778 }
4779 // VFP register lists must also be contiguous.
4780 if (RC != &getARMMCRegisterClass(ARM::GPRRegClassID) &&
4781 RC != &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID) &&
4782 EReg != EOldReg + 1)
4783 return Error(RegLoc, "non-contiguous register range");
4784
4785 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4786 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4787 ") in register list");
4788 }
4789 if (isQReg) {
4790 Reg = Reg + 1;
4791 EReg = MRI->getEncodingValue(Reg);
4792 Registers.emplace_back(EReg, Reg);
4793 }
4794 }
4795
4796 if (Parser.getTok().isNot(AsmToken::RCurly))
4797 return Error(Parser.getTok().getLoc(), "'}' expected");
4798 SMLoc E = Parser.getTok().getEndLoc();
4799 Parser.Lex(); // Eat '}' token.
4800
4801 // Push the register list operand.
4802 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E, *this));
4803
4804 // The ARM system instruction variants for LDM/STM have a '^' token here.
4805 if (Parser.getTok().is(AsmToken::Caret)) {
4806 Operands.push_back(
4807 ARMOperand::CreateToken("^", Parser.getTok().getLoc(), *this));
4808 Parser.Lex(); // Eat '^' token.
4809 }
4810
4811 return false;
4812}
4813
4814// Helper function to parse the lane index for vector lists.
4815ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4816 unsigned &Index, SMLoc &EndLoc) {
4817 MCAsmParser &Parser = getParser();
4818 Index = 0; // Always return a defined index value.
4819 if (Parser.getTok().is(AsmToken::LBrac)) {
4820 Parser.Lex(); // Eat the '['.
4821 if (Parser.getTok().is(AsmToken::RBrac)) {
4822 // "Dn[]" is the 'all lanes' syntax.
4823 LaneKind = AllLanes;
4824 EndLoc = Parser.getTok().getEndLoc();
4825 Parser.Lex(); // Eat the ']'.
4826 return ParseStatus::Success;
4827 }
4828
4829 // There's an optional '#' token here. Normally there wouldn't be, but
4830 // inline assemble puts one in, and it's friendly to accept that.
4831 if (Parser.getTok().is(AsmToken::Hash))
4832 Parser.Lex(); // Eat '#' or '$'.
4833
4834 const MCExpr *LaneIndex;
4835 SMLoc Loc = Parser.getTok().getLoc();
4836 if (getParser().parseExpression(LaneIndex))
4837 return Error(Loc, "illegal expression");
4838 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
4839 if (!CE)
4840 return Error(Loc, "lane index must be empty or an integer");
4841 if (Parser.getTok().isNot(AsmToken::RBrac))
4842 return Error(Parser.getTok().getLoc(), "']' expected");
4843 EndLoc = Parser.getTok().getEndLoc();
4844 Parser.Lex(); // Eat the ']'.
4845 int64_t Val = CE->getValue();
4846
4847 // FIXME: Make this range check context sensitive for .8, .16, .32.
4848 if (Val < 0 || Val > 7)
4849 return Error(Parser.getTok().getLoc(), "lane index out of range");
4850 Index = Val;
4851 LaneKind = IndexedLane;
4852 return ParseStatus::Success;
4853 }
4854 LaneKind = NoLanes;
4855 return ParseStatus::Success;
4856}
4857
4858// parse a vector register list
4859ParseStatus ARMAsmParser::parseVectorList(OperandVector &Operands) {
4860 MCAsmParser &Parser = getParser();
4861 VectorLaneTy LaneKind;
4862 unsigned LaneIndex;
4863 SMLoc S = Parser.getTok().getLoc();
4864 // As an extension (to match gas), support a plain D register or Q register
4865 // (without encosing curly braces) as a single or double entry list,
4866 // respectively.
4867 // If there is no lane supplied, just parse as a register and
4868 // use the custom matcher to convert to list if necessary
4869 if (!hasMVE() && Parser.getTok().is(AsmToken::Identifier)) {
4870 SMLoc E = Parser.getTok().getEndLoc();
4871 MCRegister Reg = tryParseRegister();
4872 if (!Reg)
4873 return ParseStatus::NoMatch;
4874 if (getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg)) {
4875 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex, E);
4876 if (!Res.isSuccess())
4877 return Res;
4878 switch (LaneKind) {
4879 case NoLanes:
4880 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4881 break;
4882 case AllLanes:
4883 Operands.push_back(
4884 ARMOperand::CreateVectorListAllLanes(Reg, 1, false, S, E, *this));
4885 break;
4886 case IndexedLane:
4887 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4888 Reg, 1, LaneIndex, false, S, E, *this));
4889 break;
4890 }
4891 return ParseStatus::Success;
4892 }
4893 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4894 Reg = getDRegFromQReg(Reg);
4895 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex, E);
4896 if (!Res.isSuccess())
4897 return Res;
4898 switch (LaneKind) {
4899 case NoLanes:
4900 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4901 break;
4902 case AllLanes:
4903 Reg = MRI->getMatchingSuperReg(
4904 Reg, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
4905 Operands.push_back(
4906 ARMOperand::CreateVectorListAllLanes(Reg, 2, false, S, E, *this));
4907 break;
4908 case IndexedLane:
4909 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4910 Reg, 2, LaneIndex, false, S, E, *this));
4911 break;
4912 }
4913 return ParseStatus::Success;
4914 }
4915 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4916 return ParseStatus::Success;
4917 }
4918
4919 if (Parser.getTok().isNot(AsmToken::LCurly))
4920 return ParseStatus::NoMatch;
4921
4922 Parser.Lex(); // Eat '{' token.
4923 SMLoc RegLoc = Parser.getTok().getLoc();
4924
4925 MCRegister Reg = tryParseRegister();
4926 if (!Reg)
4927 return Error(RegLoc, "register expected");
4928 unsigned Count = 1;
4929 int Spacing = 0;
4930 MCRegister FirstReg = Reg;
4931
4932 if (hasMVE() && !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Reg))
4933 return Error(Parser.getTok().getLoc(),
4934 "vector register in range Q0-Q7 expected");
4935 // The list is of D registers, but we also allow Q regs and just interpret
4936 // them as the two D sub-registers.
4937 else if (!hasMVE() &&
4938 getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4939 FirstReg = Reg = getDRegFromQReg(Reg);
4940 Spacing = 1; // double-spacing requires explicit D registers, otherwise
4941 // it's ambiguous with four-register single spaced.
4942 Reg = Reg + 1;
4943 ++Count;
4944 }
4945
4946 SMLoc E;
4947 if (!parseVectorLane(LaneKind, LaneIndex, E).isSuccess())
4948 return ParseStatus::Failure;
4949
4950 while (Parser.getTok().is(AsmToken::Comma) ||
4951 Parser.getTok().is(AsmToken::Minus)) {
4952 if (Parser.getTok().is(AsmToken::Minus)) {
4953 if (!Spacing)
4954 Spacing = 1; // Register range implies a single spaced list.
4955 else if (Spacing == 2)
4956 return Error(Parser.getTok().getLoc(),
4957 "sequential registers in double spaced list");
4958 Parser.Lex(); // Eat the minus.
4959 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4960 MCRegister EndReg = tryParseRegister();
4961 if (!EndReg)
4962 return Error(AfterMinusLoc, "register expected");
4963 // Allow Q regs and just interpret them as the two D sub-registers.
4964 if (!hasMVE() &&
4965 getARMMCRegisterClass(ARM::QPRRegClassID).contains(EndReg))
4966 EndReg = getDRegFromQReg(EndReg) + 1;
4967 // If the register is the same as the start reg, there's nothing
4968 // more to do.
4969 if (Reg == EndReg)
4970 continue;
4971 // The register must be in the same register class as the first.
4972 if ((hasMVE() &&
4973 !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(EndReg)) ||
4974 (!hasMVE() &&
4975 !getARMMCRegisterClass(ARM::DPRRegClassID).contains(EndReg)))
4976 return Error(AfterMinusLoc, "invalid register in register list");
4977 // Ranges must go from low to high.
4978 if (Reg > EndReg)
4979 return Error(AfterMinusLoc, "bad range in register list");
4980 // Parse the lane specifier if present.
4981 VectorLaneTy NextLaneKind;
4982 unsigned NextLaneIndex;
4983 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
4984 return ParseStatus::Failure;
4985 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4986 return Error(AfterMinusLoc, "mismatched lane index in register list");
4987
4988 // Add all the registers in the range to the register list.
4989 Count += EndReg - Reg;
4990 Reg = EndReg;
4991 continue;
4992 }
4993 Parser.Lex(); // Eat the comma.
4994 RegLoc = Parser.getTok().getLoc();
4995 MCRegister OldReg = Reg;
4996 Reg = tryParseRegister();
4997 if (!Reg)
4998 return Error(RegLoc, "register expected");
4999
5000 if (hasMVE()) {
5001 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Reg))
5002 return Error(RegLoc, "vector register in range Q0-Q7 expected");
5003 Spacing = 1;
5004 }
5005 // vector register lists must be contiguous.
5006 // It's OK to use the enumeration values directly here rather, as the
5007 // VFP register classes have the enum sorted properly.
5008 //
5009 // The list is of D registers, but we also allow Q regs and just interpret
5010 // them as the two D sub-registers.
5011 else if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
5012 if (!Spacing)
5013 Spacing = 1; // Register range implies a single spaced list.
5014 else if (Spacing == 2)
5015 return Error(
5016 RegLoc,
5017 "invalid register in double-spaced list (must be 'D' register')");
5018 Reg = getDRegFromQReg(Reg);
5019 if (Reg != OldReg + 1)
5020 return Error(RegLoc, "non-contiguous register range");
5021 Reg = Reg + 1;
5022 Count += 2;
5023 // Parse the lane specifier if present.
5024 VectorLaneTy NextLaneKind;
5025 unsigned NextLaneIndex;
5026 SMLoc LaneLoc = Parser.getTok().getLoc();
5027 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
5028 return ParseStatus::Failure;
5029 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5030 return Error(LaneLoc, "mismatched lane index in register list");
5031 continue;
5032 }
5033 // Normal D register.
5034 // Figure out the register spacing (single or double) of the list if
5035 // we don't know it already.
5036 if (!Spacing)
5037 Spacing = 1 + (Reg == OldReg + 2);
5038
5039 // Just check that it's contiguous and keep going.
5040 if (Reg != OldReg + Spacing)
5041 return Error(RegLoc, "non-contiguous register range");
5042 ++Count;
5043 // Parse the lane specifier if present.
5044 VectorLaneTy NextLaneKind;
5045 unsigned NextLaneIndex;
5046 SMLoc EndLoc = Parser.getTok().getLoc();
5047 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
5048 return ParseStatus::Failure;
5049 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5050 return Error(EndLoc, "mismatched lane index in register list");
5051 }
5052
5053 if (Parser.getTok().isNot(AsmToken::RCurly))
5054 return Error(Parser.getTok().getLoc(), "'}' expected");
5055 E = Parser.getTok().getEndLoc();
5056 Parser.Lex(); // Eat '}' token.
5057
5058 switch (LaneKind) {
5059 case NoLanes:
5060 case AllLanes: {
5061 // Two-register operands have been converted to the
5062 // composite register classes.
5063 if (Count == 2 && !hasMVE()) {
5064 const MCRegisterClass *RC =
5065 (Spacing == 1) ? &getARMMCRegisterClass(ARM::DPairRegClassID)
5066 : &getARMMCRegisterClass(ARM::DPairSpcRegClassID);
5067 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
5068 }
5069 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5070 ARMOperand::CreateVectorListAllLanes);
5071 Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E, *this));
5072 break;
5073 }
5074 case IndexedLane:
5075 Operands.push_back(ARMOperand::CreateVectorListIndexed(
5076 FirstReg, Count, LaneIndex, (Spacing == 2), S, E, *this));
5077 break;
5078 }
5079 return ParseStatus::Success;
5080}
5081
5082/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
5083ParseStatus ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
5084 MCAsmParser &Parser = getParser();
5085 SMLoc S = Parser.getTok().getLoc();
5086 const AsmToken &Tok = Parser.getTok();
5087 unsigned Opt;
5088
5089 if (Tok.is(AsmToken::Identifier)) {
5090 StringRef OptStr = Tok.getString();
5091
5092 Opt = StringSwitch<unsigned>(OptStr.lower())
5093 .Case("sy", ARM_MB::SY)
5094 .Case("st", ARM_MB::ST)
5095 .Case("ld", ARM_MB::LD)
5096 .Case("sh", ARM_MB::ISH)
5097 .Case("ish", ARM_MB::ISH)
5098 .Case("shst", ARM_MB::ISHST)
5099 .Case("ishst", ARM_MB::ISHST)
5100 .Case("ishld", ARM_MB::ISHLD)
5101 .Case("nsh", ARM_MB::NSH)
5102 .Case("un", ARM_MB::NSH)
5103 .Case("nshst", ARM_MB::NSHST)
5104 .Case("nshld", ARM_MB::NSHLD)
5105 .Case("unst", ARM_MB::NSHST)
5106 .Case("osh", ARM_MB::OSH)
5107 .Case("oshst", ARM_MB::OSHST)
5108 .Case("oshld", ARM_MB::OSHLD)
5109 .Default(~0U);
5110
5111 // ishld, oshld, nshld and ld are only available from ARMv8.
5112 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD ||
5113 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD))
5114 Opt = ~0U;
5115
5116 if (Opt == ~0U)
5117 return ParseStatus::NoMatch;
5118
5119 Parser.Lex(); // Eat identifier token.
5120 } else if (Tok.is(AsmToken::Hash) ||
5121 Tok.is(AsmToken::Dollar) ||
5122 Tok.is(AsmToken::Integer)) {
5123 if (Parser.getTok().isNot(AsmToken::Integer))
5124 Parser.Lex(); // Eat '#' or '$'.
5125 SMLoc Loc = Parser.getTok().getLoc();
5126
5127 const MCExpr *MemBarrierID;
5128 if (getParser().parseExpression(MemBarrierID))
5129 return Error(Loc, "illegal expression");
5130
5131 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
5132 if (!CE)
5133 return Error(Loc, "constant expression expected");
5134
5135 int Val = CE->getValue();
5136 if (Val & ~0xf)
5137 return Error(Loc, "immediate value out of range");
5138
5139 Opt = ARM_MB::RESERVED_0 + Val;
5140 } else
5141 return Error(Parser.getTok().getLoc(),
5142 "expected an immediate or barrier type");
5143
5144 Operands.push_back(
5145 ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S, *this));
5146 return ParseStatus::Success;
5147}
5148
5149ParseStatus
5150ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) {
5151 MCAsmParser &Parser = getParser();
5152 SMLoc S = Parser.getTok().getLoc();
5153 const AsmToken &Tok = Parser.getTok();
5154
5155 if (Tok.isNot(AsmToken::Identifier))
5156 return ParseStatus::NoMatch;
5157
5158 if (!Tok.getString().equals_insensitive("csync"))
5159 return ParseStatus::NoMatch;
5160
5161 Parser.Lex(); // Eat identifier token.
5162
5163 Operands.push_back(
5164 ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S, *this));
5165 return ParseStatus::Success;
5166}
5167
5168/// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
5169ParseStatus
5170ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
5171 MCAsmParser &Parser = getParser();
5172 SMLoc S = Parser.getTok().getLoc();
5173 const AsmToken &Tok = Parser.getTok();
5174 unsigned Opt;
5175
5176 if (Tok.is(AsmToken::Identifier)) {
5177 StringRef OptStr = Tok.getString();
5178
5179 if (OptStr.equals_insensitive("sy"))
5180 Opt = ARM_ISB::SY;
5181 else
5182 return ParseStatus::NoMatch;
5183
5184 Parser.Lex(); // Eat identifier token.
5185 } else if (Tok.is(AsmToken::Hash) ||
5186 Tok.is(AsmToken::Dollar) ||
5187 Tok.is(AsmToken::Integer)) {
5188 if (Parser.getTok().isNot(AsmToken::Integer))
5189 Parser.Lex(); // Eat '#' or '$'.
5190 SMLoc Loc = Parser.getTok().getLoc();
5191
5192 const MCExpr *ISBarrierID;
5193 if (getParser().parseExpression(ISBarrierID))
5194 return Error(Loc, "illegal expression");
5195
5196 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID);
5197 if (!CE)
5198 return Error(Loc, "constant expression expected");
5199
5200 int Val = CE->getValue();
5201 if (Val & ~0xf)
5202 return Error(Loc, "immediate value out of range");
5203
5204 Opt = ARM_ISB::RESERVED_0 + Val;
5205 } else
5206 return Error(Parser.getTok().getLoc(),
5207 "expected an immediate or barrier type");
5208
5209 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
5210 (ARM_ISB::InstSyncBOpt)Opt, S, *this));
5211 return ParseStatus::Success;
5212}
5213
5214/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
5215ParseStatus ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {
5216 MCAsmParser &Parser = getParser();
5217 SMLoc S = Parser.getTok().getLoc();
5218 const AsmToken &Tok = Parser.getTok();
5219 if (!Tok.is(AsmToken::Identifier))
5220 return ParseStatus::NoMatch;
5221 StringRef IFlagsStr = Tok.getString();
5222
5223 // An iflags string of "none" is interpreted to mean that none of the AIF
5224 // bits are set. Not a terribly useful instruction, but a valid encoding.
5225 unsigned IFlags = 0;
5226 if (IFlagsStr != "none") {
5227 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
5228 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1).lower())
5229 .Case("a", ARM_PROC::A)
5230 .Case("i", ARM_PROC::I)
5231 .Case("f", ARM_PROC::F)
5232 .Default(~0U);
5233
5234 // If some specific iflag is already set, it means that some letter is
5235 // present more than once, this is not acceptable.
5236 if (Flag == ~0U || (IFlags & Flag))
5237 return ParseStatus::NoMatch;
5238
5239 IFlags |= Flag;
5240 }
5241 }
5242
5243 Parser.Lex(); // Eat identifier token.
5244 Operands.push_back(
5245 ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S, *this));
5246 return ParseStatus::Success;
5247}
5248
5249/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
5250ParseStatus ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {
5251 // Don't parse two MSR registers in a row
5252 if (static_cast<ARMOperand &>(*Operands.back()).isMSRMask() ||
5253 static_cast<ARMOperand &>(*Operands.back()).isBankedReg())
5254 return ParseStatus::NoMatch;
5255 MCAsmParser &Parser = getParser();
5256 SMLoc S = Parser.getTok().getLoc();
5257 const AsmToken &Tok = Parser.getTok();
5258
5259 if (Tok.is(AsmToken::Integer)) {
5260 int64_t Val = Tok.getIntVal();
5261 if (Val > 255 || Val < 0) {
5262 return ParseStatus::NoMatch;
5263 }
5264 unsigned SYSmvalue = Val & 0xFF;
5265 Parser.Lex();
5266 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this));
5267 return ParseStatus::Success;
5268 }
5269
5270 if (!Tok.is(AsmToken::Identifier))
5271 return ParseStatus::NoMatch;
5272 StringRef Mask = Tok.getString();
5273
5274 if (isMClass()) {
5275 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower());
5276 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5277 return ParseStatus::NoMatch;
5278
5279 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5280
5281 Parser.Lex(); // Eat identifier token.
5282 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this));
5283 return ParseStatus::Success;
5284 }
5285
5286 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
5287 size_t Start = 0, Next = Mask.find('_');
5288 StringRef Flags = "";
5289 std::string SpecReg = Mask.slice(Start, Next).lower();
5290 if (Next != StringRef::npos)
5291 Flags = Mask.substr(Next + 1);
5292
5293 // FlagsVal contains the complete mask:
5294 // 3-0: Mask
5295 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5296 unsigned FlagsVal = 0;
5297
5298 if (SpecReg == "apsr") {
5299 FlagsVal = StringSwitch<unsigned>(Flags)
5300 .Case("nzcvq", 0x8) // same as CPSR_f
5301 .Case("g", 0x4) // same as CPSR_s
5302 .Case("nzcvqg", 0xc) // same as CPSR_fs
5303 .Default(~0U);
5304
5305 if (FlagsVal == ~0U) {
5306 if (!Flags.empty())
5307 return ParseStatus::NoMatch;
5308 else
5309 FlagsVal = 8; // No flag
5310 }
5311 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
5312 // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
5313 if (Flags == "all" || Flags == "")
5314 Flags = "fc";
5315 for (int i = 0, e = Flags.size(); i != e; ++i) {
5316 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
5317 .Case("c", 1)
5318 .Case("x", 2)
5319 .Case("s", 4)
5320 .Case("f", 8)
5321 .Default(~0U);
5322
5323 // If some specific flag is already set, it means that some letter is
5324 // present more than once, this is not acceptable.
5325 if (Flag == ~0U || (FlagsVal & Flag))
5326 return ParseStatus::NoMatch;
5327 FlagsVal |= Flag;
5328 }
5329 } else // No match for special register.
5330 return ParseStatus::NoMatch;
5331
5332 // Special register without flags is NOT equivalent to "fc" flags.
5333 // NOTE: This is a divergence from gas' behavior. Uncommenting the following
5334 // two lines would enable gas compatibility at the expense of breaking
5335 // round-tripping.
5336 //
5337 // if (!FlagsVal)
5338 // FlagsVal = 0x9;
5339
5340 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5341 if (SpecReg == "spsr")
5342 FlagsVal |= 16;
5343
5344 Parser.Lex(); // Eat identifier token.
5345 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *this));
5346 return ParseStatus::Success;
5347}
5348
5349/// parseBankedRegOperand - Try to parse a banked register (e.g. "lr_irq") for
5350/// use in the MRS/MSR instructions added to support virtualization.
5351ParseStatus ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
5352 // Don't parse two Banked registers in a row
5353 if (static_cast<ARMOperand &>(*Operands.back()).isBankedReg() ||
5354 static_cast<ARMOperand &>(*Operands.back()).isMSRMask())
5355 return ParseStatus::NoMatch;
5356 MCAsmParser &Parser = getParser();
5357 SMLoc S = Parser.getTok().getLoc();
5358 const AsmToken &Tok = Parser.getTok();
5359 if (!Tok.is(AsmToken::Identifier))
5360 return ParseStatus::NoMatch;
5361 StringRef RegName = Tok.getString();
5362
5363 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.lower());
5364 if (!TheReg)
5365 return ParseStatus::NoMatch;
5366 unsigned Encoding = TheReg->Encoding;
5367
5368 Parser.Lex(); // Eat identifier token.
5369 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S, *this));
5370 return ParseStatus::Success;
5371}
5372
5373// FIXME: Unify the different methods for handling shift operators
5374// and use TableGen matching mechanisms to do the validation rather than
5375// separate parsing paths.
5376ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands,
5377 ARM_AM::ShiftOpc Op, int Low, int High) {
5378 MCAsmParser &Parser = getParser();
5379 auto ShiftCodeOpt = tryParseShiftToken();
5380
5381 if (!ShiftCodeOpt.has_value())
5382 return ParseStatus::NoMatch;
5383 auto ShiftCode = ShiftCodeOpt.value();
5384
5385 // The wrong shift code has been provided. Can error here as has matched the
5386 // correct operand in this case.
5387 if (ShiftCode != Op)
5388 return Error(Parser.getTok().getLoc(),
5389 ARM_AM::getShiftOpcStr(Op) + " operand expected.");
5390
5391 Parser.Lex(); // Eat shift type token.
5392
5393 // There must be a '#' and a shift amount.
5394 if (Parser.getTok().isNot(AsmToken::Hash) &&
5395 Parser.getTok().isNot(AsmToken::Dollar))
5396 return ParseStatus::NoMatch;
5397 Parser.Lex(); // Eat hash token.
5398
5399 const MCExpr *ShiftAmount;
5400 SMLoc Loc = Parser.getTok().getLoc();
5401 SMLoc EndLoc;
5402 if (getParser().parseExpression(ShiftAmount, EndLoc))
5403 return Error(Loc, "illegal expression");
5404 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5405 if (!CE)
5406 return Error(Loc, "constant expression expected");
5407 int Val = CE->getValue();
5408 if (Val < Low || Val > High)
5409 return Error(Loc, "immediate value out of range");
5410
5411 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *this));
5412
5413 return ParseStatus::Success;
5414}
5415
5416ParseStatus ARMAsmParser::parseSetEndImm(OperandVector &Operands) {
5417 MCAsmParser &Parser = getParser();
5418 const AsmToken &Tok = Parser.getTok();
5419 SMLoc S = Tok.getLoc();
5420 if (Tok.isNot(AsmToken::Identifier))
5421 return Error(S, "'be' or 'le' operand expected");
5422 int Val = StringSwitch<int>(Tok.getString().lower())
5423 .Case("be", 1)
5424 .Case("le", 0)
5425 .Default(-1);
5426 Parser.Lex(); // Eat the token.
5427
5428 if (Val == -1)
5429 return Error(S, "'be' or 'le' operand expected");
5430 Operands.push_back(ARMOperand::CreateImm(
5431 MCConstantExpr::create(Val, getContext()), S, Tok.getEndLoc(), *this));
5432 return ParseStatus::Success;
5433}
5434
5435/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
5436/// instructions. Legal values are:
5437/// lsl #n 'n' in [0,31]
5438/// asr #n 'n' in [1,32]
5439/// n == 32 encoded as n == 0.
5440ParseStatus ARMAsmParser::parseShifterImm(OperandVector &Operands) {
5441 MCAsmParser &Parser = getParser();
5442 const AsmToken &Tok = Parser.getTok();
5443 SMLoc S = Tok.getLoc();
5444 if (Tok.isNot(AsmToken::Identifier))
5445 return ParseStatus::NoMatch;
5446 StringRef ShiftName = Tok.getString();
5447 bool isASR;
5448 if (ShiftName == "lsl" || ShiftName == "LSL")
5449 isASR = false;
5450 else if (ShiftName == "asr" || ShiftName == "ASR")
5451 isASR = true;
5452 else
5453 return ParseStatus::NoMatch;
5454 Parser.Lex(); // Eat the operator.
5455
5456 // A '#' and a shift amount.
5457 if (Parser.getTok().isNot(AsmToken::Hash) &&
5458 Parser.getTok().isNot(AsmToken::Dollar))
5459 return Error(Parser.getTok().getLoc(), "'#' expected");
5460 Parser.Lex(); // Eat hash token.
5461 SMLoc ExLoc = Parser.getTok().getLoc();
5462
5463 const MCExpr *ShiftAmount;
5464 SMLoc EndLoc;
5465 if (getParser().parseExpression(ShiftAmount, EndLoc))
5466 return Error(ExLoc, "malformed shift expression");
5467 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5468 if (!CE)
5469 return Error(ExLoc, "shift amount must be an immediate");
5470
5471 int64_t Val = CE->getValue();
5472 if (isASR) {
5473 // Shift amount must be in [1,32]
5474 if (Val < 1 || Val > 32)
5475 return Error(ExLoc, "'asr' shift amount must be in range [1,32]");
5476 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
5477 if (isThumb() && Val == 32)
5478 return Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode");
5479 if (Val == 32) Val = 0;
5480 } else {
5481 // Shift amount must be in [1,32]
5482 if (Val < 0 || Val > 31)
5483 return Error(ExLoc, "'lsr' shift amount must be in range [0,31]");
5484 }
5485
5486 Operands.push_back(
5487 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *this));
5488
5489 return ParseStatus::Success;
5490}
5491
5492/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
5493/// of instructions. Legal values are:
5494/// ror #n 'n' in {0, 8, 16, 24}
5495ParseStatus ARMAsmParser::parseRotImm(OperandVector &Operands) {
5496 MCAsmParser &Parser = getParser();
5497 const AsmToken &Tok = Parser.getTok();
5498 SMLoc S = Tok.getLoc();
5499 if (Tok.isNot(AsmToken::Identifier))
5500 return ParseStatus::NoMatch;
5501 StringRef ShiftName = Tok.getString();
5502 if (ShiftName != "ror" && ShiftName != "ROR")
5503 return ParseStatus::NoMatch;
5504 Parser.Lex(); // Eat the operator.
5505
5506 // A '#' and a rotate amount.
5507 if (Parser.getTok().isNot(AsmToken::Hash) &&
5508 Parser.getTok().isNot(AsmToken::Dollar))
5509 return Error(Parser.getTok().getLoc(), "'#' expected");
5510 Parser.Lex(); // Eat hash token.
5511 SMLoc ExLoc = Parser.getTok().getLoc();
5512
5513 const MCExpr *ShiftAmount;
5514 SMLoc EndLoc;
5515 if (getParser().parseExpression(ShiftAmount, EndLoc))
5516 return Error(ExLoc, "malformed rotate expression");
5517 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5518 if (!CE)
5519 return Error(ExLoc, "rotate amount must be an immediate");
5520
5521 int64_t Val = CE->getValue();
5522 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
5523 // normally, zero is represented in asm by omitting the rotate operand
5524 // entirely.
5525 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5526 return Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24");
5527
5528 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *this));
5529
5530 return ParseStatus::Success;
5531}
5532
5533ParseStatus ARMAsmParser::parseModImm(OperandVector &Operands) {
5534 MCAsmParser &Parser = getParser();
5535 AsmLexer &Lexer = getLexer();
5536 int64_t Imm1, Imm2;
5537
5538 SMLoc S = Parser.getTok().getLoc();
5539
5540 // 1) A mod_imm operand can appear in the place of a register name:
5541 // add r0, #mod_imm
5542 // add r0, r0, #mod_imm
5543 // to correctly handle the latter, we bail out as soon as we see an
5544 // identifier.
5545 //
5546 // 2) Similarly, we do not want to parse into complex operands:
5547 // mov r0, #mod_imm
5548 // mov r0, :lower16:(_foo)
5549 if (Parser.getTok().is(AsmToken::Identifier) ||
5550 Parser.getTok().is(AsmToken::Colon))
5551 return ParseStatus::NoMatch;
5552
5553 // Hash (dollar) is optional as per the ARMARM
5554 if (Parser.getTok().is(AsmToken::Hash) ||
5555 Parser.getTok().is(AsmToken::Dollar)) {
5556 // Avoid parsing into complex operands (#:)
5557 if (Lexer.peekTok().is(AsmToken::Colon))
5558 return ParseStatus::NoMatch;
5559
5560 // Eat the hash (dollar)
5561 Parser.Lex();
5562 }
5563
5564 SMLoc Sx1, Ex1;
5565 Sx1 = Parser.getTok().getLoc();
5566 const MCExpr *Imm1Exp;
5567 if (getParser().parseExpression(Imm1Exp, Ex1))
5568 return Error(Sx1, "malformed expression");
5569
5570 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
5571
5572 if (CE) {
5573 // Immediate must fit within 32-bits
5574 Imm1 = CE->getValue();
5575 int Enc = ARM_AM::getSOImmVal(Imm1);
5576 if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) {
5577 // We have a match!
5578 Operands.push_back(ARMOperand::CreateModImm(
5579 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *this));
5580 return ParseStatus::Success;
5581 }
5582
5583 // We have parsed an immediate which is not for us, fallback to a plain
5584 // immediate. This can happen for instruction aliases. For an example,
5585 // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
5586 // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
5587 // instruction with a mod_imm operand. The alias is defined such that the
5588 // parser method is shared, that's why we have to do this here.
5589 if (Parser.getTok().is(AsmToken::EndOfStatement)) {
5590 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this));
5591 return ParseStatus::Success;
5592 }
5593 } else {
5594 // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
5595 // MCFixup). Fallback to a plain immediate.
5596 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this));
5597 return ParseStatus::Success;
5598 }
5599
5600 // From this point onward, we expect the input to be a (#bits, #rot) pair
5601 if (Parser.getTok().isNot(AsmToken::Comma))
5602 return Error(Sx1,
5603 "expected modified immediate operand: #[0, 255], #even[0-30]");
5604
5605 if (Imm1 & ~0xFF)
5606 return Error(Sx1, "immediate operand must a number in the range [0, 255]");
5607
5608 // Eat the comma
5609 Parser.Lex();
5610
5611 // Repeat for #rot
5612 SMLoc Sx2, Ex2;
5613 Sx2 = Parser.getTok().getLoc();
5614
5615 // Eat the optional hash (dollar)
5616 if (Parser.getTok().is(AsmToken::Hash) ||
5617 Parser.getTok().is(AsmToken::Dollar))
5618 Parser.Lex();
5619
5620 const MCExpr *Imm2Exp;
5621 if (getParser().parseExpression(Imm2Exp, Ex2))
5622 return Error(Sx2, "malformed expression");
5623
5624 CE = dyn_cast<MCConstantExpr>(Imm2Exp);
5625
5626 if (CE) {
5627 Imm2 = CE->getValue();
5628 if (!(Imm2 & ~0x1E)) {
5629 // We have a match!
5630 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *this));
5631 return ParseStatus::Success;
5632 }
5633 return Error(Sx2,
5634 "immediate operand must an even number in the range [0, 30]");
5635 } else {
5636 return Error(Sx2, "constant expression expected");
5637 }
5638}
5639
5640ParseStatus ARMAsmParser::parseBitfield(OperandVector &Operands) {
5641 MCAsmParser &Parser = getParser();
5642 SMLoc S = Parser.getTok().getLoc();
5643 // The bitfield descriptor is really two operands, the LSB and the width.
5644 if (Parser.getTok().isNot(AsmToken::Hash) &&
5645 Parser.getTok().isNot(AsmToken::Dollar))
5646 return ParseStatus::NoMatch;
5647 Parser.Lex(); // Eat hash token.
5648
5649 const MCExpr *LSBExpr;
5650 SMLoc E = Parser.getTok().getLoc();
5651 if (getParser().parseExpression(LSBExpr))
5652 return Error(E, "malformed immediate expression");
5653 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
5654 if (!CE)
5655 return Error(E, "'lsb' operand must be an immediate");
5656
5657 int64_t LSB = CE->getValue();
5658 // The LSB must be in the range [0,31]
5659 if (LSB < 0 || LSB > 31)
5660 return Error(E, "'lsb' operand must be in the range [0,31]");
5661 E = Parser.getTok().getLoc();
5662
5663 // Expect another immediate operand.
5664 if (Parser.getTok().isNot(AsmToken::Comma))
5665 return Error(Parser.getTok().getLoc(), "too few operands");
5666 Parser.Lex(); // Eat hash token.
5667 if (Parser.getTok().isNot(AsmToken::Hash) &&
5668 Parser.getTok().isNot(AsmToken::Dollar))
5669 return Error(Parser.getTok().getLoc(), "'#' expected");
5670 Parser.Lex(); // Eat hash token.
5671
5672 const MCExpr *WidthExpr;
5673 SMLoc EndLoc;
5674 if (getParser().parseExpression(WidthExpr, EndLoc))
5675 return Error(E, "malformed immediate expression");
5676 CE = dyn_cast<MCConstantExpr>(WidthExpr);
5677 if (!CE)
5678 return Error(E, "'width' operand must be an immediate");
5679
5680 int64_t Width = CE->getValue();
5681 // The LSB must be in the range [1,32-lsb]
5682 if (Width < 1 || Width > 32 - LSB)
5683 return Error(E, "'width' operand must be in the range [1,32-lsb]");
5684
5685 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *this));
5686
5687 return ParseStatus::Success;
5688}
5689
5690ParseStatus ARMAsmParser::parsePostIdxReg(OperandVector &Operands) {
5691 // Check for a post-index addressing register operand. Specifically:
5692 // postidx_reg := '+' register {, shift}
5693 // | '-' register {, shift}
5694 // | register {, shift}
5695
5696 // This method must return ParseStatus::NoMatch without consuming any tokens
5697 // in the case where there is no match, as other alternatives take other
5698 // parse methods.
5699 MCAsmParser &Parser = getParser();
5700 AsmToken Tok = Parser.getTok();
5701 SMLoc S = Tok.getLoc();
5702 bool haveEaten = false;
5703 bool isAdd = true;
5704 if (Tok.is(AsmToken::Plus)) {
5705 Parser.Lex(); // Eat the '+' token.
5706 haveEaten = true;
5707 } else if (Tok.is(AsmToken::Minus)) {
5708 Parser.Lex(); // Eat the '-' token.
5709 isAdd = false;
5710 haveEaten = true;
5711 }
5712
5713 SMLoc E = Parser.getTok().getEndLoc();
5714 MCRegister Reg = tryParseRegister();
5715 if (!Reg) {
5716 if (!haveEaten)
5717 return ParseStatus::NoMatch;
5718 return Error(Parser.getTok().getLoc(), "register expected");
5719 }
5720
5722 unsigned ShiftImm = 0;
5723 if (Parser.getTok().is(AsmToken::Comma)) {
5724 Parser.Lex(); // Eat the ','.
5725 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5726 return ParseStatus::Failure;
5727
5728 // FIXME: Only approximates end...may include intervening whitespace.
5729 E = Parser.getTok().getLoc();
5730 }
5731
5732 Operands.push_back(
5733 ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, ShiftImm, S, E, *this));
5734
5735 return ParseStatus::Success;
5736}
5737
5738ParseStatus ARMAsmParser::parseAM3Offset(OperandVector &Operands) {
5739 // Check for a post-index addressing register operand. Specifically:
5740 // am3offset := '+' register
5741 // | '-' register
5742 // | register
5743 // | # imm
5744 // | # + imm
5745 // | # - imm
5746
5747 // This method must return ParseStatus::NoMatch without consuming any tokens
5748 // in the case where there is no match, as other alternatives take other
5749 // parse methods.
5750 MCAsmParser &Parser = getParser();
5751 AsmToken Tok = Parser.getTok();
5752 SMLoc S = Tok.getLoc();
5753
5754 // Do immediates first, as we always parse those if we have a '#'.
5755 if (Parser.getTok().is(AsmToken::Hash) ||
5756 Parser.getTok().is(AsmToken::Dollar)) {
5757 Parser.Lex(); // Eat '#' or '$'.
5758 // Explicitly look for a '-', as we need to encode negative zero
5759 // differently.
5760 bool isNegative = Parser.getTok().is(AsmToken::Minus);
5761 const MCExpr *Offset;
5762 SMLoc E;
5763 if (getParser().parseExpression(Offset, E))
5764 return ParseStatus::Failure;
5765 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
5766 if (!CE)
5767 return Error(S, "constant expression expected");
5768 // Negative zero is encoded as the flag value
5769 // std::numeric_limits<int32_t>::min().
5770 int32_t Val = CE->getValue();
5771 if (isNegative && Val == 0)
5772 Val = std::numeric_limits<int32_t>::min();
5773
5774 Operands.push_back(ARMOperand::CreateImm(
5775 MCConstantExpr::create(Val, getContext()), S, E, *this));
5776
5777 return ParseStatus::Success;
5778 }
5779
5780 bool haveEaten = false;
5781 bool isAdd = true;
5782 if (Tok.is(AsmToken::Plus)) {
5783 Parser.Lex(); // Eat the '+' token.
5784 haveEaten = true;
5785 } else if (Tok.is(AsmToken::Minus)) {
5786 Parser.Lex(); // Eat the '-' token.
5787 isAdd = false;
5788 haveEaten = true;
5789 }
5790
5791 Tok = Parser.getTok();
5792 MCRegister Reg = tryParseRegister();
5793 if (!Reg) {
5794 if (!haveEaten)
5795 return ParseStatus::NoMatch;
5796 return Error(Tok.getLoc(), "register expected");
5797 }
5798
5799 Operands.push_back(ARMOperand::CreatePostIdxReg(
5800 Reg, isAdd, ARM_AM::no_shift, 0, S, Tok.getEndLoc(), *this));
5801
5802 return ParseStatus::Success;
5803}
5804
5805// Finds the index of the first CondCode operator, if there is none returns 0
5807 unsigned MnemonicOpsEndInd) {
5808 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
5809 auto Op = static_cast<ARMOperand &>(*Operands[I]);
5810 if (Op.isCondCode())
5811 return I;
5812 }
5813 return 0;
5814}
5815
5817 unsigned MnemonicOpsEndInd) {
5818 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
5819 auto Op = static_cast<ARMOperand &>(*Operands[I]);
5820 if (Op.isCCOut())
5821 return I;
5822 }
5823 return 0;
5824}
5825
5826/// Convert parsed operands to MCInst. Needed here because this instruction
5827/// only has two register operands, but multiplication is commutative so
5828/// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN".
5829void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5830 const OperandVector &Operands) {
5831 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5832 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5833 unsigned CondOutI = findCCOutInd(Operands, MnemonicOpsEndInd);
5834
5835 // 2 operand form
5836 unsigned RegRd = MnemonicOpsEndInd;
5837 unsigned RegRn = MnemonicOpsEndInd + 1;
5838 unsigned RegRm = MnemonicOpsEndInd;
5839
5840 if (Operands.size() == MnemonicOpsEndInd + 3) {
5841 // If we have a three-operand form, make sure to set Rn to be the operand
5842 // that isn't the same as Rd.
5843 if (((ARMOperand &)*Operands[RegRd]).getReg() ==
5844 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1]).getReg()) {
5845 RegRn = MnemonicOpsEndInd + 2;
5846 RegRm = MnemonicOpsEndInd + 1;
5847 } else {
5848 RegRn = MnemonicOpsEndInd + 1;
5849 RegRm = MnemonicOpsEndInd + 2;
5850 }
5851 }
5852
5853 // Rd
5854 ((ARMOperand &)*Operands[RegRd]).addRegOperands(Inst, 1);
5855 // CCOut
5856 if (CondOutI != 0) {
5857 ((ARMOperand &)*Operands[CondOutI]).addCCOutOperands(Inst, 1);
5858 } else {
5859 ARMOperand Op =
5860 *ARMOperand::CreateCCOut(0, Operands[0]->getEndLoc(), *this);
5861 Op.addCCOutOperands(Inst, 1);
5862 }
5863 // Rn
5864 ((ARMOperand &)*Operands[RegRn]).addRegOperands(Inst, 1);
5865 // Rm
5866 ((ARMOperand &)*Operands[RegRm]).addRegOperands(Inst, 1);
5867
5868 // Cond code
5869 if (CondI != 0) {
5870 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5871 } else {
5872 ARMOperand Op = *ARMOperand::CreateCondCode(
5873 llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this);
5874 Op.addCondCodeOperands(Inst, 2);
5875 }
5876}
5877
5878void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5879 const OperandVector &Operands) {
5880 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5881 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5882 unsigned Cond =
5883 (CondI == 0 ? ARMCC::AL
5884 : static_cast<ARMOperand &>(*Operands[CondI]).getCondCode());
5885
5886 // first decide whether or not the branch should be conditional
5887 // by looking at it's location relative to an IT block
5888 if(inITBlock()) {
5889 // inside an IT block we cannot have any conditional branches. any
5890 // such instructions needs to be converted to unconditional form
5891 switch(Inst.getOpcode()) {
5892 case ARM::tBcc: Inst.setOpcode(ARM::tB); break;
5893 case ARM::t2Bcc: Inst.setOpcode(ARM::t2B); break;
5894 }
5895 } else {
5896 switch(Inst.getOpcode()) {
5897 case ARM::tB:
5898 case ARM::tBcc:
5899 Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc);
5900 break;
5901 case ARM::t2B:
5902 case ARM::t2Bcc:
5903 Inst.setOpcode(Cond == ARMCC::AL ? ARM::t2B : ARM::t2Bcc);
5904 break;
5905 }
5906 }
5907
5908 // now decide on encoding size based on branch target range
5909 switch(Inst.getOpcode()) {
5910 // classify tB as either t2B or t1B based on range of immediate operand
5911 case ARM::tB: {
5912 ARMOperand &op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
5913 if (!op.isSignedOffset<11, 1>() && isThumb() && hasV8MBaseline())
5914 Inst.setOpcode(ARM::t2B);
5915 break;
5916 }
5917 // classify tBcc as either t2Bcc or t1Bcc based on range of immediate operand
5918 case ARM::tBcc: {
5919 ARMOperand &op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
5920 if (!op.isSignedOffset<8, 1>() && isThumb() && hasV8MBaseline())
5921 Inst.setOpcode(ARM::t2Bcc);
5922 break;
5923 }
5924 }
5925 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5926 if (CondI != 0) {
5927 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5928 } else {
5929 ARMOperand Op = *ARMOperand::CreateCondCode(
5930 llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this);
5931 Op.addCondCodeOperands(Inst, 2);
5932 }
5933}
5934
5935void ARMAsmParser::cvtMVEVMOVQtoDReg(
5936 MCInst &Inst, const OperandVector &Operands) {
5937
5938 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5939 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5940
5941 // mnemonic, condition code, Rt, Rt2, Qd, idx, Qd again, idx2
5942 assert(Operands.size() == MnemonicOpsEndInd + 6);
5943
5944 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1); // Rt
5945 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1])
5946 .addRegOperands(Inst, 1); // Rt2
5947 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 2])
5948 .addRegOperands(Inst, 1); // Qd
5949 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 3])
5950 .addMVEPairVectorIndexOperands(Inst, 1); // idx
5951 // skip second copy of Qd in Operands[6]
5952 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 5])
5953 .addMVEPairVectorIndexOperands(Inst, 1); // idx2
5954 if (CondI != 0) {
5955 ((ARMOperand &)*Operands[CondI])
5956 .addCondCodeOperands(Inst, 2); // condition code
5957 } else {
5958 ARMOperand Op =
5959 *ARMOperand::CreateCondCode(ARMCC::AL, Operands[0]->getEndLoc(), *this);
5960 Op.addCondCodeOperands(Inst, 2);
5961 }
5962}
5963
5964/// Parse an ARM memory expression, return false if successful else return true
5965/// or an error. The first token must be a '[' when called.
5966bool ARMAsmParser::parseMemory(OperandVector &Operands) {
5967 MCAsmParser &Parser = getParser();
5968 SMLoc S, E;
5969 if (Parser.getTok().isNot(AsmToken::LBrac))
5970 return TokError("Token is not a Left Bracket");
5971 S = Parser.getTok().getLoc();
5972 Parser.Lex(); // Eat left bracket token.
5973
5974 const AsmToken &BaseRegTok = Parser.getTok();
5975 MCRegister BaseReg = tryParseRegister();
5976 if (!BaseReg)
5977 return Error(BaseRegTok.getLoc(), "register expected");
5978
5979 // The next token must either be a comma, a colon or a closing bracket.
5980 const AsmToken &Tok = Parser.getTok();
5981 if (!Tok.is(AsmToken::Colon) && !Tok.is(AsmToken::Comma) &&
5982 !Tok.is(AsmToken::RBrac))
5983 return Error(Tok.getLoc(), "malformed memory operand");
5984
5985 if (Tok.is(AsmToken::RBrac)) {
5986 E = Tok.getEndLoc();
5987 Parser.Lex(); // Eat right bracket token.
5988
5989 Operands.push_back(ARMOperand::CreateMem(
5990 BaseReg, nullptr, 0, ARM_AM::no_shift, 0, 0, false, S, E, *this));
5991
5992 // If there's a pre-indexing writeback marker, '!', just add it as a token
5993 // operand. It's rather odd, but syntactically valid.
5994 if (Parser.getTok().is(AsmToken::Exclaim)) {
5995 Operands.push_back(
5996 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
5997 Parser.Lex(); // Eat the '!'.
5998 }
5999
6000 return false;
6001 }
6002
6003 assert((Tok.is(AsmToken::Colon) || Tok.is(AsmToken::Comma)) &&
6004 "Lost colon or comma in memory operand?!");
6005 if (Tok.is(AsmToken::Comma)) {
6006 Parser.Lex(); // Eat the comma.
6007 }
6008
6009 // If we have a ':', it's an alignment specifier.
6010 if (Parser.getTok().is(AsmToken::Colon)) {
6011 Parser.Lex(); // Eat the ':'.
6012 E = Parser.getTok().getLoc();
6013 SMLoc AlignmentLoc = Tok.getLoc();
6014
6015 const MCExpr *Expr;
6016 if (getParser().parseExpression(Expr))
6017 return true;
6018
6019 // The expression has to be a constant. Memory references with relocations
6020 // don't come through here, as they use the <label> forms of the relevant
6021 // instructions.
6022 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
6023 if (!CE)
6024 return Error (E, "constant expression expected");
6025
6026 unsigned Align = 0;
6027 switch (CE->getValue()) {
6028 default:
6029 return Error(E,
6030 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6031 case 16: Align = 2; break;
6032 case 32: Align = 4; break;
6033 case 64: Align = 8; break;
6034 case 128: Align = 16; break;
6035 case 256: Align = 32; break;
6036 }
6037
6038 // Now we should have the closing ']'
6039 if (Parser.getTok().isNot(AsmToken::RBrac))
6040 return Error(Parser.getTok().getLoc(), "']' expected");
6041 E = Parser.getTok().getEndLoc();
6042 Parser.Lex(); // Eat right bracket token.
6043
6044 // Don't worry about range checking the value here. That's handled by
6045 // the is*() predicates.
6046 Operands.push_back(ARMOperand::CreateMem(BaseReg, nullptr, 0,
6047 ARM_AM::no_shift, 0, Align, false,
6048 S, E, *this, AlignmentLoc));
6049
6050 // If there's a pre-indexing writeback marker, '!', just add it as a token
6051 // operand.
6052 if (Parser.getTok().is(AsmToken::Exclaim)) {
6053 Operands.push_back(
6054 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6055 Parser.Lex(); // Eat the '!'.
6056 }
6057
6058 return false;
6059 }
6060
6061 // If we have a '#' or '$', it's an immediate offset, else assume it's a
6062 // register offset. Be friendly and also accept a plain integer or expression
6063 // (without a leading hash) for gas compatibility.
6064 if (Parser.getTok().is(AsmToken::Hash) ||
6065 Parser.getTok().is(AsmToken::Dollar) ||
6066 Parser.getTok().is(AsmToken::LParen) ||
6067 Parser.getTok().is(AsmToken::Integer)) {
6068 if (Parser.getTok().is(AsmToken::Hash) ||
6069 Parser.getTok().is(AsmToken::Dollar))
6070 Parser.Lex(); // Eat '#' or '$'
6071 E = Parser.getTok().getLoc();
6072
6073 bool isNegative = getParser().getTok().is(AsmToken::Minus);
6074 const MCExpr *Offset, *AdjustedOffset;
6075 if (getParser().parseExpression(Offset))
6076 return true;
6077
6078 if (const auto *CE = dyn_cast<MCConstantExpr>(Offset)) {
6079 // If the constant was #-0, represent it as
6080 // std::numeric_limits<int32_t>::min().
6081 int32_t Val = CE->getValue();
6082 if (isNegative && Val == 0)
6083 CE = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
6084 getContext());
6085 // Don't worry about range checking the value here. That's handled by
6086 // the is*() predicates.
6087 AdjustedOffset = CE;
6088 } else
6089 AdjustedOffset = Offset;
6090 Operands.push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6091 ARM_AM::no_shift, 0, 0, false, S,
6092 E, *this));
6093
6094 // Now we should have the closing ']'
6095 if (Parser.getTok().isNot(AsmToken::RBrac))
6096 return Error(Parser.getTok().getLoc(), "']' expected");
6097 E = Parser.getTok().getEndLoc();
6098 Parser.Lex(); // Eat right bracket token.
6099
6100 // If there's a pre-indexing writeback marker, '!', just add it as a token
6101 // operand.
6102 if (Parser.getTok().is(AsmToken::Exclaim)) {
6103 Operands.push_back(
6104 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6105 Parser.Lex(); // Eat the '!'.
6106 }
6107
6108 return false;
6109 }
6110
6111 // The register offset is optionally preceded by a '+' or '-'
6112 bool isNegative = false;
6113 if (Parser.getTok().is(AsmToken::Minus)) {
6114 isNegative = true;
6115 Parser.Lex(); // Eat the '-'.
6116 } else if (Parser.getTok().is(AsmToken::Plus)) {
6117 // Nothing to do.
6118 Parser.Lex(); // Eat the '+'.
6119 }
6120
6121 E = Parser.getTok().getLoc();
6122 MCRegister OffsetReg = tryParseRegister();
6123 if (!OffsetReg)
6124 return Error(E, "register expected");
6125
6126 // If there's a shift operator, handle it.
6128 unsigned ShiftImm = 0;
6129 if (Parser.getTok().is(AsmToken::Comma)) {
6130 Parser.Lex(); // Eat the ','.
6131 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6132 return true;
6133 }
6134
6135 // Now we should have the closing ']'
6136 if (Parser.getTok().isNot(AsmToken::RBrac))
6137 return Error(Parser.getTok().getLoc(), "']' expected");
6138 E = Parser.getTok().getEndLoc();
6139 Parser.Lex(); // Eat right bracket token.
6140
6141 Operands.push_back(ARMOperand::CreateMem(BaseReg, nullptr, OffsetReg,
6142 ShiftType, ShiftImm, 0, isNegative,
6143 S, E, *this));
6144
6145 // If there's a pre-indexing writeback marker, '!', just add it as a token
6146 // operand.
6147 if (Parser.getTok().is(AsmToken::Exclaim)) {
6148 Operands.push_back(
6149 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6150 Parser.Lex(); // Eat the '!'.
6151 }
6152
6153 return false;
6154}
6155
6156/// parseMemRegOffsetShift - one of these two:
6157/// ( lsl | lsr | asr | ror ) , # shift_amount
6158/// rrx
6159/// return true if it parses a shift otherwise it returns false.
6160bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
6161 unsigned &Amount) {
6162 MCAsmParser &Parser = getParser();
6163 SMLoc Loc = Parser.getTok().getLoc();
6164 const AsmToken &Tok = Parser.getTok();
6165 if (Tok.isNot(AsmToken::Identifier))
6166 return Error(Loc, "illegal shift operator");
6167 StringRef ShiftName = Tok.getString();
6168 if (ShiftName == "lsl" || ShiftName == "LSL" ||
6169 ShiftName == "asl" || ShiftName == "ASL")
6170 St = ARM_AM::lsl;
6171 else if (ShiftName == "lsr" || ShiftName == "LSR")
6172 St = ARM_AM::lsr;
6173 else if (ShiftName == "asr" || ShiftName == "ASR")
6174 St = ARM_AM::asr;
6175 else if (ShiftName == "ror" || ShiftName == "ROR")
6176 St = ARM_AM::ror;
6177 else if (ShiftName == "rrx" || ShiftName == "RRX")
6178 St = ARM_AM::rrx;
6179 else if (ShiftName == "uxtw" || ShiftName == "UXTW")
6180 St = ARM_AM::uxtw;
6181 else
6182 return Error(Loc, "illegal shift operator");
6183 Parser.Lex(); // Eat shift type token.
6184
6185 // rrx stands alone.
6186 Amount = 0;
6187 if (St != ARM_AM::rrx) {
6188 Loc = Parser.getTok().getLoc();
6189 // A '#' and a shift amount.
6190 const AsmToken &HashTok = Parser.getTok();
6191 if (HashTok.isNot(AsmToken::Hash) &&
6192 HashTok.isNot(AsmToken::Dollar))
6193 return Error(HashTok.getLoc(), "'#' expected");
6194 Parser.Lex(); // Eat hash token.
6195
6196 const MCExpr *Expr;
6197 if (getParser().parseExpression(Expr))
6198 return true;
6199 // Range check the immediate.
6200 // lsl, ror: 0 <= imm <= 31
6201 // lsr, asr: 0 <= imm <= 32
6202 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
6203 if (!CE)
6204 return Error(Loc, "shift amount must be an immediate");
6205 int64_t Imm = CE->getValue();
6206 if (Imm < 0 ||
6207 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
6208 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
6209 return Error(Loc, "immediate shift value out of range");
6210 // If <ShiftTy> #0, turn it into a no_shift.
6211 if (Imm == 0)
6212 St = ARM_AM::lsl;
6213 // For consistency, treat lsr #32 and asr #32 as having immediate value 0.
6214 if (Imm == 32)
6215 Imm = 0;
6216 Amount = Imm;
6217 }
6218
6219 return false;
6220}
6221
6222/// parseFPImm - A floating point immediate expression operand.
6223ParseStatus ARMAsmParser::parseFPImm(OperandVector &Operands) {
6224 LLVM_DEBUG(dbgs() << "PARSE FPImm, Ops: " << Operands.size());
6225
6226 MCAsmParser &Parser = getParser();
6227 // Anything that can accept a floating point constant as an operand
6228 // needs to go through here, as the regular parseExpression is
6229 // integer only.
6230 //
6231 // This routine still creates a generic Immediate operand, containing
6232 // a bitcast of the 64-bit floating point value. The various operands
6233 // that accept floats can check whether the value is valid for them
6234 // via the standard is*() predicates.
6235
6236 SMLoc S = Parser.getTok().getLoc();
6237
6238 if (Parser.getTok().isNot(AsmToken::Hash) &&
6239 Parser.getTok().isNot(AsmToken::Dollar))
6240 return ParseStatus::NoMatch;
6241
6242 // Disambiguate the VMOV forms that can accept an FP immediate.
6243 // vmov.f32 <sreg>, #imm
6244 // vmov.f64 <dreg>, #imm
6245 // vmov.f32 <dreg>, #imm @ vector f32x2
6246 // vmov.f32 <qreg>, #imm @ vector f32x4
6247 //
6248 // There are also the NEON VMOV instructions which expect an
6249 // integer constant. Make sure we don't try to parse an FPImm
6250 // for these:
6251 // vmov.i{8|16|32|64} <dreg|qreg>, #imm
6252
6253 bool isVmovf = false;
6254 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
6255 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
6256 ARMOperand &TyOp = static_cast<ARMOperand &>(*Operands[I]);
6257 if (TyOp.isToken() &&
6258 (TyOp.getToken() == ".f32" || TyOp.getToken() == ".f64" ||
6259 TyOp.getToken() == ".f16")) {
6260 isVmovf = true;
6261 break;
6262 }
6263 }
6264
6265 ARMOperand &Mnemonic = static_cast<ARMOperand &>(*Operands[0]);
6266 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() == "fconstd" ||
6267 Mnemonic.getToken() == "fconsts");
6268 if (!(isVmovf || isFconst))
6269 return ParseStatus::NoMatch;
6270
6271 Parser.Lex(); // Eat '#' or '$'.
6272
6273 // Handle negation, as that still comes through as a separate token.
6274 bool isNegative = false;
6275 if (Parser.getTok().is(AsmToken::Minus)) {
6276 isNegative = true;
6277 Parser.Lex();
6278 }
6279 const AsmToken &Tok = Parser.getTok();
6280 SMLoc Loc = Tok.getLoc();
6281 if (Tok.is(AsmToken::Real) && isVmovf) {
6282 APFloat RealVal(APFloat::IEEEsingle(), Tok.getString());
6283 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
6284 // If we had a '-' in front, toggle the sign bit.
6285 IntVal ^= (uint64_t)isNegative << 31;
6286 Parser.Lex(); // Eat the token.
6287 Operands.push_back(
6288 ARMOperand::CreateImm(MCConstantExpr::create(IntVal, getContext()), S,
6289 Parser.getTok().getLoc(), *this));
6290 return ParseStatus::Success;
6291 }
6292 // Also handle plain integers. Instructions which allow floating point
6293 // immediates also allow a raw encoded 8-bit value.
6294 if (Tok.is(AsmToken::Integer) && isFconst) {
6295 int64_t Val = Tok.getIntVal();
6296 Parser.Lex(); // Eat the token.
6297 if (Val > 255 || Val < 0)
6298 return Error(Loc, "encoded floating point value out of range");
6299 float RealVal = ARM_AM::getFPImmFloat(Val);
6300 Val = APFloat(RealVal).bitcastToAPInt().getZExtValue();
6301
6302 Operands.push_back(
6303 ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S,
6304 Parser.getTok().getLoc(), *this));
6305 return ParseStatus::Success;
6306 }
6307
6308 return Error(Loc, "invalid floating point immediate");
6309}
6310
6311/// Parse a arm instruction operand. For now this parses the operand regardless
6312/// of the mnemonic.
6313bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6314 MCAsmParser &Parser = getParser();
6315 SMLoc S, E;
6316
6317 // Check if the current operand has a custom associated parser, if so, try to
6318 // custom parse the operand, or fallback to the general approach.
6319 ParseStatus ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6320 if (ResTy.isSuccess())
6321 return false;
6322 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6323 // there was a match, but an error occurred, in which case, just return that
6324 // the operand parsing failed.
6325 if (ResTy.isFailure())
6326 return true;
6327
6328 switch (getLexer().getKind()) {
6329 default:
6330 Error(Parser.getTok().getLoc(), "unexpected token in operand");
6331 return true;
6332 case AsmToken::Identifier: {
6333 // If we've seen a branch mnemonic, the next operand must be a label. This
6334 // is true even if the label is a register name. So "br r1" means branch to
6335 // label "r1".
6336 bool ExpectLabel = Mnemonic == "b" || Mnemonic == "bl";
6337 if (!ExpectLabel) {
6338 if (!tryParseRegisterWithWriteBack(Operands))
6339 return false;
6340 int Res = tryParseShiftRegister(Operands);
6341 if (Res == 0) // success
6342 return false;
6343 else if (Res == -1) // irrecoverable error
6344 return true;
6345 // If this is VMRS, check for the apsr_nzcv operand.
6346 if (Mnemonic == "vmrs" &&
6347 Parser.getTok().getString().equals_insensitive("apsr_nzcv")) {
6348 S = Parser.getTok().getLoc();
6349 Parser.Lex();
6350 Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S, *this));
6351 return false;
6352 }
6353 }
6354
6355 // Fall though for the Identifier case that is not a register or a
6356 // special name.
6357 [[fallthrough]];
6358 }
6359 case AsmToken::LParen: // parenthesized expressions like (_strcmp-4)
6360 case AsmToken::Integer: // things like 1f and 2b as a branch targets
6361 case AsmToken::String: // quoted label names.
6362 case AsmToken::Dot: { // . as a branch target
6363 // This was not a register so parse other operands that start with an
6364 // identifier (like labels) as expressions and create them as immediates.
6365 const MCExpr *IdVal;
6366 S = Parser.getTok().getLoc();
6367 if (getParser().parseExpression(IdVal))
6368 return true;
6369 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6370 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E, *this));
6371 return false;
6372 }
6373 case AsmToken::LBrac:
6374 return parseMemory(Operands);
6375 case AsmToken::LCurly: {
6376 bool IsLazyLoadStore = Mnemonic == "vlldm" || Mnemonic == "vlstm";
6377 bool IsVSCCLRM = Mnemonic == "vscclrm";
6378 return parseRegisterList(Operands, !Mnemonic.starts_with("clr"), false,
6379 IsLazyLoadStore, IsVSCCLRM);
6380 }
6381 case AsmToken::Dollar:
6382 case AsmToken::Hash: {
6383 // #42 -> immediate
6384 // $ 42 -> immediate
6385 // $foo -> symbol name
6386 // $42 -> symbol name
6387 S = Parser.getTok().getLoc();
6388
6389 // Favor the interpretation of $-prefixed operands as symbol names.
6390 // Cases where immediates are explicitly expected are handled by their
6391 // specific ParseMethod implementations.
6392 auto AdjacentToken = getLexer().peekTok(/*ShouldSkipSpace=*/false);
6393 bool ExpectIdentifier = Parser.getTok().is(AsmToken::Dollar) &&
6394 (AdjacentToken.is(AsmToken::Identifier) ||
6395 AdjacentToken.is(AsmToken::Integer));
6396 if (!ExpectIdentifier) {
6397 // Token is not part of identifier. Drop leading $ or # before parsing
6398 // expression.
6399 Parser.Lex();
6400 }
6401
6402 if (Parser.getTok().isNot(AsmToken::Colon)) {
6403 bool IsNegative = Parser.getTok().is(AsmToken::Minus);
6404 const MCExpr *ImmVal;
6405 if (getParser().parseExpression(ImmVal))
6406 return true;
6407 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
6408 if (CE) {
6409 int32_t Val = CE->getValue();
6410 if (IsNegative && Val == 0)
6411 ImmVal = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
6412 getContext());
6413 }
6414 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6415 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E, *this));
6416
6417 // There can be a trailing '!' on operands that we want as a separate
6418 // '!' Token operand. Handle that here. For example, the compatibility
6419 // alias for 'srsdb sp!, #imm' is 'srsdb #imm!'.
6420 if (Parser.getTok().is(AsmToken::Exclaim)) {
6421 Operands.push_back(ARMOperand::CreateToken(
6422 Parser.getTok().getString(), Parser.getTok().getLoc(), *this));
6423 Parser.Lex(); // Eat exclaim token
6424 }
6425 return false;
6426 }
6427 // w/ a ':' after the '#', it's just like a plain ':'.
6428 [[fallthrough]];
6429 }
6430 case AsmToken::Colon: {
6431 S = Parser.getTok().getLoc();
6432 // ":lower16:", ":upper16:", ":lower0_7:", ":lower8_15:", ":upper0_7:" and
6433 // ":upper8_15:", expression prefixes
6434 // FIXME: Check it's an expression prefix,
6435 // e.g. (FOO - :lower16:BAR) isn't legal.
6436 ARM::Specifier Spec;
6437 if (parsePrefix(Spec))
6438 return true;
6439
6440 const MCExpr *SubExprVal;
6441 if (getParser().parseExpression(SubExprVal))
6442 return true;
6443
6444 const auto *ExprVal =
6445 MCSpecifierExpr::create(SubExprVal, Spec, getContext(), S);
6446 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6447 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E, *this));
6448 return false;
6449 }
6450 case AsmToken::Equal: {
6451 S = Parser.getTok().getLoc();
6452 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
6453 return Error(S, "unexpected token in operand");
6454 Parser.Lex(); // Eat '='
6455 const MCExpr *SubExprVal;
6456 if (getParser().parseExpression(SubExprVal))
6457 return true;
6458 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6459
6460 // execute-only: we assume that assembly programmers know what they are
6461 // doing and allow literal pool creation here
6462 Operands.push_back(
6463 ARMOperand::CreateConstantPoolImm(SubExprVal, S, E, *this));
6464 return false;
6465 }
6466 }
6467}
6468
6469bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6470 const MCExpr *Expr = nullptr;
6471 SMLoc L = getParser().getTok().getLoc();
6472 if (check(getParser().parseExpression(Expr), L, "expected expression"))
6473 return true;
6474 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
6475 if (check(!Value, L, "expected constant expression"))
6476 return true;
6477 Out = Value->getValue();
6478 return false;
6479}
6480
6481// parsePrefix - Parse ARM 16-bit relocations expression prefixes, i.e.
6482// :lower16: and :upper16: and Thumb 8-bit relocation expression prefixes, i.e.
6483// :upper8_15:, :upper0_7:, :lower8_15: and :lower0_7:
6484bool ARMAsmParser::parsePrefix(ARM::Specifier &Spec) {
6485 MCAsmParser &Parser = getParser();
6486 Spec = ARM::S_None;
6487
6488 // consume an optional '#' (GNU compatibility)
6489 if (getLexer().is(AsmToken::Hash))
6490 Parser.Lex();
6491
6492 assert(getLexer().is(AsmToken::Colon) && "expected a :");
6493 Parser.Lex(); // Eat ':'
6494
6495 if (getLexer().isNot(AsmToken::Identifier)) {
6496 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
6497 return true;
6498 }
6499
6500 enum {
6501 COFF = (1 << MCContext::IsCOFF),
6502 ELF = (1 << MCContext::IsELF),
6503 MACHO = (1 << MCContext::IsMachO),
6504 WASM = (1 << MCContext::IsWasm),
6505 };
6506 static const struct PrefixEntry {
6507 const char *Spelling;
6508 ARM::Specifier Spec;
6509 uint8_t SupportedFormats;
6510 } PrefixEntries[] = {
6511 {"upper16", ARM::S_HI16, COFF | ELF | MACHO},
6512 {"lower16", ARM::S_LO16, COFF | ELF | MACHO},
6513 {"upper8_15", ARM::S_HI_8_15, ELF},
6514 {"upper0_7", ARM::S_HI_0_7, ELF},
6515 {"lower8_15", ARM::S_LO_8_15, ELF},
6516 {"lower0_7", ARM::S_LO_0_7, ELF},
6517 };
6518
6519 StringRef IDVal = Parser.getTok().getIdentifier();
6520
6521 const auto &Prefix =
6522 llvm::find_if(PrefixEntries, [&IDVal](const PrefixEntry &PE) {
6523 return PE.Spelling == IDVal;
6524 });
6525 if (Prefix == std::end(PrefixEntries)) {
6526 Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
6527 return true;
6528 }
6529
6530 uint8_t CurrentFormat;
6531 switch (getContext().getObjectFileType()) {
6532 case MCContext::IsMachO:
6533 CurrentFormat = MACHO;
6534 break;
6535 case MCContext::IsELF:
6536 CurrentFormat = ELF;
6537 break;
6538 case MCContext::IsCOFF:
6539 CurrentFormat = COFF;
6540 break;
6541 case MCContext::IsWasm:
6542 CurrentFormat = WASM;
6543 break;
6544 case MCContext::IsGOFF:
6545 case MCContext::IsSPIRV:
6546 case MCContext::IsXCOFF:
6548 llvm_unreachable("unexpected object format");
6549 break;
6550 }
6551
6552 if (~Prefix->SupportedFormats & CurrentFormat) {
6553 Error(Parser.getTok().getLoc(),
6554 "cannot represent relocation in the current file format");
6555 return true;
6556 }
6557
6558 Spec = Prefix->Spec;
6559 Parser.Lex();
6560
6561 if (getLexer().isNot(AsmToken::Colon)) {
6562 Error(Parser.getTok().getLoc(), "unexpected token after prefix");
6563 return true;
6564 }
6565 Parser.Lex(); // Eat the last ':'
6566
6567 // consume an optional trailing '#' (GNU compatibility) bla
6568 parseOptionalToken(AsmToken::Hash);
6569
6570 return false;
6571}
6572
6573/// Given a mnemonic, split out possible predication code and carry
6574/// setting letters to form a canonical mnemonic and flags.
6575//
6576// FIXME: Would be nice to autogen this.
6577// FIXME: This is a bit of a maze of special cases.
6578StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6579 ARMCC::CondCodes &PredicationCode,
6580 ARMVCC::VPTCodes &VPTPredicationCode,
6581 bool &CarrySetting,
6582 unsigned &ProcessorIMod,
6583 StringRef &ITMask) {
6584 PredicationCode = ARMCC::AL;
6585 VPTPredicationCode = ARMVCC::None;
6586 CarrySetting = false;
6587 ProcessorIMod = 0;
6588
6589 // Ignore some mnemonics we know aren't predicated forms.
6590 //
6591 // FIXME: Would be nice to autogen this.
6592 if ((Mnemonic == "movs" && isThumb()) || Mnemonic == "teq" ||
6593 Mnemonic == "vceq" || Mnemonic == "svc" || Mnemonic == "mls" ||
6594 Mnemonic == "smmls" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
6595 Mnemonic == "vnmls" || Mnemonic == "vacge" || Mnemonic == "vcge" ||
6596 Mnemonic == "vclt" || Mnemonic == "vacgt" || Mnemonic == "vaclt" ||
6597 Mnemonic == "vacle" || Mnemonic == "hlt" || Mnemonic == "vcgt" ||
6598 Mnemonic == "vcle" || Mnemonic == "smlal" || Mnemonic == "umaal" ||
6599 Mnemonic == "umlal" || Mnemonic == "vabal" || Mnemonic == "vmlal" ||
6600 Mnemonic == "vpadal" || Mnemonic == "vqdmlal" || Mnemonic == "fmuls" ||
6601 Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" ||
6602 Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" ||
6603 Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" ||
6604 Mnemonic == "vrintm" || Mnemonic == "hvc" ||
6605 Mnemonic.starts_with("vsel") || Mnemonic == "vins" ||
6606 Mnemonic == "vmovx" || Mnemonic == "bxns" || Mnemonic == "blxns" ||
6607 Mnemonic == "vdot" || Mnemonic == "vmmla" || Mnemonic == "vudot" ||
6608 Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
6609 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || Mnemonic == "wls" ||
6610 Mnemonic == "le" || Mnemonic == "dls" || Mnemonic == "csel" ||
6611 Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" ||
6612 Mnemonic == "cinc" || Mnemonic == "cinv" || Mnemonic == "cneg" ||
6613 Mnemonic == "cset" || Mnemonic == "csetm" || Mnemonic == "aut" ||
6614 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "bti")
6615 return Mnemonic;
6616
6617 // First, split out any predication code. Ignore mnemonics we know aren't
6618 // predicated but do have a carry-set and so weren't caught above.
6619 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
6620 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
6621 Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
6622 Mnemonic != "sbcs" && Mnemonic != "rscs" &&
6623 !(hasMVE() &&
6624 (Mnemonic == "vmine" || Mnemonic == "vshle" || Mnemonic == "vshlt" ||
6625 Mnemonic == "vshllt" || Mnemonic == "vrshle" || Mnemonic == "vrshlt" ||
6626 Mnemonic == "vmvne" || Mnemonic == "vorne" || Mnemonic == "vnege" ||
6627 Mnemonic == "vnegt" || Mnemonic == "vmule" || Mnemonic == "vmult" ||
6628 Mnemonic == "vrintne" || Mnemonic == "vcmult" ||
6629 Mnemonic == "vcmule" || Mnemonic == "vpsele" || Mnemonic == "vpselt" ||
6630 Mnemonic.starts_with("vq")))) {
6631 unsigned CC = ARMCondCodeFromString(Mnemonic.substr(Mnemonic.size()-2));
6632 if (CC != ~0U) {
6633 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
6634 PredicationCode = static_cast<ARMCC::CondCodes>(CC);
6635 }
6636 }
6637
6638 // Next, determine if we have a carry setting bit. We explicitly ignore all
6639 // the instructions we know end in 's'.
6640 if (Mnemonic.ends_with("s") &&
6641 !(Mnemonic == "cps" || Mnemonic == "mls" || Mnemonic == "mrs" ||
6642 Mnemonic == "smmls" || Mnemonic == "vabs" || Mnemonic == "vcls" ||
6643 Mnemonic == "vmls" || Mnemonic == "vmrs" || Mnemonic == "vnmls" ||
6644 Mnemonic == "vqabs" || Mnemonic == "vrecps" || Mnemonic == "vrsqrts" ||
6645 Mnemonic == "srs" || Mnemonic == "flds" || Mnemonic == "fmrs" ||
6646 Mnemonic == "fsqrts" || Mnemonic == "fsubs" || Mnemonic == "fsts" ||
6647 Mnemonic == "fcpys" || Mnemonic == "fdivs" || Mnemonic == "fmuls" ||
6648 Mnemonic == "fcmps" || Mnemonic == "fcmpzs" || Mnemonic == "vfms" ||
6649 Mnemonic == "vfnms" || Mnemonic == "fconsts" || Mnemonic == "bxns" ||
6650 Mnemonic == "blxns" || Mnemonic == "vfmas" || Mnemonic == "vmlas" ||
6651 (Mnemonic == "movs" && isThumb()))) {
6652 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
6653 CarrySetting = true;
6654 }
6655
6656 // The "cps" instruction can have a interrupt mode operand which is glued into
6657 // the mnemonic. Check if this is the case, split it and parse the imod op
6658 if (Mnemonic.starts_with("cps")) {
6659 // Split out any imod code.
6660 unsigned IMod =
6661 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
6662 .Case("ie", ARM_PROC::IE)
6663 .Case("id", ARM_PROC::ID)
6664 .Default(~0U);
6665 if (IMod != ~0U) {
6666 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
6667 ProcessorIMod = IMod;
6668 }
6669 }
6670
6671 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic != "vmovlt" &&
6672 Mnemonic != "vshllt" && Mnemonic != "vrshrnt" && Mnemonic != "vshrnt" &&
6673 Mnemonic != "vqrshrunt" && Mnemonic != "vqshrunt" &&
6674 Mnemonic != "vqrshrnt" && Mnemonic != "vqshrnt" && Mnemonic != "vmullt" &&
6675 Mnemonic != "vqmovnt" && Mnemonic != "vqmovunt" && Mnemonic != "vmovnt" &&
6676 Mnemonic != "vqdmullt" && Mnemonic != "vpnot" && Mnemonic != "vcvtt" &&
6677 Mnemonic != "vcvt") {
6678 unsigned VCC =
6679 ARMVectorCondCodeFromString(Mnemonic.substr(Mnemonic.size() - 1));
6680 if (VCC != ~0U) {
6681 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-1);
6682 VPTPredicationCode = static_cast<ARMVCC::VPTCodes>(VCC);
6683 }
6684 return Mnemonic;
6685 }
6686
6687 // The "it" instruction has the condition mask on the end of the mnemonic.
6688 if (Mnemonic.starts_with("it")) {
6689 ITMask = Mnemonic.substr(2);
6690 Mnemonic = Mnemonic.slice(0, 2);
6691 }
6692
6693 if (Mnemonic.starts_with("vpst")) {
6694 ITMask = Mnemonic.substr(4);
6695 Mnemonic = Mnemonic.slice(0, 4);
6696 } else if (Mnemonic.starts_with("vpt")) {
6697 ITMask = Mnemonic.substr(3);
6698 Mnemonic = Mnemonic.slice(0, 3);
6699 }
6700
6701 return Mnemonic;
6702}
6703
6704/// Given a canonical mnemonic, determine if the instruction ever allows
6705/// inclusion of carry set or predication code operands.
6706//
6707// FIXME: It would be nice to autogen this.
6708void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6709 StringRef ExtraToken,
6710 StringRef FullInst,
6711 bool &CanAcceptCarrySet,
6712 bool &CanAcceptPredicationCode,
6713 bool &CanAcceptVPTPredicationCode) {
6714 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6715
6716 CanAcceptCarrySet =
6717 Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
6718 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
6719 Mnemonic == "add" || Mnemonic == "adc" || Mnemonic == "mul" ||
6720 Mnemonic == "bic" || Mnemonic == "asr" || Mnemonic == "orr" ||
6721 Mnemonic == "mvn" || Mnemonic == "rsb" || Mnemonic == "rsc" ||
6722 Mnemonic == "orn" || Mnemonic == "sbc" || Mnemonic == "eor" ||
6723 Mnemonic == "neg" || Mnemonic == "vfm" || Mnemonic == "vfnm" ||
6724 (!isThumb() &&
6725 (Mnemonic == "smull" || Mnemonic == "mov" || Mnemonic == "mla" ||
6726 Mnemonic == "smlal" || Mnemonic == "umlal" || Mnemonic == "umull"));
6727
6728 if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
6729 Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
6730 Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic == "udf" ||
6731 Mnemonic.starts_with("crc32") || Mnemonic.starts_with("cps") ||
6732 Mnemonic.starts_with("vsel") || Mnemonic == "vmaxnm" ||
6733 Mnemonic == "vminnm" || Mnemonic == "vcvta" || Mnemonic == "vcvtn" ||
6734 Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || Mnemonic == "vrinta" ||
6735 Mnemonic == "vrintn" || Mnemonic == "vrintp" || Mnemonic == "vrintm" ||
6736 Mnemonic.starts_with("aes") || Mnemonic == "hvc" ||
6737 Mnemonic == "setpan" || Mnemonic.starts_with("sha1") ||
6738 Mnemonic.starts_with("sha256") ||
6739 (FullInst.starts_with("vmull") && FullInst.ends_with(".p64")) ||
6740 Mnemonic == "vmovx" || Mnemonic == "vins" || Mnemonic == "vudot" ||
6741 Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
6742 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || Mnemonic == "vfmat" ||
6743 Mnemonic == "vfmab" || Mnemonic == "vdot" || Mnemonic == "vmmla" ||
6744 Mnemonic == "sb" || Mnemonic == "ssbb" || Mnemonic == "pssbb" ||
6745 Mnemonic == "vsmmla" || Mnemonic == "vummla" || Mnemonic == "vusmmla" ||
6746 Mnemonic == "vusdot" || Mnemonic == "vsudot" || Mnemonic == "bfcsel" ||
6747 Mnemonic == "wls" || Mnemonic == "dls" || Mnemonic == "le" ||
6748 Mnemonic == "csel" || Mnemonic == "csinc" || Mnemonic == "csinv" ||
6749 Mnemonic == "csneg" || Mnemonic == "cinc" || Mnemonic == "cinv" ||
6750 Mnemonic == "cneg" || Mnemonic == "cset" || Mnemonic == "csetm" ||
6751 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6752 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6753 Mnemonic.starts_with("vpt") || Mnemonic.starts_with("vpst") ||
6754 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "aut" ||
6755 Mnemonic == "bti" ||
6756 (hasMVE() &&
6757 (Mnemonic.starts_with("vst2") || Mnemonic.starts_with("vld2") ||
6758 Mnemonic.starts_with("vst4") || Mnemonic.starts_with("vld4") ||
6759 Mnemonic.starts_with("wlstp") || Mnemonic.starts_with("dlstp") ||
6760 Mnemonic.starts_with("letp")))) {
6761 // These mnemonics are never predicable
6762 CanAcceptPredicationCode = false;
6763 } else if (!isThumb()) {
6764 // Some instructions are only predicable in Thumb mode
6765 CanAcceptPredicationCode =
6766 Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" &&
6767 Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" &&
6768 Mnemonic != "dmb" && Mnemonic != "dfb" && Mnemonic != "dsb" &&
6769 Mnemonic != "isb" && Mnemonic != "pld" && Mnemonic != "pli" &&
6770 Mnemonic != "pldw" && Mnemonic != "ldc2" && Mnemonic != "ldc2l" &&
6771 Mnemonic != "stc2" && Mnemonic != "stc2l" && Mnemonic != "tsb" &&
6772 !Mnemonic.starts_with("rfe") && !Mnemonic.starts_with("srs");
6773 } else if (isThumbOne()) {
6774 if (hasV6MOps())
6775 CanAcceptPredicationCode = Mnemonic != "movs";
6776 else
6777 CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs";
6778 } else
6779 CanAcceptPredicationCode = true;
6780}
6781
6782bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6783 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I) {
6784 auto &Op = static_cast<ARMOperand &>(*Operands[I]);
6785 if (Op.isToken() && Op.getToken() == ".w")
6786 return true;
6787 }
6788 return false;
6789}
6790
6791// Some Thumb instructions have two operand forms that are not
6792// available as three operand, convert to two operand form if possible.
6793//
6794// FIXME: We would really like to be able to tablegen'erate this.
6795void ARMAsmParser::tryConvertingToTwoOperandForm(
6796 StringRef Mnemonic, ARMCC::CondCodes PredicationCode, bool CarrySetting,
6797 OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6798
6799 if (operandsContainWide(Operands, MnemonicOpsEndInd))
6800 return;
6801 if (Operands.size() != MnemonicOpsEndInd + 3)
6802 return;
6803
6804 const auto &Op3 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
6805 auto &Op4 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
6806 if (!Op3.isReg() || !Op4.isReg())
6807 return;
6808
6809 auto Op3Reg = Op3.getReg();
6810 auto Op4Reg = Op4.getReg();
6811
6812 // For most Thumb2 cases we just generate the 3 operand form and reduce
6813 // it in processInstruction(), but the 3 operand form of ADD (t2ADDrr)
6814 // won't accept SP or PC so we do the transformation here taking care
6815 // with immediate range in the 'add sp, sp #imm' case.
6816 auto &Op5 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 2]);
6817 if (isThumbTwo()) {
6818 if (Mnemonic != "add")
6819 return;
6820 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6821 (Op5.isReg() && Op5.getReg() == ARM::PC);
6822 if (!TryTransform) {
6823 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6824 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6825 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6826 Op5.isImm() && !Op5.isImm0_508s4());
6827 }
6828 if (!TryTransform)
6829 return;
6830 } else if (!isThumbOne())
6831 return;
6832
6833 if (!(Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
6834 Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
6835 Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
6836 Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic"))
6837 return;
6838
6839 // If first 2 operands of a 3 operand instruction are the same
6840 // then transform to 2 operand version of the same instruction
6841 // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
6842 bool Transform = Op3Reg == Op4Reg;
6843
6844 // For communtative operations, we might be able to transform if we swap
6845 // Op4 and Op5. The 'ADD Rdm, SP, Rdm' form is already handled specially
6846 // as tADDrsp.
6847 const ARMOperand *LastOp = &Op5;
6848 bool Swap = false;
6849 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6850 ((Mnemonic == "add" && Op4Reg != ARM::SP) ||
6851 Mnemonic == "and" || Mnemonic == "eor" ||
6852 Mnemonic == "adc" || Mnemonic == "orr")) {
6853 Swap = true;
6854 LastOp = &Op4;
6855 Transform = true;
6856 }
6857
6858 // If both registers are the same then remove one of them from
6859 // the operand list, with certain exceptions.
6860 if (Transform) {
6861 // Don't transform 'adds Rd, Rd, Rm' or 'sub{s} Rd, Rd, Rm' because the
6862 // 2 operand forms don't exist.
6863 if (((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub") &&
6864 LastOp->isReg())
6865 Transform = false;
6866
6867 // Don't transform 'add/sub{s} Rd, Rd, #imm' if the immediate fits into
6868 // 3-bits because the ARMARM says not to.
6869 if ((Mnemonic == "add" || Mnemonic == "sub") && LastOp->isImm0_7())
6870 Transform = false;
6871 }
6872
6873 if (Transform) {
6874 if (Swap)
6875 std::swap(Op4, Op5);
6876 Operands.erase(Operands.begin() + MnemonicOpsEndInd);
6877 }
6878}
6879
6880static bool isARMMCExpr(MCParsedAsmOperand &MCOp);
6881// this function returns true if the operand is one of the following
6882// relocations: :upper8_15:, :upper0_7:, :lower8_15: or :lower0_7:
6884 assert(isARMMCExpr(MCOp));
6885 ARMOperand &Op = static_cast<ARMOperand &>(MCOp);
6886 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(Op.getImm());
6887 if (ARM16Expr && (ARM16Expr->getSpecifier() == ARM::S_HI_8_15 ||
6888 ARM16Expr->getSpecifier() == ARM::S_HI_0_7 ||
6889 ARM16Expr->getSpecifier() == ARM::S_LO_8_15 ||
6890 ARM16Expr->getSpecifier() == ARM::S_LO_0_7))
6891 return true;
6892 return false;
6893}
6894
6895bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6896 StringRef Mnemonic, OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6897 if (!hasMVE() || Operands.size() <= MnemonicOpsEndInd)
6898 return true;
6899
6900 if (Mnemonic.starts_with("vld2") || Mnemonic.starts_with("vld4") ||
6901 Mnemonic.starts_with("vst2") || Mnemonic.starts_with("vst4"))
6902 return true;
6903
6904 if (Mnemonic.starts_with("vctp") || Mnemonic.starts_with("vpnot"))
6905 return false;
6906
6907 if (Mnemonic.starts_with("vmov") &&
6908 !(Mnemonic.starts_with("vmovl") || Mnemonic.starts_with("vmovn") ||
6909 Mnemonic.starts_with("vmovx"))) {
6910 for (auto &Operand : Operands) {
6911 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() ||
6912 ((*Operand).isReg() && (getARMMCRegisterClass(ARM::SPRRegClassID)
6913 .contains((*Operand).getReg()) ||
6914 getARMMCRegisterClass(ARM::DPRRegClassID)
6915 .contains((*Operand).getReg())))) {
6916 return true;
6917 }
6918 }
6919 return false;
6920 } else {
6921 for (auto &Operand : Operands) {
6922 // We check the larger class QPR instead of just the legal class
6923 // MQPR, to more accurately report errors when using Q registers
6924 // outside of the allowed range.
6925 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() ||
6926 static_cast<ARMOperand &>(*Operand).isQReg())
6927 return false;
6928 }
6929 return true;
6930 }
6931}
6932
6933// FIXME: This bit should probably be handled via an explicit match class
6934// in the .td files that matches the suffix instead of having it be
6935// a literal string token the way it is now.
6937 return Mnemonic.starts_with("vldm") || Mnemonic.starts_with("vstm");
6938}
6939
6940static void applyMnemonicAliases(StringRef &Mnemonic,
6941 const FeatureBitset &Features,
6942 unsigned VariantID);
6943
6944// The GNU assembler has aliases of ldrd, strd, ldrexd, strexd, ldaexd, and
6945// stlexd with the second register omitted. We don't have a way to do that in
6946// tablegen, so fix it up here.
6947//
6948// We have to be careful to not emit an invalid Rt2 here, because the rest of
6949// the assembly parser could then generate confusing diagnostics referring to
6950// it. If we do find anything that prevents us from doing the transformation we
6951// bail out, and let the assembly parser report an error on the instruction as
6952// it is written.
6953void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic,
6955 unsigned MnemonicOpsEndInd) {
6956 if (Mnemonic != "ldrd" && Mnemonic != "strd" && Mnemonic != "ldrexd" &&
6957 Mnemonic != "strexd" && Mnemonic != "ldaexd" && Mnemonic != "stlexd")
6958 return;
6959
6960 unsigned IdX = Mnemonic == "strexd" || Mnemonic == "stlexd"
6961 ? MnemonicOpsEndInd + 1
6962 : MnemonicOpsEndInd;
6963
6964 if (Operands.size() < IdX + 2)
6965 return;
6966
6967 ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[IdX]);
6968 ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[IdX + 1]);
6969
6970 if (!Op2.isReg())
6971 return;
6972 if (!Op3.isGPRMem())
6973 return;
6974
6975 const MCRegisterClass &GPR = MRI->getRegClass(ARM::GPRRegClassID);
6976 if (!GPR.contains(Op2.getReg()))
6977 return;
6978
6979 unsigned RtEncoding = MRI->getEncodingValue(Op2.getReg());
6980 if (!isThumb() && (RtEncoding & 1)) {
6981 // In ARM mode, the registers must be from an aligned pair, this
6982 // restriction does not apply in Thumb mode.
6983 return;
6984 }
6985 if (Op2.getReg() == ARM::PC)
6986 return;
6987 MCRegister PairedReg = GPR.getRegister(RtEncoding + 1);
6988 if (!PairedReg || PairedReg == ARM::PC ||
6989 (PairedReg == ARM::SP && !hasV8Ops()))
6990 return;
6991
6992 Operands.insert(Operands.begin() + IdX + 1,
6993 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(),
6994 Op2.getEndLoc(), *this));
6995}
6996
6997// Dual-register instruction have the following syntax:
6998// <mnemonic> <predicate>? <coproc>, <Rdest>, <Rdest+1>, <Rsrc>, ..., #imm
6999// This function tries to remove <Rdest+1> and replace <Rdest> with a pair
7000// operand. If the conversion fails an error is diagnosed, and the function
7001// returns true.
7002bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic,
7004 unsigned MnemonicOpsEndInd) {
7005 assert(MS.isCDEDualRegInstr(Mnemonic));
7006
7007 if (Operands.size() < 3 + MnemonicOpsEndInd)
7008 return false;
7009
7010 StringRef Op2Diag(
7011 "operand must be an even-numbered register in the range [r0, r10]");
7012
7013 const MCParsedAsmOperand &Op2 = *Operands[MnemonicOpsEndInd + 1];
7014 if (!Op2.isReg())
7015 return Error(Op2.getStartLoc(), Op2Diag);
7016
7017 MCRegister RNext;
7018 MCRegister RPair;
7019 switch (Op2.getReg().id()) {
7020 default:
7021 return Error(Op2.getStartLoc(), Op2Diag);
7022 case ARM::R0:
7023 RNext = ARM::R1;
7024 RPair = ARM::R0_R1;
7025 break;
7026 case ARM::R2:
7027 RNext = ARM::R3;
7028 RPair = ARM::R2_R3;
7029 break;
7030 case ARM::R4:
7031 RNext = ARM::R5;
7032 RPair = ARM::R4_R5;
7033 break;
7034 case ARM::R6:
7035 RNext = ARM::R7;
7036 RPair = ARM::R6_R7;
7037 break;
7038 case ARM::R8:
7039 RNext = ARM::R9;
7040 RPair = ARM::R8_R9;
7041 break;
7042 case ARM::R10:
7043 RNext = ARM::R11;
7044 RPair = ARM::R10_R11;
7045 break;
7046 }
7047
7048 const MCParsedAsmOperand &Op3 = *Operands[MnemonicOpsEndInd + 2];
7049 if (!Op3.isReg() || Op3.getReg() != RNext)
7050 return Error(Op3.getStartLoc(), "operand must be a consecutive register");
7051
7052 Operands.erase(Operands.begin() + MnemonicOpsEndInd + 2);
7053 Operands[MnemonicOpsEndInd + 1] =
7054 ARMOperand::CreateReg(RPair, Op2.getStartLoc(), Op2.getEndLoc(), *this);
7055 return false;
7056}
7057
7058void removeCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7059 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7060 if (static_cast<ARMOperand &>(*Operands[I]).isCondCode()) {
7061 Operands.erase(Operands.begin() + I);
7062 --MnemonicOpsEndInd;
7063 break;
7064 }
7065}
7066
7067void removeCCOut(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7068 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7069 if (static_cast<ARMOperand &>(*Operands[I]).isCCOut()) {
7070 Operands.erase(Operands.begin() + I);
7071 --MnemonicOpsEndInd;
7072 break;
7073 }
7074}
7075
7076void removeVPTCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7077 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7078 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred()) {
7079 Operands.erase(Operands.begin() + I);
7080 --MnemonicOpsEndInd;
7081 break;
7082 }
7083}
7084
7085/// Parse an arm instruction mnemonic followed by its operands.
7086bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7087 SMLoc NameLoc, OperandVector &Operands) {
7088 MCAsmParser &Parser = getParser();
7089
7090 // Apply mnemonic aliases before doing anything else, as the destination
7091 // mnemonic may include suffices and we want to handle them normally.
7092 // The generic tblgen'erated code does this later, at the start of
7093 // MatchInstructionImpl(), but that's too late for aliases that include
7094 // any sort of suffix.
7095 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
7096 unsigned AssemblerDialect = getParser().getAssemblerDialect();
7097 applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect);
7098
7099 // First check for the ARM-specific .req directive.
7100 if (Parser.getTok().is(AsmToken::Identifier) &&
7101 Parser.getTok().getIdentifier().lower() == ".req") {
7102 parseDirectiveReq(Name, NameLoc);
7103 // We always return 'error' for this, as we're done with this
7104 // statement and don't need to match the 'instruction."
7105 return true;
7106 }
7107
7108 // Create the leading tokens for the mnemonic, split by '.' characters.
7109 size_t Start = 0, Next = Name.find('.');
7110 StringRef Mnemonic = Name.slice(Start, Next);
7111 StringRef ExtraToken = Name.slice(Next, Name.find(' ', Next + 1));
7112
7113 // Split out the predication code and carry setting flag from the mnemonic.
7114 ARMCC::CondCodes PredicationCode;
7115 ARMVCC::VPTCodes VPTPredicationCode;
7116 unsigned ProcessorIMod;
7117 bool CarrySetting;
7118 StringRef ITMask;
7119 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode,
7120 CarrySetting, ProcessorIMod, ITMask);
7121
7122 // In Thumb1, only the branch (B) instruction can be predicated.
7123 if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
7124 return Error(NameLoc, "conditional execution not supported in Thumb1");
7125 }
7126
7127 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc, *this));
7128
7129 // Handle the mask for IT and VPT instructions. In ARMOperand and
7130 // MCOperand, this is stored in a format independent of the
7131 // condition code: the lowest set bit indicates the end of the
7132 // encoding, and above that, a 1 bit indicates 'else', and an 0
7133 // indicates 'then'. E.g.
7134 // IT -> 1000
7135 // ITx -> x100 (ITT -> 0100, ITE -> 1100)
7136 // ITxy -> xy10 (e.g. ITET -> 1010)
7137 // ITxyz -> xyz1 (e.g. ITEET -> 1101)
7138 // Note: See the ARM::PredBlockMask enum in
7139 // /lib/Target/ARM/Utils/ARMBaseInfo.h
7140 if (Mnemonic == "it" || Mnemonic.starts_with("vpt") ||
7141 Mnemonic.starts_with("vpst")) {
7142 SMLoc Loc = Mnemonic == "it" ? SMLoc::getFromPointer(NameLoc.getPointer() + 2) :
7143 Mnemonic == "vpt" ? SMLoc::getFromPointer(NameLoc.getPointer() + 3) :
7144 SMLoc::getFromPointer(NameLoc.getPointer() + 4);
7145 if (ITMask.size() > 3) {
7146 if (Mnemonic == "it")
7147 return Error(Loc, "too many conditions on IT instruction");
7148 return Error(Loc, "too many conditions on VPT instruction");
7149 }
7150 unsigned Mask = 8;
7151 for (char Pos : llvm::reverse(ITMask)) {
7152 if (Pos != 't' && Pos != 'e') {
7153 return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
7154 }
7155 Mask >>= 1;
7156 if (Pos == 'e')
7157 Mask |= 8;
7158 }
7159 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc, *this));
7160 }
7161
7162 // FIXME: This is all a pretty gross hack. We should automatically handle
7163 // optional operands like this via tblgen.
7164
7165 // Next, add the CCOut and ConditionCode operands, if needed.
7166 //
7167 // For mnemonics which can ever incorporate a carry setting bit or predication
7168 // code, our matching model involves us always generating CCOut and
7169 // ConditionCode operands to match the mnemonic "as written" and then we let
7170 // the matcher deal with finding the right instruction or generating an
7171 // appropriate error.
7172 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode;
7173 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet,
7174 CanAcceptPredicationCode, CanAcceptVPTPredicationCode);
7175
7176 // If we had a carry-set on an instruction that can't do that, issue an
7177 // error.
7178 if (!CanAcceptCarrySet && CarrySetting) {
7179 return Error(NameLoc, "instruction '" + Mnemonic +
7180 "' can not set flags, but 's' suffix specified");
7181 }
7182 // If we had a predication code on an instruction that can't do that, issue an
7183 // error.
7184 if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
7185 return Error(NameLoc, "instruction '" + Mnemonic +
7186 "' is not predicable, but condition code specified");
7187 }
7188
7189 // If we had a VPT predication code on an instruction that can't do that, issue an
7190 // error.
7191 if (!CanAcceptVPTPredicationCode && VPTPredicationCode != ARMVCC::None) {
7192 return Error(NameLoc, "instruction '" + Mnemonic +
7193 "' is not VPT predicable, but VPT code T/E is specified");
7194 }
7195
7196 // Add the carry setting operand, if necessary.
7197 if (CanAcceptCarrySet && CarrySetting) {
7198 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
7199 Operands.push_back(ARMOperand::CreateCCOut(
7200 CarrySetting ? ARM::CPSR : ARM::NoRegister, Loc, *this));
7201 }
7202
7203 // Add the predication code operand, if necessary.
7204 if (CanAcceptPredicationCode && PredicationCode != llvm::ARMCC::AL) {
7205 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
7206 CarrySetting);
7207 Operands.push_back(ARMOperand::CreateCondCode(
7208 ARMCC::CondCodes(PredicationCode), Loc, *this));
7209 }
7210
7211 // Add the VPT predication code operand, if necessary.
7212 // Dont add in certain cases of VCVT as this needs to be disambiguated
7213 // after operand parsing.
7214 if (CanAcceptVPTPredicationCode && VPTPredicationCode != llvm::ARMVCC::None &&
7215 !(Mnemonic.starts_with("vcvt") && Mnemonic != "vcvta" &&
7216 Mnemonic != "vcvtn" && Mnemonic != "vcvtp" && Mnemonic != "vcvtm")) {
7217 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
7218 CarrySetting);
7219 Operands.push_back(ARMOperand::CreateVPTPred(
7220 ARMVCC::VPTCodes(VPTPredicationCode), Loc, *this));
7221 }
7222
7223 // Add the processor imod operand, if necessary.
7224 if (ProcessorIMod) {
7225 Operands.push_back(ARMOperand::CreateImm(
7226 MCConstantExpr::create(ProcessorIMod, getContext()), NameLoc, NameLoc,
7227 *this));
7228 } else if (Mnemonic == "cps" && isMClass()) {
7229 return Error(NameLoc, "instruction 'cps' requires effect for M-class");
7230 }
7231
7232 // Add the remaining tokens in the mnemonic.
7233 while (Next != StringRef::npos) {
7234 Start = Next;
7235 Next = Name.find('.', Start + 1);
7236 ExtraToken = Name.slice(Start, Next);
7237
7238 // Some NEON instructions have an optional datatype suffix that is
7239 // completely ignored. Check for that.
7240 if (isDataTypeToken(ExtraToken) &&
7241 doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
7242 continue;
7243
7244 // For for ARM mode generate an error if the .n qualifier is used.
7245 if (ExtraToken == ".n" && !isThumb()) {
7246 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
7247 return Error(Loc, "instruction with .n (narrow) qualifier not allowed in "
7248 "arm mode");
7249 }
7250
7251 // The .n qualifier is always discarded as that is what the tables
7252 // and matcher expect. In ARM mode the .w qualifier has no effect,
7253 // so discard it to avoid errors that can be caused by the matcher.
7254 if (ExtraToken != ".n" && (isThumb() || ExtraToken != ".w")) {
7255 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
7256 Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc, *this));
7257 }
7258 }
7259
7260 // This marks the end of the LHS Mnemonic operators.
7261 // This is used for indexing into the non-mnemonic operators as some of the
7262 // mnemonic operators are optional and therefore indexes can differ.
7263 unsigned MnemonicOpsEndInd = Operands.size();
7264
7265 // Read the remaining operands.
7266 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7267 // Read the first operand.
7268 if (parseOperand(Operands, Mnemonic)) {
7269 return true;
7270 }
7271
7272 while (parseOptionalToken(AsmToken::Comma)) {
7273 // Parse and remember the operand.
7274 if (parseOperand(Operands, Mnemonic)) {
7275 return true;
7276 }
7277 }
7278 }
7279
7280 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
7281 return true;
7282
7283 tryConvertingToTwoOperandForm(Mnemonic, PredicationCode, CarrySetting,
7284 Operands, MnemonicOpsEndInd);
7285
7286 if (hasCDE() && MS.isCDEInstr(Mnemonic)) {
7287 // Dual-register instructions use even-odd register pairs as their
7288 // destination operand, in assembly such pair is spelled as two
7289 // consecutive registers, without any special syntax. ConvertDualRegOperand
7290 // tries to convert such operand into register pair, e.g. r2, r3 -> r2_r3.
7291 // It returns true, if an error message has been emitted. If the function
7292 // returns false, the function either succeeded or an error (e.g. missing
7293 // operand) will be diagnosed elsewhere.
7294 if (MS.isCDEDualRegInstr(Mnemonic)) {
7295 bool GotError =
7296 CDEConvertDualRegOperand(Mnemonic, Operands, MnemonicOpsEndInd);
7297 if (GotError)
7298 return GotError;
7299 }
7300 }
7301
7302 if (hasMVE()) {
7303 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7304 MnemonicOpsEndInd) &&
7305 Mnemonic == "vmov" && PredicationCode == ARMCC::LT) {
7306 // Very nasty hack to deal with the vector predicated variant of vmovlt
7307 // the scalar predicated vmov with condition 'lt'. We can not tell them
7308 // apart until we have parsed their operands.
7309 Operands.erase(Operands.begin() + 1);
7310 Operands.erase(Operands.begin());
7311 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7312 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7313 Mnemonic.size() - 1 + CarrySetting);
7314 Operands.insert(Operands.begin(),
7315 ARMOperand::CreateVPTPred(ARMVCC::None, PLoc, *this));
7316 Operands.insert(Operands.begin(), ARMOperand::CreateToken(
7317 StringRef("vmovlt"), MLoc, *this));
7318 } else if (Mnemonic == "vcvt" && PredicationCode == ARMCC::NE &&
7319 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7320 MnemonicOpsEndInd)) {
7321 // Another nasty hack to deal with the ambiguity between vcvt with scalar
7322 // predication 'ne' and vcvtn with vector predication 'e'. As above we
7323 // can only distinguish between the two after we have parsed their
7324 // operands.
7325 Operands.erase(Operands.begin() + 1);
7326 Operands.erase(Operands.begin());
7327 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7328 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7329 Mnemonic.size() - 1 + CarrySetting);
7330 Operands.insert(Operands.begin(),
7331 ARMOperand::CreateVPTPred(ARMVCC::Else, PLoc, *this));
7332 Operands.insert(Operands.begin(),
7333 ARMOperand::CreateToken(StringRef("vcvtn"), MLoc, *this));
7334 } else if (Mnemonic == "vmul" && PredicationCode == ARMCC::LT &&
7335 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7336 MnemonicOpsEndInd)) {
7337 // Another hack, this time to distinguish between scalar predicated vmul
7338 // with 'lt' predication code and the vector instruction vmullt with
7339 // vector predication code "none"
7340 removeCondCode(Operands, MnemonicOpsEndInd);
7341 Operands.erase(Operands.begin());
7342 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7343 Operands.insert(Operands.begin(), ARMOperand::CreateToken(
7344 StringRef("vmullt"), MLoc, *this));
7345 } else if (Mnemonic.starts_with("vcvt") && !Mnemonic.starts_with("vcvta") &&
7346 !Mnemonic.starts_with("vcvtn") &&
7347 !Mnemonic.starts_with("vcvtp") &&
7348 !Mnemonic.starts_with("vcvtm")) {
7349 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7350 MnemonicOpsEndInd)) {
7351 // We could not split the vector predicate off vcvt because it might
7352 // have been the scalar vcvtt instruction. Now we know its a vector
7353 // instruction, we still need to check whether its the vector
7354 // predicated vcvt with 'Then' predication or the vector vcvtt. We can
7355 // distinguish the two based on the suffixes, if it is any of
7356 // ".f16.f32", ".f32.f16", ".f16.f64" or ".f64.f16" then it is the vcvtt.
7357 if (Mnemonic.starts_with("vcvtt") && MnemonicOpsEndInd > 2) {
7358 auto Sz1 =
7359 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd - 2]);
7360 auto Sz2 =
7361 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd - 1]);
7362 if (!(Sz1.isToken() && Sz1.getToken().starts_with(".f") &&
7363 Sz2.isToken() && Sz2.getToken().starts_with(".f"))) {
7364 Operands.erase(Operands.begin());
7365 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7366 VPTPredicationCode = ARMVCC::Then;
7367
7368 Mnemonic = Mnemonic.substr(0, 4);
7369 Operands.insert(Operands.begin(),
7370 ARMOperand::CreateToken(Mnemonic, MLoc, *this));
7371 }
7372 }
7373 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7374 Mnemonic.size() + CarrySetting);
7375 // Add VPTPred
7376 Operands.insert(Operands.begin() + 1,
7377 ARMOperand::CreateVPTPred(
7378 ARMVCC::VPTCodes(VPTPredicationCode), PLoc, *this));
7379 ++MnemonicOpsEndInd;
7380 }
7381 } else if (CanAcceptVPTPredicationCode) {
7382 // For all other instructions, make sure only one of the two
7383 // predication operands is left behind, depending on whether we should
7384 // use the vector predication.
7385 if (shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7386 MnemonicOpsEndInd)) {
7387 removeVPTCondCode(Operands, MnemonicOpsEndInd);
7388 }
7389 }
7390 }
7391
7392 if (VPTPredicationCode != ARMVCC::None) {
7393 bool usedVPTPredicationCode = false;
7394 for (unsigned I = 1; I < Operands.size(); ++I)
7395 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred())
7396 usedVPTPredicationCode = true;
7397 if (!usedVPTPredicationCode) {
7398 // If we have a VPT predication code and we haven't just turned it
7399 // into an operand, then it was a mistake for splitMnemonic to
7400 // separate it from the rest of the mnemonic in the first place,
7401 // and this may lead to wrong disassembly (e.g. scalar floating
7402 // point VCMPE is actually a different instruction from VCMP, so
7403 // we mustn't treat them the same). In that situation, glue it
7404 // back on.
7405 Mnemonic = Name.slice(0, Mnemonic.size() + 1);
7406 Operands.erase(Operands.begin());
7407 Operands.insert(Operands.begin(),
7408 ARMOperand::CreateToken(Mnemonic, NameLoc, *this));
7409 }
7410 }
7411
7412 // ARM mode 'blx' need special handling, as the register operand version
7413 // is predicable, but the label operand version is not. So, we can't rely
7414 // on the Mnemonic based checking to correctly figure out when to put
7415 // a k_CondCode operand in the list. If we're trying to match the label
7416 // version, remove the k_CondCode operand here.
7417 if (!isThumb() && Mnemonic == "blx" &&
7418 Operands.size() == MnemonicOpsEndInd + 1 &&
7419 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).isImm())
7420 removeCondCode(Operands, MnemonicOpsEndInd);
7421
7422 // GNU Assembler extension (compatibility).
7423 fixupGNULDRDAlias(Mnemonic, Operands, MnemonicOpsEndInd);
7424
7425 // Adjust operands of ldrexd/strexd to MCK_GPRPair.
7426 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
7427 // a single GPRPair reg operand is used in the .td file to replace the two
7428 // GPRs. However, when parsing from asm, the two GRPs cannot be
7429 // automatically
7430 // expressed as a GPRPair, so we have to manually merge them.
7431 // FIXME: We would really like to be able to tablegen'erate this.
7432 bool IsLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd");
7433 if (!isThumb() && Operands.size() > MnemonicOpsEndInd + 1 + (!IsLoad) &&
7434 (Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" ||
7435 Mnemonic == "stlexd")) {
7436 unsigned Idx = IsLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
7437 ARMOperand &Op1 = static_cast<ARMOperand &>(*Operands[Idx]);
7438 ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[Idx + 1]);
7439
7440 const MCRegisterClass &MRC = MRI->getRegClass(ARM::GPRRegClassID);
7441 // Adjust only if Op1 is a GPR.
7442 if (Op1.isReg() && MRC.contains(Op1.getReg())) {
7443 MCRegister Reg1 = Op1.getReg();
7444 unsigned Rt = MRI->getEncodingValue(Reg1);
7445 MCRegister Reg2 = Op2.getReg();
7446 unsigned Rt2 = MRI->getEncodingValue(Reg2);
7447 // Rt2 must be Rt + 1.
7448 if (Rt + 1 != Rt2)
7449 return Error(Op2.getStartLoc(),
7450 IsLoad ? "destination operands must be sequential"
7451 : "source operands must be sequential");
7452
7453 // Rt must be even
7454 if (Rt & 1)
7455 return Error(
7456 Op1.getStartLoc(),
7457 IsLoad ? "destination operands must start start at an even register"
7458 : "source operands must start start at an even register");
7459
7460 MCRegister NewReg = MRI->getMatchingSuperReg(
7461 Reg1, ARM::gsub_0, &(MRI->getRegClass(ARM::GPRPairRegClassID)));
7462 Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7463 Op2.getEndLoc(), *this);
7464 Operands.erase(Operands.begin() + Idx + 1);
7465 }
7466 }
7467
7468 // FIXME: As said above, this is all a pretty gross hack. This instruction
7469 // does not fit with other "subs" and tblgen.
7470 // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
7471 // so the Mnemonic is "subs" and delete the CCOut operand so it will match
7472 // the table entry.
7473 if (isThumbTwo() && Mnemonic == "sub" && CarrySetting &&
7474 Operands.size() == MnemonicOpsEndInd + 3 &&
7475 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).isReg() &&
7476 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).getReg() ==
7477 ARM::PC &&
7478 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]).isReg() &&
7479 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]).getReg() ==
7480 ARM::LR &&
7481 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 2]).isImm()) {
7482 Operands.front() = ARMOperand::CreateToken("subs", NameLoc, *this);
7483 removeCCOut(Operands, MnemonicOpsEndInd);
7484 }
7485 return false;
7486}
7487
7488// Validate context-sensitive operand constraints.
7489
7490// return 'true' if register list contains non-low GPR registers,
7491// 'false' otherwise. If Reg is in the register list or is HiReg, set
7492// 'containsReg' to true.
7493static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo,
7494 MCRegister Reg, MCRegister HiReg,
7495 bool &containsReg) {
7496 containsReg = false;
7497 for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
7498 MCRegister OpReg = Inst.getOperand(i).getReg();
7499 if (OpReg == Reg)
7500 containsReg = true;
7501 // Anything other than a low register isn't legal here.
7502 if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
7503 return true;
7504 }
7505 return false;
7506}
7507
7508// Check if the specified regisgter is in the register list of the inst,
7509// starting at the indicated operand number.
7510static bool listContainsReg(const MCInst &Inst, unsigned OpNo, MCRegister Reg) {
7511 for (unsigned i = OpNo, e = Inst.getNumOperands(); i < e; ++i) {
7512 MCRegister OpReg = Inst.getOperand(i).getReg();
7513 if (OpReg == Reg)
7514 return true;
7515 }
7516 return false;
7517}
7518
7519// Return true if instruction has the interesting property of being
7520// allowed in IT blocks, but not being predicable.
7521static bool instIsBreakpoint(const MCInst &Inst) {
7522 return Inst.getOpcode() == ARM::tBKPT ||
7523 Inst.getOpcode() == ARM::BKPT ||
7524 Inst.getOpcode() == ARM::tHLT ||
7525 Inst.getOpcode() == ARM::HLT;
7526}
7527
7529 unsigned MnemonicOpsEndInd) {
7530 for (unsigned I = MnemonicOpsEndInd; I < Operands.size(); ++I) {
7531 const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[I]);
7532 if (Op.isRegList()) {
7533 return I;
7534 }
7535 }
7536 return 0;
7537}
7538
7539bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst,
7540 const OperandVector &Operands,
7541 unsigned MnemonicOpsEndInd,
7542 unsigned ListIndex, bool IsARPop) {
7543 bool ListContainsSP = listContainsReg(Inst, ListIndex, ARM::SP);
7544 bool ListContainsLR = listContainsReg(Inst, ListIndex, ARM::LR);
7545 bool ListContainsPC = listContainsReg(Inst, ListIndex, ARM::PC);
7546
7547 if (!IsARPop && ListContainsSP)
7548 return Error(
7549 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7550 "SP may not be in the register list");
7551 if (ListContainsPC && ListContainsLR)
7552 return Error(
7553 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7554 "PC and LR may not be in the register list simultaneously");
7555 return false;
7556}
7557
7558bool ARMAsmParser::validatetSTMRegList(const MCInst &Inst,
7559 const OperandVector &Operands,
7560 unsigned MnemonicOpsEndInd,
7561 unsigned ListIndex) {
7562 bool ListContainsSP = listContainsReg(Inst, ListIndex, ARM::SP);
7563 bool ListContainsPC = listContainsReg(Inst, ListIndex, ARM::PC);
7564
7565 if (ListContainsSP && ListContainsPC)
7566 return Error(
7567 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7568 "SP and PC may not be in the register list");
7569 if (ListContainsSP)
7570 return Error(
7571 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7572 "SP may not be in the register list");
7573 if (ListContainsPC)
7574 return Error(
7575 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7576 "PC may not be in the register list");
7577 return false;
7578}
7579
7580bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
7581 bool Load, bool ARMMode, bool Writeback,
7582 unsigned MnemonicOpsEndInd) {
7583 unsigned RtIndex = Load || !Writeback ? 0 : 1;
7584 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(RtIndex).getReg());
7585 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(RtIndex + 1).getReg());
7586
7587 if (ARMMode) {
7588 // Rt can't be R14.
7589 if (Rt == 14)
7590 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7591 "Rt can't be R14");
7592
7593 // Rt must be even-numbered.
7594 if ((Rt & 1) == 1)
7595 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7596 "Rt must be even-numbered");
7597
7598 // Rt2 must be Rt + 1.
7599 if (Rt2 != Rt + 1) {
7600 if (Load)
7601 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7602 "destination operands must be sequential");
7603 else
7604 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7605 "source operands must be sequential");
7606 }
7607
7608 // FIXME: Diagnose m == 15
7609 // FIXME: Diagnose ldrd with m == t || m == t2.
7610 }
7611
7612 if (!ARMMode && Load) {
7613 if (Rt2 == Rt)
7614 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7615 "destination operands can't be identical");
7616 }
7617
7618 if (Writeback) {
7619 unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg());
7620
7621 if (Rn == Rt || Rn == Rt2) {
7622 if (Load)
7623 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7624 "base register needs to be different from destination "
7625 "registers");
7626 else
7627 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7628 "source register and base register can't be identical");
7629 }
7630
7631 // FIXME: Diagnose ldrd/strd with writeback and n == 15.
7632 // (Except the immediate form of ldrd?)
7633 }
7634
7635 return false;
7636}
7637
7639 for (unsigned i = 0; i < MCID.NumOperands; ++i) {
7640 if (ARM::isVpred(MCID.operands()[i].OperandType))
7641 return i;
7642 }
7643 return -1;
7644}
7645
7647 return findFirstVectorPredOperandIdx(MCID) != -1;
7648}
7649
7651 ARMOperand &Op = static_cast<ARMOperand &>(MCOp);
7652 if (!Op.isImm())
7653 return false;
7654 return !isa<MCConstantExpr>(Op.getImm());
7655}
7656
7657// FIXME: We would really like to be able to tablegen'erate this.
7658bool ARMAsmParser::validateInstruction(MCInst &Inst,
7659 const OperandVector &Operands,
7660 unsigned MnemonicOpsEndInd) {
7661 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
7662 SMLoc Loc = Operands[0]->getStartLoc();
7663
7664 // Check the IT block state first.
7665 // NOTE: BKPT and HLT instructions have the interesting property of being
7666 // allowed in IT blocks, but not being predicable. They just always execute.
7667 if (inITBlock() && !instIsBreakpoint(Inst)) {
7668 // The instruction must be predicable.
7669 if (!MCID.isPredicable())
7670 return Error(Loc, "instructions in IT block must be predicable");
7673 if (Cond != currentITCond()) {
7674 // Find the condition code Operand to get its SMLoc information.
7675 SMLoc CondLoc = Operands[0]->getEndLoc();
7676 for (unsigned I = 1; I < Operands.size(); ++I)
7677 if (static_cast<ARMOperand &>(*Operands[I]).isCondCode())
7678 CondLoc = Operands[I]->getStartLoc();
7679 return Error(CondLoc, "incorrect condition in IT block; got '" +
7680 StringRef(ARMCondCodeToString(Cond)) +
7681 "', but expected '" +
7682 ARMCondCodeToString(currentITCond()) + "'");
7683 }
7684 // Check for non-'al' condition codes outside of the IT block.
7685 } else if (isThumbTwo() && MCID.isPredicable() &&
7686 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
7687 ARMCC::AL && Inst.getOpcode() != ARM::tBcc &&
7688 Inst.getOpcode() != ARM::t2Bcc &&
7689 Inst.getOpcode() != ARM::t2BFic) {
7690 return Error(Loc, "predicated instructions must be in IT block");
7691 } else if (!isThumb() && !useImplicitITARM() && MCID.isPredicable() &&
7692 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
7693 ARMCC::AL) {
7694 return Warning(Loc, "predicated instructions should be in IT block");
7695 } else if (!MCID.isPredicable()) {
7696 // Check the instruction doesn't have a predicate operand anyway
7697 // that it's not allowed to use. Sometimes this happens in order
7698 // to keep instructions the same shape even though one cannot
7699 // legally be predicated, e.g. vmul.f16 vs vmul.f32.
7700 for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i) {
7701 if (MCID.operands()[i].isPredicate()) {
7702 if (Inst.getOperand(i).getImm() != ARMCC::AL)
7703 return Error(Loc, "instruction is not predicable");
7704 break;
7705 }
7706 }
7707 }
7708
7709 // PC-setting instructions in an IT block, but not the last instruction of
7710 // the block, are UNPREDICTABLE.
7711 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
7712 return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block");
7713 }
7714
7715 if (inVPTBlock() && !instIsBreakpoint(Inst)) {
7716 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
7717 if (!isVectorPredicable(MCID))
7718 return Error(Loc, "instruction in VPT block must be predicable");
7719 unsigned Pred = Inst.getOperand(findFirstVectorPredOperandIdx(MCID)).getImm();
7720 unsigned VPTPred = Bit ? ARMVCC::Else : ARMVCC::Then;
7721 if (Pred != VPTPred) {
7722 SMLoc PredLoc;
7723 for (unsigned I = 1; I < Operands.size(); ++I)
7724 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred())
7725 PredLoc = Operands[I]->getStartLoc();
7726 return Error(PredLoc, "incorrect predication in VPT block; got '" +
7727 StringRef(ARMVPTPredToString(ARMVCC::VPTCodes(Pred))) +
7728 "', but expected '" +
7729 ARMVPTPredToString(ARMVCC::VPTCodes(VPTPred)) + "'");
7730 }
7731 }
7732 else if (isVectorPredicable(MCID) &&
7735 return Error(Loc, "VPT predicated instructions must be in VPT block");
7736
7737 const unsigned Opcode = Inst.getOpcode();
7738 switch (Opcode) {
7739 case ARM::VLLDM:
7740 case ARM::VLLDM_T2:
7741 case ARM::VLSTM:
7742 case ARM::VLSTM_T2: {
7743 // Since in some cases both T1 and T2 are valid, tablegen can not always
7744 // pick the correct instruction.
7745 if (Operands.size() ==
7746 MnemonicOpsEndInd + 2) { // a register list has been provided
7747 ARMOperand &Op = static_cast<ARMOperand &>(
7748 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
7749 assert(Op.isDPRRegList());
7750 auto &RegList = Op.getRegList();
7751 // T2 requires v8.1-M.Main (cannot be handled by tablegen)
7752 if (RegList.size() == 32 && !hasV8_1MMainline()) {
7753 return Error(Op.getEndLoc(), "T2 version requires v8.1-M.Main");
7754 }
7755 // When target has 32 D registers, T1 is undefined.
7756 if (hasD32() && RegList.size() != 32) {
7757 return Error(Op.getEndLoc(), "operand must be exactly {d0-d31}");
7758 }
7759 // When target has 16 D registers, both T1 and T2 are valid.
7760 if (!hasD32() && (RegList.size() != 16 && RegList.size() != 32)) {
7761 return Error(Op.getEndLoc(),
7762 "operand must be exactly {d0-d15} (T1) or {d0-d31} (T2)");
7763 }
7764 }
7765 return false;
7766 }
7767 case ARM::t2IT: {
7768 // Encoding is unpredictable if it ever results in a notional 'NV'
7769 // predicate. Since we don't parse 'NV' directly this means an 'AL'
7770 // predicate with an "else" mask bit.
7771 unsigned Cond = Inst.getOperand(0).getImm();
7772 unsigned Mask = Inst.getOperand(1).getImm();
7773
7774 // Conditions only allowing a 't' are those with no set bit except
7775 // the lowest-order one that indicates the end of the sequence. In
7776 // other words, powers of 2.
7777 if (Cond == ARMCC::AL && llvm::popcount(Mask) != 1)
7778 return Error(Loc, "unpredictable IT predicate sequence");
7779 break;
7780 }
7781 case ARM::LDRD:
7782 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ true,
7783 /*Writeback*/ false, MnemonicOpsEndInd))
7784 return true;
7785 break;
7786 case ARM::LDRD_PRE:
7787 case ARM::LDRD_POST:
7788 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ true,
7789 /*Writeback*/ true, MnemonicOpsEndInd))
7790 return true;
7791 break;
7792 case ARM::t2LDRDi8:
7793 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ false,
7794 /*Writeback*/ false, MnemonicOpsEndInd))
7795 return true;
7796 break;
7797 case ARM::t2LDRD_PRE:
7798 case ARM::t2LDRD_POST:
7799 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ false,
7800 /*Writeback*/ true, MnemonicOpsEndInd))
7801 return true;
7802 break;
7803 case ARM::t2BXJ: {
7804 const MCRegister RmReg = Inst.getOperand(0).getReg();
7805 // Rm = SP is no longer unpredictable in v8-A
7806 if (RmReg == ARM::SP && !hasV8Ops())
7807 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7808 "r13 (SP) is an unpredictable operand to BXJ");
7809 return false;
7810 }
7811 case ARM::STRD:
7812 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ true,
7813 /*Writeback*/ false, MnemonicOpsEndInd))
7814 return true;
7815 break;
7816 case ARM::STRD_PRE:
7817 case ARM::STRD_POST:
7818 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ true,
7819 /*Writeback*/ true, MnemonicOpsEndInd))
7820 return true;
7821 break;
7822 case ARM::t2STRD_PRE:
7823 case ARM::t2STRD_POST:
7824 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ false,
7825 /*Writeback*/ true, MnemonicOpsEndInd))
7826 return true;
7827 break;
7828 case ARM::STR_PRE_IMM:
7829 case ARM::STR_PRE_REG:
7830 case ARM::t2STR_PRE:
7831 case ARM::STR_POST_IMM:
7832 case ARM::STR_POST_REG:
7833 case ARM::t2STR_POST:
7834 case ARM::STRH_PRE:
7835 case ARM::t2STRH_PRE:
7836 case ARM::STRH_POST:
7837 case ARM::t2STRH_POST:
7838 case ARM::STRB_PRE_IMM:
7839 case ARM::STRB_PRE_REG:
7840 case ARM::t2STRB_PRE:
7841 case ARM::STRB_POST_IMM:
7842 case ARM::STRB_POST_REG:
7843 case ARM::t2STRB_POST: {
7844 // Rt must be different from Rn.
7845 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7846 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
7847
7848 if (Rt == Rn)
7849 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7850 "source register and base register can't be identical");
7851 return false;
7852 }
7853 case ARM::t2LDR_PRE_imm:
7854 case ARM::t2LDR_POST_imm:
7855 case ARM::t2STR_PRE_imm:
7856 case ARM::t2STR_POST_imm: {
7857 // Rt must be different from Rn.
7858 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
7859 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7860
7861 if (Rt == Rn)
7862 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7863 "destination register and base register can't be identical");
7864 if (Inst.getOpcode() == ARM::t2LDR_POST_imm ||
7865 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7866 int Imm = Inst.getOperand(2).getImm();
7867 if (Imm > 255 || Imm < -255)
7868 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7869 "operand must be in range [-255, 255]");
7870 }
7871 if (Inst.getOpcode() == ARM::t2STR_PRE_imm ||
7872 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7873 if (Inst.getOperand(0).getReg() == ARM::PC) {
7874 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7875 "operand must be a register in range [r0, r14]");
7876 }
7877 }
7878 return false;
7879 }
7880
7881 case ARM::t2LDRB_OFFSET_imm:
7882 case ARM::t2LDRB_PRE_imm:
7883 case ARM::t2LDRB_POST_imm:
7884 case ARM::t2STRB_OFFSET_imm:
7885 case ARM::t2STRB_PRE_imm:
7886 case ARM::t2STRB_POST_imm: {
7887 if (Inst.getOpcode() == ARM::t2LDRB_POST_imm ||
7888 Inst.getOpcode() == ARM::t2STRB_POST_imm ||
7889 Inst.getOpcode() == ARM::t2LDRB_PRE_imm ||
7890 Inst.getOpcode() == ARM::t2STRB_PRE_imm) {
7891 int Imm = Inst.getOperand(2).getImm();
7892 if (Imm > 255 || Imm < -255)
7893 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7894 "operand must be in range [-255, 255]");
7895 } else if (Inst.getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7896 Inst.getOpcode() == ARM::t2STRB_OFFSET_imm) {
7897 int Imm = Inst.getOperand(2).getImm();
7898 if (Imm > 0 || Imm < -255)
7899 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7900 "operand must be in range [0, 255] with a negative sign");
7901 }
7902 if (Inst.getOperand(0).getReg() == ARM::PC) {
7903 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7904 "if operand is PC, should call the LDRB (literal)");
7905 }
7906 return false;
7907 }
7908
7909 case ARM::t2LDRH_OFFSET_imm:
7910 case ARM::t2LDRH_PRE_imm:
7911 case ARM::t2LDRH_POST_imm:
7912 case ARM::t2STRH_OFFSET_imm:
7913 case ARM::t2STRH_PRE_imm:
7914 case ARM::t2STRH_POST_imm: {
7915 if (Inst.getOpcode() == ARM::t2LDRH_POST_imm ||
7916 Inst.getOpcode() == ARM::t2STRH_POST_imm ||
7917 Inst.getOpcode() == ARM::t2LDRH_PRE_imm ||
7918 Inst.getOpcode() == ARM::t2STRH_PRE_imm) {
7919 int Imm = Inst.getOperand(2).getImm();
7920 if (Imm > 255 || Imm < -255)
7921 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7922 "operand must be in range [-255, 255]");
7923 } else if (Inst.getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7924 Inst.getOpcode() == ARM::t2STRH_OFFSET_imm) {
7925 int Imm = Inst.getOperand(2).getImm();
7926 if (Imm > 0 || Imm < -255)
7927 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7928 "operand must be in range [0, 255] with a negative sign");
7929 }
7930 if (Inst.getOperand(0).getReg() == ARM::PC) {
7931 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7932 "if operand is PC, should call the LDRH (literal)");
7933 }
7934 return false;
7935 }
7936
7937 case ARM::t2LDRSB_OFFSET_imm:
7938 case ARM::t2LDRSB_PRE_imm:
7939 case ARM::t2LDRSB_POST_imm: {
7940 if (Inst.getOpcode() == ARM::t2LDRSB_POST_imm ||
7941 Inst.getOpcode() == ARM::t2LDRSB_PRE_imm) {
7942 int Imm = Inst.getOperand(2).getImm();
7943 if (Imm > 255 || Imm < -255)
7944 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7945 "operand must be in range [-255, 255]");
7946 } else if (Inst.getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7947 int Imm = Inst.getOperand(2).getImm();
7948 if (Imm > 0 || Imm < -255)
7949 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7950 "operand must be in range [0, 255] with a negative sign");
7951 }
7952 if (Inst.getOperand(0).getReg() == ARM::PC) {
7953 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7954 "if operand is PC, should call the LDRH (literal)");
7955 }
7956 return false;
7957 }
7958
7959 case ARM::t2LDRSH_OFFSET_imm:
7960 case ARM::t2LDRSH_PRE_imm:
7961 case ARM::t2LDRSH_POST_imm: {
7962 if (Inst.getOpcode() == ARM::t2LDRSH_POST_imm ||
7963 Inst.getOpcode() == ARM::t2LDRSH_PRE_imm) {
7964 int Imm = Inst.getOperand(2).getImm();
7965 if (Imm > 255 || Imm < -255)
7966 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7967 "operand must be in range [-255, 255]");
7968 } else if (Inst.getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7969 int Imm = Inst.getOperand(2).getImm();
7970 if (Imm > 0 || Imm < -255)
7971 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7972 "operand must be in range [0, 255] with a negative sign");
7973 }
7974 if (Inst.getOperand(0).getReg() == ARM::PC) {
7975 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7976 "if operand is PC, should call the LDRH (literal)");
7977 }
7978 return false;
7979 }
7980
7981 case ARM::LDR_PRE_IMM:
7982 case ARM::LDR_PRE_REG:
7983 case ARM::t2LDR_PRE:
7984 case ARM::LDR_POST_IMM:
7985 case ARM::LDR_POST_REG:
7986 case ARM::t2LDR_POST:
7987 case ARM::LDRH_PRE:
7988 case ARM::t2LDRH_PRE:
7989 case ARM::LDRH_POST:
7990 case ARM::t2LDRH_POST:
7991 case ARM::LDRSH_PRE:
7992 case ARM::t2LDRSH_PRE:
7993 case ARM::LDRSH_POST:
7994 case ARM::t2LDRSH_POST:
7995 case ARM::LDRB_PRE_IMM:
7996 case ARM::LDRB_PRE_REG:
7997 case ARM::t2LDRB_PRE:
7998 case ARM::LDRB_POST_IMM:
7999 case ARM::LDRB_POST_REG:
8000 case ARM::t2LDRB_POST:
8001 case ARM::LDRSB_PRE:
8002 case ARM::t2LDRSB_PRE:
8003 case ARM::LDRSB_POST:
8004 case ARM::t2LDRSB_POST: {
8005 // Rt must be different from Rn.
8006 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8007 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8008
8009 if (Rt == Rn)
8010 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8011 "destination register and base register can't be identical");
8012 return false;
8013 }
8014
8015 case ARM::MVE_VLDRBU8_rq:
8016 case ARM::MVE_VLDRBU16_rq:
8017 case ARM::MVE_VLDRBS16_rq:
8018 case ARM::MVE_VLDRBU32_rq:
8019 case ARM::MVE_VLDRBS32_rq:
8020 case ARM::MVE_VLDRHU16_rq:
8021 case ARM::MVE_VLDRHU16_rq_u:
8022 case ARM::MVE_VLDRHU32_rq:
8023 case ARM::MVE_VLDRHU32_rq_u:
8024 case ARM::MVE_VLDRHS32_rq:
8025 case ARM::MVE_VLDRHS32_rq_u:
8026 case ARM::MVE_VLDRWU32_rq:
8027 case ARM::MVE_VLDRWU32_rq_u:
8028 case ARM::MVE_VLDRDU64_rq:
8029 case ARM::MVE_VLDRDU64_rq_u:
8030 case ARM::MVE_VLDRWU32_qi:
8031 case ARM::MVE_VLDRWU32_qi_pre:
8032 case ARM::MVE_VLDRDU64_qi:
8033 case ARM::MVE_VLDRDU64_qi_pre: {
8034 // Qd must be different from Qm.
8035 unsigned QdIdx = 0, QmIdx = 2;
8036 bool QmIsPointer = false;
8037 switch (Opcode) {
8038 case ARM::MVE_VLDRWU32_qi:
8039 case ARM::MVE_VLDRDU64_qi:
8040 QmIdx = 1;
8041 QmIsPointer = true;
8042 break;
8043 case ARM::MVE_VLDRWU32_qi_pre:
8044 case ARM::MVE_VLDRDU64_qi_pre:
8045 QdIdx = 1;
8046 QmIsPointer = true;
8047 break;
8048 }
8049
8050 const unsigned Qd = MRI->getEncodingValue(Inst.getOperand(QdIdx).getReg());
8051 const unsigned Qm = MRI->getEncodingValue(Inst.getOperand(QmIdx).getReg());
8052
8053 if (Qd == Qm) {
8054 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8055 Twine("destination vector register and vector ") +
8056 (QmIsPointer ? "pointer" : "offset") +
8057 " register can't be identical");
8058 }
8059 return false;
8060 }
8061
8062 case ARM::SBFX:
8063 case ARM::t2SBFX:
8064 case ARM::UBFX:
8065 case ARM::t2UBFX: {
8066 // Width must be in range [1, 32-lsb].
8067 unsigned LSB = Inst.getOperand(2).getImm();
8068 unsigned Widthm1 = Inst.getOperand(3).getImm();
8069 if (Widthm1 >= 32 - LSB)
8070 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8071 "bitfield width must be in range [1,32-lsb]");
8072 return false;
8073 }
8074 // Notionally handles ARM::tLDMIA_UPD too.
8075 case ARM::tLDMIA: {
8076 // If we're parsing Thumb2, the .w variant is available and handles
8077 // most cases that are normally illegal for a Thumb1 LDM instruction.
8078 // We'll make the transformation in processInstruction() if necessary.
8079 //
8080 // Thumb LDM instructions are writeback iff the base register is not
8081 // in the register list.
8082 MCRegister Rn = Inst.getOperand(0).getReg();
8083 bool HasWritebackToken =
8084 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8085 .isToken() &&
8086 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8087 .getToken() == "!");
8088
8089 bool ListContainsBase;
8090 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), ListContainsBase) &&
8091 !isThumbTwo())
8092 return Error(
8093 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8094 "registers must be in range r0-r7");
8095 // If we should have writeback, then there should be a '!' token.
8096 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8097 return Error(
8098 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8099 "writeback operator '!' expected");
8100 // If we should not have writeback, there must not be a '!'. This is
8101 // true even for the 32-bit wide encodings.
8102 if (ListContainsBase && HasWritebackToken)
8103 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8104 "writeback operator '!' not allowed when base register "
8105 "in register list");
8106
8107 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8108 return true;
8109 break;
8110 }
8111 case ARM::LDMIA_UPD:
8112 case ARM::LDMDB_UPD:
8113 case ARM::LDMIB_UPD:
8114 case ARM::LDMDA_UPD:
8115 // ARM variants loading and updating the same register are only officially
8116 // UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
8117 if (!hasV7Ops())
8118 break;
8119 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8120 return Error(Operands.back()->getStartLoc(),
8121 "writeback register not allowed in register list");
8122 break;
8123 case ARM::t2LDMIA:
8124 case ARM::t2LDMDB:
8125 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8126 return true;
8127 break;
8128 case ARM::t2STMIA:
8129 case ARM::t2STMDB:
8130 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8131 return true;
8132 break;
8133 case ARM::t2LDMIA_UPD:
8134 case ARM::t2LDMDB_UPD:
8135 case ARM::t2STMIA_UPD:
8136 case ARM::t2STMDB_UPD:
8137 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8138 return Error(Operands.back()->getStartLoc(),
8139 "writeback register not allowed in register list");
8140
8141 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8142 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8143 return true;
8144 } else {
8145 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8146 return true;
8147 }
8148 break;
8149
8150 case ARM::sysLDMIA_UPD:
8151 case ARM::sysLDMDA_UPD:
8152 case ARM::sysLDMDB_UPD:
8153 case ARM::sysLDMIB_UPD:
8154 if (!listContainsReg(Inst, 3, ARM::PC))
8155 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8156 "writeback register only allowed on system LDM "
8157 "if PC in register-list");
8158 break;
8159 case ARM::sysSTMIA_UPD:
8160 case ARM::sysSTMDA_UPD:
8161 case ARM::sysSTMDB_UPD:
8162 case ARM::sysSTMIB_UPD:
8163 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8164 "system STM cannot have writeback register");
8165 // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
8166 // so only issue a diagnostic for thumb1. The instructions will be
8167 // switched to the t2 encodings in processInstruction() if necessary.
8168 case ARM::tPOP: {
8169 bool ListContainsBase;
8170 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC,
8171 ListContainsBase) &&
8172 !isThumbTwo())
8173 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8174 "registers must be in range r0-r7 or pc");
8175 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 2, !isMClass()))
8176 return true;
8177 break;
8178 }
8179 case ARM::tPUSH: {
8180 bool ListContainsBase;
8181 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR,
8182 ListContainsBase) &&
8183 !isThumbTwo())
8184 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8185 "registers must be in range r0-r7 or lr");
8186 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 2))
8187 return true;
8188 break;
8189 }
8190 case ARM::tSTMIA_UPD: {
8191 bool ListContainsBase, InvalidLowList;
8192 InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(),
8193 0, ListContainsBase);
8194 if (InvalidLowList && !isThumbTwo())
8195 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8196 "registers must be in range r0-r7");
8197
8198 // This would be converted to a 32-bit stm, but that's not valid if the
8199 // writeback register is in the list.
8200 if (InvalidLowList && ListContainsBase)
8201 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8202 "writeback operator '!' not allowed when base register "
8203 "in register list");
8204
8205 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 4))
8206 return true;
8207 break;
8208 }
8209 case ARM::tADDrSP:
8210 // If the non-SP source operand and the destination operand are not the
8211 // same, we need thumb2 (for the wide encoding), or we have an error.
8212 if (!isThumbTwo() &&
8213 Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
8214 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8215 "source register must be the same as destination");
8216 }
8217 break;
8218
8219 case ARM::t2ADDrr:
8220 case ARM::t2ADDrs:
8221 case ARM::t2SUBrr:
8222 case ARM::t2SUBrs:
8223 if (Inst.getOperand(0).getReg() == ARM::SP &&
8224 Inst.getOperand(1).getReg() != ARM::SP)
8225 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8226 "source register must be sp if destination is sp");
8227 break;
8228
8229 // Final range checking for Thumb unconditional branch instructions.
8230 case ARM::tB:
8231 if (!(static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]))
8232 .isSignedOffset<11, 1>())
8233 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8234 "branch target out of range");
8235 break;
8236 case ARM::t2B: {
8237 int op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8238 : MnemonicOpsEndInd + 1;
8239 ARMOperand &Operand = static_cast<ARMOperand &>(*Operands[op]);
8240 // Delay the checks of symbolic expressions until they are resolved.
8241 if (!isa<MCBinaryExpr>(Operand.getImm()) &&
8242 !Operand.isSignedOffset<24, 1>())
8243 return Error(Operands[op]->getStartLoc(), "branch target out of range");
8244 break;
8245 }
8246 // Final range checking for Thumb conditional branch instructions.
8247 case ARM::tBcc:
8248 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8249 .isSignedOffset<8, 1>())
8250 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8251 "branch target out of range");
8252 break;
8253 case ARM::t2Bcc: {
8254 int Op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8255 : MnemonicOpsEndInd + 1;
8256 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
8257 return Error(Operands[Op]->getStartLoc(), "branch target out of range");
8258 break;
8259 }
8260 case ARM::tCBZ:
8261 case ARM::tCBNZ: {
8262 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8263 .isUnsignedOffset<6, 1>())
8264 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8265 "branch target out of range");
8266 break;
8267 }
8268 case ARM::MOVi16:
8269 case ARM::MOVTi16:
8270 case ARM::t2MOVi16:
8271 case ARM::t2MOVTi16:
8272 {
8273 // We want to avoid misleadingly allowing something like "mov r0, <symbol>"
8274 // especially when we turn it into a movw and the expression <symbol> does
8275 // not have a :lower16: or :upper16 as part of the expression. We don't
8276 // want the behavior of silently truncating, which can be unexpected and
8277 // lead to bugs that are difficult to find since this is an easy mistake
8278 // to make.
8279 int i = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8280 : MnemonicOpsEndInd + 1;
8281 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[i]);
8282 const MCExpr *E = Op.getImm();
8284 break;
8285 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(E);
8286 if (!ARM16Expr || (ARM16Expr->getSpecifier() != ARM::S_HI16 &&
8287 ARM16Expr->getSpecifier() != ARM::S_LO16))
8288 return Error(
8289 Op.getStartLoc(),
8290 "immediate expression for mov requires :lower16: or :upper16");
8291 break;
8292 }
8293 case ARM::tADDi8: {
8294 int i = (Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8295 : MnemonicOpsEndInd + 2;
8296 MCParsedAsmOperand &Op = *Operands[i];
8298 return Error(Op.getStartLoc(),
8299 "Immediate expression for Thumb adds requires :lower0_7:,"
8300 " :lower8_15:, :upper0_7: or :upper8_15:");
8301 break;
8302 }
8303 case ARM::tMOVi8: {
8304 MCParsedAsmOperand &Op = *Operands[MnemonicOpsEndInd + 1];
8306 return Error(Op.getStartLoc(),
8307 "Immediate expression for Thumb movs requires :lower0_7:,"
8308 " :lower8_15:, :upper0_7: or :upper8_15:");
8309 break;
8310 }
8311 case ARM::HINT:
8312 case ARM::t2HINT: {
8313 unsigned Imm8 = Inst.getOperand(0).getImm();
8314 unsigned Pred = Inst.getOperand(1).getImm();
8315 // ESB is not predicable (pred must be AL). Without the RAS extension, this
8316 // behaves as any other unallocated hint.
8317 if (Imm8 == 0x10 && Pred != ARMCC::AL && hasRAS())
8318 return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not "
8319 "predicable, but condition "
8320 "code specified");
8321 if (Imm8 == 0x14 && Pred != ARMCC::AL)
8322 return Error(Operands[1]->getStartLoc(), "instruction 'csdb' is not "
8323 "predicable, but condition "
8324 "code specified");
8325 break;
8326 }
8327 case ARM::t2BFi:
8328 case ARM::t2BFr:
8329 case ARM::t2BFLi:
8330 case ARM::t2BFLr: {
8331 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8332 .isUnsignedOffset<4, 1>() ||
8333 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0)) {
8334 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8335 "branch location out of range or not a multiple of 2");
8336 }
8337
8338 if (Opcode == ARM::t2BFi) {
8339 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8340 .isSignedOffset<16, 1>())
8341 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8342 "branch target out of range or not a multiple of 2");
8343 } else if (Opcode == ARM::t2BFLi) {
8344 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8345 .isSignedOffset<18, 1>())
8346 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8347 "branch target out of range or not a multiple of 2");
8348 }
8349 break;
8350 }
8351 case ARM::t2BFic: {
8352 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8353 .isUnsignedOffset<4, 1>() ||
8354 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0))
8355 return Error(Operands[1]->getStartLoc(),
8356 "branch location out of range or not a multiple of 2");
8357
8358 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8359 .isSignedOffset<16, 1>())
8360 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8361 "branch target out of range or not a multiple of 2");
8362
8363 assert(Inst.getOperand(0).isImm() == Inst.getOperand(2).isImm() &&
8364 "branch location and else branch target should either both be "
8365 "immediates or both labels");
8366
8367 if (Inst.getOperand(0).isImm() && Inst.getOperand(2).isImm()) {
8368 int Diff = Inst.getOperand(2).getImm() - Inst.getOperand(0).getImm();
8369 if (Diff != 4 && Diff != 2)
8370 return Error(
8371 Operands[3]->getStartLoc(),
8372 "else branch target must be 2 or 4 greater than the branch location");
8373 }
8374 break;
8375 }
8376 case ARM::t2CLRM: {
8377 for (unsigned i = 2; i < Inst.getNumOperands(); i++) {
8378 if (Inst.getOperand(i).isReg() &&
8379 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8380 .contains(Inst.getOperand(i).getReg())) {
8381 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8382 "invalid register in register list. Valid registers are "
8383 "r0-r12, lr/r14 and APSR.");
8384 }
8385 }
8386 break;
8387 }
8388 case ARM::DSB:
8389 case ARM::t2DSB: {
8390
8391 if (Inst.getNumOperands() < 2)
8392 break;
8393
8394 unsigned Option = Inst.getOperand(0).getImm();
8395 unsigned Pred = Inst.getOperand(1).getImm();
8396
8397 // SSBB and PSSBB (DSB #0|#4) are not predicable (pred must be AL).
8398 if (Option == 0 && Pred != ARMCC::AL)
8399 return Error(Operands[1]->getStartLoc(),
8400 "instruction 'ssbb' is not predicable, but condition code "
8401 "specified");
8402 if (Option == 4 && Pred != ARMCC::AL)
8403 return Error(Operands[1]->getStartLoc(),
8404 "instruction 'pssbb' is not predicable, but condition code "
8405 "specified");
8406 break;
8407 }
8408 case ARM::VMOVRRS: {
8409 // Source registers must be sequential.
8410 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8411 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(3).getReg());
8412 if (Sm1 != Sm + 1)
8413 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8414 "source operands must be sequential");
8415 break;
8416 }
8417 case ARM::VMOVSRR: {
8418 // Destination registers must be sequential.
8419 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8420 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
8421 if (Sm1 != Sm + 1)
8422 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8423 "destination operands must be sequential");
8424 break;
8425 }
8426 case ARM::VLDMDIA:
8427 case ARM::VSTMDIA: {
8428 ARMOperand &Op =
8429 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
8430 auto &RegList = Op.getRegList();
8431 if (RegList.size() < 1 || RegList.size() > 16)
8432 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8433 "list of registers must be at least 1 and at most 16");
8434 break;
8435 }
8436 case ARM::MVE_VQDMULLs32bh:
8437 case ARM::MVE_VQDMULLs32th:
8438 case ARM::MVE_VCMULf32:
8439 case ARM::MVE_VMULLBs32:
8440 case ARM::MVE_VMULLTs32:
8441 case ARM::MVE_VMULLBu32:
8442 case ARM::MVE_VMULLTu32: {
8443 if (Operands[MnemonicOpsEndInd]->getReg() ==
8444 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8445 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8446 "Qd register and Qn register can't be identical");
8447 }
8448 if (Operands[MnemonicOpsEndInd]->getReg() ==
8449 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8450 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8451 "Qd register and Qm register can't be identical");
8452 }
8453 break;
8454 }
8455 case ARM::MVE_VREV64_8:
8456 case ARM::MVE_VREV64_16:
8457 case ARM::MVE_VREV64_32:
8458 case ARM::MVE_VQDMULL_qr_s32bh:
8459 case ARM::MVE_VQDMULL_qr_s32th: {
8460 if (Operands[MnemonicOpsEndInd]->getReg() ==
8461 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8462 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8463 "Qd register and Qn register can't be identical");
8464 }
8465 break;
8466 }
8467 case ARM::MVE_VCADDi32:
8468 case ARM::MVE_VCADDf32:
8469 case ARM::MVE_VHCADDs32: {
8470 if (Operands[MnemonicOpsEndInd]->getReg() ==
8471 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8472 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8473 "Qd register and Qm register can't be identical");
8474 }
8475 break;
8476 }
8477 case ARM::MVE_VMOV_rr_q: {
8478 if (Operands[MnemonicOpsEndInd + 2]->getReg() !=
8479 Operands[MnemonicOpsEndInd + 4]->getReg())
8480 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8481 "Q-registers must be the same");
8482 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8483 .getVectorIndex() !=
8484 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 5])
8485 .getVectorIndex() +
8486 2)
8487 return Error(Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8488 "Q-register indexes must be 2 and 0 or 3 and 1");
8489 break;
8490 }
8491 case ARM::MVE_VMOV_q_rr: {
8492 if (Operands[MnemonicOpsEndInd]->getReg() !=
8493 Operands[MnemonicOpsEndInd + 2]->getReg())
8494 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8495 "Q-registers must be the same");
8496 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8497 .getVectorIndex() !=
8498 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8499 .getVectorIndex() +
8500 2)
8501 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8502 "Q-register indexes must be 2 and 0 or 3 and 1");
8503 break;
8504 }
8505 case ARM::MVE_SQRSHR:
8506 case ARM::MVE_UQRSHL: {
8507 if (Operands[MnemonicOpsEndInd]->getReg() ==
8508 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8509 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8510 "Rda register and Rm register can't be identical");
8511 }
8512 break;
8513 }
8514 case ARM::UMAAL:
8515 case ARM::UMLAL:
8516 case ARM::UMULL:
8517 case ARM::t2UMAAL:
8518 case ARM::t2UMLAL:
8519 case ARM::t2UMULL:
8520 case ARM::SMLAL:
8521 case ARM::SMLALBB:
8522 case ARM::SMLALBT:
8523 case ARM::SMLALD:
8524 case ARM::SMLALDX:
8525 case ARM::SMLALTB:
8526 case ARM::SMLALTT:
8527 case ARM::SMLSLD:
8528 case ARM::SMLSLDX:
8529 case ARM::SMULL:
8530 case ARM::t2SMLAL:
8531 case ARM::t2SMLALBB:
8532 case ARM::t2SMLALBT:
8533 case ARM::t2SMLALD:
8534 case ARM::t2SMLALDX:
8535 case ARM::t2SMLALTB:
8536 case ARM::t2SMLALTT:
8537 case ARM::t2SMLSLD:
8538 case ARM::t2SMLSLDX:
8539 case ARM::t2SMULL: {
8540 MCRegister RdHi = Inst.getOperand(0).getReg();
8541 MCRegister RdLo = Inst.getOperand(1).getReg();
8542 if(RdHi == RdLo) {
8543 return Error(Loc,
8544 "unpredictable instruction, RdHi and RdLo must be different");
8545 }
8546 break;
8547 }
8548
8549 case ARM::CDE_CX1:
8550 case ARM::CDE_CX1A:
8551 case ARM::CDE_CX1D:
8552 case ARM::CDE_CX1DA:
8553 case ARM::CDE_CX2:
8554 case ARM::CDE_CX2A:
8555 case ARM::CDE_CX2D:
8556 case ARM::CDE_CX2DA:
8557 case ARM::CDE_CX3:
8558 case ARM::CDE_CX3A:
8559 case ARM::CDE_CX3D:
8560 case ARM::CDE_CX3DA:
8561 case ARM::CDE_VCX1_vec:
8562 case ARM::CDE_VCX1_fpsp:
8563 case ARM::CDE_VCX1_fpdp:
8564 case ARM::CDE_VCX1A_vec:
8565 case ARM::CDE_VCX1A_fpsp:
8566 case ARM::CDE_VCX1A_fpdp:
8567 case ARM::CDE_VCX2_vec:
8568 case ARM::CDE_VCX2_fpsp:
8569 case ARM::CDE_VCX2_fpdp:
8570 case ARM::CDE_VCX2A_vec:
8571 case ARM::CDE_VCX2A_fpsp:
8572 case ARM::CDE_VCX2A_fpdp:
8573 case ARM::CDE_VCX3_vec:
8574 case ARM::CDE_VCX3_fpsp:
8575 case ARM::CDE_VCX3_fpdp:
8576 case ARM::CDE_VCX3A_vec:
8577 case ARM::CDE_VCX3A_fpsp:
8578 case ARM::CDE_VCX3A_fpdp: {
8579 assert(Inst.getOperand(1).isImm() &&
8580 "CDE operand 1 must be a coprocessor ID");
8581 int64_t Coproc = Inst.getOperand(1).getImm();
8582 if (Coproc < 8 && !ARM::isCDECoproc(Coproc, *STI))
8583 return Error(Operands[1]->getStartLoc(),
8584 "coprocessor must be configured as CDE");
8585 else if (Coproc >= 8)
8586 return Error(Operands[1]->getStartLoc(),
8587 "coprocessor must be in the range [p0, p7]");
8588 break;
8589 }
8590
8591 case ARM::t2CDP:
8592 case ARM::t2CDP2:
8593 case ARM::t2LDC2L_OFFSET:
8594 case ARM::t2LDC2L_OPTION:
8595 case ARM::t2LDC2L_POST:
8596 case ARM::t2LDC2L_PRE:
8597 case ARM::t2LDC2_OFFSET:
8598 case ARM::t2LDC2_OPTION:
8599 case ARM::t2LDC2_POST:
8600 case ARM::t2LDC2_PRE:
8601 case ARM::t2LDCL_OFFSET:
8602 case ARM::t2LDCL_OPTION:
8603 case ARM::t2LDCL_POST:
8604 case ARM::t2LDCL_PRE:
8605 case ARM::t2LDC_OFFSET:
8606 case ARM::t2LDC_OPTION:
8607 case ARM::t2LDC_POST:
8608 case ARM::t2LDC_PRE:
8609 case ARM::t2MCR:
8610 case ARM::t2MCR2:
8611 case ARM::t2MCRR:
8612 case ARM::t2MCRR2:
8613 case ARM::t2MRC:
8614 case ARM::t2MRC2:
8615 case ARM::t2MRRC:
8616 case ARM::t2MRRC2:
8617 case ARM::t2STC2L_OFFSET:
8618 case ARM::t2STC2L_OPTION:
8619 case ARM::t2STC2L_POST:
8620 case ARM::t2STC2L_PRE:
8621 case ARM::t2STC2_OFFSET:
8622 case ARM::t2STC2_OPTION:
8623 case ARM::t2STC2_POST:
8624 case ARM::t2STC2_PRE:
8625 case ARM::t2STCL_OFFSET:
8626 case ARM::t2STCL_OPTION:
8627 case ARM::t2STCL_POST:
8628 case ARM::t2STCL_PRE:
8629 case ARM::t2STC_OFFSET:
8630 case ARM::t2STC_OPTION:
8631 case ARM::t2STC_POST:
8632 case ARM::t2STC_PRE: {
8633 unsigned Opcode = Inst.getOpcode();
8634 // Inst.getOperand indexes operands in the (oops ...) and (iops ...) dags,
8635 // CopInd is the index of the coprocessor operand.
8636 size_t CopInd = 0;
8637 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8638 CopInd = 2;
8639 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8640 CopInd = 1;
8641 assert(Inst.getOperand(CopInd).isImm() &&
8642 "Operand must be a coprocessor ID");
8643 int64_t Coproc = Inst.getOperand(CopInd).getImm();
8644 // Operands[2] is the coprocessor operand at syntactic level
8645 if (ARM::isCDECoproc(Coproc, *STI))
8646 return Error(Operands[2]->getStartLoc(),
8647 "coprocessor must be configured as GCP");
8648 break;
8649 }
8650
8651 case ARM::VTOSHH:
8652 case ARM::VTOUHH:
8653 case ARM::VTOSLH:
8654 case ARM::VTOULH:
8655 case ARM::VTOSHS:
8656 case ARM::VTOUHS:
8657 case ARM::VTOSLS:
8658 case ARM::VTOULS:
8659 case ARM::VTOSHD:
8660 case ARM::VTOUHD:
8661 case ARM::VTOSLD:
8662 case ARM::VTOULD:
8663 case ARM::VSHTOH:
8664 case ARM::VUHTOH:
8665 case ARM::VSLTOH:
8666 case ARM::VULTOH:
8667 case ARM::VSHTOS:
8668 case ARM::VUHTOS:
8669 case ARM::VSLTOS:
8670 case ARM::VULTOS:
8671 case ARM::VSHTOD:
8672 case ARM::VUHTOD:
8673 case ARM::VSLTOD:
8674 case ARM::VULTOD: {
8675 if (Operands[MnemonicOpsEndInd]->getReg() !=
8676 Operands[MnemonicOpsEndInd + 1]->getReg())
8677 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8678 "source and destination registers must be the same");
8679 break;
8680 }
8681 }
8682
8683 return false;
8684}
8685
8686static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
8687 switch(Opc) {
8688 default: llvm_unreachable("unexpected opcode!");
8689 // VST1LN
8690 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8691 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8693 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8694 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8695 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8696 case ARM::VST1LNdAsm_8: Spacing = 1; return ARM::VST1LNd8;
8697 case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
8698 case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
8699
8700 // VST2LN
8701 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8702 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8704 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8706
8707 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8708 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8709 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8710 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8711 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8712
8713 case ARM::VST2LNdAsm_8: Spacing = 1; return ARM::VST2LNd8;
8714 case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
8715 case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
8716 case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
8717 case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
8718
8719 // VST3LN
8720 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8721 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8723 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8725 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8726 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8727 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8728 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
8729 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8730 case ARM::VST3LNdAsm_8: Spacing = 1; return ARM::VST3LNd8;
8731 case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
8732 case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
8733 case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
8734 case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
8735
8736 // VST3
8737 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8738 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8739 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8740 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8741 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8742 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8743 case ARM::VST3dWB_register_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8744 case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8745 case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8746 case ARM::VST3qWB_register_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8747 case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8748 case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8749 case ARM::VST3dAsm_8: Spacing = 1; return ARM::VST3d8;
8750 case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
8751 case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
8752 case ARM::VST3qAsm_8: Spacing = 2; return ARM::VST3q8;
8753 case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
8754 case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
8755
8756 // VST4LN
8757 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8758 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8760 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8762 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8763 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8764 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8765 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
8766 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8767 case ARM::VST4LNdAsm_8: Spacing = 1; return ARM::VST4LNd8;
8768 case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
8769 case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
8770 case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
8771 case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
8772
8773 // VST4
8774 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8775 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8776 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8777 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8778 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8779 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8780 case ARM::VST4dWB_register_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8781 case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8782 case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8783 case ARM::VST4qWB_register_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8784 case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8785 case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8786 case ARM::VST4dAsm_8: Spacing = 1; return ARM::VST4d8;
8787 case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
8788 case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
8789 case ARM::VST4qAsm_8: Spacing = 2; return ARM::VST4q8;
8790 case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
8791 case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
8792 }
8793}
8794
8795static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
8796 switch(Opc) {
8797 default: llvm_unreachable("unexpected opcode!");
8798 // VLD1LN
8799 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8800 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8802 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8805 case ARM::VLD1LNdAsm_8: Spacing = 1; return ARM::VLD1LNd8;
8806 case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
8807 case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
8808
8809 // VLD2LN
8810 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8811 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8813 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8815 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8818 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8820 case ARM::VLD2LNdAsm_8: Spacing = 1; return ARM::VLD2LNd8;
8821 case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
8822 case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
8823 case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
8824 case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
8825
8826 // VLD3DUP
8827 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8828 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8830 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8833 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8836 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8839 case ARM::VLD3DUPdAsm_8: Spacing = 1; return ARM::VLD3DUPd8;
8840 case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
8841 case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
8842 case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
8843 case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
8844 case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
8845
8846 // VLD3LN
8847 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8848 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8850 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8852 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8855 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8857 case ARM::VLD3LNdAsm_8: Spacing = 1; return ARM::VLD3LNd8;
8858 case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
8859 case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
8860 case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
8861 case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
8862
8863 // VLD3
8864 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8865 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8867 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8870 case ARM::VLD3dWB_register_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8871 case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8872 case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8873 case ARM::VLD3qWB_register_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8874 case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8875 case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8876 case ARM::VLD3dAsm_8: Spacing = 1; return ARM::VLD3d8;
8877 case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
8878 case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
8879 case ARM::VLD3qAsm_8: Spacing = 2; return ARM::VLD3q8;
8880 case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
8881 case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
8882
8883 // VLD4LN
8884 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8885 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8887 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8889 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8892 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8894 case ARM::VLD4LNdAsm_8: Spacing = 1; return ARM::VLD4LNd8;
8895 case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
8896 case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
8897 case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
8898 case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
8899
8900 // VLD4DUP
8901 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8902 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8904 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8907 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8910 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8913 case ARM::VLD4DUPdAsm_8: Spacing = 1; return ARM::VLD4DUPd8;
8914 case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
8915 case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
8916 case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
8917 case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
8918 case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
8919
8920 // VLD4
8921 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8922 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8924 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8927 case ARM::VLD4dWB_register_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8928 case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8929 case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8930 case ARM::VLD4qWB_register_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8931 case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8932 case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8933 case ARM::VLD4dAsm_8: Spacing = 1; return ARM::VLD4d8;
8934 case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
8935 case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
8936 case ARM::VLD4qAsm_8: Spacing = 2; return ARM::VLD4q8;
8937 case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
8938 case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
8939 }
8940}
8941
8942bool ARMAsmParser::processInstruction(MCInst &Inst,
8943 const OperandVector &Operands,
8944 unsigned MnemonicOpsEndInd,
8945 MCStreamer &Out) {
8946 // Check if we have the wide qualifier, because if it's present we
8947 // must avoid selecting a 16-bit thumb instruction.
8948 bool HasWideQualifier = false;
8949 for (auto &Op : Operands) {
8950 ARMOperand &ARMOp = static_cast<ARMOperand&>(*Op);
8951 if (ARMOp.isToken() && ARMOp.getToken() == ".w") {
8952 HasWideQualifier = true;
8953 break;
8954 }
8955 }
8956
8957 switch (Inst.getOpcode()) {
8958 case ARM::VLLDM:
8959 case ARM::VLSTM: {
8960 // In some cases both T1 and T2 are valid, causing tablegen pick T1 instead
8961 // of T2
8962 if (Operands.size() ==
8963 MnemonicOpsEndInd + 2) { // a register list has been provided
8964 ARMOperand &Op = static_cast<ARMOperand &>(
8965 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
8966 assert(Op.isDPRRegList());
8967 auto &RegList = Op.getRegList();
8968 // When the register list is {d0-d31} the instruction has to be the T2
8969 // variant
8970 if (RegList.size() == 32) {
8971 const unsigned Opcode =
8972 (Inst.getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8973 MCInst TmpInst;
8974 TmpInst.setOpcode(Opcode);
8975 TmpInst.addOperand(Inst.getOperand(0));
8976 TmpInst.addOperand(Inst.getOperand(1));
8977 TmpInst.addOperand(Inst.getOperand(2));
8978 TmpInst.addOperand(Inst.getOperand(3));
8979 Inst = TmpInst;
8980 return true;
8981 }
8982 }
8983 return false;
8984 }
8985 // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
8986 case ARM::LDRT_POST:
8987 case ARM::LDRBT_POST: {
8988 const unsigned Opcode =
8989 (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8990 : ARM::LDRBT_POST_IMM;
8991 MCInst TmpInst;
8992 TmpInst.setOpcode(Opcode);
8993 TmpInst.addOperand(Inst.getOperand(0));
8994 TmpInst.addOperand(Inst.getOperand(1));
8995 TmpInst.addOperand(Inst.getOperand(1));
8996 TmpInst.addOperand(MCOperand::createReg(0));
8997 TmpInst.addOperand(MCOperand::createImm(0));
8998 TmpInst.addOperand(Inst.getOperand(2));
8999 TmpInst.addOperand(Inst.getOperand(3));
9000 Inst = TmpInst;
9001 return true;
9002 }
9003 // Alias for 'ldr{sb,h,sh}t Rt, [Rn] {, #imm}' for omitted immediate.
9004 case ARM::LDRSBTii:
9005 case ARM::LDRHTii:
9006 case ARM::LDRSHTii: {
9007 MCInst TmpInst;
9008
9009 if (Inst.getOpcode() == ARM::LDRSBTii)
9010 TmpInst.setOpcode(ARM::LDRSBTi);
9011 else if (Inst.getOpcode() == ARM::LDRHTii)
9012 TmpInst.setOpcode(ARM::LDRHTi);
9013 else if (Inst.getOpcode() == ARM::LDRSHTii)
9014 TmpInst.setOpcode(ARM::LDRSHTi);
9015 TmpInst.addOperand(Inst.getOperand(0));
9016 TmpInst.addOperand(Inst.getOperand(1));
9017 TmpInst.addOperand(Inst.getOperand(1));
9018 TmpInst.addOperand(MCOperand::createImm(256));
9019 TmpInst.addOperand(Inst.getOperand(2));
9020 Inst = TmpInst;
9021 return true;
9022 }
9023 // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction.
9024 case ARM::STRT_POST:
9025 case ARM::STRBT_POST: {
9026 const unsigned Opcode =
9027 (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9028 : ARM::STRBT_POST_IMM;
9029 MCInst TmpInst;
9030 TmpInst.setOpcode(Opcode);
9031 TmpInst.addOperand(Inst.getOperand(1));
9032 TmpInst.addOperand(Inst.getOperand(0));
9033 TmpInst.addOperand(Inst.getOperand(1));
9034 TmpInst.addOperand(MCOperand::createReg(0));
9035 TmpInst.addOperand(MCOperand::createImm(0));
9036 TmpInst.addOperand(Inst.getOperand(2));
9037 TmpInst.addOperand(Inst.getOperand(3));
9038 Inst = TmpInst;
9039 return true;
9040 }
9041 // Alias for alternate form of 'ADR Rd, #imm' instruction.
9042 case ARM::ADDri: {
9043 if (Inst.getOperand(1).getReg() != ARM::PC || Inst.getOperand(5).getReg() ||
9044 !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
9045 return false;
9046 MCInst TmpInst;
9047 TmpInst.setOpcode(ARM::ADR);
9048 TmpInst.addOperand(Inst.getOperand(0));
9049 if (Inst.getOperand(2).isImm()) {
9050 // Immediate (mod_imm) will be in its encoded form, we must unencode it
9051 // before passing it to the ADR instruction.
9052 unsigned Enc = Inst.getOperand(2).getImm();
9054 llvm::rotr<uint32_t>(Enc & 0xFF, (Enc & 0xF00) >> 7)));
9055 } else {
9056 // Turn PC-relative expression into absolute expression.
9057 // Reading PC provides the start of the current instruction + 8 and
9058 // the transform to adr is biased by that.
9059 MCSymbol *Dot = getContext().createTempSymbol();
9060 Out.emitLabel(Dot);
9061 const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
9062 const MCExpr *InstPC = MCSymbolRefExpr::create(Dot,
9063 getContext());
9064 const MCExpr *Const8 = MCConstantExpr::create(8, getContext());
9065 const MCExpr *ReadPC = MCBinaryExpr::createAdd(InstPC, Const8,
9066 getContext());
9067 const MCExpr *FixupAddr = MCBinaryExpr::createAdd(ReadPC, OpExpr,
9068 getContext());
9069 TmpInst.addOperand(MCOperand::createExpr(FixupAddr));
9070 }
9071 TmpInst.addOperand(Inst.getOperand(3));
9072 TmpInst.addOperand(Inst.getOperand(4));
9073 Inst = TmpInst;
9074 return true;
9075 }
9076 // Aliases for imm syntax of LDR instructions.
9077 case ARM::t2LDR_PRE_imm:
9078 case ARM::t2LDR_POST_imm: {
9079 MCInst TmpInst;
9080 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDR_PRE_imm ? ARM::t2LDR_PRE
9081 : ARM::t2LDR_POST);
9082 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9083 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9084 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9085 TmpInst.addOperand(Inst.getOperand(2)); // imm
9086 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9087 TmpInst.addOperand(Inst.getOperand(4));
9088 Inst = TmpInst;
9089 return true;
9090 }
9091 // Aliases for imm syntax of STR instructions.
9092 case ARM::t2STR_PRE_imm:
9093 case ARM::t2STR_POST_imm: {
9094 MCInst TmpInst;
9095 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STR_PRE_imm ? ARM::t2STR_PRE
9096 : ARM::t2STR_POST);
9097 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9098 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9099 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9100 TmpInst.addOperand(Inst.getOperand(2)); // imm
9101 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9102 TmpInst.addOperand(Inst.getOperand(4));
9103 Inst = TmpInst;
9104 return true;
9105 }
9106 // Aliases for imm syntax of LDRB instructions.
9107 case ARM::t2LDRB_OFFSET_imm: {
9108 MCInst TmpInst;
9109 TmpInst.setOpcode(ARM::t2LDRBi8);
9110 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9111 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9112 TmpInst.addOperand(Inst.getOperand(2)); // imm
9113 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9114 Inst = TmpInst;
9115 return true;
9116 }
9117 case ARM::t2LDRB_PRE_imm:
9118 case ARM::t2LDRB_POST_imm: {
9119 MCInst TmpInst;
9120 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRB_PRE_imm
9121 ? ARM::t2LDRB_PRE
9122 : ARM::t2LDRB_POST);
9123 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9124 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9125 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9126 TmpInst.addOperand(Inst.getOperand(2)); // imm
9127 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9128 TmpInst.addOperand(Inst.getOperand(4));
9129 Inst = TmpInst;
9130 return true;
9131 }
9132 // Aliases for imm syntax of STRB instructions.
9133 case ARM::t2STRB_OFFSET_imm: {
9134 MCInst TmpInst;
9135 TmpInst.setOpcode(ARM::t2STRBi8);
9136 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9137 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9138 TmpInst.addOperand(Inst.getOperand(2)); // imm
9139 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9140 Inst = TmpInst;
9141 return true;
9142 }
9143 case ARM::t2STRB_PRE_imm:
9144 case ARM::t2STRB_POST_imm: {
9145 MCInst TmpInst;
9146 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRB_PRE_imm
9147 ? ARM::t2STRB_PRE
9148 : ARM::t2STRB_POST);
9149 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9150 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9151 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9152 TmpInst.addOperand(Inst.getOperand(2)); // imm
9153 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9154 TmpInst.addOperand(Inst.getOperand(4));
9155 Inst = TmpInst;
9156 return true;
9157 }
9158 // Aliases for imm syntax of LDRH instructions.
9159 case ARM::t2LDRH_OFFSET_imm: {
9160 MCInst TmpInst;
9161 TmpInst.setOpcode(ARM::t2LDRHi8);
9162 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9163 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9164 TmpInst.addOperand(Inst.getOperand(2)); // imm
9165 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9166 Inst = TmpInst;
9167 return true;
9168 }
9169 case ARM::t2LDRH_PRE_imm:
9170 case ARM::t2LDRH_POST_imm: {
9171 MCInst TmpInst;
9172 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRH_PRE_imm
9173 ? ARM::t2LDRH_PRE
9174 : ARM::t2LDRH_POST);
9175 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9176 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9177 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9178 TmpInst.addOperand(Inst.getOperand(2)); // imm
9179 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9180 TmpInst.addOperand(Inst.getOperand(4));
9181 Inst = TmpInst;
9182 return true;
9183 }
9184 // Aliases for imm syntax of STRH instructions.
9185 case ARM::t2STRH_OFFSET_imm: {
9186 MCInst TmpInst;
9187 TmpInst.setOpcode(ARM::t2STRHi8);
9188 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9189 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9190 TmpInst.addOperand(Inst.getOperand(2)); // imm
9191 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9192 Inst = TmpInst;
9193 return true;
9194 }
9195 case ARM::t2STRH_PRE_imm:
9196 case ARM::t2STRH_POST_imm: {
9197 MCInst TmpInst;
9198 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRH_PRE_imm
9199 ? ARM::t2STRH_PRE
9200 : ARM::t2STRH_POST);
9201 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9202 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9203 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9204 TmpInst.addOperand(Inst.getOperand(2)); // imm
9205 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9206 TmpInst.addOperand(Inst.getOperand(4));
9207 Inst = TmpInst;
9208 return true;
9209 }
9210 // Aliases for imm syntax of LDRSB instructions.
9211 case ARM::t2LDRSB_OFFSET_imm: {
9212 MCInst TmpInst;
9213 TmpInst.setOpcode(ARM::t2LDRSBi8);
9214 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9215 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9216 TmpInst.addOperand(Inst.getOperand(2)); // imm
9217 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9218 Inst = TmpInst;
9219 return true;
9220 }
9221 case ARM::t2LDRSB_PRE_imm:
9222 case ARM::t2LDRSB_POST_imm: {
9223 MCInst TmpInst;
9224 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSB_PRE_imm
9225 ? ARM::t2LDRSB_PRE
9226 : ARM::t2LDRSB_POST);
9227 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9228 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9229 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9230 TmpInst.addOperand(Inst.getOperand(2)); // imm
9231 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9232 TmpInst.addOperand(Inst.getOperand(4));
9233 Inst = TmpInst;
9234 return true;
9235 }
9236 // Aliases for imm syntax of LDRSH instructions.
9237 case ARM::t2LDRSH_OFFSET_imm: {
9238 MCInst TmpInst;
9239 TmpInst.setOpcode(ARM::t2LDRSHi8);
9240 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9241 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9242 TmpInst.addOperand(Inst.getOperand(2)); // imm
9243 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9244 Inst = TmpInst;
9245 return true;
9246 }
9247 case ARM::t2LDRSH_PRE_imm:
9248 case ARM::t2LDRSH_POST_imm: {
9249 MCInst TmpInst;
9250 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSH_PRE_imm
9251 ? ARM::t2LDRSH_PRE
9252 : ARM::t2LDRSH_POST);
9253 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9254 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9255 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9256 TmpInst.addOperand(Inst.getOperand(2)); // imm
9257 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9258 TmpInst.addOperand(Inst.getOperand(4));
9259 Inst = TmpInst;
9260 return true;
9261 }
9262 // Aliases for alternate PC+imm syntax of LDR instructions.
9263 case ARM::t2LDRpcrel:
9264 // Select the narrow version if the immediate will fit.
9265 if (Inst.getOperand(1).getImm() > 0 &&
9266 Inst.getOperand(1).getImm() <= 0xff &&
9267 !HasWideQualifier)
9268 Inst.setOpcode(ARM::tLDRpci);
9269 else
9270 Inst.setOpcode(ARM::t2LDRpci);
9271 return true;
9272 case ARM::t2LDRBpcrel:
9273 Inst.setOpcode(ARM::t2LDRBpci);
9274 return true;
9275 case ARM::t2LDRHpcrel:
9276 Inst.setOpcode(ARM::t2LDRHpci);
9277 return true;
9278 case ARM::t2LDRSBpcrel:
9279 Inst.setOpcode(ARM::t2LDRSBpci);
9280 return true;
9281 case ARM::t2LDRSHpcrel:
9282 Inst.setOpcode(ARM::t2LDRSHpci);
9283 return true;
9284 case ARM::LDRConstPool:
9285 case ARM::tLDRConstPool:
9286 case ARM::t2LDRConstPool: {
9287 // Pseudo instruction ldr rt, =immediate is converted to a
9288 // MOV rt, immediate if immediate is known and representable
9289 // otherwise we create a constant pool entry that we load from.
9290 MCInst TmpInst;
9291 if (Inst.getOpcode() == ARM::LDRConstPool)
9292 TmpInst.setOpcode(ARM::LDRi12);
9293 else if (Inst.getOpcode() == ARM::tLDRConstPool)
9294 TmpInst.setOpcode(ARM::tLDRpci);
9295 else if (Inst.getOpcode() == ARM::t2LDRConstPool)
9296 TmpInst.setOpcode(ARM::t2LDRpci);
9297 const ARMOperand &PoolOperand =
9298 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
9299 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9300 // If SubExprVal is a constant we may be able to use a MOV
9301 if (isa<MCConstantExpr>(SubExprVal) &&
9302 Inst.getOperand(0).getReg() != ARM::PC &&
9303 Inst.getOperand(0).getReg() != ARM::SP) {
9304 int64_t Value =
9305 (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue();
9306 bool UseMov = true;
9307 bool MovHasS = true;
9308 if (Inst.getOpcode() == ARM::LDRConstPool) {
9309 // ARM Constant
9310 if (ARM_AM::getSOImmVal(Value) != -1) {
9312 TmpInst.setOpcode(ARM::MOVi);
9313 }
9314 else if (ARM_AM::getSOImmVal(~Value) != -1) {
9316 TmpInst.setOpcode(ARM::MVNi);
9317 }
9318 else if (hasV6T2Ops() &&
9319 Value >=0 && Value < 65536) {
9320 TmpInst.setOpcode(ARM::MOVi16);
9321 MovHasS = false;
9322 }
9323 else
9324 UseMov = false;
9325 }
9326 else {
9327 // Thumb/Thumb2 Constant
9328 if (hasThumb2() &&
9330 TmpInst.setOpcode(ARM::t2MOVi);
9331 else if (hasThumb2() &&
9332 ARM_AM::getT2SOImmVal(~Value) != -1) {
9333 TmpInst.setOpcode(ARM::t2MVNi);
9334 Value = ~Value;
9335 }
9336 else if (hasV8MBaseline() &&
9337 Value >=0 && Value < 65536) {
9338 TmpInst.setOpcode(ARM::t2MOVi16);
9339 MovHasS = false;
9340 }
9341 else
9342 UseMov = false;
9343 }
9344 if (UseMov) {
9345 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9346 TmpInst.addOperand(MCOperand::createImm(Value)); // Immediate
9347 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9348 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9349 if (MovHasS)
9350 TmpInst.addOperand(MCOperand::createReg(0)); // S
9351 Inst = TmpInst;
9352 return true;
9353 }
9354 }
9355 // No opportunity to use MOV/MVN create constant pool
9356 const MCExpr *CPLoc =
9357 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9358 PoolOperand.getStartLoc());
9359 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9360 TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool
9361 if (TmpInst.getOpcode() == ARM::LDRi12)
9362 TmpInst.addOperand(MCOperand::createImm(0)); // unused offset
9363 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9364 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9365 Inst = TmpInst;
9366 return true;
9367 }
9368 // Handle NEON VST complex aliases.
9369 case ARM::VST1LNdWB_register_Asm_8:
9370 case ARM::VST1LNdWB_register_Asm_16:
9371 case ARM::VST1LNdWB_register_Asm_32: {
9372 MCInst TmpInst;
9373 // Shuffle the operands around so the lane index operand is in the
9374 // right place.
9375 unsigned Spacing;
9376 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9377 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9378 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9379 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9380 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9381 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9382 TmpInst.addOperand(Inst.getOperand(1)); // lane
9383 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9384 TmpInst.addOperand(Inst.getOperand(6));
9385 Inst = TmpInst;
9386 return true;
9387 }
9388
9389 case ARM::VST2LNdWB_register_Asm_8:
9390 case ARM::VST2LNdWB_register_Asm_16:
9391 case ARM::VST2LNdWB_register_Asm_32:
9392 case ARM::VST2LNqWB_register_Asm_16:
9393 case ARM::VST2LNqWB_register_Asm_32: {
9394 MCInst TmpInst;
9395 // Shuffle the operands around so the lane index operand is in the
9396 // right place.
9397 unsigned Spacing;
9398 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9399 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9400 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9401 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9402 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9403 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9405 Spacing));
9406 TmpInst.addOperand(Inst.getOperand(1)); // lane
9407 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9408 TmpInst.addOperand(Inst.getOperand(6));
9409 Inst = TmpInst;
9410 return true;
9411 }
9412
9413 case ARM::VST3LNdWB_register_Asm_8:
9414 case ARM::VST3LNdWB_register_Asm_16:
9415 case ARM::VST3LNdWB_register_Asm_32:
9416 case ARM::VST3LNqWB_register_Asm_16:
9417 case ARM::VST3LNqWB_register_Asm_32: {
9418 MCInst TmpInst;
9419 // Shuffle the operands around so the lane index operand is in the
9420 // right place.
9421 unsigned Spacing;
9422 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9423 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9424 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9425 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9426 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9427 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9429 Spacing));
9431 Spacing * 2));
9432 TmpInst.addOperand(Inst.getOperand(1)); // lane
9433 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9434 TmpInst.addOperand(Inst.getOperand(6));
9435 Inst = TmpInst;
9436 return true;
9437 }
9438
9439 case ARM::VST4LNdWB_register_Asm_8:
9440 case ARM::VST4LNdWB_register_Asm_16:
9441 case ARM::VST4LNdWB_register_Asm_32:
9442 case ARM::VST4LNqWB_register_Asm_16:
9443 case ARM::VST4LNqWB_register_Asm_32: {
9444 MCInst TmpInst;
9445 // Shuffle the operands around so the lane index operand is in the
9446 // right place.
9447 unsigned Spacing;
9448 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9449 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9450 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9451 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9452 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9453 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9455 Spacing));
9457 Spacing * 2));
9459 Spacing * 3));
9460 TmpInst.addOperand(Inst.getOperand(1)); // lane
9461 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9462 TmpInst.addOperand(Inst.getOperand(6));
9463 Inst = TmpInst;
9464 return true;
9465 }
9466
9467 case ARM::VST1LNdWB_fixed_Asm_8:
9468 case ARM::VST1LNdWB_fixed_Asm_16:
9469 case ARM::VST1LNdWB_fixed_Asm_32: {
9470 MCInst TmpInst;
9471 // Shuffle the operands around so the lane index operand is in the
9472 // right place.
9473 unsigned Spacing;
9474 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9475 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9476 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9477 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9478 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9479 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9480 TmpInst.addOperand(Inst.getOperand(1)); // lane
9481 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9482 TmpInst.addOperand(Inst.getOperand(5));
9483 Inst = TmpInst;
9484 return true;
9485 }
9486
9487 case ARM::VST2LNdWB_fixed_Asm_8:
9488 case ARM::VST2LNdWB_fixed_Asm_16:
9489 case ARM::VST2LNdWB_fixed_Asm_32:
9490 case ARM::VST2LNqWB_fixed_Asm_16:
9491 case ARM::VST2LNqWB_fixed_Asm_32: {
9492 MCInst TmpInst;
9493 // Shuffle the operands around so the lane index operand is in the
9494 // right place.
9495 unsigned Spacing;
9496 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9497 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9498 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9499 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9500 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9501 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9503 Spacing));
9504 TmpInst.addOperand(Inst.getOperand(1)); // lane
9505 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9506 TmpInst.addOperand(Inst.getOperand(5));
9507 Inst = TmpInst;
9508 return true;
9509 }
9510
9511 case ARM::VST3LNdWB_fixed_Asm_8:
9512 case ARM::VST3LNdWB_fixed_Asm_16:
9513 case ARM::VST3LNdWB_fixed_Asm_32:
9514 case ARM::VST3LNqWB_fixed_Asm_16:
9515 case ARM::VST3LNqWB_fixed_Asm_32: {
9516 MCInst TmpInst;
9517 // Shuffle the operands around so the lane index operand is in the
9518 // right place.
9519 unsigned Spacing;
9520 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9521 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9522 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9523 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9524 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9525 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9527 Spacing));
9529 Spacing * 2));
9530 TmpInst.addOperand(Inst.getOperand(1)); // lane
9531 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9532 TmpInst.addOperand(Inst.getOperand(5));
9533 Inst = TmpInst;
9534 return true;
9535 }
9536
9537 case ARM::VST4LNdWB_fixed_Asm_8:
9538 case ARM::VST4LNdWB_fixed_Asm_16:
9539 case ARM::VST4LNdWB_fixed_Asm_32:
9540 case ARM::VST4LNqWB_fixed_Asm_16:
9541 case ARM::VST4LNqWB_fixed_Asm_32: {
9542 MCInst TmpInst;
9543 // Shuffle the operands around so the lane index operand is in the
9544 // right place.
9545 unsigned Spacing;
9546 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9547 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9548 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9549 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9550 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9551 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9553 Spacing));
9555 Spacing * 2));
9557 Spacing * 3));
9558 TmpInst.addOperand(Inst.getOperand(1)); // lane
9559 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9560 TmpInst.addOperand(Inst.getOperand(5));
9561 Inst = TmpInst;
9562 return true;
9563 }
9564
9565 case ARM::VST1LNdAsm_8:
9566 case ARM::VST1LNdAsm_16:
9567 case ARM::VST1LNdAsm_32: {
9568 MCInst TmpInst;
9569 // Shuffle the operands around so the lane index operand is in the
9570 // right place.
9571 unsigned Spacing;
9572 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9573 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9574 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9575 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9576 TmpInst.addOperand(Inst.getOperand(1)); // lane
9577 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9578 TmpInst.addOperand(Inst.getOperand(5));
9579 Inst = TmpInst;
9580 return true;
9581 }
9582
9583 case ARM::VST2LNdAsm_8:
9584 case ARM::VST2LNdAsm_16:
9585 case ARM::VST2LNdAsm_32:
9586 case ARM::VST2LNqAsm_16:
9587 case ARM::VST2LNqAsm_32: {
9588 MCInst TmpInst;
9589 // Shuffle the operands around so the lane index operand is in the
9590 // right place.
9591 unsigned Spacing;
9592 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9593 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9594 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9595 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9597 Spacing));
9598 TmpInst.addOperand(Inst.getOperand(1)); // lane
9599 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9600 TmpInst.addOperand(Inst.getOperand(5));
9601 Inst = TmpInst;
9602 return true;
9603 }
9604
9605 case ARM::VST3LNdAsm_8:
9606 case ARM::VST3LNdAsm_16:
9607 case ARM::VST3LNdAsm_32:
9608 case ARM::VST3LNqAsm_16:
9609 case ARM::VST3LNqAsm_32: {
9610 MCInst TmpInst;
9611 // Shuffle the operands around so the lane index operand is in the
9612 // right place.
9613 unsigned Spacing;
9614 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9615 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9616 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9617 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9619 Spacing));
9621 Spacing * 2));
9622 TmpInst.addOperand(Inst.getOperand(1)); // lane
9623 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9624 TmpInst.addOperand(Inst.getOperand(5));
9625 Inst = TmpInst;
9626 return true;
9627 }
9628
9629 case ARM::VST4LNdAsm_8:
9630 case ARM::VST4LNdAsm_16:
9631 case ARM::VST4LNdAsm_32:
9632 case ARM::VST4LNqAsm_16:
9633 case ARM::VST4LNqAsm_32: {
9634 MCInst TmpInst;
9635 // Shuffle the operands around so the lane index operand is in the
9636 // right place.
9637 unsigned Spacing;
9638 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9639 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9640 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9641 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9643 Spacing));
9645 Spacing * 2));
9647 Spacing * 3));
9648 TmpInst.addOperand(Inst.getOperand(1)); // lane
9649 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9650 TmpInst.addOperand(Inst.getOperand(5));
9651 Inst = TmpInst;
9652 return true;
9653 }
9654
9655 // Handle NEON VLD complex aliases.
9656 case ARM::VLD1LNdWB_register_Asm_8:
9657 case ARM::VLD1LNdWB_register_Asm_16:
9658 case ARM::VLD1LNdWB_register_Asm_32: {
9659 MCInst TmpInst;
9660 // Shuffle the operands around so the lane index operand is in the
9661 // right place.
9662 unsigned Spacing;
9663 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9664 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9665 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9666 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9667 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9668 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9669 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9670 TmpInst.addOperand(Inst.getOperand(1)); // lane
9671 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9672 TmpInst.addOperand(Inst.getOperand(6));
9673 Inst = TmpInst;
9674 return true;
9675 }
9676
9677 case ARM::VLD2LNdWB_register_Asm_8:
9678 case ARM::VLD2LNdWB_register_Asm_16:
9679 case ARM::VLD2LNdWB_register_Asm_32:
9680 case ARM::VLD2LNqWB_register_Asm_16:
9681 case ARM::VLD2LNqWB_register_Asm_32: {
9682 MCInst TmpInst;
9683 // Shuffle the operands around so the lane index operand is in the
9684 // right place.
9685 unsigned Spacing;
9686 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9687 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9689 Spacing));
9690 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9691 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9692 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9693 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9694 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9696 Spacing));
9697 TmpInst.addOperand(Inst.getOperand(1)); // lane
9698 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9699 TmpInst.addOperand(Inst.getOperand(6));
9700 Inst = TmpInst;
9701 return true;
9702 }
9703
9704 case ARM::VLD3LNdWB_register_Asm_8:
9705 case ARM::VLD3LNdWB_register_Asm_16:
9706 case ARM::VLD3LNdWB_register_Asm_32:
9707 case ARM::VLD3LNqWB_register_Asm_16:
9708 case ARM::VLD3LNqWB_register_Asm_32: {
9709 MCInst TmpInst;
9710 // Shuffle the operands around so the lane index operand is in the
9711 // right place.
9712 unsigned Spacing;
9713 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9714 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9716 Spacing));
9718 Spacing * 2));
9719 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9720 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9721 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9722 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9723 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9725 Spacing));
9727 Spacing * 2));
9728 TmpInst.addOperand(Inst.getOperand(1)); // lane
9729 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9730 TmpInst.addOperand(Inst.getOperand(6));
9731 Inst = TmpInst;
9732 return true;
9733 }
9734
9735 case ARM::VLD4LNdWB_register_Asm_8:
9736 case ARM::VLD4LNdWB_register_Asm_16:
9737 case ARM::VLD4LNdWB_register_Asm_32:
9738 case ARM::VLD4LNqWB_register_Asm_16:
9739 case ARM::VLD4LNqWB_register_Asm_32: {
9740 MCInst TmpInst;
9741 // Shuffle the operands around so the lane index operand is in the
9742 // right place.
9743 unsigned Spacing;
9744 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9745 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9747 Spacing));
9749 Spacing * 2));
9751 Spacing * 3));
9752 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9753 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9754 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9755 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9756 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9758 Spacing));
9760 Spacing * 2));
9762 Spacing * 3));
9763 TmpInst.addOperand(Inst.getOperand(1)); // lane
9764 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9765 TmpInst.addOperand(Inst.getOperand(6));
9766 Inst = TmpInst;
9767 return true;
9768 }
9769
9770 case ARM::VLD1LNdWB_fixed_Asm_8:
9771 case ARM::VLD1LNdWB_fixed_Asm_16:
9772 case ARM::VLD1LNdWB_fixed_Asm_32: {
9773 MCInst TmpInst;
9774 // Shuffle the operands around so the lane index operand is in the
9775 // right place.
9776 unsigned Spacing;
9777 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9778 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9779 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9780 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9781 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9782 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9783 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9784 TmpInst.addOperand(Inst.getOperand(1)); // lane
9785 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9786 TmpInst.addOperand(Inst.getOperand(5));
9787 Inst = TmpInst;
9788 return true;
9789 }
9790
9791 case ARM::VLD2LNdWB_fixed_Asm_8:
9792 case ARM::VLD2LNdWB_fixed_Asm_16:
9793 case ARM::VLD2LNdWB_fixed_Asm_32:
9794 case ARM::VLD2LNqWB_fixed_Asm_16:
9795 case ARM::VLD2LNqWB_fixed_Asm_32: {
9796 MCInst TmpInst;
9797 // Shuffle the operands around so the lane index operand is in the
9798 // right place.
9799 unsigned Spacing;
9800 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9801 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9803 Spacing));
9804 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9805 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9806 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9807 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9808 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9810 Spacing));
9811 TmpInst.addOperand(Inst.getOperand(1)); // lane
9812 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9813 TmpInst.addOperand(Inst.getOperand(5));
9814 Inst = TmpInst;
9815 return true;
9816 }
9817
9818 case ARM::VLD3LNdWB_fixed_Asm_8:
9819 case ARM::VLD3LNdWB_fixed_Asm_16:
9820 case ARM::VLD3LNdWB_fixed_Asm_32:
9821 case ARM::VLD3LNqWB_fixed_Asm_16:
9822 case ARM::VLD3LNqWB_fixed_Asm_32: {
9823 MCInst TmpInst;
9824 // Shuffle the operands around so the lane index operand is in the
9825 // right place.
9826 unsigned Spacing;
9827 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9828 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9830 Spacing));
9832 Spacing * 2));
9833 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9834 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9835 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9836 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9837 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9839 Spacing));
9841 Spacing * 2));
9842 TmpInst.addOperand(Inst.getOperand(1)); // lane
9843 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9844 TmpInst.addOperand(Inst.getOperand(5));
9845 Inst = TmpInst;
9846 return true;
9847 }
9848
9849 case ARM::VLD4LNdWB_fixed_Asm_8:
9850 case ARM::VLD4LNdWB_fixed_Asm_16:
9851 case ARM::VLD4LNdWB_fixed_Asm_32:
9852 case ARM::VLD4LNqWB_fixed_Asm_16:
9853 case ARM::VLD4LNqWB_fixed_Asm_32: {
9854 MCInst TmpInst;
9855 // Shuffle the operands around so the lane index operand is in the
9856 // right place.
9857 unsigned Spacing;
9858 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9859 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9861 Spacing));
9863 Spacing * 2));
9865 Spacing * 3));
9866 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9867 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9868 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9869 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9870 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9872 Spacing));
9874 Spacing * 2));
9876 Spacing * 3));
9877 TmpInst.addOperand(Inst.getOperand(1)); // lane
9878 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9879 TmpInst.addOperand(Inst.getOperand(5));
9880 Inst = TmpInst;
9881 return true;
9882 }
9883
9884 case ARM::VLD1LNdAsm_8:
9885 case ARM::VLD1LNdAsm_16:
9886 case ARM::VLD1LNdAsm_32: {
9887 MCInst TmpInst;
9888 // Shuffle the operands around so the lane index operand is in the
9889 // right place.
9890 unsigned Spacing;
9891 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9892 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9893 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9894 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9895 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9896 TmpInst.addOperand(Inst.getOperand(1)); // lane
9897 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9898 TmpInst.addOperand(Inst.getOperand(5));
9899 Inst = TmpInst;
9900 return true;
9901 }
9902
9903 case ARM::VLD2LNdAsm_8:
9904 case ARM::VLD2LNdAsm_16:
9905 case ARM::VLD2LNdAsm_32:
9906 case ARM::VLD2LNqAsm_16:
9907 case ARM::VLD2LNqAsm_32: {
9908 MCInst TmpInst;
9909 // Shuffle the operands around so the lane index operand is in the
9910 // right place.
9911 unsigned Spacing;
9912 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9913 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9915 Spacing));
9916 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9917 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9918 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9920 Spacing));
9921 TmpInst.addOperand(Inst.getOperand(1)); // lane
9922 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9923 TmpInst.addOperand(Inst.getOperand(5));
9924 Inst = TmpInst;
9925 return true;
9926 }
9927
9928 case ARM::VLD3LNdAsm_8:
9929 case ARM::VLD3LNdAsm_16:
9930 case ARM::VLD3LNdAsm_32:
9931 case ARM::VLD3LNqAsm_16:
9932 case ARM::VLD3LNqAsm_32: {
9933 MCInst TmpInst;
9934 // Shuffle the operands around so the lane index operand is in the
9935 // right place.
9936 unsigned Spacing;
9937 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9938 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9940 Spacing));
9942 Spacing * 2));
9943 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9944 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9945 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9947 Spacing));
9949 Spacing * 2));
9950 TmpInst.addOperand(Inst.getOperand(1)); // lane
9951 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9952 TmpInst.addOperand(Inst.getOperand(5));
9953 Inst = TmpInst;
9954 return true;
9955 }
9956
9957 case ARM::VLD4LNdAsm_8:
9958 case ARM::VLD4LNdAsm_16:
9959 case ARM::VLD4LNdAsm_32:
9960 case ARM::VLD4LNqAsm_16:
9961 case ARM::VLD4LNqAsm_32: {
9962 MCInst TmpInst;
9963 // Shuffle the operands around so the lane index operand is in the
9964 // right place.
9965 unsigned Spacing;
9966 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9967 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9969 Spacing));
9971 Spacing * 2));
9973 Spacing * 3));
9974 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9975 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9976 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9978 Spacing));
9980 Spacing * 2));
9982 Spacing * 3));
9983 TmpInst.addOperand(Inst.getOperand(1)); // lane
9984 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9985 TmpInst.addOperand(Inst.getOperand(5));
9986 Inst = TmpInst;
9987 return true;
9988 }
9989
9990 // VLD3DUP single 3-element structure to all lanes instructions.
9991 case ARM::VLD3DUPdAsm_8:
9992 case ARM::VLD3DUPdAsm_16:
9993 case ARM::VLD3DUPdAsm_32:
9994 case ARM::VLD3DUPqAsm_8:
9995 case ARM::VLD3DUPqAsm_16:
9996 case ARM::VLD3DUPqAsm_32: {
9997 MCInst TmpInst;
9998 unsigned Spacing;
9999 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10000 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10002 Spacing));
10004 Spacing * 2));
10005 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10006 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10007 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10008 TmpInst.addOperand(Inst.getOperand(4));
10009 Inst = TmpInst;
10010 return true;
10011 }
10012
10013 case ARM::VLD3DUPdWB_fixed_Asm_8:
10014 case ARM::VLD3DUPdWB_fixed_Asm_16:
10015 case ARM::VLD3DUPdWB_fixed_Asm_32:
10016 case ARM::VLD3DUPqWB_fixed_Asm_8:
10017 case ARM::VLD3DUPqWB_fixed_Asm_16:
10018 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10019 MCInst TmpInst;
10020 unsigned Spacing;
10021 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10022 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10024 Spacing));
10026 Spacing * 2));
10027 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10028 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10029 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10030 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10031 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10032 TmpInst.addOperand(Inst.getOperand(4));
10033 Inst = TmpInst;
10034 return true;
10035 }
10036
10037 case ARM::VLD3DUPdWB_register_Asm_8:
10038 case ARM::VLD3DUPdWB_register_Asm_16:
10039 case ARM::VLD3DUPdWB_register_Asm_32:
10040 case ARM::VLD3DUPqWB_register_Asm_8:
10041 case ARM::VLD3DUPqWB_register_Asm_16:
10042 case ARM::VLD3DUPqWB_register_Asm_32: {
10043 MCInst TmpInst;
10044 unsigned Spacing;
10045 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10046 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10048 Spacing));
10050 Spacing * 2));
10051 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10052 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10053 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10054 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10055 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10056 TmpInst.addOperand(Inst.getOperand(5));
10057 Inst = TmpInst;
10058 return true;
10059 }
10060
10061 // VLD3 multiple 3-element structure instructions.
10062 case ARM::VLD3dAsm_8:
10063 case ARM::VLD3dAsm_16:
10064 case ARM::VLD3dAsm_32:
10065 case ARM::VLD3qAsm_8:
10066 case ARM::VLD3qAsm_16:
10067 case ARM::VLD3qAsm_32: {
10068 MCInst TmpInst;
10069 unsigned Spacing;
10070 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10071 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10073 Spacing));
10075 Spacing * 2));
10076 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10077 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10078 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10079 TmpInst.addOperand(Inst.getOperand(4));
10080 Inst = TmpInst;
10081 return true;
10082 }
10083
10084 case ARM::VLD3dWB_fixed_Asm_8:
10085 case ARM::VLD3dWB_fixed_Asm_16:
10086 case ARM::VLD3dWB_fixed_Asm_32:
10087 case ARM::VLD3qWB_fixed_Asm_8:
10088 case ARM::VLD3qWB_fixed_Asm_16:
10089 case ARM::VLD3qWB_fixed_Asm_32: {
10090 MCInst TmpInst;
10091 unsigned Spacing;
10092 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10093 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10095 Spacing));
10097 Spacing * 2));
10098 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10099 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10100 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10101 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10102 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10103 TmpInst.addOperand(Inst.getOperand(4));
10104 Inst = TmpInst;
10105 return true;
10106 }
10107
10108 case ARM::VLD3dWB_register_Asm_8:
10109 case ARM::VLD3dWB_register_Asm_16:
10110 case ARM::VLD3dWB_register_Asm_32:
10111 case ARM::VLD3qWB_register_Asm_8:
10112 case ARM::VLD3qWB_register_Asm_16:
10113 case ARM::VLD3qWB_register_Asm_32: {
10114 MCInst TmpInst;
10115 unsigned Spacing;
10116 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10117 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10119 Spacing));
10121 Spacing * 2));
10122 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10123 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10124 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10125 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10126 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10127 TmpInst.addOperand(Inst.getOperand(5));
10128 Inst = TmpInst;
10129 return true;
10130 }
10131
10132 // VLD4DUP single 3-element structure to all lanes instructions.
10133 case ARM::VLD4DUPdAsm_8:
10134 case ARM::VLD4DUPdAsm_16:
10135 case ARM::VLD4DUPdAsm_32:
10136 case ARM::VLD4DUPqAsm_8:
10137 case ARM::VLD4DUPqAsm_16:
10138 case ARM::VLD4DUPqAsm_32: {
10139 MCInst TmpInst;
10140 unsigned Spacing;
10141 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10142 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10144 Spacing));
10146 Spacing * 2));
10148 Spacing * 3));
10149 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10150 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10151 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10152 TmpInst.addOperand(Inst.getOperand(4));
10153 Inst = TmpInst;
10154 return true;
10155 }
10156
10157 case ARM::VLD4DUPdWB_fixed_Asm_8:
10158 case ARM::VLD4DUPdWB_fixed_Asm_16:
10159 case ARM::VLD4DUPdWB_fixed_Asm_32:
10160 case ARM::VLD4DUPqWB_fixed_Asm_8:
10161 case ARM::VLD4DUPqWB_fixed_Asm_16:
10162 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10163 MCInst TmpInst;
10164 unsigned Spacing;
10165 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10166 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10168 Spacing));
10170 Spacing * 2));
10172 Spacing * 3));
10173 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10174 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10175 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10176 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10177 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10178 TmpInst.addOperand(Inst.getOperand(4));
10179 Inst = TmpInst;
10180 return true;
10181 }
10182
10183 case ARM::VLD4DUPdWB_register_Asm_8:
10184 case ARM::VLD4DUPdWB_register_Asm_16:
10185 case ARM::VLD4DUPdWB_register_Asm_32:
10186 case ARM::VLD4DUPqWB_register_Asm_8:
10187 case ARM::VLD4DUPqWB_register_Asm_16:
10188 case ARM::VLD4DUPqWB_register_Asm_32: {
10189 MCInst TmpInst;
10190 unsigned Spacing;
10191 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10192 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10194 Spacing));
10196 Spacing * 2));
10198 Spacing * 3));
10199 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10200 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10201 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10202 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10203 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10204 TmpInst.addOperand(Inst.getOperand(5));
10205 Inst = TmpInst;
10206 return true;
10207 }
10208
10209 // VLD4 multiple 4-element structure instructions.
10210 case ARM::VLD4dAsm_8:
10211 case ARM::VLD4dAsm_16:
10212 case ARM::VLD4dAsm_32:
10213 case ARM::VLD4qAsm_8:
10214 case ARM::VLD4qAsm_16:
10215 case ARM::VLD4qAsm_32: {
10216 MCInst TmpInst;
10217 unsigned Spacing;
10218 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10219 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10221 Spacing));
10223 Spacing * 2));
10225 Spacing * 3));
10226 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10227 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10228 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10229 TmpInst.addOperand(Inst.getOperand(4));
10230 Inst = TmpInst;
10231 return true;
10232 }
10233
10234 case ARM::VLD4dWB_fixed_Asm_8:
10235 case ARM::VLD4dWB_fixed_Asm_16:
10236 case ARM::VLD4dWB_fixed_Asm_32:
10237 case ARM::VLD4qWB_fixed_Asm_8:
10238 case ARM::VLD4qWB_fixed_Asm_16:
10239 case ARM::VLD4qWB_fixed_Asm_32: {
10240 MCInst TmpInst;
10241 unsigned Spacing;
10242 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10243 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10245 Spacing));
10247 Spacing * 2));
10249 Spacing * 3));
10250 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10251 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10252 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10253 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10254 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10255 TmpInst.addOperand(Inst.getOperand(4));
10256 Inst = TmpInst;
10257 return true;
10258 }
10259
10260 case ARM::VLD4dWB_register_Asm_8:
10261 case ARM::VLD4dWB_register_Asm_16:
10262 case ARM::VLD4dWB_register_Asm_32:
10263 case ARM::VLD4qWB_register_Asm_8:
10264 case ARM::VLD4qWB_register_Asm_16:
10265 case ARM::VLD4qWB_register_Asm_32: {
10266 MCInst TmpInst;
10267 unsigned Spacing;
10268 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10269 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10271 Spacing));
10273 Spacing * 2));
10275 Spacing * 3));
10276 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10277 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10278 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10279 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10280 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10281 TmpInst.addOperand(Inst.getOperand(5));
10282 Inst = TmpInst;
10283 return true;
10284 }
10285
10286 // VST3 multiple 3-element structure instructions.
10287 case ARM::VST3dAsm_8:
10288 case ARM::VST3dAsm_16:
10289 case ARM::VST3dAsm_32:
10290 case ARM::VST3qAsm_8:
10291 case ARM::VST3qAsm_16:
10292 case ARM::VST3qAsm_32: {
10293 MCInst TmpInst;
10294 unsigned Spacing;
10295 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10296 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10297 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10298 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10300 Spacing));
10302 Spacing * 2));
10303 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10304 TmpInst.addOperand(Inst.getOperand(4));
10305 Inst = TmpInst;
10306 return true;
10307 }
10308
10309 case ARM::VST3dWB_fixed_Asm_8:
10310 case ARM::VST3dWB_fixed_Asm_16:
10311 case ARM::VST3dWB_fixed_Asm_32:
10312 case ARM::VST3qWB_fixed_Asm_8:
10313 case ARM::VST3qWB_fixed_Asm_16:
10314 case ARM::VST3qWB_fixed_Asm_32: {
10315 MCInst TmpInst;
10316 unsigned Spacing;
10317 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10318 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10319 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10320 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10321 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10322 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10324 Spacing));
10326 Spacing * 2));
10327 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10328 TmpInst.addOperand(Inst.getOperand(4));
10329 Inst = TmpInst;
10330 return true;
10331 }
10332
10333 case ARM::VST3dWB_register_Asm_8:
10334 case ARM::VST3dWB_register_Asm_16:
10335 case ARM::VST3dWB_register_Asm_32:
10336 case ARM::VST3qWB_register_Asm_8:
10337 case ARM::VST3qWB_register_Asm_16:
10338 case ARM::VST3qWB_register_Asm_32: {
10339 MCInst TmpInst;
10340 unsigned Spacing;
10341 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10342 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10343 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10344 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10345 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10346 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10348 Spacing));
10350 Spacing * 2));
10351 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10352 TmpInst.addOperand(Inst.getOperand(5));
10353 Inst = TmpInst;
10354 return true;
10355 }
10356
10357 // VST4 multiple 3-element structure instructions.
10358 case ARM::VST4dAsm_8:
10359 case ARM::VST4dAsm_16:
10360 case ARM::VST4dAsm_32:
10361 case ARM::VST4qAsm_8:
10362 case ARM::VST4qAsm_16:
10363 case ARM::VST4qAsm_32: {
10364 MCInst TmpInst;
10365 unsigned Spacing;
10366 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10367 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10368 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10369 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10371 Spacing));
10373 Spacing * 2));
10375 Spacing * 3));
10376 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10377 TmpInst.addOperand(Inst.getOperand(4));
10378 Inst = TmpInst;
10379 return true;
10380 }
10381
10382 case ARM::VST4dWB_fixed_Asm_8:
10383 case ARM::VST4dWB_fixed_Asm_16:
10384 case ARM::VST4dWB_fixed_Asm_32:
10385 case ARM::VST4qWB_fixed_Asm_8:
10386 case ARM::VST4qWB_fixed_Asm_16:
10387 case ARM::VST4qWB_fixed_Asm_32: {
10388 MCInst TmpInst;
10389 unsigned Spacing;
10390 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10391 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10392 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10393 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10394 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10395 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10397 Spacing));
10399 Spacing * 2));
10401 Spacing * 3));
10402 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10403 TmpInst.addOperand(Inst.getOperand(4));
10404 Inst = TmpInst;
10405 return true;
10406 }
10407
10408 case ARM::VST4dWB_register_Asm_8:
10409 case ARM::VST4dWB_register_Asm_16:
10410 case ARM::VST4dWB_register_Asm_32:
10411 case ARM::VST4qWB_register_Asm_8:
10412 case ARM::VST4qWB_register_Asm_16:
10413 case ARM::VST4qWB_register_Asm_32: {
10414 MCInst TmpInst;
10415 unsigned Spacing;
10416 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10417 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10418 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10419 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10420 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10421 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10423 Spacing));
10425 Spacing * 2));
10427 Spacing * 3));
10428 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10429 TmpInst.addOperand(Inst.getOperand(5));
10430 Inst = TmpInst;
10431 return true;
10432 }
10433
10434 // Handle encoding choice for the shift-immediate instructions.
10435 case ARM::t2LSLri:
10436 case ARM::t2LSRri:
10437 case ARM::t2ASRri:
10438 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10439 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10440 Inst.getOperand(5).getReg() ==
10441 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10442 !HasWideQualifier) {
10443 unsigned NewOpc;
10444 switch (Inst.getOpcode()) {
10445 default: llvm_unreachable("unexpected opcode");
10446 case ARM::t2LSLri: NewOpc = ARM::tLSLri; break;
10447 case ARM::t2LSRri: NewOpc = ARM::tLSRri; break;
10448 case ARM::t2ASRri: NewOpc = ARM::tASRri; break;
10449 }
10450 // The Thumb1 operands aren't in the same order. Awesome, eh?
10451 MCInst TmpInst;
10452 TmpInst.setOpcode(NewOpc);
10453 TmpInst.addOperand(Inst.getOperand(0));
10454 TmpInst.addOperand(Inst.getOperand(5));
10455 TmpInst.addOperand(Inst.getOperand(1));
10456 TmpInst.addOperand(Inst.getOperand(2));
10457 TmpInst.addOperand(Inst.getOperand(3));
10458 TmpInst.addOperand(Inst.getOperand(4));
10459 Inst = TmpInst;
10460 return true;
10461 }
10462 return false;
10463
10464 // Handle the Thumb2 mode MOV complex aliases.
10465 case ARM::t2MOVsr:
10466 case ARM::t2MOVSsr: {
10467 // Which instruction to expand to depends on the CCOut operand and
10468 // whether we're in an IT block if the register operands are low
10469 // registers.
10470 bool isNarrow = false;
10471 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10472 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10473 isARMLowRegister(Inst.getOperand(2).getReg()) &&
10474 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
10475 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr) &&
10476 !HasWideQualifier)
10477 isNarrow = true;
10478 MCInst TmpInst;
10479 unsigned newOpc;
10480 switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
10481 default: llvm_unreachable("unexpected opcode!");
10482 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
10483 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
10484 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
10485 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break;
10486 }
10487 TmpInst.setOpcode(newOpc);
10488 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10489 if (isNarrow)
10491 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10492 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10493 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10494 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10495 TmpInst.addOperand(Inst.getOperand(5));
10496 if (!isNarrow)
10498 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10499 Inst = TmpInst;
10500 return true;
10501 }
10502 case ARM::t2MOVsi:
10503 case ARM::t2MOVSsi: {
10504 // Which instruction to expand to depends on the CCOut operand and
10505 // whether we're in an IT block if the register operands are low
10506 // registers.
10507 bool isNarrow = false;
10508 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10509 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10510 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi) &&
10511 !HasWideQualifier)
10512 isNarrow = true;
10513 MCInst TmpInst;
10514 unsigned newOpc;
10515 unsigned Shift = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
10516 unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
10517 bool isMov = false;
10518 // MOV rd, rm, LSL #0 is actually a MOV instruction
10519 if (Shift == ARM_AM::lsl && Amount == 0) {
10520 isMov = true;
10521 // The 16-bit encoding of MOV rd, rm, LSL #N is explicitly encoding T2 of
10522 // MOV (register) in the ARMv8-A and ARMv8-M manuals, and immediate 0 is
10523 // unpredictable in an IT block so the 32-bit encoding T3 has to be used
10524 // instead.
10525 if (inITBlock()) {
10526 isNarrow = false;
10527 }
10528 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10529 } else {
10530 switch(Shift) {
10531 default: llvm_unreachable("unexpected opcode!");
10532 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
10533 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
10534 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
10535 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
10536 case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
10537 }
10538 }
10539 if (Amount == 32) Amount = 0;
10540 TmpInst.setOpcode(newOpc);
10541 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10542 if (isNarrow && !isMov)
10544 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10545 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10546 if (newOpc != ARM::t2RRX && !isMov)
10547 TmpInst.addOperand(MCOperand::createImm(Amount));
10548 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10549 TmpInst.addOperand(Inst.getOperand(4));
10550 if (!isNarrow)
10552 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10553 Inst = TmpInst;
10554 return true;
10555 }
10556 // Handle the ARM mode MOV complex aliases.
10557 case ARM::ASRr:
10558 case ARM::LSRr:
10559 case ARM::LSLr:
10560 case ARM::RORr: {
10561 ARM_AM::ShiftOpc ShiftTy;
10562 switch(Inst.getOpcode()) {
10563 default: llvm_unreachable("unexpected opcode!");
10564 case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
10565 case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
10566 case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
10567 case ARM::RORr: ShiftTy = ARM_AM::ror; break;
10568 }
10569 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
10570 MCInst TmpInst;
10571 TmpInst.setOpcode(ARM::MOVsr);
10572 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10573 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10574 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10575 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10576 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10577 TmpInst.addOperand(Inst.getOperand(4));
10578 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10579 Inst = TmpInst;
10580 return true;
10581 }
10582 case ARM::ASRi:
10583 case ARM::LSRi:
10584 case ARM::LSLi:
10585 case ARM::RORi: {
10586 ARM_AM::ShiftOpc ShiftTy;
10587 switch(Inst.getOpcode()) {
10588 default: llvm_unreachable("unexpected opcode!");
10589 case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
10590 case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
10591 case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
10592 case ARM::RORi: ShiftTy = ARM_AM::ror; break;
10593 }
10594 // A shift by zero is a plain MOVr, not a MOVsi.
10595 unsigned Amt = Inst.getOperand(2).getImm();
10596 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10597 // A shift by 32 should be encoded as 0 when permitted
10598 if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
10599 Amt = 0;
10600 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
10601 MCInst TmpInst;
10602 TmpInst.setOpcode(Opc);
10603 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10604 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10605 if (Opc == ARM::MOVsi)
10606 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10607 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10608 TmpInst.addOperand(Inst.getOperand(4));
10609 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10610 Inst = TmpInst;
10611 return true;
10612 }
10613 case ARM::RRXi: {
10614 unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
10615 MCInst TmpInst;
10616 TmpInst.setOpcode(ARM::MOVsi);
10617 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10618 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10619 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10620 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10621 TmpInst.addOperand(Inst.getOperand(3));
10622 TmpInst.addOperand(Inst.getOperand(4)); // cc_out
10623 Inst = TmpInst;
10624 return true;
10625 }
10626 case ARM::t2LDMIA_UPD: {
10627 // If this is a load of a single register, then we should use
10628 // a post-indexed LDR instruction instead, per the ARM ARM.
10629 if (Inst.getNumOperands() != 5)
10630 return false;
10631 MCInst TmpInst;
10632 TmpInst.setOpcode(ARM::t2LDR_POST);
10633 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10634 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10635 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10636 TmpInst.addOperand(MCOperand::createImm(4));
10637 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10638 TmpInst.addOperand(Inst.getOperand(3));
10639 Inst = TmpInst;
10640 return true;
10641 }
10642 case ARM::t2STMDB_UPD: {
10643 // If this is a store of a single register, then we should use
10644 // a pre-indexed STR instruction instead, per the ARM ARM.
10645 if (Inst.getNumOperands() != 5)
10646 return false;
10647 MCInst TmpInst;
10648 TmpInst.setOpcode(ARM::t2STR_PRE);
10649 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10650 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10651 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10652 TmpInst.addOperand(MCOperand::createImm(-4));
10653 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10654 TmpInst.addOperand(Inst.getOperand(3));
10655 Inst = TmpInst;
10656 return true;
10657 }
10658 case ARM::LDMIA_UPD:
10659 // If this is a load of a single register via a 'pop', then we should use
10660 // a post-indexed LDR instruction instead, per the ARM ARM.
10661 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "pop" &&
10662 Inst.getNumOperands() == 5) {
10663 MCInst TmpInst;
10664 TmpInst.setOpcode(ARM::LDR_POST_IMM);
10665 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10666 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10667 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10668 TmpInst.addOperand(MCOperand::createReg(0)); // am2offset
10669 TmpInst.addOperand(MCOperand::createImm(4));
10670 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10671 TmpInst.addOperand(Inst.getOperand(3));
10672 Inst = TmpInst;
10673 return true;
10674 }
10675 break;
10676 case ARM::STMDB_UPD:
10677 // If this is a store of a single register via a 'push', then we should use
10678 // a pre-indexed STR instruction instead, per the ARM ARM.
10679 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "push" &&
10680 Inst.getNumOperands() == 5) {
10681 MCInst TmpInst;
10682 TmpInst.setOpcode(ARM::STR_PRE_IMM);
10683 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10684 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10685 TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
10686 TmpInst.addOperand(MCOperand::createImm(-4));
10687 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10688 TmpInst.addOperand(Inst.getOperand(3));
10689 Inst = TmpInst;
10690 }
10691 break;
10692 case ARM::t2ADDri12:
10693 case ARM::t2SUBri12:
10694 case ARM::t2ADDspImm12:
10695 case ARM::t2SUBspImm12: {
10696 // If the immediate fits for encoding T3 and the generic
10697 // mnemonic was used, encoding T3 is preferred.
10698 const StringRef Token = static_cast<ARMOperand &>(*Operands[0]).getToken();
10699 if ((Token != "add" && Token != "sub") ||
10700 ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
10701 break;
10702 switch (Inst.getOpcode()) {
10703 case ARM::t2ADDri12:
10704 Inst.setOpcode(ARM::t2ADDri);
10705 break;
10706 case ARM::t2SUBri12:
10707 Inst.setOpcode(ARM::t2SUBri);
10708 break;
10709 case ARM::t2ADDspImm12:
10710 Inst.setOpcode(ARM::t2ADDspImm);
10711 break;
10712 case ARM::t2SUBspImm12:
10713 Inst.setOpcode(ARM::t2SUBspImm);
10714 break;
10715 }
10716
10717 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10718 return true;
10719 }
10720 case ARM::tADDi8:
10721 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10722 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10723 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10724 // to encoding T1 if <Rd> is omitted."
10725 if (Inst.getOperand(3).isImm() &&
10726 (unsigned)Inst.getOperand(3).getImm() < 8 &&
10727 Operands.size() == MnemonicOpsEndInd + 3) {
10728 Inst.setOpcode(ARM::tADDi3);
10729 return true;
10730 }
10731 break;
10732 case ARM::tSUBi8:
10733 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10734 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10735 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10736 // to encoding T1 if <Rd> is omitted."
10737 if ((unsigned)Inst.getOperand(3).getImm() < 8 &&
10738 Operands.size() == MnemonicOpsEndInd + 3) {
10739 Inst.setOpcode(ARM::tSUBi3);
10740 return true;
10741 }
10742 break;
10743 case ARM::t2ADDri:
10744 case ARM::t2SUBri: {
10745 // If the destination and first source operand are the same, and
10746 // the flags are compatible with the current IT status, use encoding T2
10747 // instead of T3. For compatibility with the system 'as'. Make sure the
10748 // wide encoding wasn't explicit.
10749 if (HasWideQualifier)
10750 break; // source code has asked for the 32-bit instruction
10751 if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg())
10752 break; // tADDi8 can't take different input and output registers
10753 if (!isARMLowRegister(Inst.getOperand(0).getReg()))
10754 break; // high register that tADDi8 can't access
10755 if (Inst.getOperand(5).getReg() !=
10756 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10757 break; // flag-modification would require overriding the IT state
10758 if (Inst.getOperand(2).isImm()) {
10759 if ((unsigned)Inst.getOperand(2).getImm() > 255)
10760 break; // large immediate that tADDi8 can't contain
10761 } else {
10762 int i = (Operands[MnemonicOpsEndInd + 1]->isImm())
10763 ? MnemonicOpsEndInd + 1
10764 : MnemonicOpsEndInd + 2;
10765 MCParsedAsmOperand &Op = *Operands[i];
10767 break; // a type of non-immediate that tADDi8 can't represent
10768 }
10769 MCInst TmpInst;
10770 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
10771 ARM::tADDi8 : ARM::tSUBi8);
10772 TmpInst.addOperand(Inst.getOperand(0));
10773 TmpInst.addOperand(Inst.getOperand(5));
10774 TmpInst.addOperand(Inst.getOperand(0));
10775 TmpInst.addOperand(Inst.getOperand(2));
10776 TmpInst.addOperand(Inst.getOperand(3));
10777 TmpInst.addOperand(Inst.getOperand(4));
10778 Inst = TmpInst;
10779 return true;
10780 }
10781 case ARM::t2ADDspImm:
10782 case ARM::t2SUBspImm: {
10783 // Prefer T1 encoding if possible
10784 if (Inst.getOperand(5).getReg() || HasWideQualifier)
10785 break;
10786 unsigned V = Inst.getOperand(2).getImm();
10787 if (V & 3 || V > ((1 << 7) - 1) << 2)
10788 break;
10789 MCInst TmpInst;
10790 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDspImm ? ARM::tADDspi
10791 : ARM::tSUBspi);
10792 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // destination reg
10793 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // source reg
10794 TmpInst.addOperand(MCOperand::createImm(V / 4)); // immediate
10795 TmpInst.addOperand(Inst.getOperand(3)); // pred
10796 TmpInst.addOperand(Inst.getOperand(4));
10797 Inst = TmpInst;
10798 return true;
10799 }
10800 case ARM::t2ADDrr: {
10801 // If the destination and first source operand are the same, and
10802 // there's no setting of the flags, use encoding T2 instead of T3.
10803 // Note that this is only for ADD, not SUB. This mirrors the system
10804 // 'as' behaviour. Also take advantage of ADD being commutative.
10805 // Make sure the wide encoding wasn't explicit.
10806 bool Swap = false;
10807 auto DestReg = Inst.getOperand(0).getReg();
10808 bool Transform = DestReg == Inst.getOperand(1).getReg();
10809 if (!Transform && DestReg == Inst.getOperand(2).getReg()) {
10810 Transform = true;
10811 Swap = true;
10812 }
10813 if (!Transform || Inst.getOperand(5).getReg() || HasWideQualifier)
10814 break;
10815 MCInst TmpInst;
10816 TmpInst.setOpcode(ARM::tADDhirr);
10817 TmpInst.addOperand(Inst.getOperand(0));
10818 TmpInst.addOperand(Inst.getOperand(0));
10819 TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2));
10820 TmpInst.addOperand(Inst.getOperand(3));
10821 TmpInst.addOperand(Inst.getOperand(4));
10822 Inst = TmpInst;
10823 return true;
10824 }
10825 case ARM::tADDrSP:
10826 // If the non-SP source operand and the destination operand are not the
10827 // same, we need to use the 32-bit encoding if it's available.
10828 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
10829 Inst.setOpcode(ARM::t2ADDrr);
10830 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10831 return true;
10832 }
10833 break;
10834 case ARM::tB:
10835 // A Thumb conditional branch outside of an IT block is a tBcc.
10836 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
10837 Inst.setOpcode(ARM::tBcc);
10838 return true;
10839 }
10840 break;
10841 case ARM::t2B:
10842 // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
10843 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
10844 Inst.setOpcode(ARM::t2Bcc);
10845 return true;
10846 }
10847 break;
10848 case ARM::t2Bcc:
10849 // If the conditional is AL or we're in an IT block, we really want t2B.
10850 if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
10851 Inst.setOpcode(ARM::t2B);
10852 return true;
10853 }
10854 break;
10855 case ARM::tBcc:
10856 // If the conditional is AL, we really want tB.
10857 if (Inst.getOperand(1).getImm() == ARMCC::AL) {
10858 Inst.setOpcode(ARM::tB);
10859 return true;
10860 }
10861 break;
10862 case ARM::tLDMIA: {
10863 // If the register list contains any high registers, or if the writeback
10864 // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
10865 // instead if we're in Thumb2. Otherwise, this should have generated
10866 // an error in validateInstruction().
10867 MCRegister Rn = Inst.getOperand(0).getReg();
10868 bool hasWritebackToken =
10869 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10870 .isToken() &&
10871 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10872 .getToken() == "!");
10873 bool listContainsBase;
10874 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), listContainsBase) ||
10875 (!listContainsBase && !hasWritebackToken) ||
10876 (listContainsBase && hasWritebackToken)) {
10877 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10878 assert(isThumbTwo());
10879 Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10880 // If we're switching to the updating version, we need to insert
10881 // the writeback tied operand.
10882 if (hasWritebackToken)
10883 Inst.insert(Inst.begin(),
10885 return true;
10886 }
10887 break;
10888 }
10889 case ARM::tSTMIA_UPD: {
10890 // If the register list contains any high registers, we need to use
10891 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10892 // should have generated an error in validateInstruction().
10893 MCRegister Rn = Inst.getOperand(0).getReg();
10894 bool listContainsBase;
10895 if (checkLowRegisterList(Inst, 4, Rn, MCRegister(), listContainsBase)) {
10896 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10897 assert(isThumbTwo());
10898 Inst.setOpcode(ARM::t2STMIA_UPD);
10899 return true;
10900 }
10901 break;
10902 }
10903 case ARM::tPOP: {
10904 bool listContainsBase;
10905 // If the register list contains any high registers, we need to use
10906 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10907 // should have generated an error in validateInstruction().
10908 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC, listContainsBase))
10909 return false;
10910 assert(isThumbTwo());
10911 Inst.setOpcode(ARM::t2LDMIA_UPD);
10912 // Add the base register and writeback operands.
10913 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10914 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10915 return true;
10916 }
10917 case ARM::tPUSH: {
10918 bool listContainsBase;
10919 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR, listContainsBase))
10920 return false;
10921 assert(isThumbTwo());
10922 Inst.setOpcode(ARM::t2STMDB_UPD);
10923 // Add the base register and writeback operands.
10924 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10925 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10926 return true;
10927 }
10928 case ARM::t2MOVi:
10929 // If we can use the 16-bit encoding and the user didn't explicitly
10930 // request the 32-bit variant, transform it here.
10931 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10932 (Inst.getOperand(1).isImm() &&
10933 (unsigned)Inst.getOperand(1).getImm() <= 255) &&
10934 Inst.getOperand(4).getReg() ==
10935 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10936 !HasWideQualifier) {
10937 // The operands aren't in the same order for tMOVi8...
10938 MCInst TmpInst;
10939 TmpInst.setOpcode(ARM::tMOVi8);
10940 TmpInst.addOperand(Inst.getOperand(0));
10941 TmpInst.addOperand(Inst.getOperand(4));
10942 TmpInst.addOperand(Inst.getOperand(1));
10943 TmpInst.addOperand(Inst.getOperand(2));
10944 TmpInst.addOperand(Inst.getOperand(3));
10945 Inst = TmpInst;
10946 return true;
10947 }
10948 break;
10949
10950 case ARM::t2MOVr:
10951 // If we can use the 16-bit encoding and the user didn't explicitly
10952 // request the 32-bit variant, transform it here.
10953 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10954 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10955 Inst.getOperand(2).getImm() == ARMCC::AL &&
10956 Inst.getOperand(4).getReg() == ARM::CPSR &&
10957 !HasWideQualifier) {
10958 // The operands aren't the same for tMOV[S]r... (no cc_out)
10959 MCInst TmpInst;
10960 unsigned Op = Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr;
10961 TmpInst.setOpcode(Op);
10962 TmpInst.addOperand(Inst.getOperand(0));
10963 TmpInst.addOperand(Inst.getOperand(1));
10964 if (Op == ARM::tMOVr) {
10965 TmpInst.addOperand(Inst.getOperand(2));
10966 TmpInst.addOperand(Inst.getOperand(3));
10967 }
10968 Inst = TmpInst;
10969 return true;
10970 }
10971 break;
10972
10973 case ARM::t2SXTH:
10974 case ARM::t2SXTB:
10975 case ARM::t2UXTH:
10976 case ARM::t2UXTB:
10977 // If we can use the 16-bit encoding and the user didn't explicitly
10978 // request the 32-bit variant, transform it here.
10979 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10980 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10981 Inst.getOperand(2).getImm() == 0 &&
10982 !HasWideQualifier) {
10983 unsigned NewOpc;
10984 switch (Inst.getOpcode()) {
10985 default: llvm_unreachable("Illegal opcode!");
10986 case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
10987 case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
10988 case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
10989 case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
10990 }
10991 // The operands aren't the same for thumb1 (no rotate operand).
10992 MCInst TmpInst;
10993 TmpInst.setOpcode(NewOpc);
10994 TmpInst.addOperand(Inst.getOperand(0));
10995 TmpInst.addOperand(Inst.getOperand(1));
10996 TmpInst.addOperand(Inst.getOperand(3));
10997 TmpInst.addOperand(Inst.getOperand(4));
10998 Inst = TmpInst;
10999 return true;
11000 }
11001 break;
11002
11003 case ARM::MOVsi: {
11005 // rrx shifts and asr/lsr of #32 is encoded as 0
11006 if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
11007 return false;
11008 if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
11009 // Shifting by zero is accepted as a vanilla 'MOVr'
11010 MCInst TmpInst;
11011 TmpInst.setOpcode(ARM::MOVr);
11012 TmpInst.addOperand(Inst.getOperand(0));
11013 TmpInst.addOperand(Inst.getOperand(1));
11014 TmpInst.addOperand(Inst.getOperand(3));
11015 TmpInst.addOperand(Inst.getOperand(4));
11016 TmpInst.addOperand(Inst.getOperand(5));
11017 Inst = TmpInst;
11018 return true;
11019 }
11020 return false;
11021 }
11022 case ARM::ANDrsi:
11023 case ARM::ORRrsi:
11024 case ARM::EORrsi:
11025 case ARM::BICrsi:
11026 case ARM::SUBrsi:
11027 case ARM::ADDrsi: {
11028 unsigned newOpc;
11030 if (SOpc == ARM_AM::rrx) return false;
11031 switch (Inst.getOpcode()) {
11032 default: llvm_unreachable("unexpected opcode!");
11033 case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
11034 case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
11035 case ARM::EORrsi: newOpc = ARM::EORrr; break;
11036 case ARM::BICrsi: newOpc = ARM::BICrr; break;
11037 case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
11038 case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
11039 }
11040 // If the shift is by zero, use the non-shifted instruction definition.
11041 // The exception is for right shifts, where 0 == 32
11042 if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 &&
11043 !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) {
11044 MCInst TmpInst;
11045 TmpInst.setOpcode(newOpc);
11046 TmpInst.addOperand(Inst.getOperand(0));
11047 TmpInst.addOperand(Inst.getOperand(1));
11048 TmpInst.addOperand(Inst.getOperand(2));
11049 TmpInst.addOperand(Inst.getOperand(4));
11050 TmpInst.addOperand(Inst.getOperand(5));
11051 TmpInst.addOperand(Inst.getOperand(6));
11052 Inst = TmpInst;
11053 return true;
11054 }
11055 return false;
11056 }
11057 case ARM::ITasm:
11058 case ARM::t2IT: {
11059 // Set up the IT block state according to the IT instruction we just
11060 // matched.
11061 assert(!inITBlock() && "nested IT blocks?!");
11062 startExplicitITBlock(ARMCC::CondCodes(Inst.getOperand(0).getImm()),
11063 Inst.getOperand(1).getImm());
11064 break;
11065 }
11066 case ARM::t2LSLrr:
11067 case ARM::t2LSRrr:
11068 case ARM::t2ASRrr:
11069 case ARM::t2SBCrr:
11070 case ARM::t2RORrr:
11071 case ARM::t2BICrr:
11072 // Assemblers should use the narrow encodings of these instructions when permissible.
11073 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11074 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11075 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
11076 Inst.getOperand(5).getReg() ==
11077 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11078 !HasWideQualifier) {
11079 unsigned NewOpc;
11080 switch (Inst.getOpcode()) {
11081 default: llvm_unreachable("unexpected opcode");
11082 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break;
11083 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break;
11084 case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break;
11085 case ARM::t2SBCrr: NewOpc = ARM::tSBC; break;
11086 case ARM::t2RORrr: NewOpc = ARM::tROR; break;
11087 case ARM::t2BICrr: NewOpc = ARM::tBIC; break;
11088 }
11089 MCInst TmpInst;
11090 TmpInst.setOpcode(NewOpc);
11091 TmpInst.addOperand(Inst.getOperand(0));
11092 TmpInst.addOperand(Inst.getOperand(5));
11093 TmpInst.addOperand(Inst.getOperand(1));
11094 TmpInst.addOperand(Inst.getOperand(2));
11095 TmpInst.addOperand(Inst.getOperand(3));
11096 TmpInst.addOperand(Inst.getOperand(4));
11097 Inst = TmpInst;
11098 return true;
11099 }
11100 return false;
11101
11102 case ARM::t2ANDrr:
11103 case ARM::t2EORrr:
11104 case ARM::t2ADCrr:
11105 case ARM::t2ORRrr:
11106 // Assemblers should use the narrow encodings of these instructions when permissible.
11107 // These instructions are special in that they are commutable, so shorter encodings
11108 // are available more often.
11109 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11110 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11111 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() ||
11112 Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) &&
11113 Inst.getOperand(5).getReg() ==
11114 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11115 !HasWideQualifier) {
11116 unsigned NewOpc;
11117 switch (Inst.getOpcode()) {
11118 default: llvm_unreachable("unexpected opcode");
11119 case ARM::t2ADCrr: NewOpc = ARM::tADC; break;
11120 case ARM::t2ANDrr: NewOpc = ARM::tAND; break;
11121 case ARM::t2EORrr: NewOpc = ARM::tEOR; break;
11122 case ARM::t2ORRrr: NewOpc = ARM::tORR; break;
11123 }
11124 MCInst TmpInst;
11125 TmpInst.setOpcode(NewOpc);
11126 TmpInst.addOperand(Inst.getOperand(0));
11127 TmpInst.addOperand(Inst.getOperand(5));
11128 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) {
11129 TmpInst.addOperand(Inst.getOperand(1));
11130 TmpInst.addOperand(Inst.getOperand(2));
11131 } else {
11132 TmpInst.addOperand(Inst.getOperand(2));
11133 TmpInst.addOperand(Inst.getOperand(1));
11134 }
11135 TmpInst.addOperand(Inst.getOperand(3));
11136 TmpInst.addOperand(Inst.getOperand(4));
11137 Inst = TmpInst;
11138 return true;
11139 }
11140 return false;
11141 case ARM::MVE_VPST:
11142 case ARM::MVE_VPTv16i8:
11143 case ARM::MVE_VPTv8i16:
11144 case ARM::MVE_VPTv4i32:
11145 case ARM::MVE_VPTv16u8:
11146 case ARM::MVE_VPTv8u16:
11147 case ARM::MVE_VPTv4u32:
11148 case ARM::MVE_VPTv16s8:
11149 case ARM::MVE_VPTv8s16:
11150 case ARM::MVE_VPTv4s32:
11151 case ARM::MVE_VPTv4f32:
11152 case ARM::MVE_VPTv8f16:
11153 case ARM::MVE_VPTv16i8r:
11154 case ARM::MVE_VPTv8i16r:
11155 case ARM::MVE_VPTv4i32r:
11156 case ARM::MVE_VPTv16u8r:
11157 case ARM::MVE_VPTv8u16r:
11158 case ARM::MVE_VPTv4u32r:
11159 case ARM::MVE_VPTv16s8r:
11160 case ARM::MVE_VPTv8s16r:
11161 case ARM::MVE_VPTv4s32r:
11162 case ARM::MVE_VPTv4f32r:
11163 case ARM::MVE_VPTv8f16r: {
11164 assert(!inVPTBlock() && "Nested VPT blocks are not allowed");
11165 MCOperand &MO = Inst.getOperand(0);
11166 VPTState.Mask = MO.getImm();
11167 VPTState.CurPosition = 0;
11168 break;
11169 }
11170 }
11171 return false;
11172}
11173
11174unsigned
11175ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11176 const OperandVector &Operands) {
11177 unsigned Opc = Inst.getOpcode();
11178 switch (Opc) {
11179 // Prevent the mov r8 r8 encoding for nop being selected when the v6/thumb 2
11180 // encoding is available.
11181 case ARM::tMOVr: {
11182 if (Operands[0]->isToken() &&
11183 static_cast<ARMOperand &>(*Operands[0]).getToken() == "nop" &&
11184 ((isThumb() && !isThumbOne()) || hasV6MOps())) {
11185 return Match_MnemonicFail;
11186 }
11187 }
11188 [[fallthrough]];
11189 default:
11190 return Match_Success;
11191 }
11192}
11193
11194unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11195 // 16-bit thumb arithmetic instructions either require or preclude the 'S'
11196 // suffix depending on whether they're in an IT block or not.
11197 unsigned Opc = Inst.getOpcode();
11198 const MCInstrDesc &MCID = MII.get(Opc);
11200 assert(MCID.hasOptionalDef() &&
11201 "optionally flag setting instruction missing optional def operand");
11202 assert(MCID.NumOperands == Inst.getNumOperands() &&
11203 "operand count mismatch!");
11204 bool IsCPSR = false;
11205 // Check if the instruction has CPSR set.
11206 for (unsigned OpNo = 0; OpNo < MCID.NumOperands; ++OpNo) {
11207 if (MCID.operands()[OpNo].isOptionalDef() &&
11208 Inst.getOperand(OpNo).isReg() &&
11209 Inst.getOperand(OpNo).getReg() == ARM::CPSR)
11210 IsCPSR = true;
11211 }
11212
11213 // If we're parsing Thumb1, reject it completely.
11214 if (isThumbOne() && !IsCPSR)
11215 return Match_RequiresFlagSetting;
11216 // If we're parsing Thumb2, which form is legal depends on whether we're
11217 // in an IT block.
11218 if (isThumbTwo() && !IsCPSR && !inITBlock())
11219 return Match_RequiresITBlock;
11220 if (isThumbTwo() && IsCPSR && inITBlock())
11221 return Match_RequiresNotITBlock;
11222 // LSL with zero immediate is not allowed in an IT block
11223 if (Opc == ARM::tLSLri && Inst.getOperand(3).getImm() == 0 && inITBlock())
11224 return Match_RequiresNotITBlock;
11225 } else if (isThumbOne()) {
11226 // Some high-register supporting Thumb1 encodings only allow both registers
11227 // to be from r0-r7 when in Thumb2.
11228 if (Opc == ARM::tADDhirr && !hasV6MOps() &&
11229 isARMLowRegister(Inst.getOperand(1).getReg()) &&
11231 return Match_RequiresThumb2;
11232 // Others only require ARMv6 or later.
11233 else if (Opc == ARM::tMOVr && !hasV6Ops() &&
11234 isARMLowRegister(Inst.getOperand(0).getReg()) &&
11236 return Match_RequiresV6;
11237 }
11238
11239 // Before ARMv8 the rules for when SP is allowed in t2MOVr are more complex
11240 // than the loop below can handle, so it uses the GPRnopc register class and
11241 // we do SP handling here.
11242 if (Opc == ARM::t2MOVr && !hasV8Ops())
11243 {
11244 // SP as both source and destination is not allowed
11245 if (Inst.getOperand(0).getReg() == ARM::SP &&
11246 Inst.getOperand(1).getReg() == ARM::SP)
11247 return Match_RequiresV8;
11248 // When flags-setting SP as either source or destination is not allowed
11249 if (Inst.getOperand(4).getReg() == ARM::CPSR &&
11250 (Inst.getOperand(0).getReg() == ARM::SP ||
11251 Inst.getOperand(1).getReg() == ARM::SP))
11252 return Match_RequiresV8;
11253 }
11254
11255 switch (Inst.getOpcode()) {
11256 case ARM::VMRS:
11257 case ARM::VMSR:
11258 case ARM::VMRS_FPCXTS:
11259 case ARM::VMRS_FPCXTNS:
11260 case ARM::VMSR_FPCXTS:
11261 case ARM::VMSR_FPCXTNS:
11262 case ARM::VMRS_FPSCR_NZCVQC:
11263 case ARM::VMSR_FPSCR_NZCVQC:
11264 case ARM::FMSTAT:
11265 case ARM::VMRS_VPR:
11266 case ARM::VMRS_P0:
11267 case ARM::VMSR_VPR:
11268 case ARM::VMSR_P0:
11269 // Use of SP for VMRS/VMSR is only allowed in ARM mode with the exception of
11270 // ARMv8-A.
11271 if (Inst.getOperand(0).isReg() && Inst.getOperand(0).getReg() == ARM::SP &&
11272 (isThumb() && !hasV8Ops()))
11273 return Match_InvalidOperand;
11274 break;
11275 case ARM::t2TBB:
11276 case ARM::t2TBH:
11277 // Rn = sp is only allowed with ARMv8-A
11278 if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP))
11279 return Match_RequiresV8;
11280 break;
11281 case ARM::tMUL:
11282 // The second source operand must be the same register as the destination
11283 // operand.
11284 // FIXME: Ideally this would be handled by ARMGenAsmMatcher and
11285 // emitAsmTiedOperandConstraints.
11286 if (Inst.getOperand(0).getReg() != Inst.getOperand(3).getReg())
11287 return Match_InvalidTiedOperand;
11288 break;
11289 default:
11290 break;
11291 }
11292
11293 for (unsigned I = 0; I < MCID.NumOperands; ++I)
11294 if (MCID.operands()[I].RegClass == ARM::rGPRRegClassID) {
11295 // rGPRRegClass excludes PC, and also excluded SP before ARMv8
11296 const auto &Op = Inst.getOperand(I);
11297 if (!Op.isReg()) {
11298 // This can happen in awkward cases with tied operands, e.g. a
11299 // writeback load/store with a complex addressing mode in
11300 // which there's an output operand corresponding to the
11301 // updated written-back base register: the Tablegen-generated
11302 // AsmMatcher will have written a placeholder operand to that
11303 // slot in the form of an immediate 0, because it can't
11304 // generate the register part of the complex addressing-mode
11305 // operand ahead of time.
11306 continue;
11307 }
11308
11309 MCRegister Reg = Op.getReg();
11310 if ((Reg == ARM::SP) && !hasV8Ops())
11311 return Match_RequiresV8;
11312 else if (Reg == ARM::PC)
11313 return Match_InvalidOperand;
11314 }
11315
11316 return Match_Success;
11317}
11318
11319namespace llvm {
11320
11321template <> inline bool IsCPSRDead<MCInst>(const MCInst *Instr) {
11322 return true; // In an assembly source, no need to second-guess
11323}
11324
11325} // end namespace llvm
11326
11327// Returns true if Inst is unpredictable if it is in and IT block, but is not
11328// the last instruction in the block.
11329bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const {
11330 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11331
11332 // All branch & call instructions terminate IT blocks with the exception of
11333 // SVC.
11334 if (MCID.isTerminator() || (MCID.isCall() && Inst.getOpcode() != ARM::tSVC) ||
11335 MCID.isReturn() || MCID.isBranch() || MCID.isIndirectBranch())
11336 return true;
11337
11338 // Any arithmetic instruction which writes to the PC also terminates the IT
11339 // block.
11340 if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI))
11341 return true;
11342
11343 return false;
11344}
11345
11346unsigned ARMAsmParser::MatchInstruction(OperandVector &Operands, MCInst &Inst,
11347 SmallVectorImpl<NearMissInfo> &NearMisses,
11348 bool MatchingInlineAsm,
11349 bool &EmitInITBlock,
11350 MCStreamer &Out) {
11351 // If we can't use an implicit IT block here, just match as normal.
11352 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11353 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11354
11355 // Try to match the instruction in an extension of the current IT block (if
11356 // there is one).
11357 if (inImplicitITBlock()) {
11358 extendImplicitITBlock(ITState.Cond);
11359 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11360 Match_Success) {
11361 // The match succeeded, but we still have to check that the instruction is
11362 // valid in this implicit IT block.
11363 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11364 if (MCID.isPredicable()) {
11365 ARMCC::CondCodes InstCond =
11367 .getImm();
11368 ARMCC::CondCodes ITCond = currentITCond();
11369 if (InstCond == ITCond) {
11370 EmitInITBlock = true;
11371 return Match_Success;
11372 } else if (InstCond == ARMCC::getOppositeCondition(ITCond)) {
11373 invertCurrentITCondition();
11374 EmitInITBlock = true;
11375 return Match_Success;
11376 }
11377 }
11378 }
11379 rewindImplicitITPosition();
11380 }
11381
11382 // Finish the current IT block, and try to match outside any IT block.
11383 flushPendingInstructions(Out);
11384 unsigned PlainMatchResult =
11385 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11386 if (PlainMatchResult == Match_Success) {
11387 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11388 if (MCID.isPredicable()) {
11389 ARMCC::CondCodes InstCond =
11391 .getImm();
11392 // Some forms of the branch instruction have their own condition code
11393 // fields, so can be conditionally executed without an IT block.
11394 if (Inst.getOpcode() == ARM::tBcc || Inst.getOpcode() == ARM::t2Bcc) {
11395 EmitInITBlock = false;
11396 return Match_Success;
11397 }
11398 if (InstCond == ARMCC::AL) {
11399 EmitInITBlock = false;
11400 return Match_Success;
11401 }
11402 } else {
11403 EmitInITBlock = false;
11404 return Match_Success;
11405 }
11406 }
11407
11408 // Try to match in a new IT block. The matcher doesn't check the actual
11409 // condition, so we create an IT block with a dummy condition, and fix it up
11410 // once we know the actual condition.
11411 startImplicitITBlock();
11412 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11413 Match_Success) {
11414 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11415 if (MCID.isPredicable()) {
11416 ITState.Cond =
11418 .getImm();
11419 EmitInITBlock = true;
11420 return Match_Success;
11421 }
11422 }
11423 discardImplicitITBlock();
11424
11425 // If none of these succeed, return the error we got when trying to match
11426 // outside any IT blocks.
11427 EmitInITBlock = false;
11428 return PlainMatchResult;
11429}
11430
11431static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
11432 unsigned VariantID = 0);
11433
11434static const char *getSubtargetFeatureName(uint64_t Val);
11435bool ARMAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
11438 bool MatchingInlineAsm) {
11439 MCInst Inst;
11440 unsigned MatchResult;
11441 bool PendConditionalInstruction = false;
11442
11444 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
11445 PendConditionalInstruction, Out);
11446
11447 // Find the number of operators that are part of the Mnumonic (LHS).
11448 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
11449
11450 switch (MatchResult) {
11451 case Match_Success:
11452 LLVM_DEBUG(dbgs() << "Parsed as: ";
11453 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11454 dbgs() << "\n");
11455
11456 // Context sensitive operand constraints aren't handled by the matcher,
11457 // so check them here.
11458 if (validateInstruction(Inst, Operands, MnemonicOpsEndInd)) {
11459 // Still progress the IT block, otherwise one wrong condition causes
11460 // nasty cascading errors.
11461 forwardITPosition();
11462 forwardVPTPosition();
11463 return true;
11464 }
11465
11466 {
11467 // Some instructions need post-processing to, for example, tweak which
11468 // encoding is selected. Loop on it while changes happen so the
11469 // individual transformations can chain off each other. E.g.,
11470 // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
11471 while (processInstruction(Inst, Operands, MnemonicOpsEndInd, Out))
11472 LLVM_DEBUG(dbgs() << "Changed to: ";
11473 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11474 dbgs() << "\n");
11475 }
11476
11477 // Only move forward at the very end so that everything in validate
11478 // and process gets a consistent answer about whether we're in an IT
11479 // block.
11480 forwardITPosition();
11481 forwardVPTPosition();
11482
11483 // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
11484 // doesn't actually encode.
11485 if (Inst.getOpcode() == ARM::ITasm)
11486 return false;
11487
11488 Inst.setLoc(IDLoc);
11489 if (PendConditionalInstruction) {
11490 PendingConditionalInsts.push_back(Inst);
11491 if (isITBlockFull() || isITBlockTerminator(Inst))
11492 flushPendingInstructions(Out);
11493 } else {
11494 Out.emitInstruction(Inst, getSTI());
11495 }
11496 return false;
11497 case Match_NearMisses:
11498 ReportNearMisses(NearMisses, IDLoc, Operands);
11499 return true;
11500 case Match_MnemonicFail: {
11501 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11502 std::string Suggestion = ARMMnemonicSpellCheck(
11503 ((ARMOperand &)*Operands[0]).getToken(), FBS);
11504 return Error(IDLoc, "invalid instruction" + Suggestion,
11505 ((ARMOperand &)*Operands[0]).getLocRange());
11506 }
11507 }
11508
11509 llvm_unreachable("Implement any new match types added!");
11510}
11511
11512/// ParseDirective parses the arm specific directives
11513bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11514 const MCContext::Environment Format = getContext().getObjectFileType();
11515 bool IsMachO = Format == MCContext::IsMachO;
11516 bool IsCOFF = Format == MCContext::IsCOFF;
11517
11518 std::string IDVal = DirectiveID.getIdentifier().lower();
11519 if (IDVal == ".word")
11520 parseLiteralValues(4, DirectiveID.getLoc());
11521 else if (IDVal == ".short" || IDVal == ".hword")
11522 parseLiteralValues(2, DirectiveID.getLoc());
11523 else if (IDVal == ".thumb")
11524 parseDirectiveThumb(DirectiveID.getLoc());
11525 else if (IDVal == ".arm")
11526 parseDirectiveARM(DirectiveID.getLoc());
11527 else if (IDVal == ".thumb_func")
11528 parseDirectiveThumbFunc(DirectiveID.getLoc());
11529 else if (IDVal == ".code")
11530 parseDirectiveCode(DirectiveID.getLoc());
11531 else if (IDVal == ".syntax")
11532 parseDirectiveSyntax(DirectiveID.getLoc());
11533 else if (IDVal == ".unreq")
11534 parseDirectiveUnreq(DirectiveID.getLoc());
11535 else if (IDVal == ".fnend")
11536 parseDirectiveFnEnd(DirectiveID.getLoc());
11537 else if (IDVal == ".cantunwind")
11538 parseDirectiveCantUnwind(DirectiveID.getLoc());
11539 else if (IDVal == ".personality")
11540 parseDirectivePersonality(DirectiveID.getLoc());
11541 else if (IDVal == ".handlerdata")
11542 parseDirectiveHandlerData(DirectiveID.getLoc());
11543 else if (IDVal == ".setfp")
11544 parseDirectiveSetFP(DirectiveID.getLoc());
11545 else if (IDVal == ".pad")
11546 parseDirectivePad(DirectiveID.getLoc());
11547 else if (IDVal == ".save")
11548 parseDirectiveRegSave(DirectiveID.getLoc(), false);
11549 else if (IDVal == ".vsave")
11550 parseDirectiveRegSave(DirectiveID.getLoc(), true);
11551 else if (IDVal == ".ltorg" || IDVal == ".pool")
11552 parseDirectiveLtorg(DirectiveID.getLoc());
11553 else if (IDVal == ".even")
11554 parseDirectiveEven(DirectiveID.getLoc());
11555 else if (IDVal == ".personalityindex")
11556 parseDirectivePersonalityIndex(DirectiveID.getLoc());
11557 else if (IDVal == ".unwind_raw")
11558 parseDirectiveUnwindRaw(DirectiveID.getLoc());
11559 else if (IDVal == ".movsp")
11560 parseDirectiveMovSP(DirectiveID.getLoc());
11561 else if (IDVal == ".arch_extension")
11562 parseDirectiveArchExtension(DirectiveID.getLoc());
11563 else if (IDVal == ".align")
11564 return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
11565 else if (IDVal == ".thumb_set")
11566 parseDirectiveThumbSet(DirectiveID.getLoc());
11567 else if (IDVal == ".inst")
11568 parseDirectiveInst(DirectiveID.getLoc());
11569 else if (IDVal == ".inst.n")
11570 parseDirectiveInst(DirectiveID.getLoc(), 'n');
11571 else if (IDVal == ".inst.w")
11572 parseDirectiveInst(DirectiveID.getLoc(), 'w');
11573 else if (!IsMachO && !IsCOFF) {
11574 if (IDVal == ".arch")
11575 parseDirectiveArch(DirectiveID.getLoc());
11576 else if (IDVal == ".cpu")
11577 parseDirectiveCPU(DirectiveID.getLoc());
11578 else if (IDVal == ".eabi_attribute")
11579 parseDirectiveEabiAttr(DirectiveID.getLoc());
11580 else if (IDVal == ".fpu")
11581 parseDirectiveFPU(DirectiveID.getLoc());
11582 else if (IDVal == ".fnstart")
11583 parseDirectiveFnStart(DirectiveID.getLoc());
11584 else if (IDVal == ".object_arch")
11585 parseDirectiveObjectArch(DirectiveID.getLoc());
11586 else if (IDVal == ".tlsdescseq")
11587 parseDirectiveTLSDescSeq(DirectiveID.getLoc());
11588 else
11589 return true;
11590 } else if (IsCOFF) {
11591 if (IDVal == ".seh_stackalloc")
11592 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/false);
11593 else if (IDVal == ".seh_stackalloc_w")
11594 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/true);
11595 else if (IDVal == ".seh_save_regs")
11596 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/false);
11597 else if (IDVal == ".seh_save_regs_w")
11598 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/true);
11599 else if (IDVal == ".seh_save_sp")
11600 parseDirectiveSEHSaveSP(DirectiveID.getLoc());
11601 else if (IDVal == ".seh_save_fregs")
11602 parseDirectiveSEHSaveFRegs(DirectiveID.getLoc());
11603 else if (IDVal == ".seh_save_lr")
11604 parseDirectiveSEHSaveLR(DirectiveID.getLoc());
11605 else if (IDVal == ".seh_endprologue")
11606 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/false);
11607 else if (IDVal == ".seh_endprologue_fragment")
11608 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/true);
11609 else if (IDVal == ".seh_nop")
11610 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/false);
11611 else if (IDVal == ".seh_nop_w")
11612 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/true);
11613 else if (IDVal == ".seh_startepilogue")
11614 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/false);
11615 else if (IDVal == ".seh_startepilogue_cond")
11616 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/true);
11617 else if (IDVal == ".seh_endepilogue")
11618 parseDirectiveSEHEpilogEnd(DirectiveID.getLoc());
11619 else if (IDVal == ".seh_custom")
11620 parseDirectiveSEHCustom(DirectiveID.getLoc());
11621 else
11622 return true;
11623 } else
11624 return true;
11625 return false;
11626}
11627
11628/// parseLiteralValues
11629/// ::= .hword expression [, expression]*
11630/// ::= .short expression [, expression]*
11631/// ::= .word expression [, expression]*
11632bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
11633 auto parseOne = [&]() -> bool {
11634 const MCExpr *Value;
11635 if (getParser().parseExpression(Value))
11636 return true;
11637 getParser().getStreamer().emitValue(Value, Size, L);
11638 return false;
11639 };
11640 return (parseMany(parseOne));
11641}
11642
11643/// parseDirectiveThumb
11644/// ::= .thumb
11645bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11646 if (parseEOL() || check(!hasThumb(), L, "target does not support Thumb mode"))
11647 return true;
11648
11649 if (!isThumb())
11650 SwitchMode();
11651
11652 getTargetStreamer().emitCode16();
11653 getParser().getStreamer().emitCodeAlignment(Align(2), getSTI(), 0);
11654 return false;
11655}
11656
11657/// parseDirectiveARM
11658/// ::= .arm
11659bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11660 if (parseEOL() || check(!hasARM(), L, "target does not support ARM mode"))
11661 return true;
11662
11663 if (isThumb())
11664 SwitchMode();
11665 getTargetStreamer().emitCode32();
11666 getParser().getStreamer().emitCodeAlignment(Align(4), getSTI(), 0);
11667 return false;
11668}
11669
11670void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11671 // We need to flush the current implicit IT block on a label, because it is
11672 // not legal to branch into an IT block.
11673 flushPendingInstructions(getStreamer());
11674}
11675
11676void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11677 if (NextSymbolIsThumb) {
11678 getTargetStreamer().emitThumbFunc(Symbol);
11679 NextSymbolIsThumb = false;
11680 }
11681}
11682
11683/// parseDirectiveThumbFunc
11684/// ::= .thumbfunc symbol_name
11685bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11686 MCAsmParser &Parser = getParser();
11687 const auto Format = getContext().getObjectFileType();
11688 bool IsMachO = Format == MCContext::IsMachO;
11689
11690 // Darwin asm has (optionally) function name after .thumb_func direction
11691 // ELF doesn't
11692
11693 if (IsMachO) {
11694 if (Parser.getTok().is(AsmToken::Identifier) ||
11695 Parser.getTok().is(AsmToken::String)) {
11696 MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
11697 Parser.getTok().getIdentifier());
11698 getTargetStreamer().emitThumbFunc(Func);
11699 Parser.Lex();
11700 if (parseEOL())
11701 return true;
11702 return false;
11703 }
11704 }
11705
11706 if (parseEOL())
11707 return true;
11708
11709 // .thumb_func implies .thumb
11710 if (!isThumb())
11711 SwitchMode();
11712
11713 getTargetStreamer().emitCode16();
11714
11715 NextSymbolIsThumb = true;
11716 return false;
11717}
11718
11719/// parseDirectiveSyntax
11720/// ::= .syntax unified | divided
11721bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11722 MCAsmParser &Parser = getParser();
11723 const AsmToken &Tok = Parser.getTok();
11724 if (Tok.isNot(AsmToken::Identifier)) {
11725 Error(L, "unexpected token in .syntax directive");
11726 return false;
11727 }
11728
11729 StringRef Mode = Tok.getString();
11730 Parser.Lex();
11731 if (check(Mode == "divided" || Mode == "DIVIDED", L,
11732 "'.syntax divided' arm assembly not supported") ||
11733 check(Mode != "unified" && Mode != "UNIFIED", L,
11734 "unrecognized syntax mode in .syntax directive") ||
11735 parseEOL())
11736 return true;
11737
11738 // TODO tell the MC streamer the mode
11739 // getParser().getStreamer().Emit???();
11740 return false;
11741}
11742
11743/// parseDirectiveCode
11744/// ::= .code 16 | 32
11745bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11746 MCAsmParser &Parser = getParser();
11747 const AsmToken &Tok = Parser.getTok();
11748 if (Tok.isNot(AsmToken::Integer))
11749 return Error(L, "unexpected token in .code directive");
11750 int64_t Val = Parser.getTok().getIntVal();
11751 if (Val != 16 && Val != 32) {
11752 Error(L, "invalid operand to .code directive");
11753 return false;
11754 }
11755 Parser.Lex();
11756
11757 if (parseEOL())
11758 return true;
11759
11760 if (Val == 16) {
11761 if (!hasThumb())
11762 return Error(L, "target does not support Thumb mode");
11763
11764 if (!isThumb())
11765 SwitchMode();
11766 getTargetStreamer().emitCode16();
11767 } else {
11768 if (!hasARM())
11769 return Error(L, "target does not support ARM mode");
11770
11771 if (isThumb())
11772 SwitchMode();
11773 getTargetStreamer().emitCode32();
11774 }
11775
11776 return false;
11777}
11778
11779/// parseDirectiveReq
11780/// ::= name .req registername
11781bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11782 MCAsmParser &Parser = getParser();
11783 Parser.Lex(); // Eat the '.req' token.
11784 MCRegister Reg;
11785 SMLoc SRegLoc, ERegLoc;
11786 const bool parseResult = parseRegister(Reg, SRegLoc, ERegLoc);
11787 if (check(parseResult, SRegLoc, "register name expected") || parseEOL())
11788 return true;
11789
11790 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg)
11791 return Error(SRegLoc,
11792 "redefinition of '" + Name + "' does not match original.");
11793
11794 return false;
11795}
11796
11797/// parseDirectiveUneq
11798/// ::= .unreq registername
11799bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11800 MCAsmParser &Parser = getParser();
11801 if (Parser.getTok().isNot(AsmToken::Identifier))
11802 return Error(L, "unexpected input in .unreq directive.");
11803 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
11804 Parser.Lex(); // Eat the identifier.
11805 return parseEOL();
11806}
11807
11808// After changing arch/CPU, try to put the ARM/Thumb mode back to what it was
11809// before, if supported by the new target, or emit mapping symbols for the mode
11810// switch.
11811void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) {
11812 if (WasThumb != isThumb()) {
11813 if (WasThumb && hasThumb()) {
11814 // Stay in Thumb mode
11815 SwitchMode();
11816 } else if (!WasThumb && hasARM()) {
11817 // Stay in ARM mode
11818 SwitchMode();
11819 } else {
11820 // Mode switch forced, because the new arch doesn't support the old mode.
11821 if (isThumb())
11822 getTargetStreamer().emitCode16();
11823 else
11824 getTargetStreamer().emitCode32();
11825 // Warn about the implicit mode switch. GAS does not switch modes here,
11826 // but instead stays in the old mode, reporting an error on any following
11827 // instructions as the mode does not exist on the target.
11828 Warning(Loc, Twine("new target does not support ") +
11829 (WasThumb ? "thumb" : "arm") + " mode, switching to " +
11830 (!WasThumb ? "thumb" : "arm") + " mode");
11831 }
11832 }
11833}
11834
11835/// parseDirectiveArch
11836/// ::= .arch token
11837bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11838 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11840
11841 if (ID == ARM::ArchKind::INVALID)
11842 return Error(L, "Unknown arch name");
11843
11844 bool WasThumb = isThumb();
11845 MCSubtargetInfo &STI = copySTI();
11846 STI.setDefaultFeatures("", /*TuneCPU*/ "",
11847 ("+" + ARM::getArchName(ID)).str());
11848 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11849 FixModeAfterArchChange(WasThumb, L);
11850
11851 getTargetStreamer().emitArch(ID);
11852 return false;
11853}
11854
11855/// parseDirectiveEabiAttr
11856/// ::= .eabi_attribute int, int [, "str"]
11857/// ::= .eabi_attribute Tag_name, int [, "str"]
11858bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11859 MCAsmParser &Parser = getParser();
11860 int64_t Tag;
11861 SMLoc TagLoc;
11862 TagLoc = Parser.getTok().getLoc();
11863 if (Parser.getTok().is(AsmToken::Identifier)) {
11864 StringRef Name = Parser.getTok().getIdentifier();
11865 std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString(
11867 if (!Ret) {
11868 Error(TagLoc, "attribute name not recognised: " + Name);
11869 return false;
11870 }
11871 Tag = *Ret;
11872 Parser.Lex();
11873 } else {
11874 const MCExpr *AttrExpr;
11875
11876 TagLoc = Parser.getTok().getLoc();
11877 if (Parser.parseExpression(AttrExpr))
11878 return true;
11879
11880 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
11881 if (check(!CE, TagLoc, "expected numeric constant"))
11882 return true;
11883
11884 Tag = CE->getValue();
11885 }
11886
11887 if (Parser.parseComma())
11888 return true;
11889
11890 StringRef StringValue = "";
11891 bool IsStringValue = false;
11892
11893 int64_t IntegerValue = 0;
11894 bool IsIntegerValue = false;
11895
11897 IsStringValue = true;
11898 else if (Tag == ARMBuildAttrs::compatibility) {
11899 IsStringValue = true;
11900 IsIntegerValue = true;
11901 } else if (Tag < 32 || Tag % 2 == 0)
11902 IsIntegerValue = true;
11903 else if (Tag % 2 == 1)
11904 IsStringValue = true;
11905 else
11906 llvm_unreachable("invalid tag type");
11907
11908 if (IsIntegerValue) {
11909 const MCExpr *ValueExpr;
11910 SMLoc ValueExprLoc = Parser.getTok().getLoc();
11911 if (Parser.parseExpression(ValueExpr))
11912 return true;
11913
11914 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
11915 if (!CE)
11916 return Error(ValueExprLoc, "expected numeric constant");
11917 IntegerValue = CE->getValue();
11918 }
11919
11921 if (Parser.parseComma())
11922 return true;
11923 }
11924
11925 std::string EscapedValue;
11926 if (IsStringValue) {
11927 if (Parser.getTok().isNot(AsmToken::String))
11928 return Error(Parser.getTok().getLoc(), "bad string constant");
11929
11931 if (Parser.parseEscapedString(EscapedValue))
11932 return Error(Parser.getTok().getLoc(), "bad escaped string constant");
11933
11934 StringValue = EscapedValue;
11935 } else {
11936 StringValue = Parser.getTok().getStringContents();
11937 Parser.Lex();
11938 }
11939 }
11940
11941 if (Parser.parseEOL())
11942 return true;
11943
11944 if (IsIntegerValue && IsStringValue) {
11946 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
11947 } else if (IsIntegerValue)
11948 getTargetStreamer().emitAttribute(Tag, IntegerValue);
11949 else if (IsStringValue)
11950 getTargetStreamer().emitTextAttribute(Tag, StringValue);
11951 return false;
11952}
11953
11954/// parseDirectiveCPU
11955/// ::= .cpu str
11956bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11957 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11958 getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
11959
11960 // FIXME: This is using table-gen data, but should be moved to
11961 // ARMTargetParser once that is table-gen'd.
11962 if (!getSTI().isCPUStringValid(CPU))
11963 return Error(L, "Unknown CPU name");
11964
11965 bool WasThumb = isThumb();
11966 MCSubtargetInfo &STI = copySTI();
11967 STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
11968 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11969 FixModeAfterArchChange(WasThumb, L);
11970
11971 return false;
11972}
11973
11974/// parseDirectiveFPU
11975/// ::= .fpu str
11976bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11977 SMLoc FPUNameLoc = getTok().getLoc();
11978 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11979
11981 std::vector<StringRef> Features;
11982 if (!ARM::getFPUFeatures(ID, Features))
11983 return Error(FPUNameLoc, "Unknown FPU name");
11984
11985 MCSubtargetInfo &STI = copySTI();
11986 for (auto Feature : Features)
11987 STI.ApplyFeatureFlag(Feature);
11988 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11989
11990 getTargetStreamer().emitFPU(ID);
11991 return false;
11992}
11993
11994/// parseDirectiveFnStart
11995/// ::= .fnstart
11996bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
11997 if (parseEOL())
11998 return true;
11999
12000 if (UC.hasFnStart()) {
12001 Error(L, ".fnstart starts before the end of previous one");
12002 UC.emitFnStartLocNotes();
12003 return true;
12004 }
12005
12006 // Reset the unwind directives parser state
12007 UC.reset();
12008
12009 getTargetStreamer().emitFnStart();
12010
12011 UC.recordFnStart(L);
12012 return false;
12013}
12014
12015/// parseDirectiveFnEnd
12016/// ::= .fnend
12017bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12018 if (parseEOL())
12019 return true;
12020 // Check the ordering of unwind directives
12021 if (!UC.hasFnStart())
12022 return Error(L, ".fnstart must precede .fnend directive");
12023
12024 // Reset the unwind directives parser state
12025 getTargetStreamer().emitFnEnd();
12026
12027 UC.reset();
12028 return false;
12029}
12030
12031/// parseDirectiveCantUnwind
12032/// ::= .cantunwind
12033bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12034 if (parseEOL())
12035 return true;
12036
12037 UC.recordCantUnwind(L);
12038 // Check the ordering of unwind directives
12039 if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive"))
12040 return true;
12041
12042 if (UC.hasHandlerData()) {
12043 Error(L, ".cantunwind can't be used with .handlerdata directive");
12044 UC.emitHandlerDataLocNotes();
12045 return true;
12046 }
12047 if (UC.hasPersonality()) {
12048 Error(L, ".cantunwind can't be used with .personality directive");
12049 UC.emitPersonalityLocNotes();
12050 return true;
12051 }
12052
12053 getTargetStreamer().emitCantUnwind();
12054 return false;
12055}
12056
12057/// parseDirectivePersonality
12058/// ::= .personality name
12059bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12060 MCAsmParser &Parser = getParser();
12061 bool HasExistingPersonality = UC.hasPersonality();
12062
12063 // Parse the name of the personality routine
12064 if (Parser.getTok().isNot(AsmToken::Identifier))
12065 return Error(L, "unexpected input in .personality directive.");
12066 StringRef Name(Parser.getTok().getIdentifier());
12067 Parser.Lex();
12068
12069 if (parseEOL())
12070 return true;
12071
12072 UC.recordPersonality(L);
12073
12074 // Check the ordering of unwind directives
12075 if (!UC.hasFnStart())
12076 return Error(L, ".fnstart must precede .personality directive");
12077 if (UC.cantUnwind()) {
12078 Error(L, ".personality can't be used with .cantunwind directive");
12079 UC.emitCantUnwindLocNotes();
12080 return true;
12081 }
12082 if (UC.hasHandlerData()) {
12083 Error(L, ".personality must precede .handlerdata directive");
12084 UC.emitHandlerDataLocNotes();
12085 return true;
12086 }
12087 if (HasExistingPersonality) {
12088 Error(L, "multiple personality directives");
12089 UC.emitPersonalityLocNotes();
12090 return true;
12091 }
12092
12093 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12094 getTargetStreamer().emitPersonality(PR);
12095 return false;
12096}
12097
12098/// parseDirectiveHandlerData
12099/// ::= .handlerdata
12100bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12101 if (parseEOL())
12102 return true;
12103
12104 UC.recordHandlerData(L);
12105 // Check the ordering of unwind directives
12106 if (!UC.hasFnStart())
12107 return Error(L, ".fnstart must precede .personality directive");
12108 if (UC.cantUnwind()) {
12109 Error(L, ".handlerdata can't be used with .cantunwind directive");
12110 UC.emitCantUnwindLocNotes();
12111 return true;
12112 }
12113
12114 getTargetStreamer().emitHandlerData();
12115 return false;
12116}
12117
12118/// parseDirectiveSetFP
12119/// ::= .setfp fpreg, spreg [, offset]
12120bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12121 MCAsmParser &Parser = getParser();
12122 // Check the ordering of unwind directives
12123 if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") ||
12124 check(UC.hasHandlerData(), L,
12125 ".setfp must precede .handlerdata directive"))
12126 return true;
12127
12128 // Parse fpreg
12129 SMLoc FPRegLoc = Parser.getTok().getLoc();
12130 MCRegister FPReg = tryParseRegister();
12131
12132 if (check(!FPReg, FPRegLoc, "frame pointer register expected") ||
12133 Parser.parseComma())
12134 return true;
12135
12136 // Parse spreg
12137 SMLoc SPRegLoc = Parser.getTok().getLoc();
12138 MCRegister SPReg = tryParseRegister();
12139 if (check(!SPReg, SPRegLoc, "stack pointer register expected") ||
12140 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
12141 "register should be either $sp or the latest fp register"))
12142 return true;
12143
12144 // Update the frame pointer register
12145 UC.saveFPReg(FPReg);
12146
12147 // Parse offset
12148 int64_t Offset = 0;
12149 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12150 if (Parser.getTok().isNot(AsmToken::Hash) &&
12151 Parser.getTok().isNot(AsmToken::Dollar))
12152 return Error(Parser.getTok().getLoc(), "'#' expected");
12153 Parser.Lex(); // skip hash token.
12154
12155 const MCExpr *OffsetExpr;
12156 SMLoc ExLoc = Parser.getTok().getLoc();
12157 SMLoc EndLoc;
12158 if (getParser().parseExpression(OffsetExpr, EndLoc))
12159 return Error(ExLoc, "malformed setfp offset");
12160 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12161 if (check(!CE, ExLoc, "setfp offset must be an immediate"))
12162 return true;
12163 Offset = CE->getValue();
12164 }
12165
12166 if (Parser.parseEOL())
12167 return true;
12168
12169 getTargetStreamer().emitSetFP(FPReg, SPReg, Offset);
12170 return false;
12171}
12172
12173/// parseDirectivePad
12174/// ::= .pad offset
12175bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12176 MCAsmParser &Parser = getParser();
12177 // Check the ordering of unwind directives
12178 if (!UC.hasFnStart())
12179 return Error(L, ".fnstart must precede .pad directive");
12180 if (UC.hasHandlerData())
12181 return Error(L, ".pad must precede .handlerdata directive");
12182
12183 // Parse the offset
12184 if (Parser.getTok().isNot(AsmToken::Hash) &&
12185 Parser.getTok().isNot(AsmToken::Dollar))
12186 return Error(Parser.getTok().getLoc(), "'#' expected");
12187 Parser.Lex(); // skip hash token.
12188
12189 const MCExpr *OffsetExpr;
12190 SMLoc ExLoc = Parser.getTok().getLoc();
12191 SMLoc EndLoc;
12192 if (getParser().parseExpression(OffsetExpr, EndLoc))
12193 return Error(ExLoc, "malformed pad offset");
12194 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12195 if (!CE)
12196 return Error(ExLoc, "pad offset must be an immediate");
12197
12198 if (parseEOL())
12199 return true;
12200
12201 getTargetStreamer().emitPad(CE->getValue());
12202 return false;
12203}
12204
12205/// parseDirectiveRegSave
12206/// ::= .save { registers }
12207/// ::= .vsave { registers }
12208bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
12209 // Check the ordering of unwind directives
12210 if (!UC.hasFnStart())
12211 return Error(L, ".fnstart must precede .save or .vsave directives");
12212 if (UC.hasHandlerData())
12213 return Error(L, ".save or .vsave must precede .handlerdata directive");
12214
12215 // RAII object to make sure parsed operands are deleted.
12217
12218 // Parse the register list
12219 if (parseRegisterList(Operands, true, true) || parseEOL())
12220 return true;
12221 ARMOperand &Op = (ARMOperand &)*Operands[0];
12222 if (!IsVector && !Op.isRegList())
12223 return Error(L, ".save expects GPR registers");
12224 if (IsVector && !Op.isDPRRegList())
12225 return Error(L, ".vsave expects DPR registers");
12226
12227 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
12228 return false;
12229}
12230
12231/// parseDirectiveInst
12232/// ::= .inst opcode [, ...]
12233/// ::= .inst.n opcode [, ...]
12234/// ::= .inst.w opcode [, ...]
12235bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
12236 int Width = 4;
12237
12238 if (isThumb()) {
12239 switch (Suffix) {
12240 case 'n':
12241 Width = 2;
12242 break;
12243 case 'w':
12244 break;
12245 default:
12246 Width = 0;
12247 break;
12248 }
12249 } else {
12250 if (Suffix)
12251 return Error(Loc, "width suffixes are invalid in ARM mode");
12252 }
12253
12254 auto parseOne = [&]() -> bool {
12255 const MCExpr *Expr;
12256 if (getParser().parseExpression(Expr))
12257 return true;
12258 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
12259 if (!Value) {
12260 return Error(Loc, "expected constant expression");
12261 }
12262
12263 char CurSuffix = Suffix;
12264 switch (Width) {
12265 case 2:
12266 if (Value->getValue() > 0xffff)
12267 return Error(Loc, "inst.n operand is too big, use inst.w instead");
12268 break;
12269 case 4:
12270 if (Value->getValue() > 0xffffffff)
12271 return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +
12272 " operand is too big");
12273 break;
12274 case 0:
12275 // Thumb mode, no width indicated. Guess from the opcode, if possible.
12276 if (Value->getValue() < 0xe800)
12277 CurSuffix = 'n';
12278 else if (Value->getValue() >= 0xe8000000)
12279 CurSuffix = 'w';
12280 else
12281 return Error(Loc, "cannot determine Thumb instruction size, "
12282 "use inst.n/inst.w instead");
12283 break;
12284 default:
12285 llvm_unreachable("only supported widths are 2 and 4");
12286 }
12287
12288 getTargetStreamer().emitInst(Value->getValue(), CurSuffix);
12289 forwardITPosition();
12290 forwardVPTPosition();
12291 return false;
12292 };
12293
12294 if (parseOptionalToken(AsmToken::EndOfStatement))
12295 return Error(Loc, "expected expression following directive");
12296 if (parseMany(parseOne))
12297 return true;
12298 return false;
12299}
12300
12301/// parseDirectiveLtorg
12302/// ::= .ltorg | .pool
12303bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12304 if (parseEOL())
12305 return true;
12306 getTargetStreamer().emitCurrentConstantPool();
12307 return false;
12308}
12309
12310bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12311 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12312
12313 if (parseEOL())
12314 return true;
12315
12316 if (!Section) {
12317 getStreamer().initSections(getSTI());
12318 Section = getStreamer().getCurrentSectionOnly();
12319 }
12320
12321 assert(Section && "must have section to emit alignment");
12322 if (getContext().getAsmInfo().useCodeAlign(*Section))
12323 getStreamer().emitCodeAlignment(Align(2), getSTI());
12324 else
12325 getStreamer().emitValueToAlignment(Align(2));
12326
12327 return false;
12328}
12329
12330/// parseDirectivePersonalityIndex
12331/// ::= .personalityindex index
12332bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12333 MCAsmParser &Parser = getParser();
12334 bool HasExistingPersonality = UC.hasPersonality();
12335
12336 const MCExpr *IndexExpression;
12337 SMLoc IndexLoc = Parser.getTok().getLoc();
12338 if (Parser.parseExpression(IndexExpression) || parseEOL()) {
12339 return true;
12340 }
12341
12342 UC.recordPersonalityIndex(L);
12343
12344 if (!UC.hasFnStart()) {
12345 return Error(L, ".fnstart must precede .personalityindex directive");
12346 }
12347 if (UC.cantUnwind()) {
12348 Error(L, ".personalityindex cannot be used with .cantunwind");
12349 UC.emitCantUnwindLocNotes();
12350 return true;
12351 }
12352 if (UC.hasHandlerData()) {
12353 Error(L, ".personalityindex must precede .handlerdata directive");
12354 UC.emitHandlerDataLocNotes();
12355 return true;
12356 }
12357 if (HasExistingPersonality) {
12358 Error(L, "multiple personality directives");
12359 UC.emitPersonalityLocNotes();
12360 return true;
12361 }
12362
12363 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression);
12364 if (!CE)
12365 return Error(IndexLoc, "index must be a constant number");
12366 if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX)
12367 return Error(IndexLoc,
12368 "personality routine index should be in range [0-3]");
12369
12370 getTargetStreamer().emitPersonalityIndex(CE->getValue());
12371 return false;
12372}
12373
12374/// parseDirectiveUnwindRaw
12375/// ::= .unwind_raw offset, opcode [, opcode...]
12376bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12377 MCAsmParser &Parser = getParser();
12378 int64_t StackOffset;
12379 const MCExpr *OffsetExpr;
12380 SMLoc OffsetLoc = getLexer().getLoc();
12381
12382 if (!UC.hasFnStart())
12383 return Error(L, ".fnstart must precede .unwind_raw directives");
12384 if (getParser().parseExpression(OffsetExpr))
12385 return Error(OffsetLoc, "expected expression");
12386
12387 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12388 if (!CE)
12389 return Error(OffsetLoc, "offset must be a constant");
12390
12391 StackOffset = CE->getValue();
12392
12393 if (Parser.parseComma())
12394 return true;
12395
12397
12398 auto parseOne = [&]() -> bool {
12399 const MCExpr *OE = nullptr;
12400 SMLoc OpcodeLoc = getLexer().getLoc();
12401 if (check(getLexer().is(AsmToken::EndOfStatement) ||
12402 Parser.parseExpression(OE),
12403 OpcodeLoc, "expected opcode expression"))
12404 return true;
12405 const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE);
12406 if (!OC)
12407 return Error(OpcodeLoc, "opcode value must be a constant");
12408 const int64_t Opcode = OC->getValue();
12409 if (Opcode & ~0xff)
12410 return Error(OpcodeLoc, "invalid opcode");
12411 Opcodes.push_back(uint8_t(Opcode));
12412 return false;
12413 };
12414
12415 // Must have at least 1 element
12416 SMLoc OpcodeLoc = getLexer().getLoc();
12417 if (parseOptionalToken(AsmToken::EndOfStatement))
12418 return Error(OpcodeLoc, "expected opcode expression");
12419 if (parseMany(parseOne))
12420 return true;
12421
12422 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12423 return false;
12424}
12425
12426/// parseDirectiveTLSDescSeq
12427/// ::= .tlsdescseq tls-variable
12428bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12429 MCAsmParser &Parser = getParser();
12430
12431 if (getLexer().isNot(AsmToken::Identifier))
12432 return TokError("expected variable after '.tlsdescseq' directive");
12433
12434 auto *Sym = getContext().getOrCreateSymbol(Parser.getTok().getIdentifier());
12435 const auto *SRE =
12437 Lex();
12438
12439 if (parseEOL())
12440 return true;
12441
12442 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12443 return false;
12444}
12445
12446/// parseDirectiveMovSP
12447/// ::= .movsp reg [, #offset]
12448bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12449 MCAsmParser &Parser = getParser();
12450 if (!UC.hasFnStart())
12451 return Error(L, ".fnstart must precede .movsp directives");
12452 if (UC.getFPReg() != ARM::SP)
12453 return Error(L, "unexpected .movsp directive");
12454
12455 SMLoc SPRegLoc = Parser.getTok().getLoc();
12456 MCRegister SPReg = tryParseRegister();
12457 if (!SPReg)
12458 return Error(SPRegLoc, "register expected");
12459 if (SPReg == ARM::SP || SPReg == ARM::PC)
12460 return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
12461
12462 int64_t Offset = 0;
12463 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12464 if (Parser.parseToken(AsmToken::Hash, "expected #constant"))
12465 return true;
12466
12467 const MCExpr *OffsetExpr;
12468 SMLoc OffsetLoc = Parser.getTok().getLoc();
12469
12470 if (Parser.parseExpression(OffsetExpr))
12471 return Error(OffsetLoc, "malformed offset expression");
12472
12473 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12474 if (!CE)
12475 return Error(OffsetLoc, "offset must be an immediate constant");
12476
12477 Offset = CE->getValue();
12478 }
12479
12480 if (parseEOL())
12481 return true;
12482
12483 getTargetStreamer().emitMovSP(SPReg, Offset);
12484 UC.saveFPReg(SPReg);
12485
12486 return false;
12487}
12488
12489/// parseDirectiveObjectArch
12490/// ::= .object_arch name
12491bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12492 MCAsmParser &Parser = getParser();
12493 if (getLexer().isNot(AsmToken::Identifier))
12494 return Error(getLexer().getLoc(), "unexpected token");
12495
12496 StringRef Arch = Parser.getTok().getString();
12497 SMLoc ArchLoc = Parser.getTok().getLoc();
12498 Lex();
12499
12501
12502 if (ID == ARM::ArchKind::INVALID)
12503 return Error(ArchLoc, "unknown architecture '" + Arch + "'");
12504 if (parseToken(AsmToken::EndOfStatement))
12505 return true;
12506
12507 getTargetStreamer().emitObjectArch(ID);
12508 return false;
12509}
12510
12511/// parseDirectiveAlign
12512/// ::= .align
12513bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12514 // NOTE: if this is not the end of the statement, fall back to the target
12515 // agnostic handling for this directive which will correctly handle this.
12516 if (parseOptionalToken(AsmToken::EndOfStatement)) {
12517 // '.align' is target specifically handled to mean 2**2 byte alignment.
12518 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12519 assert(Section && "must have section to emit alignment");
12520 if (getContext().getAsmInfo().useCodeAlign(*Section))
12521 getStreamer().emitCodeAlignment(Align(4), getSTI(), 0);
12522 else
12523 getStreamer().emitValueToAlignment(Align(4), 0, 1, 0);
12524 return false;
12525 }
12526 return true;
12527}
12528
12529/// parseDirectiveThumbSet
12530/// ::= .thumb_set name, value
12531bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12532 MCAsmParser &Parser = getParser();
12533
12534 StringRef Name;
12535 if (check(Parser.parseIdentifier(Name),
12536 "expected identifier after '.thumb_set'") ||
12537 Parser.parseComma())
12538 return true;
12539
12540 MCSymbol *Sym;
12541 const MCExpr *Value;
12542 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
12543 Parser, Sym, Value))
12544 return true;
12545
12546 getTargetStreamer().emitThumbSet(Sym, Value);
12547 return false;
12548}
12549
12550/// parseDirectiveSEHAllocStack
12551/// ::= .seh_stackalloc
12552/// ::= .seh_stackalloc_w
12553bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L, bool Wide) {
12554 int64_t Size;
12555 if (parseImmExpr(Size))
12556 return true;
12557 getTargetStreamer().emitARMWinCFIAllocStack(Size, Wide);
12558 return false;
12559}
12560
12561/// parseDirectiveSEHSaveRegs
12562/// ::= .seh_save_regs
12563/// ::= .seh_save_regs_w
12564bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L, bool Wide) {
12566
12567 if (parseRegisterList(Operands) || parseEOL())
12568 return true;
12569 ARMOperand &Op = (ARMOperand &)*Operands[0];
12570 if (!Op.isRegList())
12571 return Error(L, ".seh_save_regs{_w} expects GPR registers");
12572 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12573 uint32_t Mask = 0;
12574 for (size_t i = 0; i < RegList.size(); ++i) {
12575 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12576 if (Reg == 15) // pc -> lr
12577 Reg = 14;
12578 if (Reg == 13)
12579 return Error(L, ".seh_save_regs{_w} can't include SP");
12580 assert(Reg < 16U && "Register out of range");
12581 unsigned Bit = (1u << Reg);
12582 Mask |= Bit;
12583 }
12584 if (!Wide && (Mask & 0x1f00) != 0)
12585 return Error(L,
12586 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12587 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12588 return false;
12589}
12590
12591/// parseDirectiveSEHSaveSP
12592/// ::= .seh_save_sp
12593bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12594 MCRegister Reg = tryParseRegister();
12595 if (!Reg || !MRI->getRegClass(ARM::GPRRegClassID).contains(Reg))
12596 return Error(L, "expected GPR");
12597 unsigned Index = MRI->getEncodingValue(Reg);
12598 if (Index > 14 || Index == 13)
12599 return Error(L, "invalid register for .seh_save_sp");
12600 getTargetStreamer().emitARMWinCFISaveSP(Index);
12601 return false;
12602}
12603
12604/// parseDirectiveSEHSaveFRegs
12605/// ::= .seh_save_fregs
12606bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12608
12609 if (parseRegisterList(Operands) || parseEOL())
12610 return true;
12611 ARMOperand &Op = (ARMOperand &)*Operands[0];
12612 if (!Op.isDPRRegList())
12613 return Error(L, ".seh_save_fregs expects DPR registers");
12614 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12615 uint32_t Mask = 0;
12616 for (size_t i = 0; i < RegList.size(); ++i) {
12617 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12618 assert(Reg < 32U && "Register out of range");
12619 unsigned Bit = (1u << Reg);
12620 Mask |= Bit;
12621 }
12622
12623 if (Mask == 0)
12624 return Error(L, ".seh_save_fregs missing registers");
12625
12626 unsigned First = 0;
12627 while ((Mask & 1) == 0) {
12628 First++;
12629 Mask >>= 1;
12630 }
12631 if (((Mask + 1) & Mask) != 0)
12632 return Error(L,
12633 ".seh_save_fregs must take a contiguous range of registers");
12634 unsigned Last = First;
12635 while ((Mask & 2) != 0) {
12636 Last++;
12637 Mask >>= 1;
12638 }
12639 if (First < 16 && Last >= 16)
12640 return Error(L, ".seh_save_fregs must be all d0-d15 or d16-d31");
12641 getTargetStreamer().emitARMWinCFISaveFRegs(First, Last);
12642 return false;
12643}
12644
12645/// parseDirectiveSEHSaveLR
12646/// ::= .seh_save_lr
12647bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12648 int64_t Offset;
12649 if (parseImmExpr(Offset))
12650 return true;
12651 getTargetStreamer().emitARMWinCFISaveLR(Offset);
12652 return false;
12653}
12654
12655/// parseDirectiveSEHPrologEnd
12656/// ::= .seh_endprologue
12657/// ::= .seh_endprologue_fragment
12658bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L, bool Fragment) {
12659 getTargetStreamer().emitARMWinCFIPrologEnd(Fragment);
12660 return false;
12661}
12662
12663/// parseDirectiveSEHNop
12664/// ::= .seh_nop
12665/// ::= .seh_nop_w
12666bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L, bool Wide) {
12667 getTargetStreamer().emitARMWinCFINop(Wide);
12668 return false;
12669}
12670
12671/// parseDirectiveSEHEpilogStart
12672/// ::= .seh_startepilogue
12673/// ::= .seh_startepilogue_cond
12674bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L, bool Condition) {
12675 unsigned CC = ARMCC::AL;
12676 if (Condition) {
12677 MCAsmParser &Parser = getParser();
12678 SMLoc S = Parser.getTok().getLoc();
12679 const AsmToken &Tok = Parser.getTok();
12680 if (!Tok.is(AsmToken::Identifier))
12681 return Error(S, ".seh_startepilogue_cond missing condition");
12682 CC = ARMCondCodeFromString(Tok.getString());
12683 if (CC == ~0U)
12684 return Error(S, "invalid condition");
12685 Parser.Lex(); // Eat the token.
12686 }
12687
12688 getTargetStreamer().emitARMWinCFIEpilogStart(CC);
12689 return false;
12690}
12691
12692/// parseDirectiveSEHEpilogEnd
12693/// ::= .seh_endepilogue
12694bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12695 getTargetStreamer().emitARMWinCFIEpilogEnd();
12696 return false;
12697}
12698
12699/// parseDirectiveSEHCustom
12700/// ::= .seh_custom
12701bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12702 unsigned Opcode = 0;
12703 do {
12704 int64_t Byte;
12705 if (parseImmExpr(Byte))
12706 return true;
12707 if (Byte > 0xff || Byte < 0)
12708 return Error(L, "Invalid byte value in .seh_custom");
12709 if (Opcode > 0x00ffffff)
12710 return Error(L, "Too many bytes in .seh_custom");
12711 // Store the bytes as one big endian number in Opcode. In a multi byte
12712 // opcode sequence, the first byte can't be zero.
12713 Opcode = (Opcode << 8) | Byte;
12714 } while (parseOptionalToken(AsmToken::Comma));
12715 getTargetStreamer().emitARMWinCFICustom(Opcode);
12716 return false;
12717}
12718
12719/// Force static initialization.
12726
12727#define GET_REGISTER_MATCHER
12728#define GET_SUBTARGET_FEATURE_NAME
12729#define GET_MATCHER_IMPLEMENTATION
12730#define GET_MNEMONIC_SPELL_CHECKER
12731#include "ARMGenAsmMatcher.inc"
12732
12733// Some diagnostics need to vary with subtarget features, so they are handled
12734// here. For example, the DPR class has either 16 or 32 registers, depending
12735// on the FPU available.
12736const char *
12737ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12738 switch (MatchError) {
12739 // rGPR contains sp starting with ARMv8.
12740 case Match_rGPR:
12741 return hasV8Ops() ? "operand must be a register in range [r0, r14]"
12742 : "operand must be a register in range [r0, r12] or r14";
12743 // DPR contains 16 registers for some FPUs, and 32 for others.
12744 case Match_DPR:
12745 return hasD32() ? "operand must be a register in range [d0, d31]"
12746 : "operand must be a register in range [d0, d15]";
12747 case Match_DPR_RegList:
12748 return hasD32() ? "operand must be a list of registers in range [d0, d31]"
12749 : "operand must be a list of registers in range [d0, d15]";
12750
12751 // For all other diags, use the static string from tablegen.
12752 default:
12753 return getMatchKindDiag(MatchError);
12754 }
12755}
12756
12757// Process the list of near-misses, throwing away ones we don't want to report
12758// to the user, and converting the rest to a source location and string that
12759// should be reported.
12760void
12761ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12762 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12763 SMLoc IDLoc, OperandVector &Operands) {
12764 // TODO: If operand didn't match, sub in a dummy one and run target
12765 // predicate, so that we can avoid reporting near-misses that are invalid?
12766 // TODO: Many operand types dont have SuperClasses set, so we report
12767 // redundant ones.
12768 // TODO: Some operands are superclasses of registers (e.g.
12769 // MCK_RegShiftedImm), we don't have any way to represent that currently.
12770 // TODO: This is not all ARM-specific, can some of it be factored out?
12771
12772 // Record some information about near-misses that we have already seen, so
12773 // that we can avoid reporting redundant ones. For example, if there are
12774 // variants of an instruction that take 8- and 16-bit immediates, we want
12775 // to only report the widest one.
12776 std::multimap<unsigned, unsigned> OperandMissesSeen;
12777 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12778 bool ReportedTooFewOperands = false;
12779
12780 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
12781
12782 // Process the near-misses in reverse order, so that we see more general ones
12783 // first, and so can avoid emitting more specific ones.
12784 for (NearMissInfo &I : reverse(NearMissesIn)) {
12785 switch (I.getKind()) {
12787 SMLoc OperandLoc =
12788 ((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
12789 const char *OperandDiag =
12790 getCustomOperandDiag((ARMMatchResultTy)I.getOperandError());
12791
12792 // If we have already emitted a message for a superclass, don't also report
12793 // the sub-class. We consider all operand classes that we don't have a
12794 // specialised diagnostic for to be equal for the propose of this check,
12795 // so that we don't report the generic error multiple times on the same
12796 // operand.
12797 unsigned DupCheckMatchClass = OperandDiag ? I.getOperandClass() : ~0U;
12798 auto PrevReports = OperandMissesSeen.equal_range(I.getOperandIndex());
12799 if (std::any_of(PrevReports.first, PrevReports.second,
12800 [DupCheckMatchClass](
12801 const std::pair<unsigned, unsigned> Pair) {
12802 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12803 return Pair.second == DupCheckMatchClass;
12804 else
12805 return isSubclass((MatchClassKind)DupCheckMatchClass,
12806 (MatchClassKind)Pair.second);
12807 }))
12808 break;
12809 OperandMissesSeen.insert(
12810 std::make_pair(I.getOperandIndex(), DupCheckMatchClass));
12811
12812 NearMissMessage Message;
12813 Message.Loc = OperandLoc;
12814 if (OperandDiag) {
12815 Message.Message = OperandDiag;
12816 } else if (I.getOperandClass() == InvalidMatchClass) {
12817 Message.Message = "too many operands for instruction";
12818 } else {
12819 Message.Message = "invalid operand for instruction";
12820 LLVM_DEBUG(
12821 dbgs() << "Missing diagnostic string for operand class "
12822 << getMatchClassName((MatchClassKind)I.getOperandClass())
12823 << I.getOperandClass() << ", error " << I.getOperandError()
12824 << ", opcode " << MII.getName(I.getOpcode()) << "\n");
12825 }
12826 NearMissesOut.emplace_back(Message);
12827 break;
12828 }
12830 const FeatureBitset &MissingFeatures = I.getFeatures();
12831 // Don't report the same set of features twice.
12832 if (FeatureMissesSeen.count(MissingFeatures))
12833 break;
12834 FeatureMissesSeen.insert(MissingFeatures);
12835
12836 // Special case: don't report a feature set which includes arm-mode for
12837 // targets that don't have ARM mode.
12838 if (MissingFeatures.test(Feature_IsARMBit) && !hasARM())
12839 break;
12840 // Don't report any near-misses that both require switching instruction
12841 // set, and adding other subtarget features.
12842 if (isThumb() && MissingFeatures.test(Feature_IsARMBit) &&
12843 MissingFeatures.count() > 1)
12844 break;
12845 if (!isThumb() && MissingFeatures.test(Feature_IsThumbBit) &&
12846 MissingFeatures.count() > 1)
12847 break;
12848 if (!isThumb() && MissingFeatures.test(Feature_IsThumb2Bit) &&
12849 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12850 Feature_IsThumbBit})).any())
12851 break;
12852 if (isMClass() && MissingFeatures.test(Feature_HasNEONBit))
12853 break;
12854
12855 NearMissMessage Message;
12856 Message.Loc = IDLoc;
12857 raw_svector_ostream OS(Message.Message);
12858
12859 OS << "instruction requires:";
12860 for (unsigned Feature : MissingFeatures)
12861 OS << ' ' << getSubtargetFeatureName(Feature);
12862
12863 NearMissesOut.emplace_back(Message);
12864
12865 break;
12866 }
12868 NearMissMessage Message;
12869 Message.Loc = IDLoc;
12870 switch (I.getPredicateError()) {
12871 case Match_RequiresNotITBlock:
12872 Message.Message = "flag setting instruction only valid outside IT block";
12873 break;
12874 case Match_RequiresITBlock:
12875 Message.Message = "instruction only valid inside IT block";
12876 break;
12877 case Match_RequiresV6:
12878 Message.Message = "instruction variant requires ARMv6 or later";
12879 break;
12880 case Match_RequiresThumb2:
12881 Message.Message = "instruction variant requires Thumb2";
12882 break;
12883 case Match_RequiresV8:
12884 Message.Message = "instruction variant requires ARMv8 or later";
12885 break;
12886 case Match_RequiresFlagSetting:
12887 Message.Message = "no flag-preserving variant of this instruction available";
12888 break;
12889 case Match_InvalidTiedOperand: {
12890 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[0]);
12891 if (Op.isToken() && Op.getToken() == "mul") {
12892 Message.Message = "destination register must match a source register";
12893 Message.Loc = Operands[MnemonicOpsEndInd]->getStartLoc();
12894 } else {
12895 llvm_unreachable("Match_InvalidTiedOperand only used for tMUL.");
12896 }
12897 break;
12898 }
12899 case Match_InvalidOperand:
12900 Message.Message = "invalid operand for instruction";
12901 break;
12902 default:
12903 llvm_unreachable("Unhandled target predicate error");
12904 break;
12905 }
12906 NearMissesOut.emplace_back(Message);
12907 break;
12908 }
12910 if (!ReportedTooFewOperands) {
12911 SMLoc EndLoc = ((ARMOperand &)*Operands.back()).getEndLoc();
12912 NearMissesOut.emplace_back(NearMissMessage{
12913 EndLoc, StringRef("too few operands for instruction")});
12914 ReportedTooFewOperands = true;
12915 }
12916 break;
12917 }
12919 // This should never leave the matcher.
12920 llvm_unreachable("not a near-miss");
12921 break;
12922 }
12923 }
12924}
12925
12926void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
12927 SMLoc IDLoc, OperandVector &Operands) {
12929 FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
12930
12931 if (Messages.size() == 0) {
12932 // No near-misses were found, so the best we can do is "invalid
12933 // instruction".
12934 Error(IDLoc, "invalid instruction");
12935 } else if (Messages.size() == 1) {
12936 // One near miss was found, report it as the sole error.
12937 Error(Messages[0].Loc, Messages[0].Message);
12938 } else {
12939 // More than one near miss, so report a generic "invalid instruction"
12940 // error, followed by notes for each of the near-misses.
12941 Error(IDLoc, "invalid instruction, any one of the following would fix this:");
12942 for (auto &M : Messages) {
12943 Note(M.Loc, M.Message);
12944 }
12945 }
12946}
12947
12948bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
12949 // FIXME: This structure should be moved inside ARMTargetParser
12950 // when we start to table-generate them, and we can use the ARM
12951 // flags below, that were generated by table-gen.
12952 static const struct {
12953 const uint64_t Kind;
12954 const FeatureBitset ArchCheck;
12955 const FeatureBitset Features;
12956 } Extensions[] = {
12957 {ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}},
12958 {ARM::AEK_AES,
12959 {Feature_HasV8Bit},
12960 {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12962 {Feature_HasV8Bit},
12963 {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12965 {Feature_HasV8Bit},
12966 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12968 {Feature_HasV8_1MMainlineBit},
12969 {ARM::HasMVEFloatOps}},
12970 {ARM::AEK_FP,
12971 {Feature_HasV8Bit},
12972 {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12974 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12975 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}},
12976 {ARM::AEK_MP,
12977 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12978 {ARM::FeatureMP}},
12980 {Feature_HasV8Bit},
12981 {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12982 {ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}},
12983 // FIXME: Only available in A-class, isel not predicated
12984 {ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}},
12986 {Feature_HasV8_2aBit},
12987 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
12988 {ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
12989 {ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
12990 {ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI}},
12991 // FIXME: Unsupported extensions.
12992 {ARM::AEK_OS, {}, {}},
12993 {ARM::AEK_IWMMXT, {}, {}},
12994 {ARM::AEK_IWMMXT2, {}, {}},
12995 {ARM::AEK_MAVERICK, {}, {}},
12996 {ARM::AEK_XSCALE, {}, {}},
12997 };
12998 bool EnableFeature = !Name.consume_front_insensitive("no");
13000 if (FeatureKind == ARM::AEK_INVALID)
13001 return Error(ExtLoc, "unknown architectural extension: " + Name);
13002
13003 for (const auto &Extension : Extensions) {
13004 if (Extension.Kind != FeatureKind)
13005 continue;
13006
13007 if (Extension.Features.none())
13008 return Error(ExtLoc, "unsupported architectural extension: " + Name);
13009
13010 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck)
13011 return Error(ExtLoc, "architectural extension '" + Name +
13012 "' is not "
13013 "allowed for the current base architecture");
13014
13015 MCSubtargetInfo &STI = copySTI();
13016 if (EnableFeature) {
13018 } else {
13020 }
13021 FeatureBitset Features = ComputeAvailableFeatures(STI.getFeatureBits());
13022 setAvailableFeatures(Features);
13023 return true;
13024 }
13025 return false;
13026}
13027
13028/// parseDirectiveArchExtension
13029/// ::= .arch_extension [no]feature
13030bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
13031
13032 MCAsmParser &Parser = getParser();
13033
13034 if (getLexer().isNot(AsmToken::Identifier))
13035 return Error(getLexer().getLoc(), "expected architecture extension name");
13036
13037 StringRef Name = Parser.getTok().getString();
13038 SMLoc ExtLoc = Parser.getTok().getLoc();
13039 Lex();
13040
13041 if (parseEOL())
13042 return true;
13043
13044 if (Name == "nocrypto") {
13045 enableArchExtFeature("nosha2", ExtLoc);
13046 enableArchExtFeature("noaes", ExtLoc);
13047 }
13048
13049 if (enableArchExtFeature(Name, ExtLoc))
13050 return false;
13051
13052 return Error(ExtLoc, "unknown architectural extension: " + Name);
13053}
13054
13055// Define this matcher function after the auto-generated include so we
13056// have the match class enum definitions.
13057unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13058 unsigned Kind) {
13059 ARMOperand &Op = static_cast<ARMOperand &>(AsmOp);
13060 // If the kind is a token for a literal immediate, check if our asm
13061 // operand matches. This is for InstAliases which have a fixed-value
13062 // immediate in the syntax.
13063 switch (Kind) {
13064 default: break;
13065 case MCK__HASH_0:
13066 if (Op.isImm())
13067 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13068 if (CE->getValue() == 0)
13069 return Match_Success;
13070 break;
13071 case MCK__HASH_8:
13072 if (Op.isImm())
13073 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13074 if (CE->getValue() == 8)
13075 return Match_Success;
13076 break;
13077 case MCK__HASH_16:
13078 if (Op.isImm())
13079 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13080 if (CE->getValue() == 16)
13081 return Match_Success;
13082 break;
13083 case MCK_ModImm:
13084 if (Op.isImm()) {
13085 const MCExpr *SOExpr = Op.getImm();
13086 int64_t Value;
13087 if (!SOExpr->evaluateAsAbsolute(Value))
13088 return Match_Success;
13089 assert((Value >= std::numeric_limits<int32_t>::min() &&
13090 Value <= std::numeric_limits<uint32_t>::max()) &&
13091 "expression value must be representable in 32 bits");
13092 }
13093 break;
13094 case MCK_rGPR:
13095 if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP)
13096 return Match_Success;
13097 return Match_rGPR;
13098 }
13099 return Match_InvalidOperand;
13100}
13101
13102bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic,
13103 StringRef ExtraToken) {
13104 if (!hasMVE())
13105 return false;
13106
13107 if (MS.isVPTPredicableCDEInstr(Mnemonic) ||
13108 (Mnemonic.starts_with("vldrh") && Mnemonic != "vldrhi") ||
13109 (Mnemonic.starts_with("vmov") &&
13110 !(ExtraToken == ".f16" || ExtraToken == ".32" || ExtraToken == ".16" ||
13111 ExtraToken == ".8")) ||
13112 (Mnemonic.starts_with("vrint") && Mnemonic != "vrintr") ||
13113 (Mnemonic.starts_with("vstrh") && Mnemonic != "vstrhi"))
13114 return true;
13115
13116 const char *predicable_prefixes[] = {
13117 "vabav", "vabd", "vabs", "vadc", "vadd",
13118 "vaddlv", "vaddv", "vand", "vbic", "vbrsr",
13119 "vcadd", "vcls", "vclz", "vcmla", "vcmp",
13120 "vcmul", "vctp", "vcvt", "vddup", "vdup",
13121 "vdwdup", "veor", "vfma", "vfmas", "vfms",
13122 "vhadd", "vhcadd", "vhsub", "vidup", "viwdup",
13123 "vldrb", "vldrd", "vldrw", "vmax", "vmaxa",
13124 "vmaxav", "vmaxnm", "vmaxnma", "vmaxnmav", "vmaxnmv",
13125 "vmaxv", "vmin", "vminav", "vminnm", "vminnmav",
13126 "vminnmv", "vminv", "vmla", "vmladav", "vmlaldav",
13127 "vmlalv", "vmlas", "vmlav", "vmlsdav", "vmlsldav",
13128 "vmovlb", "vmovlt", "vmovnb", "vmovnt", "vmul",
13129 "vmvn", "vneg", "vorn", "vorr", "vpnot",
13130 "vpsel", "vqabs", "vqadd", "vqdmladh", "vqdmlah",
13131 "vqdmlash", "vqdmlsdh", "vqdmulh", "vqdmull", "vqmovn",
13132 "vqmovun", "vqneg", "vqrdmladh", "vqrdmlah", "vqrdmlash",
13133 "vqrdmlsdh", "vqrdmulh", "vqrshl", "vqrshrn", "vqrshrun",
13134 "vqshl", "vqshrn", "vqshrun", "vqsub", "vrev16",
13135 "vrev32", "vrev64", "vrhadd", "vrmlaldavh", "vrmlalvh",
13136 "vrmlsldavh", "vrmulh", "vrshl", "vrshr", "vrshrn",
13137 "vsbc", "vshl", "vshlc", "vshll", "vshr",
13138 "vshrn", "vsli", "vsri", "vstrb", "vstrd",
13139 "vstrw", "vsub"};
13140
13141 return any_of(predicable_prefixes, [&Mnemonic](const char *prefix) {
13142 return Mnemonic.starts_with(prefix);
13143 });
13144}
13145
13146std::unique_ptr<ARMOperand> ARMAsmParser::defaultCondCodeOp() {
13147 return ARMOperand::CreateCondCode(ARMCC::AL, SMLoc(), *this);
13148}
13149
13150std::unique_ptr<ARMOperand> ARMAsmParser::defaultCCOutOp() {
13151 return ARMOperand::CreateCCOut(0, SMLoc(), *this);
13152}
13153
13154std::unique_ptr<ARMOperand> ARMAsmParser::defaultVPTPredOp() {
13155 return ARMOperand::CreateVPTPred(ARMVCC::None, SMLoc(), *this);
13156}
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
unsigned Imm
unsigned uint64_t
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing)
static bool instIsBreakpoint(const MCInst &Inst)
unsigned findCCOutInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
static bool isDataTypeToken(StringRef Tok)
}
static MCRegister getNextRegister(MCRegister Reg)
static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing)
unsigned getRegListInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
static bool isVectorPredicable(const MCInstrDesc &MCID)
static bool listContainsReg(const MCInst &Inst, unsigned OpNo, MCRegister Reg)
static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp)
MatchCoprocessorOperandName - Try to parse an coprocessor related instruction with a symbolic operand...
void removeCCOut(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo, MCRegister Reg, MCRegister HiReg, bool &containsReg)
static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMAsmParser()
Force static initialization.
static int findFirstVectorPredOperandIdx(const MCInstrDesc &MCID)
static bool isThumbI8Relocation(MCParsedAsmOperand &MCOp)
bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd)
void removeCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool insertNoDuplicates(SmallVectorImpl< std::pair< unsigned, MCRegister > > &Regs, unsigned Enc, MCRegister Reg)
static unsigned getMnemonicOpsEndInd(const OperandVector &Operands)
static bool isARMMCExpr(MCParsedAsmOperand &MCOp)
unsigned findCondCodeInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
void removeVPTCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool isThumb(const MCSubtargetInfo &STI)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static cl::opt< bool > AddBuildAttributes("csky-add-build-attributes", cl::init(true))
static Register getFPReg(const CSKYSubtarget &STI)
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
#define op(i)
Value * getPointer(Value *Ptr)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
#define I(x, y, z)
Definition MD5.cpp:57
static bool containsReg(SmallSetVector< Register, 32 > LocalDefsV, const BitVector &LocalDefsP, Register Reg, const TargetRegisterInfo *TRI)
Check if target reg is contained in given lists, which are: LocalDefsV as given list for virtual regs...
Register Reg
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t High
#define P(N)
static constexpr MCPhysReg FPReg
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI Fold Operands
SI Pre allocate WWM Registers
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
const char * Msg
static cl::opt< ExtensionSet, false, SPIRVExtensionsParser > Extensions("spirv-ext", cl::desc("Specify list of enabled SPIR-V extensions"))
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
This file implements the SmallBitVector class.
This file defines the SmallSet class.
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
Definition AsmLexer.h:122
LLVM_ABI SMLoc getLoc() const
Definition AsmLexer.cpp:31
int64_t getIntVal() const
Definition MCAsmMacro.h:108
bool isNot(TokenKind K) const
Definition MCAsmMacro.h:76
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition MCAsmMacro.h:103
StringRef getStringContents() const
Get the contents of a string token (without quotes).
Definition MCAsmMacro.h:83
bool is(TokenKind K) const
Definition MCAsmMacro.h:75
LLVM_ABI SMLoc getEndLoc() const
Definition AsmLexer.cpp:33
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Definition MCAsmMacro.h:92
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Base class for user error types.
Definition Error.h:354
Container class for subtarget features.
constexpr bool test(unsigned I) const
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Generic assembler parser interface, for use by target specific assembly parsers.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual void Note(SMLoc L, const Twine &Msg, SMRange Range={})=0
Emit a note at the location L, with the message Msg.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:342
int64_t getValue() const
Definition MCExpr.h:171
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
@ Constant
Constant expressions.
Definition MCExpr.h:42
SMLoc getLoc() const
Definition MCExpr.h:86
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getNumOperands() const
Definition MCInst.h:212
void setLoc(SMLoc loc)
Definition MCInst.h:207
unsigned getOpcode() const
Definition MCInst.h:202
LLVM_ABI void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCContext *Ctx=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Definition MCInst.cpp:90
iterator insert(iterator I, const MCOperand &Op)
Definition MCInst.h:232
void addOperand(const MCOperand Op)
Definition MCInst.h:215
iterator begin()
Definition MCInst.h:227
void setOpcode(unsigned Op)
Definition MCInst.h:201
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool isIndirectBranch() const
Return true if this is an indirect branch, such as a branch through a register.
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
LLVM_ABI bool hasDefOfPhysReg(const MCInst &MI, MCRegister Reg, const MCRegisterInfo &RI) const
Return true if this instruction defines the specified physical register, either explicitly or implici...
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
bool isReturn() const
Return true if the instruction is a return.
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getID() const
getID() - Return the register class ID number.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
constexpr unsigned id() const
Definition MCRegister.h:82
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Definition MCStreamer.h:336
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
const FeatureBitset & ApplyFeatureFlag(StringRef FS)
Apply a feature flag and return the re-computed feature bits, including all feature bits implied by t...
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Target specific streamer interface.
Definition MCStreamer.h:95
MCStreamer & getStreamer()
Definition MCStreamer.h:103
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
Definition SMLoc.h:22
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:35
constexpr const char * getPointer() const
Definition SMLoc.h:33
Represents a range in source code.
Definition SMLoc.h:47
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:128
iterator end()
Definition StringMap.h:213
iterator find(StringRef Key)
Definition StringMap.h:226
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition StringMap.h:274
void erase(iterator I)
Definition StringMap.h:417
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition StringMap.h:310
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static constexpr size_t npos
Definition StringRef.h:58
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:720
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:270
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Definition StringRef.h:170
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition StringSet.h:25
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition StringSet.h:39
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
LLVM_ABI const TagNameMap & getARMAttributeTags()
static CondCodes getOppositeCondition(CondCodes CC)
Definition ARMBaseInfo.h:49
@ ThumbArithFlagSetting
unsigned getSORegOffset(unsigned Op)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
unsigned encodeNEONi16splat(unsigned Value)
float getFPImmFloat(unsigned Imm)
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset)
getAM5Opc - This function encodes the addrmode5 opc field.
ShiftOpc getSORegShOp(unsigned Op)
bool isNEONi16splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
unsigned getAM5FP16Opc(AddrOpc Opc, unsigned char Offset)
getAM5FP16Opc - This function encodes the addrmode5fp16 opc field.
unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
bool isNEONi32splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
StringRef getShiftOpcStr(ShiftOpc Op)
unsigned encodeNEONi32splat(unsigned Value)
Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR.
static const char * IFlagsToString(unsigned val)
Definition ARMBaseInfo.h:37
LLVM_ABI bool getFPUFeatures(FPUKind FPUKind, std::vector< StringRef > &Features)
LLVM_ABI StringRef getArchName(ArchKind AK)
LLVM_ABI uint64_t parseArchExt(StringRef ArchExt)
LLVM_ABI ArchKind parseArch(StringRef Arch)
bool isVpred(OperandType op)
uint16_t Specifier
LLVM_ABI FPUKind parseFPU(StringRef FPU)
bool isCDECoproc(size_t Coproc, const MCSubtargetInfo &STI)
@ D16
Only 16 D registers.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Entry
Definition COFF.h:862
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:51
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Definition Threading.h:280
static const char * ARMVPTPredToString(ARMVCC::VPTCodes CC)
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
constexpr T rotr(T V, int R)
Definition bit.h:399
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
@ Load
The value being inserted comes from a load (InsertElement only).
Target & getTheThumbBETarget()
static unsigned ARMCondCodeFromString(StringRef CC)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:156
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition STLExtras.h:1970
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
bool IsCPSRDead< MCInst >(const MCInst *Instr)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
static bool isValidCoprocessorNumber(unsigned Num, const FeatureBitset &featureBits)
isValidCoprocessorNumber - decide whether an explicit coprocessor number is legal in generic instruct...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
static unsigned ARMVectorCondCodeFromString(StringRef CC)
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
@ Always
Always emit .debug_str_offsets talbes as DWARF64 for testing.
Definition DWP.h:32
Target & getTheARMLETarget()
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...