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 = (cast<MCConstantExpr>(SubExprVal))->getValue();
9305 bool UseMov = true;
9306 bool MovHasS = true;
9307 if (Inst.getOpcode() == ARM::LDRConstPool) {
9308 // ARM Constant
9309 if (ARM_AM::getSOImmVal(Value) != -1) {
9311 TmpInst.setOpcode(ARM::MOVi);
9312 }
9313 else if (ARM_AM::getSOImmVal(~Value) != -1) {
9315 TmpInst.setOpcode(ARM::MVNi);
9316 }
9317 else if (hasV6T2Ops() &&
9318 Value >=0 && Value < 65536) {
9319 TmpInst.setOpcode(ARM::MOVi16);
9320 MovHasS = false;
9321 }
9322 else
9323 UseMov = false;
9324 }
9325 else {
9326 // Thumb/Thumb2 Constant
9327 if (hasThumb2() &&
9329 TmpInst.setOpcode(ARM::t2MOVi);
9330 else if (hasThumb2() &&
9331 ARM_AM::getT2SOImmVal(~Value) != -1) {
9332 TmpInst.setOpcode(ARM::t2MVNi);
9333 Value = ~Value;
9334 }
9335 else if (hasV8MBaseline() &&
9336 Value >=0 && Value < 65536) {
9337 TmpInst.setOpcode(ARM::t2MOVi16);
9338 MovHasS = false;
9339 }
9340 else
9341 UseMov = false;
9342 }
9343 if (UseMov) {
9344 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9345 TmpInst.addOperand(MCOperand::createImm(Value)); // Immediate
9346 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9347 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9348 if (MovHasS)
9349 TmpInst.addOperand(MCOperand::createReg(0)); // S
9350 Inst = TmpInst;
9351 return true;
9352 }
9353 }
9354 // No opportunity to use MOV/MVN create constant pool
9355 const MCExpr *CPLoc =
9356 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9357 PoolOperand.getStartLoc());
9358 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9359 TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool
9360 if (TmpInst.getOpcode() == ARM::LDRi12)
9361 TmpInst.addOperand(MCOperand::createImm(0)); // unused offset
9362 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9363 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9364 Inst = TmpInst;
9365 return true;
9366 }
9367 // Handle NEON VST complex aliases.
9368 case ARM::VST1LNdWB_register_Asm_8:
9369 case ARM::VST1LNdWB_register_Asm_16:
9370 case ARM::VST1LNdWB_register_Asm_32: {
9371 MCInst TmpInst;
9372 // Shuffle the operands around so the lane index operand is in the
9373 // right place.
9374 unsigned Spacing;
9375 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9376 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9377 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9378 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9379 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9380 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9381 TmpInst.addOperand(Inst.getOperand(1)); // lane
9382 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9383 TmpInst.addOperand(Inst.getOperand(6));
9384 Inst = TmpInst;
9385 return true;
9386 }
9387
9388 case ARM::VST2LNdWB_register_Asm_8:
9389 case ARM::VST2LNdWB_register_Asm_16:
9390 case ARM::VST2LNdWB_register_Asm_32:
9391 case ARM::VST2LNqWB_register_Asm_16:
9392 case ARM::VST2LNqWB_register_Asm_32: {
9393 MCInst TmpInst;
9394 // Shuffle the operands around so the lane index operand is in the
9395 // right place.
9396 unsigned Spacing;
9397 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9398 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9399 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9400 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9401 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9402 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9404 Spacing));
9405 TmpInst.addOperand(Inst.getOperand(1)); // lane
9406 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9407 TmpInst.addOperand(Inst.getOperand(6));
9408 Inst = TmpInst;
9409 return true;
9410 }
9411
9412 case ARM::VST3LNdWB_register_Asm_8:
9413 case ARM::VST3LNdWB_register_Asm_16:
9414 case ARM::VST3LNdWB_register_Asm_32:
9415 case ARM::VST3LNqWB_register_Asm_16:
9416 case ARM::VST3LNqWB_register_Asm_32: {
9417 MCInst TmpInst;
9418 // Shuffle the operands around so the lane index operand is in the
9419 // right place.
9420 unsigned Spacing;
9421 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9422 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9423 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9424 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9425 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9426 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9428 Spacing));
9430 Spacing * 2));
9431 TmpInst.addOperand(Inst.getOperand(1)); // lane
9432 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9433 TmpInst.addOperand(Inst.getOperand(6));
9434 Inst = TmpInst;
9435 return true;
9436 }
9437
9438 case ARM::VST4LNdWB_register_Asm_8:
9439 case ARM::VST4LNdWB_register_Asm_16:
9440 case ARM::VST4LNdWB_register_Asm_32:
9441 case ARM::VST4LNqWB_register_Asm_16:
9442 case ARM::VST4LNqWB_register_Asm_32: {
9443 MCInst TmpInst;
9444 // Shuffle the operands around so the lane index operand is in the
9445 // right place.
9446 unsigned Spacing;
9447 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9448 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9449 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9450 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9451 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9452 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9454 Spacing));
9456 Spacing * 2));
9458 Spacing * 3));
9459 TmpInst.addOperand(Inst.getOperand(1)); // lane
9460 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9461 TmpInst.addOperand(Inst.getOperand(6));
9462 Inst = TmpInst;
9463 return true;
9464 }
9465
9466 case ARM::VST1LNdWB_fixed_Asm_8:
9467 case ARM::VST1LNdWB_fixed_Asm_16:
9468 case ARM::VST1LNdWB_fixed_Asm_32: {
9469 MCInst TmpInst;
9470 // Shuffle the operands around so the lane index operand is in the
9471 // right place.
9472 unsigned Spacing;
9473 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9474 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9475 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9476 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9477 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9478 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9479 TmpInst.addOperand(Inst.getOperand(1)); // lane
9480 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9481 TmpInst.addOperand(Inst.getOperand(5));
9482 Inst = TmpInst;
9483 return true;
9484 }
9485
9486 case ARM::VST2LNdWB_fixed_Asm_8:
9487 case ARM::VST2LNdWB_fixed_Asm_16:
9488 case ARM::VST2LNdWB_fixed_Asm_32:
9489 case ARM::VST2LNqWB_fixed_Asm_16:
9490 case ARM::VST2LNqWB_fixed_Asm_32: {
9491 MCInst TmpInst;
9492 // Shuffle the operands around so the lane index operand is in the
9493 // right place.
9494 unsigned Spacing;
9495 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9496 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9497 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9498 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9499 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9500 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9502 Spacing));
9503 TmpInst.addOperand(Inst.getOperand(1)); // lane
9504 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9505 TmpInst.addOperand(Inst.getOperand(5));
9506 Inst = TmpInst;
9507 return true;
9508 }
9509
9510 case ARM::VST3LNdWB_fixed_Asm_8:
9511 case ARM::VST3LNdWB_fixed_Asm_16:
9512 case ARM::VST3LNdWB_fixed_Asm_32:
9513 case ARM::VST3LNqWB_fixed_Asm_16:
9514 case ARM::VST3LNqWB_fixed_Asm_32: {
9515 MCInst TmpInst;
9516 // Shuffle the operands around so the lane index operand is in the
9517 // right place.
9518 unsigned Spacing;
9519 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9520 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9521 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9522 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9523 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9524 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9526 Spacing));
9528 Spacing * 2));
9529 TmpInst.addOperand(Inst.getOperand(1)); // lane
9530 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9531 TmpInst.addOperand(Inst.getOperand(5));
9532 Inst = TmpInst;
9533 return true;
9534 }
9535
9536 case ARM::VST4LNdWB_fixed_Asm_8:
9537 case ARM::VST4LNdWB_fixed_Asm_16:
9538 case ARM::VST4LNdWB_fixed_Asm_32:
9539 case ARM::VST4LNqWB_fixed_Asm_16:
9540 case ARM::VST4LNqWB_fixed_Asm_32: {
9541 MCInst TmpInst;
9542 // Shuffle the operands around so the lane index operand is in the
9543 // right place.
9544 unsigned Spacing;
9545 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9546 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9547 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9548 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9549 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9550 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9552 Spacing));
9554 Spacing * 2));
9556 Spacing * 3));
9557 TmpInst.addOperand(Inst.getOperand(1)); // lane
9558 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9559 TmpInst.addOperand(Inst.getOperand(5));
9560 Inst = TmpInst;
9561 return true;
9562 }
9563
9564 case ARM::VST1LNdAsm_8:
9565 case ARM::VST1LNdAsm_16:
9566 case ARM::VST1LNdAsm_32: {
9567 MCInst TmpInst;
9568 // Shuffle the operands around so the lane index operand is in the
9569 // right place.
9570 unsigned Spacing;
9571 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9572 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9573 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9574 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9575 TmpInst.addOperand(Inst.getOperand(1)); // lane
9576 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9577 TmpInst.addOperand(Inst.getOperand(5));
9578 Inst = TmpInst;
9579 return true;
9580 }
9581
9582 case ARM::VST2LNdAsm_8:
9583 case ARM::VST2LNdAsm_16:
9584 case ARM::VST2LNdAsm_32:
9585 case ARM::VST2LNqAsm_16:
9586 case ARM::VST2LNqAsm_32: {
9587 MCInst TmpInst;
9588 // Shuffle the operands around so the lane index operand is in the
9589 // right place.
9590 unsigned Spacing;
9591 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9592 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9593 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9594 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9596 Spacing));
9597 TmpInst.addOperand(Inst.getOperand(1)); // lane
9598 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9599 TmpInst.addOperand(Inst.getOperand(5));
9600 Inst = TmpInst;
9601 return true;
9602 }
9603
9604 case ARM::VST3LNdAsm_8:
9605 case ARM::VST3LNdAsm_16:
9606 case ARM::VST3LNdAsm_32:
9607 case ARM::VST3LNqAsm_16:
9608 case ARM::VST3LNqAsm_32: {
9609 MCInst TmpInst;
9610 // Shuffle the operands around so the lane index operand is in the
9611 // right place.
9612 unsigned Spacing;
9613 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9614 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9615 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9616 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9618 Spacing));
9620 Spacing * 2));
9621 TmpInst.addOperand(Inst.getOperand(1)); // lane
9622 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9623 TmpInst.addOperand(Inst.getOperand(5));
9624 Inst = TmpInst;
9625 return true;
9626 }
9627
9628 case ARM::VST4LNdAsm_8:
9629 case ARM::VST4LNdAsm_16:
9630 case ARM::VST4LNdAsm_32:
9631 case ARM::VST4LNqAsm_16:
9632 case ARM::VST4LNqAsm_32: {
9633 MCInst TmpInst;
9634 // Shuffle the operands around so the lane index operand is in the
9635 // right place.
9636 unsigned Spacing;
9637 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9638 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9639 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9640 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9642 Spacing));
9644 Spacing * 2));
9646 Spacing * 3));
9647 TmpInst.addOperand(Inst.getOperand(1)); // lane
9648 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9649 TmpInst.addOperand(Inst.getOperand(5));
9650 Inst = TmpInst;
9651 return true;
9652 }
9653
9654 // Handle NEON VLD complex aliases.
9655 case ARM::VLD1LNdWB_register_Asm_8:
9656 case ARM::VLD1LNdWB_register_Asm_16:
9657 case ARM::VLD1LNdWB_register_Asm_32: {
9658 MCInst TmpInst;
9659 // Shuffle the operands around so the lane index operand is in the
9660 // right place.
9661 unsigned Spacing;
9662 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9663 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9664 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9665 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9666 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9667 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9668 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9669 TmpInst.addOperand(Inst.getOperand(1)); // lane
9670 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9671 TmpInst.addOperand(Inst.getOperand(6));
9672 Inst = TmpInst;
9673 return true;
9674 }
9675
9676 case ARM::VLD2LNdWB_register_Asm_8:
9677 case ARM::VLD2LNdWB_register_Asm_16:
9678 case ARM::VLD2LNdWB_register_Asm_32:
9679 case ARM::VLD2LNqWB_register_Asm_16:
9680 case ARM::VLD2LNqWB_register_Asm_32: {
9681 MCInst TmpInst;
9682 // Shuffle the operands around so the lane index operand is in the
9683 // right place.
9684 unsigned Spacing;
9685 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9686 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9688 Spacing));
9689 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9690 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9691 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9692 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9693 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9695 Spacing));
9696 TmpInst.addOperand(Inst.getOperand(1)); // lane
9697 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9698 TmpInst.addOperand(Inst.getOperand(6));
9699 Inst = TmpInst;
9700 return true;
9701 }
9702
9703 case ARM::VLD3LNdWB_register_Asm_8:
9704 case ARM::VLD3LNdWB_register_Asm_16:
9705 case ARM::VLD3LNdWB_register_Asm_32:
9706 case ARM::VLD3LNqWB_register_Asm_16:
9707 case ARM::VLD3LNqWB_register_Asm_32: {
9708 MCInst TmpInst;
9709 // Shuffle the operands around so the lane index operand is in the
9710 // right place.
9711 unsigned Spacing;
9712 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9713 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9715 Spacing));
9717 Spacing * 2));
9718 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9719 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9720 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9721 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9722 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9724 Spacing));
9726 Spacing * 2));
9727 TmpInst.addOperand(Inst.getOperand(1)); // lane
9728 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9729 TmpInst.addOperand(Inst.getOperand(6));
9730 Inst = TmpInst;
9731 return true;
9732 }
9733
9734 case ARM::VLD4LNdWB_register_Asm_8:
9735 case ARM::VLD4LNdWB_register_Asm_16:
9736 case ARM::VLD4LNdWB_register_Asm_32:
9737 case ARM::VLD4LNqWB_register_Asm_16:
9738 case ARM::VLD4LNqWB_register_Asm_32: {
9739 MCInst TmpInst;
9740 // Shuffle the operands around so the lane index operand is in the
9741 // right place.
9742 unsigned Spacing;
9743 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9744 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9746 Spacing));
9748 Spacing * 2));
9750 Spacing * 3));
9751 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9752 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9753 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9754 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9755 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9757 Spacing));
9759 Spacing * 2));
9761 Spacing * 3));
9762 TmpInst.addOperand(Inst.getOperand(1)); // lane
9763 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9764 TmpInst.addOperand(Inst.getOperand(6));
9765 Inst = TmpInst;
9766 return true;
9767 }
9768
9769 case ARM::VLD1LNdWB_fixed_Asm_8:
9770 case ARM::VLD1LNdWB_fixed_Asm_16:
9771 case ARM::VLD1LNdWB_fixed_Asm_32: {
9772 MCInst TmpInst;
9773 // Shuffle the operands around so the lane index operand is in the
9774 // right place.
9775 unsigned Spacing;
9776 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9777 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9778 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9779 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9780 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9781 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9782 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9783 TmpInst.addOperand(Inst.getOperand(1)); // lane
9784 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9785 TmpInst.addOperand(Inst.getOperand(5));
9786 Inst = TmpInst;
9787 return true;
9788 }
9789
9790 case ARM::VLD2LNdWB_fixed_Asm_8:
9791 case ARM::VLD2LNdWB_fixed_Asm_16:
9792 case ARM::VLD2LNdWB_fixed_Asm_32:
9793 case ARM::VLD2LNqWB_fixed_Asm_16:
9794 case ARM::VLD2LNqWB_fixed_Asm_32: {
9795 MCInst TmpInst;
9796 // Shuffle the operands around so the lane index operand is in the
9797 // right place.
9798 unsigned Spacing;
9799 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9800 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9802 Spacing));
9803 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9804 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9805 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9806 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9807 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9809 Spacing));
9810 TmpInst.addOperand(Inst.getOperand(1)); // lane
9811 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9812 TmpInst.addOperand(Inst.getOperand(5));
9813 Inst = TmpInst;
9814 return true;
9815 }
9816
9817 case ARM::VLD3LNdWB_fixed_Asm_8:
9818 case ARM::VLD3LNdWB_fixed_Asm_16:
9819 case ARM::VLD3LNdWB_fixed_Asm_32:
9820 case ARM::VLD3LNqWB_fixed_Asm_16:
9821 case ARM::VLD3LNqWB_fixed_Asm_32: {
9822 MCInst TmpInst;
9823 // Shuffle the operands around so the lane index operand is in the
9824 // right place.
9825 unsigned Spacing;
9826 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9827 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9829 Spacing));
9831 Spacing * 2));
9832 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9833 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9834 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9835 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9836 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9838 Spacing));
9840 Spacing * 2));
9841 TmpInst.addOperand(Inst.getOperand(1)); // lane
9842 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9843 TmpInst.addOperand(Inst.getOperand(5));
9844 Inst = TmpInst;
9845 return true;
9846 }
9847
9848 case ARM::VLD4LNdWB_fixed_Asm_8:
9849 case ARM::VLD4LNdWB_fixed_Asm_16:
9850 case ARM::VLD4LNdWB_fixed_Asm_32:
9851 case ARM::VLD4LNqWB_fixed_Asm_16:
9852 case ARM::VLD4LNqWB_fixed_Asm_32: {
9853 MCInst TmpInst;
9854 // Shuffle the operands around so the lane index operand is in the
9855 // right place.
9856 unsigned Spacing;
9857 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9858 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9860 Spacing));
9862 Spacing * 2));
9864 Spacing * 3));
9865 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9866 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9867 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9868 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9869 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9871 Spacing));
9873 Spacing * 2));
9875 Spacing * 3));
9876 TmpInst.addOperand(Inst.getOperand(1)); // lane
9877 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9878 TmpInst.addOperand(Inst.getOperand(5));
9879 Inst = TmpInst;
9880 return true;
9881 }
9882
9883 case ARM::VLD1LNdAsm_8:
9884 case ARM::VLD1LNdAsm_16:
9885 case ARM::VLD1LNdAsm_32: {
9886 MCInst TmpInst;
9887 // Shuffle the operands around so the lane index operand is in the
9888 // right place.
9889 unsigned Spacing;
9890 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9891 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9892 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9893 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9894 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9895 TmpInst.addOperand(Inst.getOperand(1)); // lane
9896 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9897 TmpInst.addOperand(Inst.getOperand(5));
9898 Inst = TmpInst;
9899 return true;
9900 }
9901
9902 case ARM::VLD2LNdAsm_8:
9903 case ARM::VLD2LNdAsm_16:
9904 case ARM::VLD2LNdAsm_32:
9905 case ARM::VLD2LNqAsm_16:
9906 case ARM::VLD2LNqAsm_32: {
9907 MCInst TmpInst;
9908 // Shuffle the operands around so the lane index operand is in the
9909 // right place.
9910 unsigned Spacing;
9911 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9912 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9914 Spacing));
9915 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9916 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9917 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9919 Spacing));
9920 TmpInst.addOperand(Inst.getOperand(1)); // lane
9921 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9922 TmpInst.addOperand(Inst.getOperand(5));
9923 Inst = TmpInst;
9924 return true;
9925 }
9926
9927 case ARM::VLD3LNdAsm_8:
9928 case ARM::VLD3LNdAsm_16:
9929 case ARM::VLD3LNdAsm_32:
9930 case ARM::VLD3LNqAsm_16:
9931 case ARM::VLD3LNqAsm_32: {
9932 MCInst TmpInst;
9933 // Shuffle the operands around so the lane index operand is in the
9934 // right place.
9935 unsigned Spacing;
9936 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9937 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9939 Spacing));
9941 Spacing * 2));
9942 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9943 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9944 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9946 Spacing));
9948 Spacing * 2));
9949 TmpInst.addOperand(Inst.getOperand(1)); // lane
9950 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9951 TmpInst.addOperand(Inst.getOperand(5));
9952 Inst = TmpInst;
9953 return true;
9954 }
9955
9956 case ARM::VLD4LNdAsm_8:
9957 case ARM::VLD4LNdAsm_16:
9958 case ARM::VLD4LNdAsm_32:
9959 case ARM::VLD4LNqAsm_16:
9960 case ARM::VLD4LNqAsm_32: {
9961 MCInst TmpInst;
9962 // Shuffle the operands around so the lane index operand is in the
9963 // right place.
9964 unsigned Spacing;
9965 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9966 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9968 Spacing));
9970 Spacing * 2));
9972 Spacing * 3));
9973 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9974 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9975 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9977 Spacing));
9979 Spacing * 2));
9981 Spacing * 3));
9982 TmpInst.addOperand(Inst.getOperand(1)); // lane
9983 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9984 TmpInst.addOperand(Inst.getOperand(5));
9985 Inst = TmpInst;
9986 return true;
9987 }
9988
9989 // VLD3DUP single 3-element structure to all lanes instructions.
9990 case ARM::VLD3DUPdAsm_8:
9991 case ARM::VLD3DUPdAsm_16:
9992 case ARM::VLD3DUPdAsm_32:
9993 case ARM::VLD3DUPqAsm_8:
9994 case ARM::VLD3DUPqAsm_16:
9995 case ARM::VLD3DUPqAsm_32: {
9996 MCInst TmpInst;
9997 unsigned Spacing;
9998 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9999 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10001 Spacing));
10003 Spacing * 2));
10004 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10005 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10006 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10007 TmpInst.addOperand(Inst.getOperand(4));
10008 Inst = TmpInst;
10009 return true;
10010 }
10011
10012 case ARM::VLD3DUPdWB_fixed_Asm_8:
10013 case ARM::VLD3DUPdWB_fixed_Asm_16:
10014 case ARM::VLD3DUPdWB_fixed_Asm_32:
10015 case ARM::VLD3DUPqWB_fixed_Asm_8:
10016 case ARM::VLD3DUPqWB_fixed_Asm_16:
10017 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10018 MCInst TmpInst;
10019 unsigned Spacing;
10020 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10021 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10023 Spacing));
10025 Spacing * 2));
10026 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10027 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10028 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10029 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10030 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10031 TmpInst.addOperand(Inst.getOperand(4));
10032 Inst = TmpInst;
10033 return true;
10034 }
10035
10036 case ARM::VLD3DUPdWB_register_Asm_8:
10037 case ARM::VLD3DUPdWB_register_Asm_16:
10038 case ARM::VLD3DUPdWB_register_Asm_32:
10039 case ARM::VLD3DUPqWB_register_Asm_8:
10040 case ARM::VLD3DUPqWB_register_Asm_16:
10041 case ARM::VLD3DUPqWB_register_Asm_32: {
10042 MCInst TmpInst;
10043 unsigned Spacing;
10044 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10045 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10047 Spacing));
10049 Spacing * 2));
10050 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10051 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10052 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10053 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10054 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10055 TmpInst.addOperand(Inst.getOperand(5));
10056 Inst = TmpInst;
10057 return true;
10058 }
10059
10060 // VLD3 multiple 3-element structure instructions.
10061 case ARM::VLD3dAsm_8:
10062 case ARM::VLD3dAsm_16:
10063 case ARM::VLD3dAsm_32:
10064 case ARM::VLD3qAsm_8:
10065 case ARM::VLD3qAsm_16:
10066 case ARM::VLD3qAsm_32: {
10067 MCInst TmpInst;
10068 unsigned Spacing;
10069 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10070 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10072 Spacing));
10074 Spacing * 2));
10075 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10076 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10077 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10078 TmpInst.addOperand(Inst.getOperand(4));
10079 Inst = TmpInst;
10080 return true;
10081 }
10082
10083 case ARM::VLD3dWB_fixed_Asm_8:
10084 case ARM::VLD3dWB_fixed_Asm_16:
10085 case ARM::VLD3dWB_fixed_Asm_32:
10086 case ARM::VLD3qWB_fixed_Asm_8:
10087 case ARM::VLD3qWB_fixed_Asm_16:
10088 case ARM::VLD3qWB_fixed_Asm_32: {
10089 MCInst TmpInst;
10090 unsigned Spacing;
10091 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10092 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10094 Spacing));
10096 Spacing * 2));
10097 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10098 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10099 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10100 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10101 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10102 TmpInst.addOperand(Inst.getOperand(4));
10103 Inst = TmpInst;
10104 return true;
10105 }
10106
10107 case ARM::VLD3dWB_register_Asm_8:
10108 case ARM::VLD3dWB_register_Asm_16:
10109 case ARM::VLD3dWB_register_Asm_32:
10110 case ARM::VLD3qWB_register_Asm_8:
10111 case ARM::VLD3qWB_register_Asm_16:
10112 case ARM::VLD3qWB_register_Asm_32: {
10113 MCInst TmpInst;
10114 unsigned Spacing;
10115 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10116 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10118 Spacing));
10120 Spacing * 2));
10121 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10122 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10123 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10124 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10125 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10126 TmpInst.addOperand(Inst.getOperand(5));
10127 Inst = TmpInst;
10128 return true;
10129 }
10130
10131 // VLD4DUP single 3-element structure to all lanes instructions.
10132 case ARM::VLD4DUPdAsm_8:
10133 case ARM::VLD4DUPdAsm_16:
10134 case ARM::VLD4DUPdAsm_32:
10135 case ARM::VLD4DUPqAsm_8:
10136 case ARM::VLD4DUPqAsm_16:
10137 case ARM::VLD4DUPqAsm_32: {
10138 MCInst TmpInst;
10139 unsigned Spacing;
10140 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10141 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10143 Spacing));
10145 Spacing * 2));
10147 Spacing * 3));
10148 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10149 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10150 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10151 TmpInst.addOperand(Inst.getOperand(4));
10152 Inst = TmpInst;
10153 return true;
10154 }
10155
10156 case ARM::VLD4DUPdWB_fixed_Asm_8:
10157 case ARM::VLD4DUPdWB_fixed_Asm_16:
10158 case ARM::VLD4DUPdWB_fixed_Asm_32:
10159 case ARM::VLD4DUPqWB_fixed_Asm_8:
10160 case ARM::VLD4DUPqWB_fixed_Asm_16:
10161 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10162 MCInst TmpInst;
10163 unsigned Spacing;
10164 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10165 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10167 Spacing));
10169 Spacing * 2));
10171 Spacing * 3));
10172 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10173 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10174 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10175 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10176 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10177 TmpInst.addOperand(Inst.getOperand(4));
10178 Inst = TmpInst;
10179 return true;
10180 }
10181
10182 case ARM::VLD4DUPdWB_register_Asm_8:
10183 case ARM::VLD4DUPdWB_register_Asm_16:
10184 case ARM::VLD4DUPdWB_register_Asm_32:
10185 case ARM::VLD4DUPqWB_register_Asm_8:
10186 case ARM::VLD4DUPqWB_register_Asm_16:
10187 case ARM::VLD4DUPqWB_register_Asm_32: {
10188 MCInst TmpInst;
10189 unsigned Spacing;
10190 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10191 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10193 Spacing));
10195 Spacing * 2));
10197 Spacing * 3));
10198 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10199 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10200 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10201 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10202 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10203 TmpInst.addOperand(Inst.getOperand(5));
10204 Inst = TmpInst;
10205 return true;
10206 }
10207
10208 // VLD4 multiple 4-element structure instructions.
10209 case ARM::VLD4dAsm_8:
10210 case ARM::VLD4dAsm_16:
10211 case ARM::VLD4dAsm_32:
10212 case ARM::VLD4qAsm_8:
10213 case ARM::VLD4qAsm_16:
10214 case ARM::VLD4qAsm_32: {
10215 MCInst TmpInst;
10216 unsigned Spacing;
10217 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10218 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10220 Spacing));
10222 Spacing * 2));
10224 Spacing * 3));
10225 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10226 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10227 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10228 TmpInst.addOperand(Inst.getOperand(4));
10229 Inst = TmpInst;
10230 return true;
10231 }
10232
10233 case ARM::VLD4dWB_fixed_Asm_8:
10234 case ARM::VLD4dWB_fixed_Asm_16:
10235 case ARM::VLD4dWB_fixed_Asm_32:
10236 case ARM::VLD4qWB_fixed_Asm_8:
10237 case ARM::VLD4qWB_fixed_Asm_16:
10238 case ARM::VLD4qWB_fixed_Asm_32: {
10239 MCInst TmpInst;
10240 unsigned Spacing;
10241 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10242 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10244 Spacing));
10246 Spacing * 2));
10248 Spacing * 3));
10249 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10250 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10251 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10252 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10253 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10254 TmpInst.addOperand(Inst.getOperand(4));
10255 Inst = TmpInst;
10256 return true;
10257 }
10258
10259 case ARM::VLD4dWB_register_Asm_8:
10260 case ARM::VLD4dWB_register_Asm_16:
10261 case ARM::VLD4dWB_register_Asm_32:
10262 case ARM::VLD4qWB_register_Asm_8:
10263 case ARM::VLD4qWB_register_Asm_16:
10264 case ARM::VLD4qWB_register_Asm_32: {
10265 MCInst TmpInst;
10266 unsigned Spacing;
10267 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10268 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10270 Spacing));
10272 Spacing * 2));
10274 Spacing * 3));
10275 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10276 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10277 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10278 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10279 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10280 TmpInst.addOperand(Inst.getOperand(5));
10281 Inst = TmpInst;
10282 return true;
10283 }
10284
10285 // VST3 multiple 3-element structure instructions.
10286 case ARM::VST3dAsm_8:
10287 case ARM::VST3dAsm_16:
10288 case ARM::VST3dAsm_32:
10289 case ARM::VST3qAsm_8:
10290 case ARM::VST3qAsm_16:
10291 case ARM::VST3qAsm_32: {
10292 MCInst TmpInst;
10293 unsigned Spacing;
10294 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10295 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10296 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10297 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10299 Spacing));
10301 Spacing * 2));
10302 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10303 TmpInst.addOperand(Inst.getOperand(4));
10304 Inst = TmpInst;
10305 return true;
10306 }
10307
10308 case ARM::VST3dWB_fixed_Asm_8:
10309 case ARM::VST3dWB_fixed_Asm_16:
10310 case ARM::VST3dWB_fixed_Asm_32:
10311 case ARM::VST3qWB_fixed_Asm_8:
10312 case ARM::VST3qWB_fixed_Asm_16:
10313 case ARM::VST3qWB_fixed_Asm_32: {
10314 MCInst TmpInst;
10315 unsigned Spacing;
10316 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10317 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10318 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10319 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10320 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10321 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10323 Spacing));
10325 Spacing * 2));
10326 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10327 TmpInst.addOperand(Inst.getOperand(4));
10328 Inst = TmpInst;
10329 return true;
10330 }
10331
10332 case ARM::VST3dWB_register_Asm_8:
10333 case ARM::VST3dWB_register_Asm_16:
10334 case ARM::VST3dWB_register_Asm_32:
10335 case ARM::VST3qWB_register_Asm_8:
10336 case ARM::VST3qWB_register_Asm_16:
10337 case ARM::VST3qWB_register_Asm_32: {
10338 MCInst TmpInst;
10339 unsigned Spacing;
10340 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10341 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10342 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10343 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10344 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10345 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10347 Spacing));
10349 Spacing * 2));
10350 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10351 TmpInst.addOperand(Inst.getOperand(5));
10352 Inst = TmpInst;
10353 return true;
10354 }
10355
10356 // VST4 multiple 3-element structure instructions.
10357 case ARM::VST4dAsm_8:
10358 case ARM::VST4dAsm_16:
10359 case ARM::VST4dAsm_32:
10360 case ARM::VST4qAsm_8:
10361 case ARM::VST4qAsm_16:
10362 case ARM::VST4qAsm_32: {
10363 MCInst TmpInst;
10364 unsigned Spacing;
10365 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10366 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10367 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10368 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10370 Spacing));
10372 Spacing * 2));
10374 Spacing * 3));
10375 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10376 TmpInst.addOperand(Inst.getOperand(4));
10377 Inst = TmpInst;
10378 return true;
10379 }
10380
10381 case ARM::VST4dWB_fixed_Asm_8:
10382 case ARM::VST4dWB_fixed_Asm_16:
10383 case ARM::VST4dWB_fixed_Asm_32:
10384 case ARM::VST4qWB_fixed_Asm_8:
10385 case ARM::VST4qWB_fixed_Asm_16:
10386 case ARM::VST4qWB_fixed_Asm_32: {
10387 MCInst TmpInst;
10388 unsigned Spacing;
10389 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10390 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10391 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10392 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10393 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10394 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10396 Spacing));
10398 Spacing * 2));
10400 Spacing * 3));
10401 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10402 TmpInst.addOperand(Inst.getOperand(4));
10403 Inst = TmpInst;
10404 return true;
10405 }
10406
10407 case ARM::VST4dWB_register_Asm_8:
10408 case ARM::VST4dWB_register_Asm_16:
10409 case ARM::VST4dWB_register_Asm_32:
10410 case ARM::VST4qWB_register_Asm_8:
10411 case ARM::VST4qWB_register_Asm_16:
10412 case ARM::VST4qWB_register_Asm_32: {
10413 MCInst TmpInst;
10414 unsigned Spacing;
10415 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10416 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10417 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10418 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10419 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10420 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10422 Spacing));
10424 Spacing * 2));
10426 Spacing * 3));
10427 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10428 TmpInst.addOperand(Inst.getOperand(5));
10429 Inst = TmpInst;
10430 return true;
10431 }
10432
10433 // Handle encoding choice for the shift-immediate instructions.
10434 case ARM::t2LSLri:
10435 case ARM::t2LSRri:
10436 case ARM::t2ASRri:
10437 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10438 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10439 Inst.getOperand(5).getReg() ==
10440 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10441 !HasWideQualifier) {
10442 unsigned NewOpc;
10443 switch (Inst.getOpcode()) {
10444 default: llvm_unreachable("unexpected opcode");
10445 case ARM::t2LSLri: NewOpc = ARM::tLSLri; break;
10446 case ARM::t2LSRri: NewOpc = ARM::tLSRri; break;
10447 case ARM::t2ASRri: NewOpc = ARM::tASRri; break;
10448 }
10449 // The Thumb1 operands aren't in the same order. Awesome, eh?
10450 MCInst TmpInst;
10451 TmpInst.setOpcode(NewOpc);
10452 TmpInst.addOperand(Inst.getOperand(0));
10453 TmpInst.addOperand(Inst.getOperand(5));
10454 TmpInst.addOperand(Inst.getOperand(1));
10455 TmpInst.addOperand(Inst.getOperand(2));
10456 TmpInst.addOperand(Inst.getOperand(3));
10457 TmpInst.addOperand(Inst.getOperand(4));
10458 Inst = TmpInst;
10459 return true;
10460 }
10461 return false;
10462
10463 // Handle the Thumb2 mode MOV complex aliases.
10464 case ARM::t2MOVsr:
10465 case ARM::t2MOVSsr: {
10466 // Which instruction to expand to depends on the CCOut operand and
10467 // whether we're in an IT block if the register operands are low
10468 // registers.
10469 bool isNarrow = false;
10470 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10471 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10472 isARMLowRegister(Inst.getOperand(2).getReg()) &&
10473 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
10474 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr) &&
10475 !HasWideQualifier)
10476 isNarrow = true;
10477 MCInst TmpInst;
10478 unsigned newOpc;
10479 switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
10480 default: llvm_unreachable("unexpected opcode!");
10481 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
10482 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
10483 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
10484 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break;
10485 }
10486 TmpInst.setOpcode(newOpc);
10487 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10488 if (isNarrow)
10490 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10491 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10492 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10493 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10494 TmpInst.addOperand(Inst.getOperand(5));
10495 if (!isNarrow)
10497 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10498 Inst = TmpInst;
10499 return true;
10500 }
10501 case ARM::t2MOVsi:
10502 case ARM::t2MOVSsi: {
10503 // Which instruction to expand to depends on the CCOut operand and
10504 // whether we're in an IT block if the register operands are low
10505 // registers.
10506 bool isNarrow = false;
10507 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10508 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10509 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi) &&
10510 !HasWideQualifier)
10511 isNarrow = true;
10512 MCInst TmpInst;
10513 unsigned newOpc;
10514 unsigned Shift = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
10515 unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
10516 bool isMov = false;
10517 // MOV rd, rm, LSL #0 is actually a MOV instruction
10518 if (Shift == ARM_AM::lsl && Amount == 0) {
10519 isMov = true;
10520 // The 16-bit encoding of MOV rd, rm, LSL #N is explicitly encoding T2 of
10521 // MOV (register) in the ARMv8-A and ARMv8-M manuals, and immediate 0 is
10522 // unpredictable in an IT block so the 32-bit encoding T3 has to be used
10523 // instead.
10524 if (inITBlock()) {
10525 isNarrow = false;
10526 }
10527 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10528 } else {
10529 switch(Shift) {
10530 default: llvm_unreachable("unexpected opcode!");
10531 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
10532 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
10533 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
10534 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
10535 case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
10536 }
10537 }
10538 if (Amount == 32) Amount = 0;
10539 TmpInst.setOpcode(newOpc);
10540 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10541 if (isNarrow && !isMov)
10543 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10544 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10545 if (newOpc != ARM::t2RRX && !isMov)
10546 TmpInst.addOperand(MCOperand::createImm(Amount));
10547 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10548 TmpInst.addOperand(Inst.getOperand(4));
10549 if (!isNarrow)
10551 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10552 Inst = TmpInst;
10553 return true;
10554 }
10555 // Handle the ARM mode MOV complex aliases.
10556 case ARM::ASRr:
10557 case ARM::LSRr:
10558 case ARM::LSLr:
10559 case ARM::RORr: {
10560 ARM_AM::ShiftOpc ShiftTy;
10561 switch(Inst.getOpcode()) {
10562 default: llvm_unreachable("unexpected opcode!");
10563 case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
10564 case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
10565 case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
10566 case ARM::RORr: ShiftTy = ARM_AM::ror; break;
10567 }
10568 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
10569 MCInst TmpInst;
10570 TmpInst.setOpcode(ARM::MOVsr);
10571 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10572 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10573 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10574 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10575 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10576 TmpInst.addOperand(Inst.getOperand(4));
10577 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10578 Inst = TmpInst;
10579 return true;
10580 }
10581 case ARM::ASRi:
10582 case ARM::LSRi:
10583 case ARM::LSLi:
10584 case ARM::RORi: {
10585 ARM_AM::ShiftOpc ShiftTy;
10586 switch(Inst.getOpcode()) {
10587 default: llvm_unreachable("unexpected opcode!");
10588 case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
10589 case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
10590 case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
10591 case ARM::RORi: ShiftTy = ARM_AM::ror; break;
10592 }
10593 // A shift by zero is a plain MOVr, not a MOVsi.
10594 unsigned Amt = Inst.getOperand(2).getImm();
10595 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10596 // A shift by 32 should be encoded as 0 when permitted
10597 if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
10598 Amt = 0;
10599 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
10600 MCInst TmpInst;
10601 TmpInst.setOpcode(Opc);
10602 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10603 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10604 if (Opc == ARM::MOVsi)
10605 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10606 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10607 TmpInst.addOperand(Inst.getOperand(4));
10608 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10609 Inst = TmpInst;
10610 return true;
10611 }
10612 case ARM::RRXi: {
10613 unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
10614 MCInst TmpInst;
10615 TmpInst.setOpcode(ARM::MOVsi);
10616 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10617 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10618 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10619 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10620 TmpInst.addOperand(Inst.getOperand(3));
10621 TmpInst.addOperand(Inst.getOperand(4)); // cc_out
10622 Inst = TmpInst;
10623 return true;
10624 }
10625 case ARM::t2LDMIA_UPD: {
10626 // If this is a load of a single register, then we should use
10627 // a post-indexed LDR instruction instead, per the ARM ARM.
10628 if (Inst.getNumOperands() != 5)
10629 return false;
10630 MCInst TmpInst;
10631 TmpInst.setOpcode(ARM::t2LDR_POST);
10632 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10633 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10634 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10635 TmpInst.addOperand(MCOperand::createImm(4));
10636 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10637 TmpInst.addOperand(Inst.getOperand(3));
10638 Inst = TmpInst;
10639 return true;
10640 }
10641 case ARM::t2STMDB_UPD: {
10642 // If this is a store of a single register, then we should use
10643 // a pre-indexed STR instruction instead, per the ARM ARM.
10644 if (Inst.getNumOperands() != 5)
10645 return false;
10646 MCInst TmpInst;
10647 TmpInst.setOpcode(ARM::t2STR_PRE);
10648 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10649 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10650 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10651 TmpInst.addOperand(MCOperand::createImm(-4));
10652 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10653 TmpInst.addOperand(Inst.getOperand(3));
10654 Inst = TmpInst;
10655 return true;
10656 }
10657 case ARM::LDMIA_UPD:
10658 // If this is a load of a single register via a 'pop', then we should use
10659 // a post-indexed LDR instruction instead, per the ARM ARM.
10660 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "pop" &&
10661 Inst.getNumOperands() == 5) {
10662 MCInst TmpInst;
10663 TmpInst.setOpcode(ARM::LDR_POST_IMM);
10664 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10665 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10666 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10667 TmpInst.addOperand(MCOperand::createReg(0)); // am2offset
10668 TmpInst.addOperand(MCOperand::createImm(4));
10669 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10670 TmpInst.addOperand(Inst.getOperand(3));
10671 Inst = TmpInst;
10672 return true;
10673 }
10674 break;
10675 case ARM::STMDB_UPD:
10676 // If this is a store of a single register via a 'push', then we should use
10677 // a pre-indexed STR instruction instead, per the ARM ARM.
10678 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "push" &&
10679 Inst.getNumOperands() == 5) {
10680 MCInst TmpInst;
10681 TmpInst.setOpcode(ARM::STR_PRE_IMM);
10682 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10683 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10684 TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
10685 TmpInst.addOperand(MCOperand::createImm(-4));
10686 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10687 TmpInst.addOperand(Inst.getOperand(3));
10688 Inst = TmpInst;
10689 }
10690 break;
10691 case ARM::t2ADDri12:
10692 case ARM::t2SUBri12:
10693 case ARM::t2ADDspImm12:
10694 case ARM::t2SUBspImm12: {
10695 // If the immediate fits for encoding T3 and the generic
10696 // mnemonic was used, encoding T3 is preferred.
10697 const StringRef Token = static_cast<ARMOperand &>(*Operands[0]).getToken();
10698 if ((Token != "add" && Token != "sub") ||
10699 ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
10700 break;
10701 switch (Inst.getOpcode()) {
10702 case ARM::t2ADDri12:
10703 Inst.setOpcode(ARM::t2ADDri);
10704 break;
10705 case ARM::t2SUBri12:
10706 Inst.setOpcode(ARM::t2SUBri);
10707 break;
10708 case ARM::t2ADDspImm12:
10709 Inst.setOpcode(ARM::t2ADDspImm);
10710 break;
10711 case ARM::t2SUBspImm12:
10712 Inst.setOpcode(ARM::t2SUBspImm);
10713 break;
10714 }
10715
10716 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10717 return true;
10718 }
10719 case ARM::tADDi8:
10720 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10721 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10722 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10723 // to encoding T1 if <Rd> is omitted."
10724 if (Inst.getOperand(3).isImm() &&
10725 (unsigned)Inst.getOperand(3).getImm() < 8 &&
10726 Operands.size() == MnemonicOpsEndInd + 3) {
10727 Inst.setOpcode(ARM::tADDi3);
10728 return true;
10729 }
10730 break;
10731 case ARM::tSUBi8:
10732 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10733 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10734 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10735 // to encoding T1 if <Rd> is omitted."
10736 if ((unsigned)Inst.getOperand(3).getImm() < 8 &&
10737 Operands.size() == MnemonicOpsEndInd + 3) {
10738 Inst.setOpcode(ARM::tSUBi3);
10739 return true;
10740 }
10741 break;
10742 case ARM::t2ADDri:
10743 case ARM::t2SUBri: {
10744 // If the destination and first source operand are the same, and
10745 // the flags are compatible with the current IT status, use encoding T2
10746 // instead of T3. For compatibility with the system 'as'. Make sure the
10747 // wide encoding wasn't explicit.
10748 if (HasWideQualifier)
10749 break; // source code has asked for the 32-bit instruction
10750 if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg())
10751 break; // tADDi8 can't take different input and output registers
10752 if (!isARMLowRegister(Inst.getOperand(0).getReg()))
10753 break; // high register that tADDi8 can't access
10754 if (Inst.getOperand(5).getReg() !=
10755 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10756 break; // flag-modification would require overriding the IT state
10757 if (Inst.getOperand(2).isImm()) {
10758 if ((unsigned)Inst.getOperand(2).getImm() > 255)
10759 break; // large immediate that tADDi8 can't contain
10760 } else {
10761 int i = (Operands[MnemonicOpsEndInd + 1]->isImm())
10762 ? MnemonicOpsEndInd + 1
10763 : MnemonicOpsEndInd + 2;
10764 MCParsedAsmOperand &Op = *Operands[i];
10766 break; // a type of non-immediate that tADDi8 can't represent
10767 }
10768 MCInst TmpInst;
10769 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
10770 ARM::tADDi8 : ARM::tSUBi8);
10771 TmpInst.addOperand(Inst.getOperand(0));
10772 TmpInst.addOperand(Inst.getOperand(5));
10773 TmpInst.addOperand(Inst.getOperand(0));
10774 TmpInst.addOperand(Inst.getOperand(2));
10775 TmpInst.addOperand(Inst.getOperand(3));
10776 TmpInst.addOperand(Inst.getOperand(4));
10777 Inst = TmpInst;
10778 return true;
10779 }
10780 case ARM::t2ADDspImm:
10781 case ARM::t2SUBspImm: {
10782 // Prefer T1 encoding if possible
10783 if (Inst.getOperand(5).getReg() || HasWideQualifier)
10784 break;
10785 unsigned V = Inst.getOperand(2).getImm();
10786 if (V & 3 || V > ((1 << 7) - 1) << 2)
10787 break;
10788 MCInst TmpInst;
10789 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDspImm ? ARM::tADDspi
10790 : ARM::tSUBspi);
10791 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // destination reg
10792 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // source reg
10793 TmpInst.addOperand(MCOperand::createImm(V / 4)); // immediate
10794 TmpInst.addOperand(Inst.getOperand(3)); // pred
10795 TmpInst.addOperand(Inst.getOperand(4));
10796 Inst = TmpInst;
10797 return true;
10798 }
10799 case ARM::t2ADDrr: {
10800 // If the destination and first source operand are the same, and
10801 // there's no setting of the flags, use encoding T2 instead of T3.
10802 // Note that this is only for ADD, not SUB. This mirrors the system
10803 // 'as' behaviour. Also take advantage of ADD being commutative.
10804 // Make sure the wide encoding wasn't explicit.
10805 bool Swap = false;
10806 auto DestReg = Inst.getOperand(0).getReg();
10807 bool Transform = DestReg == Inst.getOperand(1).getReg();
10808 if (!Transform && DestReg == Inst.getOperand(2).getReg()) {
10809 Transform = true;
10810 Swap = true;
10811 }
10812 if (!Transform || Inst.getOperand(5).getReg() || HasWideQualifier)
10813 break;
10814 MCInst TmpInst;
10815 TmpInst.setOpcode(ARM::tADDhirr);
10816 TmpInst.addOperand(Inst.getOperand(0));
10817 TmpInst.addOperand(Inst.getOperand(0));
10818 TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2));
10819 TmpInst.addOperand(Inst.getOperand(3));
10820 TmpInst.addOperand(Inst.getOperand(4));
10821 Inst = TmpInst;
10822 return true;
10823 }
10824 case ARM::tADDrSP:
10825 // If the non-SP source operand and the destination operand are not the
10826 // same, we need to use the 32-bit encoding if it's available.
10827 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
10828 Inst.setOpcode(ARM::t2ADDrr);
10829 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10830 return true;
10831 }
10832 break;
10833 case ARM::tB:
10834 // A Thumb conditional branch outside of an IT block is a tBcc.
10835 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
10836 Inst.setOpcode(ARM::tBcc);
10837 return true;
10838 }
10839 break;
10840 case ARM::t2B:
10841 // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
10842 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
10843 Inst.setOpcode(ARM::t2Bcc);
10844 return true;
10845 }
10846 break;
10847 case ARM::t2Bcc:
10848 // If the conditional is AL or we're in an IT block, we really want t2B.
10849 if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
10850 Inst.setOpcode(ARM::t2B);
10851 return true;
10852 }
10853 break;
10854 case ARM::tBcc:
10855 // If the conditional is AL, we really want tB.
10856 if (Inst.getOperand(1).getImm() == ARMCC::AL) {
10857 Inst.setOpcode(ARM::tB);
10858 return true;
10859 }
10860 break;
10861 case ARM::tLDMIA: {
10862 // If the register list contains any high registers, or if the writeback
10863 // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
10864 // instead if we're in Thumb2. Otherwise, this should have generated
10865 // an error in validateInstruction().
10866 MCRegister Rn = Inst.getOperand(0).getReg();
10867 bool hasWritebackToken =
10868 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10869 .isToken() &&
10870 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10871 .getToken() == "!");
10872 bool listContainsBase;
10873 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), listContainsBase) ||
10874 (!listContainsBase && !hasWritebackToken) ||
10875 (listContainsBase && hasWritebackToken)) {
10876 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10877 assert(isThumbTwo());
10878 Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10879 // If we're switching to the updating version, we need to insert
10880 // the writeback tied operand.
10881 if (hasWritebackToken)
10882 Inst.insert(Inst.begin(),
10884 return true;
10885 }
10886 break;
10887 }
10888 case ARM::tSTMIA_UPD: {
10889 // If the register list contains any high registers, we need to use
10890 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10891 // should have generated an error in validateInstruction().
10892 MCRegister Rn = Inst.getOperand(0).getReg();
10893 bool listContainsBase;
10894 if (checkLowRegisterList(Inst, 4, Rn, MCRegister(), listContainsBase)) {
10895 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10896 assert(isThumbTwo());
10897 Inst.setOpcode(ARM::t2STMIA_UPD);
10898 return true;
10899 }
10900 break;
10901 }
10902 case ARM::tPOP: {
10903 bool listContainsBase;
10904 // If the register list contains any high registers, we need to use
10905 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10906 // should have generated an error in validateInstruction().
10907 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC, listContainsBase))
10908 return false;
10909 assert(isThumbTwo());
10910 Inst.setOpcode(ARM::t2LDMIA_UPD);
10911 // Add the base register and writeback operands.
10912 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10913 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10914 return true;
10915 }
10916 case ARM::tPUSH: {
10917 bool listContainsBase;
10918 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR, listContainsBase))
10919 return false;
10920 assert(isThumbTwo());
10921 Inst.setOpcode(ARM::t2STMDB_UPD);
10922 // Add the base register and writeback operands.
10923 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10924 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10925 return true;
10926 }
10927 case ARM::t2MOVi:
10928 // If we can use the 16-bit encoding and the user didn't explicitly
10929 // request the 32-bit variant, transform it here.
10930 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10931 (Inst.getOperand(1).isImm() &&
10932 (unsigned)Inst.getOperand(1).getImm() <= 255) &&
10933 Inst.getOperand(4).getReg() ==
10934 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10935 !HasWideQualifier) {
10936 // The operands aren't in the same order for tMOVi8...
10937 MCInst TmpInst;
10938 TmpInst.setOpcode(ARM::tMOVi8);
10939 TmpInst.addOperand(Inst.getOperand(0));
10940 TmpInst.addOperand(Inst.getOperand(4));
10941 TmpInst.addOperand(Inst.getOperand(1));
10942 TmpInst.addOperand(Inst.getOperand(2));
10943 TmpInst.addOperand(Inst.getOperand(3));
10944 Inst = TmpInst;
10945 return true;
10946 }
10947 break;
10948
10949 case ARM::t2MOVr:
10950 // If we can use the 16-bit encoding and the user didn't explicitly
10951 // request the 32-bit variant, transform it here.
10952 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10953 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10954 Inst.getOperand(2).getImm() == ARMCC::AL &&
10955 Inst.getOperand(4).getReg() == ARM::CPSR &&
10956 !HasWideQualifier) {
10957 // The operands aren't the same for tMOV[S]r... (no cc_out)
10958 MCInst TmpInst;
10959 unsigned Op = Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr;
10960 TmpInst.setOpcode(Op);
10961 TmpInst.addOperand(Inst.getOperand(0));
10962 TmpInst.addOperand(Inst.getOperand(1));
10963 if (Op == ARM::tMOVr) {
10964 TmpInst.addOperand(Inst.getOperand(2));
10965 TmpInst.addOperand(Inst.getOperand(3));
10966 }
10967 Inst = TmpInst;
10968 return true;
10969 }
10970 break;
10971
10972 case ARM::t2SXTH:
10973 case ARM::t2SXTB:
10974 case ARM::t2UXTH:
10975 case ARM::t2UXTB:
10976 // If we can use the 16-bit encoding and the user didn't explicitly
10977 // request the 32-bit variant, transform it here.
10978 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10979 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10980 Inst.getOperand(2).getImm() == 0 &&
10981 !HasWideQualifier) {
10982 unsigned NewOpc;
10983 switch (Inst.getOpcode()) {
10984 default: llvm_unreachable("Illegal opcode!");
10985 case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
10986 case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
10987 case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
10988 case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
10989 }
10990 // The operands aren't the same for thumb1 (no rotate operand).
10991 MCInst TmpInst;
10992 TmpInst.setOpcode(NewOpc);
10993 TmpInst.addOperand(Inst.getOperand(0));
10994 TmpInst.addOperand(Inst.getOperand(1));
10995 TmpInst.addOperand(Inst.getOperand(3));
10996 TmpInst.addOperand(Inst.getOperand(4));
10997 Inst = TmpInst;
10998 return true;
10999 }
11000 break;
11001
11002 case ARM::MOVsi: {
11004 // rrx shifts and asr/lsr of #32 is encoded as 0
11005 if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
11006 return false;
11007 if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
11008 // Shifting by zero is accepted as a vanilla 'MOVr'
11009 MCInst TmpInst;
11010 TmpInst.setOpcode(ARM::MOVr);
11011 TmpInst.addOperand(Inst.getOperand(0));
11012 TmpInst.addOperand(Inst.getOperand(1));
11013 TmpInst.addOperand(Inst.getOperand(3));
11014 TmpInst.addOperand(Inst.getOperand(4));
11015 TmpInst.addOperand(Inst.getOperand(5));
11016 Inst = TmpInst;
11017 return true;
11018 }
11019 return false;
11020 }
11021 case ARM::ANDrsi:
11022 case ARM::ORRrsi:
11023 case ARM::EORrsi:
11024 case ARM::BICrsi:
11025 case ARM::SUBrsi:
11026 case ARM::ADDrsi: {
11027 unsigned newOpc;
11029 if (SOpc == ARM_AM::rrx) return false;
11030 switch (Inst.getOpcode()) {
11031 default: llvm_unreachable("unexpected opcode!");
11032 case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
11033 case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
11034 case ARM::EORrsi: newOpc = ARM::EORrr; break;
11035 case ARM::BICrsi: newOpc = ARM::BICrr; break;
11036 case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
11037 case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
11038 }
11039 // If the shift is by zero, use the non-shifted instruction definition.
11040 // The exception is for right shifts, where 0 == 32
11041 if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 &&
11042 !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) {
11043 MCInst TmpInst;
11044 TmpInst.setOpcode(newOpc);
11045 TmpInst.addOperand(Inst.getOperand(0));
11046 TmpInst.addOperand(Inst.getOperand(1));
11047 TmpInst.addOperand(Inst.getOperand(2));
11048 TmpInst.addOperand(Inst.getOperand(4));
11049 TmpInst.addOperand(Inst.getOperand(5));
11050 TmpInst.addOperand(Inst.getOperand(6));
11051 Inst = TmpInst;
11052 return true;
11053 }
11054 return false;
11055 }
11056 case ARM::ITasm:
11057 case ARM::t2IT: {
11058 // Set up the IT block state according to the IT instruction we just
11059 // matched.
11060 assert(!inITBlock() && "nested IT blocks?!");
11061 startExplicitITBlock(ARMCC::CondCodes(Inst.getOperand(0).getImm()),
11062 Inst.getOperand(1).getImm());
11063 break;
11064 }
11065 case ARM::t2LSLrr:
11066 case ARM::t2LSRrr:
11067 case ARM::t2ASRrr:
11068 case ARM::t2SBCrr:
11069 case ARM::t2RORrr:
11070 case ARM::t2BICrr:
11071 // Assemblers should use the narrow encodings of these instructions when permissible.
11072 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11073 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11074 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
11075 Inst.getOperand(5).getReg() ==
11076 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11077 !HasWideQualifier) {
11078 unsigned NewOpc;
11079 switch (Inst.getOpcode()) {
11080 default: llvm_unreachable("unexpected opcode");
11081 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break;
11082 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break;
11083 case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break;
11084 case ARM::t2SBCrr: NewOpc = ARM::tSBC; break;
11085 case ARM::t2RORrr: NewOpc = ARM::tROR; break;
11086 case ARM::t2BICrr: NewOpc = ARM::tBIC; break;
11087 }
11088 MCInst TmpInst;
11089 TmpInst.setOpcode(NewOpc);
11090 TmpInst.addOperand(Inst.getOperand(0));
11091 TmpInst.addOperand(Inst.getOperand(5));
11092 TmpInst.addOperand(Inst.getOperand(1));
11093 TmpInst.addOperand(Inst.getOperand(2));
11094 TmpInst.addOperand(Inst.getOperand(3));
11095 TmpInst.addOperand(Inst.getOperand(4));
11096 Inst = TmpInst;
11097 return true;
11098 }
11099 return false;
11100
11101 case ARM::t2ANDrr:
11102 case ARM::t2EORrr:
11103 case ARM::t2ADCrr:
11104 case ARM::t2ORRrr:
11105 // Assemblers should use the narrow encodings of these instructions when permissible.
11106 // These instructions are special in that they are commutable, so shorter encodings
11107 // are available more often.
11108 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11109 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11110 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() ||
11111 Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) &&
11112 Inst.getOperand(5).getReg() ==
11113 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11114 !HasWideQualifier) {
11115 unsigned NewOpc;
11116 switch (Inst.getOpcode()) {
11117 default: llvm_unreachable("unexpected opcode");
11118 case ARM::t2ADCrr: NewOpc = ARM::tADC; break;
11119 case ARM::t2ANDrr: NewOpc = ARM::tAND; break;
11120 case ARM::t2EORrr: NewOpc = ARM::tEOR; break;
11121 case ARM::t2ORRrr: NewOpc = ARM::tORR; break;
11122 }
11123 MCInst TmpInst;
11124 TmpInst.setOpcode(NewOpc);
11125 TmpInst.addOperand(Inst.getOperand(0));
11126 TmpInst.addOperand(Inst.getOperand(5));
11127 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) {
11128 TmpInst.addOperand(Inst.getOperand(1));
11129 TmpInst.addOperand(Inst.getOperand(2));
11130 } else {
11131 TmpInst.addOperand(Inst.getOperand(2));
11132 TmpInst.addOperand(Inst.getOperand(1));
11133 }
11134 TmpInst.addOperand(Inst.getOperand(3));
11135 TmpInst.addOperand(Inst.getOperand(4));
11136 Inst = TmpInst;
11137 return true;
11138 }
11139 return false;
11140 case ARM::MVE_VPST:
11141 case ARM::MVE_VPTv16i8:
11142 case ARM::MVE_VPTv8i16:
11143 case ARM::MVE_VPTv4i32:
11144 case ARM::MVE_VPTv16u8:
11145 case ARM::MVE_VPTv8u16:
11146 case ARM::MVE_VPTv4u32:
11147 case ARM::MVE_VPTv16s8:
11148 case ARM::MVE_VPTv8s16:
11149 case ARM::MVE_VPTv4s32:
11150 case ARM::MVE_VPTv4f32:
11151 case ARM::MVE_VPTv8f16:
11152 case ARM::MVE_VPTv16i8r:
11153 case ARM::MVE_VPTv8i16r:
11154 case ARM::MVE_VPTv4i32r:
11155 case ARM::MVE_VPTv16u8r:
11156 case ARM::MVE_VPTv8u16r:
11157 case ARM::MVE_VPTv4u32r:
11158 case ARM::MVE_VPTv16s8r:
11159 case ARM::MVE_VPTv8s16r:
11160 case ARM::MVE_VPTv4s32r:
11161 case ARM::MVE_VPTv4f32r:
11162 case ARM::MVE_VPTv8f16r: {
11163 assert(!inVPTBlock() && "Nested VPT blocks are not allowed");
11164 MCOperand &MO = Inst.getOperand(0);
11165 VPTState.Mask = MO.getImm();
11166 VPTState.CurPosition = 0;
11167 break;
11168 }
11169 }
11170 return false;
11171}
11172
11173unsigned
11174ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11175 const OperandVector &Operands) {
11176 unsigned Opc = Inst.getOpcode();
11177 switch (Opc) {
11178 // Prevent the mov r8 r8 encoding for nop being selected when the v6/thumb 2
11179 // encoding is available.
11180 case ARM::tMOVr: {
11181 if (Operands[0]->isToken() &&
11182 static_cast<ARMOperand &>(*Operands[0]).getToken() == "nop" &&
11183 ((isThumb() && !isThumbOne()) || hasV6MOps())) {
11184 return Match_MnemonicFail;
11185 }
11186 }
11187 [[fallthrough]];
11188 default:
11189 return Match_Success;
11190 }
11191}
11192
11193unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11194 // 16-bit thumb arithmetic instructions either require or preclude the 'S'
11195 // suffix depending on whether they're in an IT block or not.
11196 unsigned Opc = Inst.getOpcode();
11197 const MCInstrDesc &MCID = MII.get(Opc);
11199 assert(MCID.hasOptionalDef() &&
11200 "optionally flag setting instruction missing optional def operand");
11201 assert(MCID.NumOperands == Inst.getNumOperands() &&
11202 "operand count mismatch!");
11203 bool IsCPSR = false;
11204 // Check if the instruction has CPSR set.
11205 for (unsigned OpNo = 0; OpNo < MCID.NumOperands; ++OpNo) {
11206 if (MCID.operands()[OpNo].isOptionalDef() &&
11207 Inst.getOperand(OpNo).isReg() &&
11208 Inst.getOperand(OpNo).getReg() == ARM::CPSR)
11209 IsCPSR = true;
11210 }
11211
11212 // If we're parsing Thumb1, reject it completely.
11213 if (isThumbOne() && !IsCPSR)
11214 return Match_RequiresFlagSetting;
11215 // If we're parsing Thumb2, which form is legal depends on whether we're
11216 // in an IT block.
11217 if (isThumbTwo() && !IsCPSR && !inITBlock())
11218 return Match_RequiresITBlock;
11219 if (isThumbTwo() && IsCPSR && inITBlock())
11220 return Match_RequiresNotITBlock;
11221 // LSL with zero immediate is not allowed in an IT block
11222 if (Opc == ARM::tLSLri && Inst.getOperand(3).getImm() == 0 && inITBlock())
11223 return Match_RequiresNotITBlock;
11224 } else if (isThumbOne()) {
11225 // Some high-register supporting Thumb1 encodings only allow both registers
11226 // to be from r0-r7 when in Thumb2.
11227 if (Opc == ARM::tADDhirr && !hasV6MOps() &&
11228 isARMLowRegister(Inst.getOperand(1).getReg()) &&
11230 return Match_RequiresThumb2;
11231 // Others only require ARMv6 or later.
11232 else if (Opc == ARM::tMOVr && !hasV6Ops() &&
11233 isARMLowRegister(Inst.getOperand(0).getReg()) &&
11235 return Match_RequiresV6;
11236 }
11237
11238 // Before ARMv8 the rules for when SP is allowed in t2MOVr are more complex
11239 // than the loop below can handle, so it uses the GPRnopc register class and
11240 // we do SP handling here.
11241 if (Opc == ARM::t2MOVr && !hasV8Ops())
11242 {
11243 // SP as both source and destination is not allowed
11244 if (Inst.getOperand(0).getReg() == ARM::SP &&
11245 Inst.getOperand(1).getReg() == ARM::SP)
11246 return Match_RequiresV8;
11247 // When flags-setting SP as either source or destination is not allowed
11248 if (Inst.getOperand(4).getReg() == ARM::CPSR &&
11249 (Inst.getOperand(0).getReg() == ARM::SP ||
11250 Inst.getOperand(1).getReg() == ARM::SP))
11251 return Match_RequiresV8;
11252 }
11253
11254 switch (Inst.getOpcode()) {
11255 case ARM::VMRS:
11256 case ARM::VMSR:
11257 case ARM::VMRS_FPCXTS:
11258 case ARM::VMRS_FPCXTNS:
11259 case ARM::VMSR_FPCXTS:
11260 case ARM::VMSR_FPCXTNS:
11261 case ARM::VMRS_FPSCR_NZCVQC:
11262 case ARM::VMSR_FPSCR_NZCVQC:
11263 case ARM::FMSTAT:
11264 case ARM::VMRS_VPR:
11265 case ARM::VMRS_P0:
11266 case ARM::VMSR_VPR:
11267 case ARM::VMSR_P0:
11268 // Use of SP for VMRS/VMSR is only allowed in ARM mode with the exception of
11269 // ARMv8-A.
11270 if (Inst.getOperand(0).isReg() && Inst.getOperand(0).getReg() == ARM::SP &&
11271 (isThumb() && !hasV8Ops()))
11272 return Match_InvalidOperand;
11273 break;
11274 case ARM::t2TBB:
11275 case ARM::t2TBH:
11276 // Rn = sp is only allowed with ARMv8-A
11277 if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP))
11278 return Match_RequiresV8;
11279 break;
11280 case ARM::tMUL:
11281 // The second source operand must be the same register as the destination
11282 // operand.
11283 // FIXME: Ideally this would be handled by ARMGenAsmMatcher and
11284 // emitAsmTiedOperandConstraints.
11285 if (Inst.getOperand(0).getReg() != Inst.getOperand(3).getReg())
11286 return Match_InvalidTiedOperand;
11287 break;
11288 default:
11289 break;
11290 }
11291
11292 for (unsigned I = 0; I < MCID.NumOperands; ++I)
11293 if (MCID.operands()[I].RegClass == ARM::rGPRRegClassID) {
11294 // rGPRRegClass excludes PC, and also excluded SP before ARMv8
11295 const auto &Op = Inst.getOperand(I);
11296 if (!Op.isReg()) {
11297 // This can happen in awkward cases with tied operands, e.g. a
11298 // writeback load/store with a complex addressing mode in
11299 // which there's an output operand corresponding to the
11300 // updated written-back base register: the Tablegen-generated
11301 // AsmMatcher will have written a placeholder operand to that
11302 // slot in the form of an immediate 0, because it can't
11303 // generate the register part of the complex addressing-mode
11304 // operand ahead of time.
11305 continue;
11306 }
11307
11308 MCRegister Reg = Op.getReg();
11309 if ((Reg == ARM::SP) && !hasV8Ops())
11310 return Match_RequiresV8;
11311 else if (Reg == ARM::PC)
11312 return Match_InvalidOperand;
11313 }
11314
11315 return Match_Success;
11316}
11317
11318namespace llvm {
11319
11320template <> inline bool IsCPSRDead<MCInst>(const MCInst *Instr) {
11321 return true; // In an assembly source, no need to second-guess
11322}
11323
11324} // end namespace llvm
11325
11326// Returns true if Inst is unpredictable if it is in and IT block, but is not
11327// the last instruction in the block.
11328bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const {
11329 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11330
11331 // All branch & call instructions terminate IT blocks with the exception of
11332 // SVC.
11333 if (MCID.isTerminator() || (MCID.isCall() && Inst.getOpcode() != ARM::tSVC) ||
11334 MCID.isReturn() || MCID.isBranch() || MCID.isIndirectBranch())
11335 return true;
11336
11337 // Any arithmetic instruction which writes to the PC also terminates the IT
11338 // block.
11339 if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI))
11340 return true;
11341
11342 return false;
11343}
11344
11345unsigned ARMAsmParser::MatchInstruction(OperandVector &Operands, MCInst &Inst,
11346 SmallVectorImpl<NearMissInfo> &NearMisses,
11347 bool MatchingInlineAsm,
11348 bool &EmitInITBlock,
11349 MCStreamer &Out) {
11350 // If we can't use an implicit IT block here, just match as normal.
11351 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11352 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11353
11354 // Try to match the instruction in an extension of the current IT block (if
11355 // there is one).
11356 if (inImplicitITBlock()) {
11357 extendImplicitITBlock(ITState.Cond);
11358 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11359 Match_Success) {
11360 // The match succeeded, but we still have to check that the instruction is
11361 // valid in this implicit IT block.
11362 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11363 if (MCID.isPredicable()) {
11364 ARMCC::CondCodes InstCond =
11366 .getImm();
11367 ARMCC::CondCodes ITCond = currentITCond();
11368 if (InstCond == ITCond) {
11369 EmitInITBlock = true;
11370 return Match_Success;
11371 } else if (InstCond == ARMCC::getOppositeCondition(ITCond)) {
11372 invertCurrentITCondition();
11373 EmitInITBlock = true;
11374 return Match_Success;
11375 }
11376 }
11377 }
11378 rewindImplicitITPosition();
11379 }
11380
11381 // Finish the current IT block, and try to match outside any IT block.
11382 flushPendingInstructions(Out);
11383 unsigned PlainMatchResult =
11384 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11385 if (PlainMatchResult == Match_Success) {
11386 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11387 if (MCID.isPredicable()) {
11388 ARMCC::CondCodes InstCond =
11390 .getImm();
11391 // Some forms of the branch instruction have their own condition code
11392 // fields, so can be conditionally executed without an IT block.
11393 if (Inst.getOpcode() == ARM::tBcc || Inst.getOpcode() == ARM::t2Bcc) {
11394 EmitInITBlock = false;
11395 return Match_Success;
11396 }
11397 if (InstCond == ARMCC::AL) {
11398 EmitInITBlock = false;
11399 return Match_Success;
11400 }
11401 } else {
11402 EmitInITBlock = false;
11403 return Match_Success;
11404 }
11405 }
11406
11407 // Try to match in a new IT block. The matcher doesn't check the actual
11408 // condition, so we create an IT block with a dummy condition, and fix it up
11409 // once we know the actual condition.
11410 startImplicitITBlock();
11411 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11412 Match_Success) {
11413 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11414 if (MCID.isPredicable()) {
11415 ITState.Cond =
11417 .getImm();
11418 EmitInITBlock = true;
11419 return Match_Success;
11420 }
11421 }
11422 discardImplicitITBlock();
11423
11424 // If none of these succeed, return the error we got when trying to match
11425 // outside any IT blocks.
11426 EmitInITBlock = false;
11427 return PlainMatchResult;
11428}
11429
11430static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
11431 unsigned VariantID = 0);
11432
11433static const char *getSubtargetFeatureName(uint64_t Val);
11434bool ARMAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
11437 bool MatchingInlineAsm) {
11438 MCInst Inst;
11439 unsigned MatchResult;
11440 bool PendConditionalInstruction = false;
11441
11443 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
11444 PendConditionalInstruction, Out);
11445
11446 // Find the number of operators that are part of the Mnumonic (LHS).
11447 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
11448
11449 switch (MatchResult) {
11450 case Match_Success:
11451 LLVM_DEBUG(dbgs() << "Parsed as: ";
11452 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11453 dbgs() << "\n");
11454
11455 // Context sensitive operand constraints aren't handled by the matcher,
11456 // so check them here.
11457 if (validateInstruction(Inst, Operands, MnemonicOpsEndInd)) {
11458 // Still progress the IT block, otherwise one wrong condition causes
11459 // nasty cascading errors.
11460 forwardITPosition();
11461 forwardVPTPosition();
11462 return true;
11463 }
11464
11465 {
11466 // Some instructions need post-processing to, for example, tweak which
11467 // encoding is selected. Loop on it while changes happen so the
11468 // individual transformations can chain off each other. E.g.,
11469 // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
11470 while (processInstruction(Inst, Operands, MnemonicOpsEndInd, Out))
11471 LLVM_DEBUG(dbgs() << "Changed to: ";
11472 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11473 dbgs() << "\n");
11474 }
11475
11476 // Only move forward at the very end so that everything in validate
11477 // and process gets a consistent answer about whether we're in an IT
11478 // block.
11479 forwardITPosition();
11480 forwardVPTPosition();
11481
11482 // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
11483 // doesn't actually encode.
11484 if (Inst.getOpcode() == ARM::ITasm)
11485 return false;
11486
11487 Inst.setLoc(IDLoc);
11488 if (PendConditionalInstruction) {
11489 PendingConditionalInsts.push_back(Inst);
11490 if (isITBlockFull() || isITBlockTerminator(Inst))
11491 flushPendingInstructions(Out);
11492 } else {
11493 Out.emitInstruction(Inst, getSTI());
11494 }
11495 return false;
11496 case Match_NearMisses:
11497 ReportNearMisses(NearMisses, IDLoc, Operands);
11498 return true;
11499 case Match_MnemonicFail: {
11500 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11501 std::string Suggestion = ARMMnemonicSpellCheck(
11502 ((ARMOperand &)*Operands[0]).getToken(), FBS);
11503 return Error(IDLoc, "invalid instruction" + Suggestion,
11504 ((ARMOperand &)*Operands[0]).getLocRange());
11505 }
11506 }
11507
11508 llvm_unreachable("Implement any new match types added!");
11509}
11510
11511/// ParseDirective parses the arm specific directives
11512bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11513 const MCContext::Environment Format = getContext().getObjectFileType();
11514 bool IsMachO = Format == MCContext::IsMachO;
11515 bool IsCOFF = Format == MCContext::IsCOFF;
11516
11517 std::string IDVal = DirectiveID.getIdentifier().lower();
11518 if (IDVal == ".word")
11519 parseLiteralValues(4, DirectiveID.getLoc());
11520 else if (IDVal == ".short" || IDVal == ".hword")
11521 parseLiteralValues(2, DirectiveID.getLoc());
11522 else if (IDVal == ".thumb")
11523 parseDirectiveThumb(DirectiveID.getLoc());
11524 else if (IDVal == ".arm")
11525 parseDirectiveARM(DirectiveID.getLoc());
11526 else if (IDVal == ".thumb_func")
11527 parseDirectiveThumbFunc(DirectiveID.getLoc());
11528 else if (IDVal == ".code")
11529 parseDirectiveCode(DirectiveID.getLoc());
11530 else if (IDVal == ".syntax")
11531 parseDirectiveSyntax(DirectiveID.getLoc());
11532 else if (IDVal == ".unreq")
11533 parseDirectiveUnreq(DirectiveID.getLoc());
11534 else if (IDVal == ".fnend")
11535 parseDirectiveFnEnd(DirectiveID.getLoc());
11536 else if (IDVal == ".cantunwind")
11537 parseDirectiveCantUnwind(DirectiveID.getLoc());
11538 else if (IDVal == ".personality")
11539 parseDirectivePersonality(DirectiveID.getLoc());
11540 else if (IDVal == ".handlerdata")
11541 parseDirectiveHandlerData(DirectiveID.getLoc());
11542 else if (IDVal == ".setfp")
11543 parseDirectiveSetFP(DirectiveID.getLoc());
11544 else if (IDVal == ".pad")
11545 parseDirectivePad(DirectiveID.getLoc());
11546 else if (IDVal == ".save")
11547 parseDirectiveRegSave(DirectiveID.getLoc(), false);
11548 else if (IDVal == ".vsave")
11549 parseDirectiveRegSave(DirectiveID.getLoc(), true);
11550 else if (IDVal == ".ltorg" || IDVal == ".pool")
11551 parseDirectiveLtorg(DirectiveID.getLoc());
11552 else if (IDVal == ".even")
11553 parseDirectiveEven(DirectiveID.getLoc());
11554 else if (IDVal == ".personalityindex")
11555 parseDirectivePersonalityIndex(DirectiveID.getLoc());
11556 else if (IDVal == ".unwind_raw")
11557 parseDirectiveUnwindRaw(DirectiveID.getLoc());
11558 else if (IDVal == ".movsp")
11559 parseDirectiveMovSP(DirectiveID.getLoc());
11560 else if (IDVal == ".arch_extension")
11561 parseDirectiveArchExtension(DirectiveID.getLoc());
11562 else if (IDVal == ".align")
11563 return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
11564 else if (IDVal == ".thumb_set")
11565 parseDirectiveThumbSet(DirectiveID.getLoc());
11566 else if (IDVal == ".inst")
11567 parseDirectiveInst(DirectiveID.getLoc());
11568 else if (IDVal == ".inst.n")
11569 parseDirectiveInst(DirectiveID.getLoc(), 'n');
11570 else if (IDVal == ".inst.w")
11571 parseDirectiveInst(DirectiveID.getLoc(), 'w');
11572 else if (!IsMachO && !IsCOFF) {
11573 if (IDVal == ".arch")
11574 parseDirectiveArch(DirectiveID.getLoc());
11575 else if (IDVal == ".cpu")
11576 parseDirectiveCPU(DirectiveID.getLoc());
11577 else if (IDVal == ".eabi_attribute")
11578 parseDirectiveEabiAttr(DirectiveID.getLoc());
11579 else if (IDVal == ".fpu")
11580 parseDirectiveFPU(DirectiveID.getLoc());
11581 else if (IDVal == ".fnstart")
11582 parseDirectiveFnStart(DirectiveID.getLoc());
11583 else if (IDVal == ".object_arch")
11584 parseDirectiveObjectArch(DirectiveID.getLoc());
11585 else if (IDVal == ".tlsdescseq")
11586 parseDirectiveTLSDescSeq(DirectiveID.getLoc());
11587 else
11588 return true;
11589 } else if (IsCOFF) {
11590 if (IDVal == ".seh_stackalloc")
11591 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/false);
11592 else if (IDVal == ".seh_stackalloc_w")
11593 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/true);
11594 else if (IDVal == ".seh_save_regs")
11595 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/false);
11596 else if (IDVal == ".seh_save_regs_w")
11597 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/true);
11598 else if (IDVal == ".seh_save_sp")
11599 parseDirectiveSEHSaveSP(DirectiveID.getLoc());
11600 else if (IDVal == ".seh_save_fregs")
11601 parseDirectiveSEHSaveFRegs(DirectiveID.getLoc());
11602 else if (IDVal == ".seh_save_lr")
11603 parseDirectiveSEHSaveLR(DirectiveID.getLoc());
11604 else if (IDVal == ".seh_endprologue")
11605 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/false);
11606 else if (IDVal == ".seh_endprologue_fragment")
11607 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/true);
11608 else if (IDVal == ".seh_nop")
11609 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/false);
11610 else if (IDVal == ".seh_nop_w")
11611 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/true);
11612 else if (IDVal == ".seh_startepilogue")
11613 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/false);
11614 else if (IDVal == ".seh_startepilogue_cond")
11615 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/true);
11616 else if (IDVal == ".seh_endepilogue")
11617 parseDirectiveSEHEpilogEnd(DirectiveID.getLoc());
11618 else if (IDVal == ".seh_custom")
11619 parseDirectiveSEHCustom(DirectiveID.getLoc());
11620 else
11621 return true;
11622 } else
11623 return true;
11624 return false;
11625}
11626
11627/// parseLiteralValues
11628/// ::= .hword expression [, expression]*
11629/// ::= .short expression [, expression]*
11630/// ::= .word expression [, expression]*
11631bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
11632 auto parseOne = [&]() -> bool {
11633 const MCExpr *Value;
11634 if (getParser().parseExpression(Value))
11635 return true;
11636 getParser().getStreamer().emitValue(Value, Size, L);
11637 return false;
11638 };
11639 return (parseMany(parseOne));
11640}
11641
11642/// parseDirectiveThumb
11643/// ::= .thumb
11644bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11645 if (parseEOL() || check(!hasThumb(), L, "target does not support Thumb mode"))
11646 return true;
11647
11648 if (!isThumb())
11649 SwitchMode();
11650
11651 getTargetStreamer().emitCode16();
11652 getParser().getStreamer().emitCodeAlignment(Align(2), getSTI(), 0);
11653 return false;
11654}
11655
11656/// parseDirectiveARM
11657/// ::= .arm
11658bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11659 if (parseEOL() || check(!hasARM(), L, "target does not support ARM mode"))
11660 return true;
11661
11662 if (isThumb())
11663 SwitchMode();
11664 getTargetStreamer().emitCode32();
11665 getParser().getStreamer().emitCodeAlignment(Align(4), getSTI(), 0);
11666 return false;
11667}
11668
11669void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11670 // We need to flush the current implicit IT block on a label, because it is
11671 // not legal to branch into an IT block.
11672 flushPendingInstructions(getStreamer());
11673}
11674
11675void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11676 if (NextSymbolIsThumb) {
11677 getTargetStreamer().emitThumbFunc(Symbol);
11678 NextSymbolIsThumb = false;
11679 }
11680}
11681
11682/// parseDirectiveThumbFunc
11683/// ::= .thumbfunc symbol_name
11684bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11685 MCAsmParser &Parser = getParser();
11686 const auto Format = getContext().getObjectFileType();
11687 bool IsMachO = Format == MCContext::IsMachO;
11688
11689 // Darwin asm has (optionally) function name after .thumb_func direction
11690 // ELF doesn't
11691
11692 if (IsMachO) {
11693 if (Parser.getTok().is(AsmToken::Identifier) ||
11694 Parser.getTok().is(AsmToken::String)) {
11695 MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
11696 Parser.getTok().getIdentifier());
11697 getTargetStreamer().emitThumbFunc(Func);
11698 Parser.Lex();
11699 if (parseEOL())
11700 return true;
11701 return false;
11702 }
11703 }
11704
11705 if (parseEOL())
11706 return true;
11707
11708 // .thumb_func implies .thumb
11709 if (!isThumb())
11710 SwitchMode();
11711
11712 getTargetStreamer().emitCode16();
11713
11714 NextSymbolIsThumb = true;
11715 return false;
11716}
11717
11718/// parseDirectiveSyntax
11719/// ::= .syntax unified | divided
11720bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11721 MCAsmParser &Parser = getParser();
11722 const AsmToken &Tok = Parser.getTok();
11723 if (Tok.isNot(AsmToken::Identifier)) {
11724 Error(L, "unexpected token in .syntax directive");
11725 return false;
11726 }
11727
11728 StringRef Mode = Tok.getString();
11729 Parser.Lex();
11730 if (check(Mode == "divided" || Mode == "DIVIDED", L,
11731 "'.syntax divided' arm assembly not supported") ||
11732 check(Mode != "unified" && Mode != "UNIFIED", L,
11733 "unrecognized syntax mode in .syntax directive") ||
11734 parseEOL())
11735 return true;
11736
11737 // TODO tell the MC streamer the mode
11738 // getParser().getStreamer().Emit???();
11739 return false;
11740}
11741
11742/// parseDirectiveCode
11743/// ::= .code 16 | 32
11744bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11745 MCAsmParser &Parser = getParser();
11746 const AsmToken &Tok = Parser.getTok();
11747 if (Tok.isNot(AsmToken::Integer))
11748 return Error(L, "unexpected token in .code directive");
11749 int64_t Val = Parser.getTok().getIntVal();
11750 if (Val != 16 && Val != 32) {
11751 Error(L, "invalid operand to .code directive");
11752 return false;
11753 }
11754 Parser.Lex();
11755
11756 if (parseEOL())
11757 return true;
11758
11759 if (Val == 16) {
11760 if (!hasThumb())
11761 return Error(L, "target does not support Thumb mode");
11762
11763 if (!isThumb())
11764 SwitchMode();
11765 getTargetStreamer().emitCode16();
11766 } else {
11767 if (!hasARM())
11768 return Error(L, "target does not support ARM mode");
11769
11770 if (isThumb())
11771 SwitchMode();
11772 getTargetStreamer().emitCode32();
11773 }
11774
11775 return false;
11776}
11777
11778/// parseDirectiveReq
11779/// ::= name .req registername
11780bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11781 MCAsmParser &Parser = getParser();
11782 Parser.Lex(); // Eat the '.req' token.
11783 MCRegister Reg;
11784 SMLoc SRegLoc, ERegLoc;
11785 const bool parseResult = parseRegister(Reg, SRegLoc, ERegLoc);
11786 if (check(parseResult, SRegLoc, "register name expected") || parseEOL())
11787 return true;
11788
11789 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg)
11790 return Error(SRegLoc,
11791 "redefinition of '" + Name + "' does not match original.");
11792
11793 return false;
11794}
11795
11796/// parseDirectiveUneq
11797/// ::= .unreq registername
11798bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11799 MCAsmParser &Parser = getParser();
11800 if (Parser.getTok().isNot(AsmToken::Identifier))
11801 return Error(L, "unexpected input in .unreq directive.");
11802 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
11803 Parser.Lex(); // Eat the identifier.
11804 return parseEOL();
11805}
11806
11807// After changing arch/CPU, try to put the ARM/Thumb mode back to what it was
11808// before, if supported by the new target, or emit mapping symbols for the mode
11809// switch.
11810void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) {
11811 if (WasThumb != isThumb()) {
11812 if (WasThumb && hasThumb()) {
11813 // Stay in Thumb mode
11814 SwitchMode();
11815 } else if (!WasThumb && hasARM()) {
11816 // Stay in ARM mode
11817 SwitchMode();
11818 } else {
11819 // Mode switch forced, because the new arch doesn't support the old mode.
11820 if (isThumb())
11821 getTargetStreamer().emitCode16();
11822 else
11823 getTargetStreamer().emitCode32();
11824 // Warn about the implicit mode switch. GAS does not switch modes here,
11825 // but instead stays in the old mode, reporting an error on any following
11826 // instructions as the mode does not exist on the target.
11827 Warning(Loc, Twine("new target does not support ") +
11828 (WasThumb ? "thumb" : "arm") + " mode, switching to " +
11829 (!WasThumb ? "thumb" : "arm") + " mode");
11830 }
11831 }
11832}
11833
11834/// parseDirectiveArch
11835/// ::= .arch token
11836bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11837 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11839
11840 if (ID == ARM::ArchKind::INVALID)
11841 return Error(L, "Unknown arch name");
11842
11843 bool WasThumb = isThumb();
11844 MCSubtargetInfo &STI = copySTI();
11845 STI.setDefaultFeatures("", /*TuneCPU*/ "",
11846 ("+" + ARM::getArchName(ID)).str());
11847 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11848 FixModeAfterArchChange(WasThumb, L);
11849
11850 getTargetStreamer().emitArch(ID);
11851 return false;
11852}
11853
11854/// parseDirectiveEabiAttr
11855/// ::= .eabi_attribute int, int [, "str"]
11856/// ::= .eabi_attribute Tag_name, int [, "str"]
11857bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11858 MCAsmParser &Parser = getParser();
11859 int64_t Tag;
11860 SMLoc TagLoc;
11861 TagLoc = Parser.getTok().getLoc();
11862 if (Parser.getTok().is(AsmToken::Identifier)) {
11863 StringRef Name = Parser.getTok().getIdentifier();
11864 std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString(
11866 if (!Ret) {
11867 Error(TagLoc, "attribute name not recognised: " + Name);
11868 return false;
11869 }
11870 Tag = *Ret;
11871 Parser.Lex();
11872 } else {
11873 const MCExpr *AttrExpr;
11874
11875 TagLoc = Parser.getTok().getLoc();
11876 if (Parser.parseExpression(AttrExpr))
11877 return true;
11878
11879 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
11880 if (check(!CE, TagLoc, "expected numeric constant"))
11881 return true;
11882
11883 Tag = CE->getValue();
11884 }
11885
11886 if (Parser.parseComma())
11887 return true;
11888
11889 StringRef StringValue = "";
11890 bool IsStringValue = false;
11891
11892 int64_t IntegerValue = 0;
11893 bool IsIntegerValue = false;
11894
11896 IsStringValue = true;
11897 else if (Tag == ARMBuildAttrs::compatibility) {
11898 IsStringValue = true;
11899 IsIntegerValue = true;
11900 } else if (Tag < 32 || Tag % 2 == 0)
11901 IsIntegerValue = true;
11902 else if (Tag % 2 == 1)
11903 IsStringValue = true;
11904 else
11905 llvm_unreachable("invalid tag type");
11906
11907 if (IsIntegerValue) {
11908 const MCExpr *ValueExpr;
11909 SMLoc ValueExprLoc = Parser.getTok().getLoc();
11910 if (Parser.parseExpression(ValueExpr))
11911 return true;
11912
11913 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
11914 if (!CE)
11915 return Error(ValueExprLoc, "expected numeric constant");
11916 IntegerValue = CE->getValue();
11917 }
11918
11920 if (Parser.parseComma())
11921 return true;
11922 }
11923
11924 std::string EscapedValue;
11925 if (IsStringValue) {
11926 if (Parser.getTok().isNot(AsmToken::String))
11927 return Error(Parser.getTok().getLoc(), "bad string constant");
11928
11930 if (Parser.parseEscapedString(EscapedValue))
11931 return Error(Parser.getTok().getLoc(), "bad escaped string constant");
11932
11933 StringValue = EscapedValue;
11934 } else {
11935 StringValue = Parser.getTok().getStringContents();
11936 Parser.Lex();
11937 }
11938 }
11939
11940 if (Parser.parseEOL())
11941 return true;
11942
11943 if (IsIntegerValue && IsStringValue) {
11945 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
11946 } else if (IsIntegerValue)
11947 getTargetStreamer().emitAttribute(Tag, IntegerValue);
11948 else if (IsStringValue)
11949 getTargetStreamer().emitTextAttribute(Tag, StringValue);
11950 return false;
11951}
11952
11953/// parseDirectiveCPU
11954/// ::= .cpu str
11955bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11956 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11957 getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
11958
11959 // FIXME: This is using table-gen data, but should be moved to
11960 // ARMTargetParser once that is table-gen'd.
11961 if (!getSTI().isCPUStringValid(CPU))
11962 return Error(L, "Unknown CPU name");
11963
11964 bool WasThumb = isThumb();
11965 MCSubtargetInfo &STI = copySTI();
11966 STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
11967 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11968 FixModeAfterArchChange(WasThumb, L);
11969
11970 return false;
11971}
11972
11973/// parseDirectiveFPU
11974/// ::= .fpu str
11975bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11976 SMLoc FPUNameLoc = getTok().getLoc();
11977 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11978
11980 std::vector<StringRef> Features;
11981 if (!ARM::getFPUFeatures(ID, Features))
11982 return Error(FPUNameLoc, "Unknown FPU name");
11983
11984 MCSubtargetInfo &STI = copySTI();
11985 for (auto Feature : Features)
11986 STI.ApplyFeatureFlag(Feature);
11987 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11988
11989 getTargetStreamer().emitFPU(ID);
11990 return false;
11991}
11992
11993/// parseDirectiveFnStart
11994/// ::= .fnstart
11995bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
11996 if (parseEOL())
11997 return true;
11998
11999 if (UC.hasFnStart()) {
12000 Error(L, ".fnstart starts before the end of previous one");
12001 UC.emitFnStartLocNotes();
12002 return true;
12003 }
12004
12005 // Reset the unwind directives parser state
12006 UC.reset();
12007
12008 getTargetStreamer().emitFnStart();
12009
12010 UC.recordFnStart(L);
12011 return false;
12012}
12013
12014/// parseDirectiveFnEnd
12015/// ::= .fnend
12016bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12017 if (parseEOL())
12018 return true;
12019 // Check the ordering of unwind directives
12020 if (!UC.hasFnStart())
12021 return Error(L, ".fnstart must precede .fnend directive");
12022
12023 // Reset the unwind directives parser state
12024 getTargetStreamer().emitFnEnd();
12025
12026 UC.reset();
12027 return false;
12028}
12029
12030/// parseDirectiveCantUnwind
12031/// ::= .cantunwind
12032bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12033 if (parseEOL())
12034 return true;
12035
12036 UC.recordCantUnwind(L);
12037 // Check the ordering of unwind directives
12038 if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive"))
12039 return true;
12040
12041 if (UC.hasHandlerData()) {
12042 Error(L, ".cantunwind can't be used with .handlerdata directive");
12043 UC.emitHandlerDataLocNotes();
12044 return true;
12045 }
12046 if (UC.hasPersonality()) {
12047 Error(L, ".cantunwind can't be used with .personality directive");
12048 UC.emitPersonalityLocNotes();
12049 return true;
12050 }
12051
12052 getTargetStreamer().emitCantUnwind();
12053 return false;
12054}
12055
12056/// parseDirectivePersonality
12057/// ::= .personality name
12058bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12059 MCAsmParser &Parser = getParser();
12060 bool HasExistingPersonality = UC.hasPersonality();
12061
12062 // Parse the name of the personality routine
12063 if (Parser.getTok().isNot(AsmToken::Identifier))
12064 return Error(L, "unexpected input in .personality directive.");
12065 StringRef Name(Parser.getTok().getIdentifier());
12066 Parser.Lex();
12067
12068 if (parseEOL())
12069 return true;
12070
12071 UC.recordPersonality(L);
12072
12073 // Check the ordering of unwind directives
12074 if (!UC.hasFnStart())
12075 return Error(L, ".fnstart must precede .personality directive");
12076 if (UC.cantUnwind()) {
12077 Error(L, ".personality can't be used with .cantunwind directive");
12078 UC.emitCantUnwindLocNotes();
12079 return true;
12080 }
12081 if (UC.hasHandlerData()) {
12082 Error(L, ".personality must precede .handlerdata directive");
12083 UC.emitHandlerDataLocNotes();
12084 return true;
12085 }
12086 if (HasExistingPersonality) {
12087 Error(L, "multiple personality directives");
12088 UC.emitPersonalityLocNotes();
12089 return true;
12090 }
12091
12092 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12093 getTargetStreamer().emitPersonality(PR);
12094 return false;
12095}
12096
12097/// parseDirectiveHandlerData
12098/// ::= .handlerdata
12099bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12100 if (parseEOL())
12101 return true;
12102
12103 UC.recordHandlerData(L);
12104 // Check the ordering of unwind directives
12105 if (!UC.hasFnStart())
12106 return Error(L, ".fnstart must precede .personality directive");
12107 if (UC.cantUnwind()) {
12108 Error(L, ".handlerdata can't be used with .cantunwind directive");
12109 UC.emitCantUnwindLocNotes();
12110 return true;
12111 }
12112
12113 getTargetStreamer().emitHandlerData();
12114 return false;
12115}
12116
12117/// parseDirectiveSetFP
12118/// ::= .setfp fpreg, spreg [, offset]
12119bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12120 MCAsmParser &Parser = getParser();
12121 // Check the ordering of unwind directives
12122 if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") ||
12123 check(UC.hasHandlerData(), L,
12124 ".setfp must precede .handlerdata directive"))
12125 return true;
12126
12127 // Parse fpreg
12128 SMLoc FPRegLoc = Parser.getTok().getLoc();
12129 MCRegister FPReg = tryParseRegister();
12130
12131 if (check(!FPReg, FPRegLoc, "frame pointer register expected") ||
12132 Parser.parseComma())
12133 return true;
12134
12135 // Parse spreg
12136 SMLoc SPRegLoc = Parser.getTok().getLoc();
12137 MCRegister SPReg = tryParseRegister();
12138 if (check(!SPReg, SPRegLoc, "stack pointer register expected") ||
12139 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
12140 "register should be either $sp or the latest fp register"))
12141 return true;
12142
12143 // Update the frame pointer register
12144 UC.saveFPReg(FPReg);
12145
12146 // Parse offset
12147 int64_t Offset = 0;
12148 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12149 if (Parser.getTok().isNot(AsmToken::Hash) &&
12150 Parser.getTok().isNot(AsmToken::Dollar))
12151 return Error(Parser.getTok().getLoc(), "'#' expected");
12152 Parser.Lex(); // skip hash token.
12153
12154 const MCExpr *OffsetExpr;
12155 SMLoc ExLoc = Parser.getTok().getLoc();
12156 SMLoc EndLoc;
12157 if (getParser().parseExpression(OffsetExpr, EndLoc))
12158 return Error(ExLoc, "malformed setfp offset");
12159 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12160 if (check(!CE, ExLoc, "setfp offset must be an immediate"))
12161 return true;
12162 Offset = CE->getValue();
12163 }
12164
12165 if (Parser.parseEOL())
12166 return true;
12167
12168 getTargetStreamer().emitSetFP(FPReg, SPReg, Offset);
12169 return false;
12170}
12171
12172/// parseDirectivePad
12173/// ::= .pad offset
12174bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12175 MCAsmParser &Parser = getParser();
12176 // Check the ordering of unwind directives
12177 if (!UC.hasFnStart())
12178 return Error(L, ".fnstart must precede .pad directive");
12179 if (UC.hasHandlerData())
12180 return Error(L, ".pad must precede .handlerdata directive");
12181
12182 // Parse the offset
12183 if (Parser.getTok().isNot(AsmToken::Hash) &&
12184 Parser.getTok().isNot(AsmToken::Dollar))
12185 return Error(Parser.getTok().getLoc(), "'#' expected");
12186 Parser.Lex(); // skip hash token.
12187
12188 const MCExpr *OffsetExpr;
12189 SMLoc ExLoc = Parser.getTok().getLoc();
12190 SMLoc EndLoc;
12191 if (getParser().parseExpression(OffsetExpr, EndLoc))
12192 return Error(ExLoc, "malformed pad offset");
12193 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12194 if (!CE)
12195 return Error(ExLoc, "pad offset must be an immediate");
12196
12197 if (parseEOL())
12198 return true;
12199
12200 getTargetStreamer().emitPad(CE->getValue());
12201 return false;
12202}
12203
12204/// parseDirectiveRegSave
12205/// ::= .save { registers }
12206/// ::= .vsave { registers }
12207bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
12208 // Check the ordering of unwind directives
12209 if (!UC.hasFnStart())
12210 return Error(L, ".fnstart must precede .save or .vsave directives");
12211 if (UC.hasHandlerData())
12212 return Error(L, ".save or .vsave must precede .handlerdata directive");
12213
12214 // RAII object to make sure parsed operands are deleted.
12216
12217 // Parse the register list
12218 if (parseRegisterList(Operands, true, true) || parseEOL())
12219 return true;
12220 ARMOperand &Op = (ARMOperand &)*Operands[0];
12221 if (!IsVector && !Op.isRegList())
12222 return Error(L, ".save expects GPR registers");
12223 if (IsVector && !Op.isDPRRegList())
12224 return Error(L, ".vsave expects DPR registers");
12225
12226 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
12227 return false;
12228}
12229
12230/// parseDirectiveInst
12231/// ::= .inst opcode [, ...]
12232/// ::= .inst.n opcode [, ...]
12233/// ::= .inst.w opcode [, ...]
12234bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
12235 int Width = 4;
12236
12237 if (isThumb()) {
12238 switch (Suffix) {
12239 case 'n':
12240 Width = 2;
12241 break;
12242 case 'w':
12243 break;
12244 default:
12245 Width = 0;
12246 break;
12247 }
12248 } else {
12249 if (Suffix)
12250 return Error(Loc, "width suffixes are invalid in ARM mode");
12251 }
12252
12253 auto parseOne = [&]() -> bool {
12254 const MCExpr *Expr;
12255 if (getParser().parseExpression(Expr))
12256 return true;
12257 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
12258 if (!Value) {
12259 return Error(Loc, "expected constant expression");
12260 }
12261
12262 char CurSuffix = Suffix;
12263 switch (Width) {
12264 case 2:
12265 if (Value->getValue() > 0xffff)
12266 return Error(Loc, "inst.n operand is too big, use inst.w instead");
12267 break;
12268 case 4:
12269 if (Value->getValue() > 0xffffffff)
12270 return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +
12271 " operand is too big");
12272 break;
12273 case 0:
12274 // Thumb mode, no width indicated. Guess from the opcode, if possible.
12275 if (Value->getValue() < 0xe800)
12276 CurSuffix = 'n';
12277 else if (Value->getValue() >= 0xe8000000)
12278 CurSuffix = 'w';
12279 else
12280 return Error(Loc, "cannot determine Thumb instruction size, "
12281 "use inst.n/inst.w instead");
12282 break;
12283 default:
12284 llvm_unreachable("only supported widths are 2 and 4");
12285 }
12286
12287 getTargetStreamer().emitInst(Value->getValue(), CurSuffix);
12288 forwardITPosition();
12289 forwardVPTPosition();
12290 return false;
12291 };
12292
12293 if (parseOptionalToken(AsmToken::EndOfStatement))
12294 return Error(Loc, "expected expression following directive");
12295 if (parseMany(parseOne))
12296 return true;
12297 return false;
12298}
12299
12300/// parseDirectiveLtorg
12301/// ::= .ltorg | .pool
12302bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12303 if (parseEOL())
12304 return true;
12305 getTargetStreamer().emitCurrentConstantPool();
12306 return false;
12307}
12308
12309bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12310 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12311
12312 if (parseEOL())
12313 return true;
12314
12315 if (!Section) {
12316 getStreamer().initSections(getSTI());
12317 Section = getStreamer().getCurrentSectionOnly();
12318 }
12319
12320 assert(Section && "must have section to emit alignment");
12321 if (getContext().getAsmInfo().useCodeAlign(*Section))
12322 getStreamer().emitCodeAlignment(Align(2), getSTI());
12323 else
12324 getStreamer().emitValueToAlignment(Align(2));
12325
12326 return false;
12327}
12328
12329/// parseDirectivePersonalityIndex
12330/// ::= .personalityindex index
12331bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12332 MCAsmParser &Parser = getParser();
12333 bool HasExistingPersonality = UC.hasPersonality();
12334
12335 const MCExpr *IndexExpression;
12336 SMLoc IndexLoc = Parser.getTok().getLoc();
12337 if (Parser.parseExpression(IndexExpression) || parseEOL()) {
12338 return true;
12339 }
12340
12341 UC.recordPersonalityIndex(L);
12342
12343 if (!UC.hasFnStart()) {
12344 return Error(L, ".fnstart must precede .personalityindex directive");
12345 }
12346 if (UC.cantUnwind()) {
12347 Error(L, ".personalityindex cannot be used with .cantunwind");
12348 UC.emitCantUnwindLocNotes();
12349 return true;
12350 }
12351 if (UC.hasHandlerData()) {
12352 Error(L, ".personalityindex must precede .handlerdata directive");
12353 UC.emitHandlerDataLocNotes();
12354 return true;
12355 }
12356 if (HasExistingPersonality) {
12357 Error(L, "multiple personality directives");
12358 UC.emitPersonalityLocNotes();
12359 return true;
12360 }
12361
12362 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression);
12363 if (!CE)
12364 return Error(IndexLoc, "index must be a constant number");
12365 if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX)
12366 return Error(IndexLoc,
12367 "personality routine index should be in range [0-3]");
12368
12369 getTargetStreamer().emitPersonalityIndex(CE->getValue());
12370 return false;
12371}
12372
12373/// parseDirectiveUnwindRaw
12374/// ::= .unwind_raw offset, opcode [, opcode...]
12375bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12376 MCAsmParser &Parser = getParser();
12377 int64_t StackOffset;
12378 const MCExpr *OffsetExpr;
12379 SMLoc OffsetLoc = getLexer().getLoc();
12380
12381 if (!UC.hasFnStart())
12382 return Error(L, ".fnstart must precede .unwind_raw directives");
12383 if (getParser().parseExpression(OffsetExpr))
12384 return Error(OffsetLoc, "expected expression");
12385
12386 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12387 if (!CE)
12388 return Error(OffsetLoc, "offset must be a constant");
12389
12390 StackOffset = CE->getValue();
12391
12392 if (Parser.parseComma())
12393 return true;
12394
12396
12397 auto parseOne = [&]() -> bool {
12398 const MCExpr *OE = nullptr;
12399 SMLoc OpcodeLoc = getLexer().getLoc();
12400 if (check(getLexer().is(AsmToken::EndOfStatement) ||
12401 Parser.parseExpression(OE),
12402 OpcodeLoc, "expected opcode expression"))
12403 return true;
12404 const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE);
12405 if (!OC)
12406 return Error(OpcodeLoc, "opcode value must be a constant");
12407 const int64_t Opcode = OC->getValue();
12408 if (Opcode & ~0xff)
12409 return Error(OpcodeLoc, "invalid opcode");
12410 Opcodes.push_back(uint8_t(Opcode));
12411 return false;
12412 };
12413
12414 // Must have at least 1 element
12415 SMLoc OpcodeLoc = getLexer().getLoc();
12416 if (parseOptionalToken(AsmToken::EndOfStatement))
12417 return Error(OpcodeLoc, "expected opcode expression");
12418 if (parseMany(parseOne))
12419 return true;
12420
12421 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12422 return false;
12423}
12424
12425/// parseDirectiveTLSDescSeq
12426/// ::= .tlsdescseq tls-variable
12427bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12428 MCAsmParser &Parser = getParser();
12429
12430 if (getLexer().isNot(AsmToken::Identifier))
12431 return TokError("expected variable after '.tlsdescseq' directive");
12432
12433 auto *Sym = getContext().getOrCreateSymbol(Parser.getTok().getIdentifier());
12434 const auto *SRE =
12436 Lex();
12437
12438 if (parseEOL())
12439 return true;
12440
12441 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12442 return false;
12443}
12444
12445/// parseDirectiveMovSP
12446/// ::= .movsp reg [, #offset]
12447bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12448 MCAsmParser &Parser = getParser();
12449 if (!UC.hasFnStart())
12450 return Error(L, ".fnstart must precede .movsp directives");
12451 if (UC.getFPReg() != ARM::SP)
12452 return Error(L, "unexpected .movsp directive");
12453
12454 SMLoc SPRegLoc = Parser.getTok().getLoc();
12455 MCRegister SPReg = tryParseRegister();
12456 if (!SPReg)
12457 return Error(SPRegLoc, "register expected");
12458 if (SPReg == ARM::SP || SPReg == ARM::PC)
12459 return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
12460
12461 int64_t Offset = 0;
12462 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12463 if (Parser.parseToken(AsmToken::Hash, "expected #constant"))
12464 return true;
12465
12466 const MCExpr *OffsetExpr;
12467 SMLoc OffsetLoc = Parser.getTok().getLoc();
12468
12469 if (Parser.parseExpression(OffsetExpr))
12470 return Error(OffsetLoc, "malformed offset expression");
12471
12472 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12473 if (!CE)
12474 return Error(OffsetLoc, "offset must be an immediate constant");
12475
12476 Offset = CE->getValue();
12477 }
12478
12479 if (parseEOL())
12480 return true;
12481
12482 getTargetStreamer().emitMovSP(SPReg, Offset);
12483 UC.saveFPReg(SPReg);
12484
12485 return false;
12486}
12487
12488/// parseDirectiveObjectArch
12489/// ::= .object_arch name
12490bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12491 MCAsmParser &Parser = getParser();
12492 if (getLexer().isNot(AsmToken::Identifier))
12493 return Error(getLexer().getLoc(), "unexpected token");
12494
12495 StringRef Arch = Parser.getTok().getString();
12496 SMLoc ArchLoc = Parser.getTok().getLoc();
12497 Lex();
12498
12500
12501 if (ID == ARM::ArchKind::INVALID)
12502 return Error(ArchLoc, "unknown architecture '" + Arch + "'");
12503 if (parseToken(AsmToken::EndOfStatement))
12504 return true;
12505
12506 getTargetStreamer().emitObjectArch(ID);
12507 return false;
12508}
12509
12510/// parseDirectiveAlign
12511/// ::= .align
12512bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12513 // NOTE: if this is not the end of the statement, fall back to the target
12514 // agnostic handling for this directive which will correctly handle this.
12515 if (parseOptionalToken(AsmToken::EndOfStatement)) {
12516 // '.align' is target specifically handled to mean 2**2 byte alignment.
12517 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12518 assert(Section && "must have section to emit alignment");
12519 if (getContext().getAsmInfo().useCodeAlign(*Section))
12520 getStreamer().emitCodeAlignment(Align(4), getSTI(), 0);
12521 else
12522 getStreamer().emitValueToAlignment(Align(4), 0, 1, 0);
12523 return false;
12524 }
12525 return true;
12526}
12527
12528/// parseDirectiveThumbSet
12529/// ::= .thumb_set name, value
12530bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12531 MCAsmParser &Parser = getParser();
12532
12533 StringRef Name;
12534 if (check(Parser.parseIdentifier(Name),
12535 "expected identifier after '.thumb_set'") ||
12536 Parser.parseComma())
12537 return true;
12538
12539 MCSymbol *Sym;
12540 const MCExpr *Value;
12541 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
12542 Parser, Sym, Value))
12543 return true;
12544
12545 getTargetStreamer().emitThumbSet(Sym, Value);
12546 return false;
12547}
12548
12549/// parseDirectiveSEHAllocStack
12550/// ::= .seh_stackalloc
12551/// ::= .seh_stackalloc_w
12552bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L, bool Wide) {
12553 int64_t Size;
12554 if (parseImmExpr(Size))
12555 return true;
12556 getTargetStreamer().emitARMWinCFIAllocStack(Size, Wide);
12557 return false;
12558}
12559
12560/// parseDirectiveSEHSaveRegs
12561/// ::= .seh_save_regs
12562/// ::= .seh_save_regs_w
12563bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L, bool Wide) {
12565
12566 if (parseRegisterList(Operands) || parseEOL())
12567 return true;
12568 ARMOperand &Op = (ARMOperand &)*Operands[0];
12569 if (!Op.isRegList())
12570 return Error(L, ".seh_save_regs{_w} expects GPR registers");
12571 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12572 uint32_t Mask = 0;
12573 for (size_t i = 0; i < RegList.size(); ++i) {
12574 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12575 if (Reg == 15) // pc -> lr
12576 Reg = 14;
12577 if (Reg == 13)
12578 return Error(L, ".seh_save_regs{_w} can't include SP");
12579 assert(Reg < 16U && "Register out of range");
12580 unsigned Bit = (1u << Reg);
12581 Mask |= Bit;
12582 }
12583 if (!Wide && (Mask & 0x1f00) != 0)
12584 return Error(L,
12585 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12586 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12587 return false;
12588}
12589
12590/// parseDirectiveSEHSaveSP
12591/// ::= .seh_save_sp
12592bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12593 MCRegister Reg = tryParseRegister();
12594 if (!Reg || !MRI->getRegClass(ARM::GPRRegClassID).contains(Reg))
12595 return Error(L, "expected GPR");
12596 unsigned Index = MRI->getEncodingValue(Reg);
12597 if (Index > 14 || Index == 13)
12598 return Error(L, "invalid register for .seh_save_sp");
12599 getTargetStreamer().emitARMWinCFISaveSP(Index);
12600 return false;
12601}
12602
12603/// parseDirectiveSEHSaveFRegs
12604/// ::= .seh_save_fregs
12605bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12607
12608 if (parseRegisterList(Operands) || parseEOL())
12609 return true;
12610 ARMOperand &Op = (ARMOperand &)*Operands[0];
12611 if (!Op.isDPRRegList())
12612 return Error(L, ".seh_save_fregs expects DPR registers");
12613 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12614 uint32_t Mask = 0;
12615 for (size_t i = 0; i < RegList.size(); ++i) {
12616 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12617 assert(Reg < 32U && "Register out of range");
12618 unsigned Bit = (1u << Reg);
12619 Mask |= Bit;
12620 }
12621
12622 if (Mask == 0)
12623 return Error(L, ".seh_save_fregs missing registers");
12624
12625 unsigned First = 0;
12626 while ((Mask & 1) == 0) {
12627 First++;
12628 Mask >>= 1;
12629 }
12630 if (((Mask + 1) & Mask) != 0)
12631 return Error(L,
12632 ".seh_save_fregs must take a contiguous range of registers");
12633 unsigned Last = First;
12634 while ((Mask & 2) != 0) {
12635 Last++;
12636 Mask >>= 1;
12637 }
12638 if (First < 16 && Last >= 16)
12639 return Error(L, ".seh_save_fregs must be all d0-d15 or d16-d31");
12640 getTargetStreamer().emitARMWinCFISaveFRegs(First, Last);
12641 return false;
12642}
12643
12644/// parseDirectiveSEHSaveLR
12645/// ::= .seh_save_lr
12646bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12647 int64_t Offset;
12648 if (parseImmExpr(Offset))
12649 return true;
12650 getTargetStreamer().emitARMWinCFISaveLR(Offset);
12651 return false;
12652}
12653
12654/// parseDirectiveSEHPrologEnd
12655/// ::= .seh_endprologue
12656/// ::= .seh_endprologue_fragment
12657bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L, bool Fragment) {
12658 getTargetStreamer().emitARMWinCFIPrologEnd(Fragment);
12659 return false;
12660}
12661
12662/// parseDirectiveSEHNop
12663/// ::= .seh_nop
12664/// ::= .seh_nop_w
12665bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L, bool Wide) {
12666 getTargetStreamer().emitARMWinCFINop(Wide);
12667 return false;
12668}
12669
12670/// parseDirectiveSEHEpilogStart
12671/// ::= .seh_startepilogue
12672/// ::= .seh_startepilogue_cond
12673bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L, bool Condition) {
12674 unsigned CC = ARMCC::AL;
12675 if (Condition) {
12676 MCAsmParser &Parser = getParser();
12677 SMLoc S = Parser.getTok().getLoc();
12678 const AsmToken &Tok = Parser.getTok();
12679 if (!Tok.is(AsmToken::Identifier))
12680 return Error(S, ".seh_startepilogue_cond missing condition");
12681 CC = ARMCondCodeFromString(Tok.getString());
12682 if (CC == ~0U)
12683 return Error(S, "invalid condition");
12684 Parser.Lex(); // Eat the token.
12685 }
12686
12687 getTargetStreamer().emitARMWinCFIEpilogStart(CC);
12688 return false;
12689}
12690
12691/// parseDirectiveSEHEpilogEnd
12692/// ::= .seh_endepilogue
12693bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12694 getTargetStreamer().emitARMWinCFIEpilogEnd();
12695 return false;
12696}
12697
12698/// parseDirectiveSEHCustom
12699/// ::= .seh_custom
12700bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12701 unsigned Opcode = 0;
12702 do {
12703 int64_t Byte;
12704 if (parseImmExpr(Byte))
12705 return true;
12706 if (Byte > 0xff || Byte < 0)
12707 return Error(L, "Invalid byte value in .seh_custom");
12708 if (Opcode > 0x00ffffff)
12709 return Error(L, "Too many bytes in .seh_custom");
12710 // Store the bytes as one big endian number in Opcode. In a multi byte
12711 // opcode sequence, the first byte can't be zero.
12712 Opcode = (Opcode << 8) | Byte;
12713 } while (parseOptionalToken(AsmToken::Comma));
12714 getTargetStreamer().emitARMWinCFICustom(Opcode);
12715 return false;
12716}
12717
12718/// Force static initialization.
12725
12726#define GET_REGISTER_MATCHER
12727#define GET_SUBTARGET_FEATURE_NAME
12728#define GET_MATCHER_IMPLEMENTATION
12729#define GET_MNEMONIC_SPELL_CHECKER
12730#include "ARMGenAsmMatcher.inc"
12731
12732// Some diagnostics need to vary with subtarget features, so they are handled
12733// here. For example, the DPR class has either 16 or 32 registers, depending
12734// on the FPU available.
12735const char *
12736ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12737 switch (MatchError) {
12738 // rGPR contains sp starting with ARMv8.
12739 case Match_rGPR:
12740 return hasV8Ops() ? "operand must be a register in range [r0, r14]"
12741 : "operand must be a register in range [r0, r12] or r14";
12742 // DPR contains 16 registers for some FPUs, and 32 for others.
12743 case Match_DPR:
12744 return hasD32() ? "operand must be a register in range [d0, d31]"
12745 : "operand must be a register in range [d0, d15]";
12746 case Match_DPR_RegList:
12747 return hasD32() ? "operand must be a list of registers in range [d0, d31]"
12748 : "operand must be a list of registers in range [d0, d15]";
12749
12750 // For all other diags, use the static string from tablegen.
12751 default:
12752 return getMatchKindDiag(MatchError);
12753 }
12754}
12755
12756// Process the list of near-misses, throwing away ones we don't want to report
12757// to the user, and converting the rest to a source location and string that
12758// should be reported.
12759void
12760ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12761 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12762 SMLoc IDLoc, OperandVector &Operands) {
12763 // TODO: If operand didn't match, sub in a dummy one and run target
12764 // predicate, so that we can avoid reporting near-misses that are invalid?
12765 // TODO: Many operand types dont have SuperClasses set, so we report
12766 // redundant ones.
12767 // TODO: Some operands are superclasses of registers (e.g.
12768 // MCK_RegShiftedImm), we don't have any way to represent that currently.
12769 // TODO: This is not all ARM-specific, can some of it be factored out?
12770
12771 // Record some information about near-misses that we have already seen, so
12772 // that we can avoid reporting redundant ones. For example, if there are
12773 // variants of an instruction that take 8- and 16-bit immediates, we want
12774 // to only report the widest one.
12775 std::multimap<unsigned, unsigned> OperandMissesSeen;
12776 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12777 bool ReportedTooFewOperands = false;
12778
12779 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
12780
12781 // Process the near-misses in reverse order, so that we see more general ones
12782 // first, and so can avoid emitting more specific ones.
12783 for (NearMissInfo &I : reverse(NearMissesIn)) {
12784 switch (I.getKind()) {
12786 SMLoc OperandLoc =
12787 ((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
12788 const char *OperandDiag =
12789 getCustomOperandDiag((ARMMatchResultTy)I.getOperandError());
12790
12791 // If we have already emitted a message for a superclass, don't also report
12792 // the sub-class. We consider all operand classes that we don't have a
12793 // specialised diagnostic for to be equal for the propose of this check,
12794 // so that we don't report the generic error multiple times on the same
12795 // operand.
12796 unsigned DupCheckMatchClass = OperandDiag ? I.getOperandClass() : ~0U;
12797 auto PrevReports = OperandMissesSeen.equal_range(I.getOperandIndex());
12798 if (std::any_of(PrevReports.first, PrevReports.second,
12799 [DupCheckMatchClass](
12800 const std::pair<unsigned, unsigned> Pair) {
12801 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12802 return Pair.second == DupCheckMatchClass;
12803 else
12804 return isSubclass((MatchClassKind)DupCheckMatchClass,
12805 (MatchClassKind)Pair.second);
12806 }))
12807 break;
12808 OperandMissesSeen.insert(
12809 std::make_pair(I.getOperandIndex(), DupCheckMatchClass));
12810
12811 NearMissMessage Message;
12812 Message.Loc = OperandLoc;
12813 if (OperandDiag) {
12814 Message.Message = OperandDiag;
12815 } else if (I.getOperandClass() == InvalidMatchClass) {
12816 Message.Message = "too many operands for instruction";
12817 } else {
12818 Message.Message = "invalid operand for instruction";
12819 LLVM_DEBUG(
12820 dbgs() << "Missing diagnostic string for operand class "
12821 << getMatchClassName((MatchClassKind)I.getOperandClass())
12822 << I.getOperandClass() << ", error " << I.getOperandError()
12823 << ", opcode " << MII.getName(I.getOpcode()) << "\n");
12824 }
12825 NearMissesOut.emplace_back(Message);
12826 break;
12827 }
12829 const FeatureBitset &MissingFeatures = I.getFeatures();
12830 // Don't report the same set of features twice.
12831 if (FeatureMissesSeen.count(MissingFeatures))
12832 break;
12833 FeatureMissesSeen.insert(MissingFeatures);
12834
12835 // Special case: don't report a feature set which includes arm-mode for
12836 // targets that don't have ARM mode.
12837 if (MissingFeatures.test(Feature_IsARMBit) && !hasARM())
12838 break;
12839 // Don't report any near-misses that both require switching instruction
12840 // set, and adding other subtarget features.
12841 if (isThumb() && MissingFeatures.test(Feature_IsARMBit) &&
12842 MissingFeatures.count() > 1)
12843 break;
12844 if (!isThumb() && MissingFeatures.test(Feature_IsThumbBit) &&
12845 MissingFeatures.count() > 1)
12846 break;
12847 if (!isThumb() && MissingFeatures.test(Feature_IsThumb2Bit) &&
12848 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12849 Feature_IsThumbBit})).any())
12850 break;
12851 if (isMClass() && MissingFeatures.test(Feature_HasNEONBit))
12852 break;
12853
12854 NearMissMessage Message;
12855 Message.Loc = IDLoc;
12856 raw_svector_ostream OS(Message.Message);
12857
12858 OS << "instruction requires:";
12859 for (unsigned Feature : MissingFeatures)
12860 OS << ' ' << getSubtargetFeatureName(Feature);
12861
12862 NearMissesOut.emplace_back(Message);
12863
12864 break;
12865 }
12867 NearMissMessage Message;
12868 Message.Loc = IDLoc;
12869 switch (I.getPredicateError()) {
12870 case Match_RequiresNotITBlock:
12871 Message.Message = "flag setting instruction only valid outside IT block";
12872 break;
12873 case Match_RequiresITBlock:
12874 Message.Message = "instruction only valid inside IT block";
12875 break;
12876 case Match_RequiresV6:
12877 Message.Message = "instruction variant requires ARMv6 or later";
12878 break;
12879 case Match_RequiresThumb2:
12880 Message.Message = "instruction variant requires Thumb2";
12881 break;
12882 case Match_RequiresV8:
12883 Message.Message = "instruction variant requires ARMv8 or later";
12884 break;
12885 case Match_RequiresFlagSetting:
12886 Message.Message = "no flag-preserving variant of this instruction available";
12887 break;
12888 case Match_InvalidTiedOperand: {
12889 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[0]);
12890 if (Op.isToken() && Op.getToken() == "mul") {
12891 Message.Message = "destination register must match a source register";
12892 Message.Loc = Operands[MnemonicOpsEndInd]->getStartLoc();
12893 } else {
12894 llvm_unreachable("Match_InvalidTiedOperand only used for tMUL.");
12895 }
12896 break;
12897 }
12898 case Match_InvalidOperand:
12899 Message.Message = "invalid operand for instruction";
12900 break;
12901 default:
12902 llvm_unreachable("Unhandled target predicate error");
12903 break;
12904 }
12905 NearMissesOut.emplace_back(Message);
12906 break;
12907 }
12909 if (!ReportedTooFewOperands) {
12910 SMLoc EndLoc = ((ARMOperand &)*Operands.back()).getEndLoc();
12911 NearMissesOut.emplace_back(NearMissMessage{
12912 EndLoc, StringRef("too few operands for instruction")});
12913 ReportedTooFewOperands = true;
12914 }
12915 break;
12916 }
12918 // This should never leave the matcher.
12919 llvm_unreachable("not a near-miss");
12920 break;
12921 }
12922 }
12923}
12924
12925void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
12926 SMLoc IDLoc, OperandVector &Operands) {
12928 FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
12929
12930 if (Messages.size() == 0) {
12931 // No near-misses were found, so the best we can do is "invalid
12932 // instruction".
12933 Error(IDLoc, "invalid instruction");
12934 } else if (Messages.size() == 1) {
12935 // One near miss was found, report it as the sole error.
12936 Error(Messages[0].Loc, Messages[0].Message);
12937 } else {
12938 // More than one near miss, so report a generic "invalid instruction"
12939 // error, followed by notes for each of the near-misses.
12940 Error(IDLoc, "invalid instruction, any one of the following would fix this:");
12941 for (auto &M : Messages) {
12942 Note(M.Loc, M.Message);
12943 }
12944 }
12945}
12946
12947bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
12948 // FIXME: This structure should be moved inside ARMTargetParser
12949 // when we start to table-generate them, and we can use the ARM
12950 // flags below, that were generated by table-gen.
12951 static const struct {
12952 const uint64_t Kind;
12953 const FeatureBitset ArchCheck;
12954 const FeatureBitset Features;
12955 } Extensions[] = {
12956 {ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}},
12957 {ARM::AEK_AES,
12958 {Feature_HasV8Bit},
12959 {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12961 {Feature_HasV8Bit},
12962 {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12964 {Feature_HasV8Bit},
12965 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12967 {Feature_HasV8_1MMainlineBit},
12968 {ARM::HasMVEFloatOps}},
12969 {ARM::AEK_FP,
12970 {Feature_HasV8Bit},
12971 {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12973 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12974 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}},
12975 {ARM::AEK_MP,
12976 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12977 {ARM::FeatureMP}},
12979 {Feature_HasV8Bit},
12980 {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12981 {ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}},
12982 // FIXME: Only available in A-class, isel not predicated
12983 {ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}},
12985 {Feature_HasV8_2aBit},
12986 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
12987 {ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
12988 {ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
12989 {ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI}},
12990 // FIXME: Unsupported extensions.
12991 {ARM::AEK_OS, {}, {}},
12992 {ARM::AEK_IWMMXT, {}, {}},
12993 {ARM::AEK_IWMMXT2, {}, {}},
12994 {ARM::AEK_MAVERICK, {}, {}},
12995 {ARM::AEK_XSCALE, {}, {}},
12996 };
12997 bool EnableFeature = !Name.consume_front_insensitive("no");
12999 if (FeatureKind == ARM::AEK_INVALID)
13000 return Error(ExtLoc, "unknown architectural extension: " + Name);
13001
13002 for (const auto &Extension : Extensions) {
13003 if (Extension.Kind != FeatureKind)
13004 continue;
13005
13006 if (Extension.Features.none())
13007 return Error(ExtLoc, "unsupported architectural extension: " + Name);
13008
13009 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck)
13010 return Error(ExtLoc, "architectural extension '" + Name +
13011 "' is not "
13012 "allowed for the current base architecture");
13013
13014 MCSubtargetInfo &STI = copySTI();
13015 if (EnableFeature) {
13017 } else {
13019 }
13020 FeatureBitset Features = ComputeAvailableFeatures(STI.getFeatureBits());
13021 setAvailableFeatures(Features);
13022 return true;
13023 }
13024 return false;
13025}
13026
13027/// parseDirectiveArchExtension
13028/// ::= .arch_extension [no]feature
13029bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
13030
13031 MCAsmParser &Parser = getParser();
13032
13033 if (getLexer().isNot(AsmToken::Identifier))
13034 return Error(getLexer().getLoc(), "expected architecture extension name");
13035
13036 StringRef Name = Parser.getTok().getString();
13037 SMLoc ExtLoc = Parser.getTok().getLoc();
13038 Lex();
13039
13040 if (parseEOL())
13041 return true;
13042
13043 if (Name == "nocrypto") {
13044 enableArchExtFeature("nosha2", ExtLoc);
13045 enableArchExtFeature("noaes", ExtLoc);
13046 }
13047
13048 if (enableArchExtFeature(Name, ExtLoc))
13049 return false;
13050
13051 return Error(ExtLoc, "unknown architectural extension: " + Name);
13052}
13053
13054// Define this matcher function after the auto-generated include so we
13055// have the match class enum definitions.
13056unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13057 unsigned Kind) {
13058 ARMOperand &Op = static_cast<ARMOperand &>(AsmOp);
13059 // If the kind is a token for a literal immediate, check if our asm
13060 // operand matches. This is for InstAliases which have a fixed-value
13061 // immediate in the syntax.
13062 switch (Kind) {
13063 default: break;
13064 case MCK__HASH_0:
13065 if (Op.isImm())
13066 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13067 if (CE->getValue() == 0)
13068 return Match_Success;
13069 break;
13070 case MCK__HASH_8:
13071 if (Op.isImm())
13072 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13073 if (CE->getValue() == 8)
13074 return Match_Success;
13075 break;
13076 case MCK__HASH_16:
13077 if (Op.isImm())
13078 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13079 if (CE->getValue() == 16)
13080 return Match_Success;
13081 break;
13082 case MCK_ModImm:
13083 if (Op.isImm()) {
13084 const MCExpr *SOExpr = Op.getImm();
13085 int64_t Value;
13086 if (!SOExpr->evaluateAsAbsolute(Value))
13087 return Match_Success;
13088 assert((Value >= std::numeric_limits<int32_t>::min() &&
13089 Value <= std::numeric_limits<uint32_t>::max()) &&
13090 "expression value must be representable in 32 bits");
13091 }
13092 break;
13093 case MCK_rGPR:
13094 if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP)
13095 return Match_Success;
13096 return Match_rGPR;
13097 }
13098 return Match_InvalidOperand;
13099}
13100
13101bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic,
13102 StringRef ExtraToken) {
13103 if (!hasMVE())
13104 return false;
13105
13106 if (MS.isVPTPredicableCDEInstr(Mnemonic) ||
13107 (Mnemonic.starts_with("vldrh") && Mnemonic != "vldrhi") ||
13108 (Mnemonic.starts_with("vmov") &&
13109 !(ExtraToken == ".f16" || ExtraToken == ".32" || ExtraToken == ".16" ||
13110 ExtraToken == ".8")) ||
13111 (Mnemonic.starts_with("vrint") && Mnemonic != "vrintr") ||
13112 (Mnemonic.starts_with("vstrh") && Mnemonic != "vstrhi"))
13113 return true;
13114
13115 const char *predicable_prefixes[] = {
13116 "vabav", "vabd", "vabs", "vadc", "vadd",
13117 "vaddlv", "vaddv", "vand", "vbic", "vbrsr",
13118 "vcadd", "vcls", "vclz", "vcmla", "vcmp",
13119 "vcmul", "vctp", "vcvt", "vddup", "vdup",
13120 "vdwdup", "veor", "vfma", "vfmas", "vfms",
13121 "vhadd", "vhcadd", "vhsub", "vidup", "viwdup",
13122 "vldrb", "vldrd", "vldrw", "vmax", "vmaxa",
13123 "vmaxav", "vmaxnm", "vmaxnma", "vmaxnmav", "vmaxnmv",
13124 "vmaxv", "vmin", "vminav", "vminnm", "vminnmav",
13125 "vminnmv", "vminv", "vmla", "vmladav", "vmlaldav",
13126 "vmlalv", "vmlas", "vmlav", "vmlsdav", "vmlsldav",
13127 "vmovlb", "vmovlt", "vmovnb", "vmovnt", "vmul",
13128 "vmvn", "vneg", "vorn", "vorr", "vpnot",
13129 "vpsel", "vqabs", "vqadd", "vqdmladh", "vqdmlah",
13130 "vqdmlash", "vqdmlsdh", "vqdmulh", "vqdmull", "vqmovn",
13131 "vqmovun", "vqneg", "vqrdmladh", "vqrdmlah", "vqrdmlash",
13132 "vqrdmlsdh", "vqrdmulh", "vqrshl", "vqrshrn", "vqrshrun",
13133 "vqshl", "vqshrn", "vqshrun", "vqsub", "vrev16",
13134 "vrev32", "vrev64", "vrhadd", "vrmlaldavh", "vrmlalvh",
13135 "vrmlsldavh", "vrmulh", "vrshl", "vrshr", "vrshrn",
13136 "vsbc", "vshl", "vshlc", "vshll", "vshr",
13137 "vshrn", "vsli", "vsri", "vstrb", "vstrd",
13138 "vstrw", "vsub"};
13139
13140 return any_of(predicable_prefixes, [&Mnemonic](const char *prefix) {
13141 return Mnemonic.starts_with(prefix);
13142 });
13143}
13144
13145std::unique_ptr<ARMOperand> ARMAsmParser::defaultCondCodeOp() {
13146 return ARMOperand::CreateCondCode(ARMCC::AL, SMLoc(), *this);
13147}
13148
13149std::unique_ptr<ARMOperand> ARMAsmParser::defaultCCOutOp() {
13150 return ARMOperand::CreateCCOut(0, SMLoc(), *this);
13151}
13152
13153std::unique_ptr<ARMOperand> ARMAsmParser::defaultVPTPredOp() {
13154 return ARMOperand::CreateVPTPred(ARMVCC::None, SMLoc(), *this);
13155}
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)
AMDGPU Reserve WWM Registers
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)
static constexpr Value * getValue(Ty &ValueOrUse)
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
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
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:129
iterator end()
Definition StringMap.h:214
iterator find(StringRef Key)
Definition StringMap.h:227
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition StringMap.h:275
void erase(iterator I)
Definition StringMap.h:418
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition StringMap.h:311
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:1762
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
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:1986
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:1788
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,...