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 '" +
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::t2STRi12:
7829 case ARM::t2STRi8:
7830 case ARM::t2STRs:
7831 // Rt == PC is UNPREDICTABLE.
7832 if (Inst.getOperand(0).getReg() == ARM::PC)
7833 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7834 "operand must be a register in range [r0, r14]");
7835 break;
7836 case ARM::STR_PRE_IMM:
7837 case ARM::STR_PRE_REG:
7838 case ARM::t2STR_PRE:
7839 case ARM::STR_POST_IMM:
7840 case ARM::STR_POST_REG:
7841 case ARM::t2STR_POST:
7842 case ARM::STRH_PRE:
7843 case ARM::t2STRH_PRE:
7844 case ARM::STRH_POST:
7845 case ARM::t2STRH_POST:
7846 case ARM::STRB_PRE_IMM:
7847 case ARM::STRB_PRE_REG:
7848 case ARM::t2STRB_PRE:
7849 case ARM::STRB_POST_IMM:
7850 case ARM::STRB_POST_REG:
7851 case ARM::t2STRB_POST: {
7852 // Rt must be different from Rn.
7853 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7854 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
7855
7856 if (Rt == Rn)
7857 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7858 "source register and base register can't be identical");
7859 return false;
7860 }
7861 case ARM::t2LDR_PRE_imm:
7862 case ARM::t2LDR_POST_imm:
7863 case ARM::t2STR_PRE_imm:
7864 case ARM::t2STR_POST_imm: {
7865 // Rt must be different from Rn.
7866 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
7867 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7868
7869 if (Rt == Rn)
7870 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7871 "destination register and base register can't be identical");
7872 if (Inst.getOpcode() == ARM::t2LDR_POST_imm ||
7873 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7874 int Imm = Inst.getOperand(2).getImm();
7875 if (Imm > 255 || Imm < -255)
7876 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7877 "operand must be in range [-255, 255]");
7878 }
7879 if (Inst.getOpcode() == ARM::t2STR_PRE_imm ||
7880 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7881 if (Inst.getOperand(0).getReg() == ARM::PC) {
7882 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7883 "operand must be a register in range [r0, r14]");
7884 }
7885 }
7886 return false;
7887 }
7888
7889 case ARM::t2LDRB_OFFSET_imm:
7890 case ARM::t2LDRB_PRE_imm:
7891 case ARM::t2LDRB_POST_imm:
7892 case ARM::t2STRB_OFFSET_imm:
7893 case ARM::t2STRB_PRE_imm:
7894 case ARM::t2STRB_POST_imm: {
7895 if (Inst.getOpcode() == ARM::t2LDRB_POST_imm ||
7896 Inst.getOpcode() == ARM::t2STRB_POST_imm ||
7897 Inst.getOpcode() == ARM::t2LDRB_PRE_imm ||
7898 Inst.getOpcode() == ARM::t2STRB_PRE_imm) {
7899 int Imm = Inst.getOperand(2).getImm();
7900 if (Imm > 255 || Imm < -255)
7901 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7902 "operand must be in range [-255, 255]");
7903 } else if (Inst.getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7904 Inst.getOpcode() == ARM::t2STRB_OFFSET_imm) {
7905 int Imm = Inst.getOperand(2).getImm();
7906 if (Imm > 0 || Imm < -255)
7907 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7908 "operand must be in range [0, 255] with a negative sign");
7909 }
7910 if (Inst.getOperand(0).getReg() == ARM::PC) {
7911 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7912 "if operand is PC, should call the LDRB (literal)");
7913 }
7914 return false;
7915 }
7916
7917 case ARM::t2LDRH_OFFSET_imm:
7918 case ARM::t2LDRH_PRE_imm:
7919 case ARM::t2LDRH_POST_imm:
7920 case ARM::t2STRH_OFFSET_imm:
7921 case ARM::t2STRH_PRE_imm:
7922 case ARM::t2STRH_POST_imm: {
7923 if (Inst.getOpcode() == ARM::t2LDRH_POST_imm ||
7924 Inst.getOpcode() == ARM::t2STRH_POST_imm ||
7925 Inst.getOpcode() == ARM::t2LDRH_PRE_imm ||
7926 Inst.getOpcode() == ARM::t2STRH_PRE_imm) {
7927 int Imm = Inst.getOperand(2).getImm();
7928 if (Imm > 255 || Imm < -255)
7929 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7930 "operand must be in range [-255, 255]");
7931 } else if (Inst.getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7932 Inst.getOpcode() == ARM::t2STRH_OFFSET_imm) {
7933 int Imm = Inst.getOperand(2).getImm();
7934 if (Imm > 0 || Imm < -255)
7935 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7936 "operand must be in range [0, 255] with a negative sign");
7937 }
7938 if (Inst.getOperand(0).getReg() == ARM::PC) {
7939 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7940 "if operand is PC, should call the LDRH (literal)");
7941 }
7942 return false;
7943 }
7944
7945 case ARM::t2LDRSB_OFFSET_imm:
7946 case ARM::t2LDRSB_PRE_imm:
7947 case ARM::t2LDRSB_POST_imm: {
7948 if (Inst.getOpcode() == ARM::t2LDRSB_POST_imm ||
7949 Inst.getOpcode() == ARM::t2LDRSB_PRE_imm) {
7950 int Imm = Inst.getOperand(2).getImm();
7951 if (Imm > 255 || Imm < -255)
7952 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7953 "operand must be in range [-255, 255]");
7954 } else if (Inst.getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7955 int Imm = Inst.getOperand(2).getImm();
7956 if (Imm > 0 || Imm < -255)
7957 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7958 "operand must be in range [0, 255] with a negative sign");
7959 }
7960 if (Inst.getOperand(0).getReg() == ARM::PC) {
7961 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7962 "if operand is PC, should call the LDRH (literal)");
7963 }
7964 return false;
7965 }
7966
7967 case ARM::t2LDRSH_OFFSET_imm:
7968 case ARM::t2LDRSH_PRE_imm:
7969 case ARM::t2LDRSH_POST_imm: {
7970 if (Inst.getOpcode() == ARM::t2LDRSH_POST_imm ||
7971 Inst.getOpcode() == ARM::t2LDRSH_PRE_imm) {
7972 int Imm = Inst.getOperand(2).getImm();
7973 if (Imm > 255 || Imm < -255)
7974 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7975 "operand must be in range [-255, 255]");
7976 } else if (Inst.getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7977 int Imm = Inst.getOperand(2).getImm();
7978 if (Imm > 0 || Imm < -255)
7979 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7980 "operand must be in range [0, 255] with a negative sign");
7981 }
7982 if (Inst.getOperand(0).getReg() == ARM::PC) {
7983 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7984 "if operand is PC, should call the LDRH (literal)");
7985 }
7986 return false;
7987 }
7988
7989 case ARM::LDR_PRE_IMM:
7990 case ARM::LDR_PRE_REG:
7991 case ARM::t2LDR_PRE:
7992 case ARM::LDR_POST_IMM:
7993 case ARM::LDR_POST_REG:
7994 case ARM::t2LDR_POST:
7995 case ARM::LDRH_PRE:
7996 case ARM::t2LDRH_PRE:
7997 case ARM::LDRH_POST:
7998 case ARM::t2LDRH_POST:
7999 case ARM::LDRSH_PRE:
8000 case ARM::t2LDRSH_PRE:
8001 case ARM::LDRSH_POST:
8002 case ARM::t2LDRSH_POST:
8003 case ARM::LDRB_PRE_IMM:
8004 case ARM::LDRB_PRE_REG:
8005 case ARM::t2LDRB_PRE:
8006 case ARM::LDRB_POST_IMM:
8007 case ARM::LDRB_POST_REG:
8008 case ARM::t2LDRB_POST:
8009 case ARM::LDRSB_PRE:
8010 case ARM::t2LDRSB_PRE:
8011 case ARM::LDRSB_POST:
8012 case ARM::t2LDRSB_POST: {
8013 // Rt must be different from Rn.
8014 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8015 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8016
8017 if (Rt == Rn)
8018 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8019 "destination register and base register can't be identical");
8020 return false;
8021 }
8022
8023 case ARM::MVE_VLDRBU8_rq:
8024 case ARM::MVE_VLDRBU16_rq:
8025 case ARM::MVE_VLDRBS16_rq:
8026 case ARM::MVE_VLDRBU32_rq:
8027 case ARM::MVE_VLDRBS32_rq:
8028 case ARM::MVE_VLDRHU16_rq:
8029 case ARM::MVE_VLDRHU16_rq_u:
8030 case ARM::MVE_VLDRHU32_rq:
8031 case ARM::MVE_VLDRHU32_rq_u:
8032 case ARM::MVE_VLDRHS32_rq:
8033 case ARM::MVE_VLDRHS32_rq_u:
8034 case ARM::MVE_VLDRWU32_rq:
8035 case ARM::MVE_VLDRWU32_rq_u:
8036 case ARM::MVE_VLDRDU64_rq:
8037 case ARM::MVE_VLDRDU64_rq_u:
8038 case ARM::MVE_VLDRWU32_qi:
8039 case ARM::MVE_VLDRWU32_qi_pre:
8040 case ARM::MVE_VLDRDU64_qi:
8041 case ARM::MVE_VLDRDU64_qi_pre: {
8042 // Qd must be different from Qm.
8043 unsigned QdIdx = 0, QmIdx = 2;
8044 bool QmIsPointer = false;
8045 switch (Opcode) {
8046 case ARM::MVE_VLDRWU32_qi:
8047 case ARM::MVE_VLDRDU64_qi:
8048 QmIdx = 1;
8049 QmIsPointer = true;
8050 break;
8051 case ARM::MVE_VLDRWU32_qi_pre:
8052 case ARM::MVE_VLDRDU64_qi_pre:
8053 QdIdx = 1;
8054 QmIsPointer = true;
8055 break;
8056 }
8057
8058 const unsigned Qd = MRI->getEncodingValue(Inst.getOperand(QdIdx).getReg());
8059 const unsigned Qm = MRI->getEncodingValue(Inst.getOperand(QmIdx).getReg());
8060
8061 if (Qd == Qm) {
8062 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8063 Twine("destination vector register and vector ") +
8064 (QmIsPointer ? "pointer" : "offset") +
8065 " register can't be identical");
8066 }
8067 return false;
8068 }
8069
8070 case ARM::SBFX:
8071 case ARM::t2SBFX:
8072 case ARM::UBFX:
8073 case ARM::t2UBFX: {
8074 // Width must be in range [1, 32-lsb].
8075 unsigned LSB = Inst.getOperand(2).getImm();
8076 unsigned Widthm1 = Inst.getOperand(3).getImm();
8077 if (Widthm1 >= 32 - LSB)
8078 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8079 "bitfield width must be in range [1,32-lsb]");
8080 return false;
8081 }
8082 // Notionally handles ARM::tLDMIA_UPD too.
8083 case ARM::tLDMIA: {
8084 // If we're parsing Thumb2, the .w variant is available and handles
8085 // most cases that are normally illegal for a Thumb1 LDM instruction.
8086 // We'll make the transformation in processInstruction() if necessary.
8087 //
8088 // Thumb LDM instructions are writeback iff the base register is not
8089 // in the register list.
8090 MCRegister Rn = Inst.getOperand(0).getReg();
8091 bool HasWritebackToken =
8092 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8093 .isToken() &&
8094 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8095 .getToken() == "!");
8096
8097 bool ListContainsBase;
8098 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), ListContainsBase) &&
8099 !isThumbTwo())
8100 return Error(
8101 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8102 "registers must be in range r0-r7");
8103 // If we should have writeback, then there should be a '!' token.
8104 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8105 return Error(
8106 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8107 "writeback operator '!' expected");
8108 // If we should not have writeback, there must not be a '!'. This is
8109 // true even for the 32-bit wide encodings.
8110 if (ListContainsBase && HasWritebackToken)
8111 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8112 "writeback operator '!' not allowed when base register "
8113 "in register list");
8114
8115 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8116 return true;
8117 break;
8118 }
8119 case ARM::LDMIA_UPD:
8120 case ARM::LDMDB_UPD:
8121 case ARM::LDMIB_UPD:
8122 case ARM::LDMDA_UPD:
8123 // ARM variants loading and updating the same register are only officially
8124 // UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
8125 if (!hasV7Ops())
8126 break;
8127 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8128 return Error(Operands.back()->getStartLoc(),
8129 "writeback register not allowed in register list");
8130 break;
8131 case ARM::t2LDMIA:
8132 case ARM::t2LDMDB:
8133 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8134 return true;
8135 break;
8136 case ARM::t2STMIA:
8137 case ARM::t2STMDB:
8138 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8139 return true;
8140 break;
8141 case ARM::t2LDMIA_UPD:
8142 case ARM::t2LDMDB_UPD:
8143 case ARM::t2STMIA_UPD:
8144 case ARM::t2STMDB_UPD:
8145 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8146 return Error(Operands.back()->getStartLoc(),
8147 "writeback register not allowed in register list");
8148
8149 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8150 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8151 return true;
8152 } else {
8153 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8154 return true;
8155 }
8156 break;
8157
8158 case ARM::sysLDMIA_UPD:
8159 case ARM::sysLDMDA_UPD:
8160 case ARM::sysLDMDB_UPD:
8161 case ARM::sysLDMIB_UPD:
8162 if (!listContainsReg(Inst, 3, ARM::PC))
8163 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8164 "writeback register only allowed on system LDM "
8165 "if PC in register-list");
8166 break;
8167 case ARM::sysSTMIA_UPD:
8168 case ARM::sysSTMDA_UPD:
8169 case ARM::sysSTMDB_UPD:
8170 case ARM::sysSTMIB_UPD:
8171 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8172 "system STM cannot have writeback register");
8173 // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
8174 // so only issue a diagnostic for thumb1. The instructions will be
8175 // switched to the t2 encodings in processInstruction() if necessary.
8176 case ARM::tPOP: {
8177 bool ListContainsBase;
8178 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC,
8179 ListContainsBase) &&
8180 !isThumbTwo())
8181 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8182 "registers must be in range r0-r7 or pc");
8183 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 2, !isMClass()))
8184 return true;
8185 break;
8186 }
8187 case ARM::tPUSH: {
8188 bool ListContainsBase;
8189 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR,
8190 ListContainsBase) &&
8191 !isThumbTwo())
8192 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8193 "registers must be in range r0-r7 or lr");
8194 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 2))
8195 return true;
8196 break;
8197 }
8198 case ARM::tSTMIA_UPD: {
8199 bool ListContainsBase, InvalidLowList;
8200 InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(),
8201 0, ListContainsBase);
8202 if (InvalidLowList && !isThumbTwo())
8203 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8204 "registers must be in range r0-r7");
8205
8206 // This would be converted to a 32-bit stm, but that's not valid if the
8207 // writeback register is in the list.
8208 if (InvalidLowList && ListContainsBase)
8209 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8210 "writeback operator '!' not allowed when base register "
8211 "in register list");
8212
8213 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 4))
8214 return true;
8215 break;
8216 }
8217 case ARM::tADDrSP:
8218 // If the non-SP source operand and the destination operand are not the
8219 // same, we need thumb2 (for the wide encoding), or we have an error.
8220 if (!isThumbTwo() &&
8221 Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
8222 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8223 "source register must be the same as destination");
8224 }
8225 break;
8226
8227 case ARM::t2ADDrr:
8228 case ARM::t2ADDrs:
8229 case ARM::t2SUBrr:
8230 case ARM::t2SUBrs:
8231 if (Inst.getOperand(0).getReg() == ARM::SP &&
8232 Inst.getOperand(1).getReg() != ARM::SP)
8233 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8234 "source register must be sp if destination is sp");
8235 break;
8236
8237 // Final range checking for Thumb unconditional branch instructions.
8238 case ARM::tB:
8239 if (!(static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]))
8240 .isSignedOffset<11, 1>())
8241 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8242 "branch target out of range");
8243 break;
8244 case ARM::t2B: {
8245 int op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8246 : MnemonicOpsEndInd + 1;
8247 ARMOperand &Operand = static_cast<ARMOperand &>(*Operands[op]);
8248 // Delay the checks of symbolic expressions until they are resolved.
8249 if (!isa<MCBinaryExpr>(Operand.getImm()) &&
8250 !Operand.isSignedOffset<24, 1>())
8251 return Error(Operands[op]->getStartLoc(), "branch target out of range");
8252 break;
8253 }
8254 // Final range checking for Thumb conditional branch instructions.
8255 case ARM::tBcc:
8256 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8257 .isSignedOffset<8, 1>())
8258 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8259 "branch target out of range");
8260 break;
8261 case ARM::t2Bcc: {
8262 int Op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8263 : MnemonicOpsEndInd + 1;
8264 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
8265 return Error(Operands[Op]->getStartLoc(), "branch target out of range");
8266 break;
8267 }
8268 case ARM::tCBZ:
8269 case ARM::tCBNZ: {
8270 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8271 .isUnsignedOffset<6, 1>())
8272 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8273 "branch target out of range");
8274 break;
8275 }
8276 case ARM::MOVi16:
8277 case ARM::MOVTi16:
8278 case ARM::t2MOVi16:
8279 case ARM::t2MOVTi16:
8280 {
8281 // We want to avoid misleadingly allowing something like "mov r0, <symbol>"
8282 // especially when we turn it into a movw and the expression <symbol> does
8283 // not have a :lower16: or :upper16 as part of the expression. We don't
8284 // want the behavior of silently truncating, which can be unexpected and
8285 // lead to bugs that are difficult to find since this is an easy mistake
8286 // to make.
8287 int i = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8288 : MnemonicOpsEndInd + 1;
8289 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[i]);
8290 const MCExpr *E = Op.getImm();
8292 break;
8293 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(E);
8294 if (!ARM16Expr || (ARM16Expr->getSpecifier() != ARM::S_HI16 &&
8295 ARM16Expr->getSpecifier() != ARM::S_LO16))
8296 return Error(
8297 Op.getStartLoc(),
8298 "immediate expression for mov requires :lower16: or :upper16");
8299 break;
8300 }
8301 case ARM::tADDi8: {
8302 int i = (Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8303 : MnemonicOpsEndInd + 2;
8304 MCParsedAsmOperand &Op = *Operands[i];
8306 return Error(Op.getStartLoc(),
8307 "Immediate expression for Thumb adds requires :lower0_7:,"
8308 " :lower8_15:, :upper0_7: or :upper8_15:");
8309 break;
8310 }
8311 case ARM::tMOVi8: {
8312 MCParsedAsmOperand &Op = *Operands[MnemonicOpsEndInd + 1];
8314 return Error(Op.getStartLoc(),
8315 "Immediate expression for Thumb movs requires :lower0_7:,"
8316 " :lower8_15:, :upper0_7: or :upper8_15:");
8317 break;
8318 }
8319 case ARM::HINT:
8320 case ARM::t2HINT: {
8321 unsigned Imm8 = Inst.getOperand(0).getImm();
8322 unsigned Pred = Inst.getOperand(1).getImm();
8323 // ESB is not predicable (pred must be AL). Without the RAS extension, this
8324 // behaves as any other unallocated hint.
8325 if (Imm8 == 0x10 && Pred != ARMCC::AL && hasRAS())
8326 return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not "
8327 "predicable, but condition "
8328 "code specified");
8329 if (Imm8 == 0x14 && Pred != ARMCC::AL)
8330 return Error(Operands[1]->getStartLoc(), "instruction 'csdb' is not "
8331 "predicable, but condition "
8332 "code specified");
8333 break;
8334 }
8335 case ARM::t2BFi:
8336 case ARM::t2BFr:
8337 case ARM::t2BFLi:
8338 case ARM::t2BFLr: {
8339 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8340 .isUnsignedOffset<4, 1>() ||
8341 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0)) {
8342 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8343 "branch location out of range or not a multiple of 2");
8344 }
8345
8346 if (Opcode == ARM::t2BFi) {
8347 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8348 .isSignedOffset<16, 1>())
8349 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8350 "branch target out of range or not a multiple of 2");
8351 } else if (Opcode == ARM::t2BFLi) {
8352 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8353 .isSignedOffset<18, 1>())
8354 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8355 "branch target out of range or not a multiple of 2");
8356 }
8357 break;
8358 }
8359 case ARM::t2BFic: {
8360 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8361 .isUnsignedOffset<4, 1>() ||
8362 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0))
8363 return Error(Operands[1]->getStartLoc(),
8364 "branch location out of range or not a multiple of 2");
8365
8366 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8367 .isSignedOffset<16, 1>())
8368 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8369 "branch target out of range or not a multiple of 2");
8370
8371 assert(Inst.getOperand(0).isImm() == Inst.getOperand(2).isImm() &&
8372 "branch location and else branch target should either both be "
8373 "immediates or both labels");
8374
8375 if (Inst.getOperand(0).isImm() && Inst.getOperand(2).isImm()) {
8376 int Diff = Inst.getOperand(2).getImm() - Inst.getOperand(0).getImm();
8377 if (Diff != 4 && Diff != 2)
8378 return Error(
8379 Operands[3]->getStartLoc(),
8380 "else branch target must be 2 or 4 greater than the branch location");
8381 }
8382 break;
8383 }
8384 case ARM::t2CLRM: {
8385 for (unsigned i = 2; i < Inst.getNumOperands(); i++) {
8386 if (Inst.getOperand(i).isReg() &&
8387 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8388 .contains(Inst.getOperand(i).getReg())) {
8389 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8390 "invalid register in register list. Valid registers are "
8391 "r0-r12, lr/r14 and APSR.");
8392 }
8393 }
8394 break;
8395 }
8396 case ARM::DSB:
8397 case ARM::t2DSB: {
8398
8399 if (Inst.getNumOperands() < 2)
8400 break;
8401
8402 unsigned Option = Inst.getOperand(0).getImm();
8403 unsigned Pred = Inst.getOperand(1).getImm();
8404
8405 // SSBB and PSSBB (DSB #0|#4) are not predicable (pred must be AL).
8406 if (Option == 0 && Pred != ARMCC::AL)
8407 return Error(Operands[1]->getStartLoc(),
8408 "instruction 'ssbb' is not predicable, but condition code "
8409 "specified");
8410 if (Option == 4 && Pred != ARMCC::AL)
8411 return Error(Operands[1]->getStartLoc(),
8412 "instruction 'pssbb' is not predicable, but condition code "
8413 "specified");
8414 break;
8415 }
8416 case ARM::VMOVRRS: {
8417 // Source registers must be sequential.
8418 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8419 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(3).getReg());
8420 if (Sm1 != Sm + 1)
8421 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8422 "source operands must be sequential");
8423 break;
8424 }
8425 case ARM::VMOVSRR: {
8426 // Destination registers must be sequential.
8427 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8428 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
8429 if (Sm1 != Sm + 1)
8430 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8431 "destination operands must be sequential");
8432 break;
8433 }
8434 case ARM::VLDMDIA:
8435 case ARM::VSTMDIA: {
8436 ARMOperand &Op =
8437 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
8438 auto &RegList = Op.getRegList();
8439 if (RegList.size() < 1 || RegList.size() > 16)
8440 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8441 "list of registers must be at least 1 and at most 16");
8442 break;
8443 }
8444 case ARM::MVE_VQDMULLs32bh:
8445 case ARM::MVE_VQDMULLs32th:
8446 case ARM::MVE_VCMULf32:
8447 case ARM::MVE_VMULLBs32:
8448 case ARM::MVE_VMULLTs32:
8449 case ARM::MVE_VMULLBu32:
8450 case ARM::MVE_VMULLTu32: {
8451 if (Operands[MnemonicOpsEndInd]->getReg() ==
8452 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8453 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8454 "Qd register and Qn register can't be identical");
8455 }
8456 if (Operands[MnemonicOpsEndInd]->getReg() ==
8457 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8458 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8459 "Qd register and Qm register can't be identical");
8460 }
8461 break;
8462 }
8463 case ARM::MVE_VREV64_8:
8464 case ARM::MVE_VREV64_16:
8465 case ARM::MVE_VREV64_32:
8466 case ARM::MVE_VQDMULL_qr_s32bh:
8467 case ARM::MVE_VQDMULL_qr_s32th: {
8468 if (Operands[MnemonicOpsEndInd]->getReg() ==
8469 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8470 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8471 "Qd register and Qn register can't be identical");
8472 }
8473 break;
8474 }
8475 case ARM::MVE_VCADDi32:
8476 case ARM::MVE_VCADDf32:
8477 case ARM::MVE_VHCADDs32: {
8478 if (Operands[MnemonicOpsEndInd]->getReg() ==
8479 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8480 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8481 "Qd register and Qm register can't be identical");
8482 }
8483 break;
8484 }
8485 case ARM::MVE_VMOV_rr_q: {
8486 if (Operands[MnemonicOpsEndInd + 2]->getReg() !=
8487 Operands[MnemonicOpsEndInd + 4]->getReg())
8488 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8489 "Q-registers must be the same");
8490 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8491 .getVectorIndex() !=
8492 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 5])
8493 .getVectorIndex() +
8494 2)
8495 return Error(Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8496 "Q-register indexes must be 2 and 0 or 3 and 1");
8497 break;
8498 }
8499 case ARM::MVE_VMOV_q_rr: {
8500 if (Operands[MnemonicOpsEndInd]->getReg() !=
8501 Operands[MnemonicOpsEndInd + 2]->getReg())
8502 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8503 "Q-registers must be the same");
8504 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8505 .getVectorIndex() !=
8506 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8507 .getVectorIndex() +
8508 2)
8509 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8510 "Q-register indexes must be 2 and 0 or 3 and 1");
8511 break;
8512 }
8513 case ARM::MVE_SQRSHR:
8514 case ARM::MVE_UQRSHL: {
8515 if (Operands[MnemonicOpsEndInd]->getReg() ==
8516 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8517 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8518 "Rda register and Rm register can't be identical");
8519 }
8520 break;
8521 }
8522 case ARM::UMAAL:
8523 case ARM::UMLAL:
8524 case ARM::UMULL:
8525 case ARM::t2UMAAL:
8526 case ARM::t2UMLAL:
8527 case ARM::t2UMULL:
8528 case ARM::SMLAL:
8529 case ARM::SMLALBB:
8530 case ARM::SMLALBT:
8531 case ARM::SMLALD:
8532 case ARM::SMLALDX:
8533 case ARM::SMLALTB:
8534 case ARM::SMLALTT:
8535 case ARM::SMLSLD:
8536 case ARM::SMLSLDX:
8537 case ARM::SMULL:
8538 case ARM::t2SMLAL:
8539 case ARM::t2SMLALBB:
8540 case ARM::t2SMLALBT:
8541 case ARM::t2SMLALD:
8542 case ARM::t2SMLALDX:
8543 case ARM::t2SMLALTB:
8544 case ARM::t2SMLALTT:
8545 case ARM::t2SMLSLD:
8546 case ARM::t2SMLSLDX:
8547 case ARM::t2SMULL: {
8548 MCRegister RdHi = Inst.getOperand(0).getReg();
8549 MCRegister RdLo = Inst.getOperand(1).getReg();
8550 if(RdHi == RdLo) {
8551 return Error(Loc,
8552 "unpredictable instruction, RdHi and RdLo must be different");
8553 }
8554 break;
8555 }
8556
8557 case ARM::CDE_CX1:
8558 case ARM::CDE_CX1A:
8559 case ARM::CDE_CX1D:
8560 case ARM::CDE_CX1DA:
8561 case ARM::CDE_CX2:
8562 case ARM::CDE_CX2A:
8563 case ARM::CDE_CX2D:
8564 case ARM::CDE_CX2DA:
8565 case ARM::CDE_CX3:
8566 case ARM::CDE_CX3A:
8567 case ARM::CDE_CX3D:
8568 case ARM::CDE_CX3DA:
8569 case ARM::CDE_VCX1_vec:
8570 case ARM::CDE_VCX1_fpsp:
8571 case ARM::CDE_VCX1_fpdp:
8572 case ARM::CDE_VCX1A_vec:
8573 case ARM::CDE_VCX1A_fpsp:
8574 case ARM::CDE_VCX1A_fpdp:
8575 case ARM::CDE_VCX2_vec:
8576 case ARM::CDE_VCX2_fpsp:
8577 case ARM::CDE_VCX2_fpdp:
8578 case ARM::CDE_VCX2A_vec:
8579 case ARM::CDE_VCX2A_fpsp:
8580 case ARM::CDE_VCX2A_fpdp:
8581 case ARM::CDE_VCX3_vec:
8582 case ARM::CDE_VCX3_fpsp:
8583 case ARM::CDE_VCX3_fpdp:
8584 case ARM::CDE_VCX3A_vec:
8585 case ARM::CDE_VCX3A_fpsp:
8586 case ARM::CDE_VCX3A_fpdp: {
8587 assert(Inst.getOperand(1).isImm() &&
8588 "CDE operand 1 must be a coprocessor ID");
8589 int64_t Coproc = Inst.getOperand(1).getImm();
8590 if (Coproc < 8 && !ARM::isCDECoproc(Coproc, *STI))
8591 return Error(Operands[1]->getStartLoc(),
8592 "coprocessor must be configured as CDE");
8593 else if (Coproc >= 8)
8594 return Error(Operands[1]->getStartLoc(),
8595 "coprocessor must be in the range [p0, p7]");
8596 break;
8597 }
8598
8599 case ARM::t2CDP:
8600 case ARM::t2CDP2:
8601 case ARM::t2LDC2L_OFFSET:
8602 case ARM::t2LDC2L_OPTION:
8603 case ARM::t2LDC2L_POST:
8604 case ARM::t2LDC2L_PRE:
8605 case ARM::t2LDC2_OFFSET:
8606 case ARM::t2LDC2_OPTION:
8607 case ARM::t2LDC2_POST:
8608 case ARM::t2LDC2_PRE:
8609 case ARM::t2LDCL_OFFSET:
8610 case ARM::t2LDCL_OPTION:
8611 case ARM::t2LDCL_POST:
8612 case ARM::t2LDCL_PRE:
8613 case ARM::t2LDC_OFFSET:
8614 case ARM::t2LDC_OPTION:
8615 case ARM::t2LDC_POST:
8616 case ARM::t2LDC_PRE:
8617 case ARM::t2MCR:
8618 case ARM::t2MCR2:
8619 case ARM::t2MCRR:
8620 case ARM::t2MCRR2:
8621 case ARM::t2MRC:
8622 case ARM::t2MRC2:
8623 case ARM::t2MRRC:
8624 case ARM::t2MRRC2:
8625 case ARM::t2STC2L_OFFSET:
8626 case ARM::t2STC2L_OPTION:
8627 case ARM::t2STC2L_POST:
8628 case ARM::t2STC2L_PRE:
8629 case ARM::t2STC2_OFFSET:
8630 case ARM::t2STC2_OPTION:
8631 case ARM::t2STC2_POST:
8632 case ARM::t2STC2_PRE:
8633 case ARM::t2STCL_OFFSET:
8634 case ARM::t2STCL_OPTION:
8635 case ARM::t2STCL_POST:
8636 case ARM::t2STCL_PRE:
8637 case ARM::t2STC_OFFSET:
8638 case ARM::t2STC_OPTION:
8639 case ARM::t2STC_POST:
8640 case ARM::t2STC_PRE: {
8641 unsigned Opcode = Inst.getOpcode();
8642 // Inst.getOperand indexes operands in the (oops ...) and (iops ...) dags,
8643 // CopInd is the index of the coprocessor operand.
8644 size_t CopInd = 0;
8645 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8646 CopInd = 2;
8647 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8648 CopInd = 1;
8649 assert(Inst.getOperand(CopInd).isImm() &&
8650 "Operand must be a coprocessor ID");
8651 int64_t Coproc = Inst.getOperand(CopInd).getImm();
8652 // Operands[2] is the coprocessor operand at syntactic level
8653 if (ARM::isCDECoproc(Coproc, *STI))
8654 return Error(Operands[2]->getStartLoc(),
8655 "coprocessor must be configured as GCP");
8656 break;
8657 }
8658
8659 case ARM::VTOSHH:
8660 case ARM::VTOUHH:
8661 case ARM::VTOSLH:
8662 case ARM::VTOULH:
8663 case ARM::VTOSHS:
8664 case ARM::VTOUHS:
8665 case ARM::VTOSLS:
8666 case ARM::VTOULS:
8667 case ARM::VTOSHD:
8668 case ARM::VTOUHD:
8669 case ARM::VTOSLD:
8670 case ARM::VTOULD:
8671 case ARM::VSHTOH:
8672 case ARM::VUHTOH:
8673 case ARM::VSLTOH:
8674 case ARM::VULTOH:
8675 case ARM::VSHTOS:
8676 case ARM::VUHTOS:
8677 case ARM::VSLTOS:
8678 case ARM::VULTOS:
8679 case ARM::VSHTOD:
8680 case ARM::VUHTOD:
8681 case ARM::VSLTOD:
8682 case ARM::VULTOD: {
8683 if (Operands[MnemonicOpsEndInd]->getReg() !=
8684 Operands[MnemonicOpsEndInd + 1]->getReg())
8685 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8686 "source and destination registers must be the same");
8687 break;
8688 }
8689 }
8690
8691 return false;
8692}
8693
8694static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
8695 switch(Opc) {
8696 default: llvm_unreachable("unexpected opcode!");
8697 // VST1LN
8698 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8699 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8700 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8701 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8702 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8703 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8704 case ARM::VST1LNdAsm_8: Spacing = 1; return ARM::VST1LNd8;
8705 case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
8706 case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
8707
8708 // VST2LN
8709 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8710 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8711 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8712 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8713 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8714
8715 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8716 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8717 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8718 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8719 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8720
8721 case ARM::VST2LNdAsm_8: Spacing = 1; return ARM::VST2LNd8;
8722 case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
8723 case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
8724 case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
8725 case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
8726
8727 // VST3LN
8728 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8729 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8730 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8731 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
8732 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8733 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8734 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8735 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8736 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
8737 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8738 case ARM::VST3LNdAsm_8: Spacing = 1; return ARM::VST3LNd8;
8739 case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
8740 case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
8741 case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
8742 case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
8743
8744 // VST3
8745 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8746 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8747 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8748 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8749 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8750 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8751 case ARM::VST3dWB_register_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8752 case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8753 case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8754 case ARM::VST3qWB_register_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8755 case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8756 case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8757 case ARM::VST3dAsm_8: Spacing = 1; return ARM::VST3d8;
8758 case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
8759 case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
8760 case ARM::VST3qAsm_8: Spacing = 2; return ARM::VST3q8;
8761 case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
8762 case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
8763
8764 // VST4LN
8765 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8766 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8767 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8768 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
8769 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8770 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8771 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8772 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8773 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
8774 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8775 case ARM::VST4LNdAsm_8: Spacing = 1; return ARM::VST4LNd8;
8776 case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
8777 case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
8778 case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
8779 case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
8780
8781 // VST4
8782 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8783 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8784 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8785 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8786 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8787 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8788 case ARM::VST4dWB_register_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8789 case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8790 case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8791 case ARM::VST4qWB_register_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8792 case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8793 case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8794 case ARM::VST4dAsm_8: Spacing = 1; return ARM::VST4d8;
8795 case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
8796 case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
8797 case ARM::VST4qAsm_8: Spacing = 2; return ARM::VST4q8;
8798 case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
8799 case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
8800 }
8801}
8802
8803static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
8804 switch(Opc) {
8805 default: llvm_unreachable("unexpected opcode!");
8806 // VLD1LN
8807 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8808 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8809 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8810 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8811 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8812 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8813 case ARM::VLD1LNdAsm_8: Spacing = 1; return ARM::VLD1LNd8;
8814 case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
8815 case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
8816
8817 // VLD2LN
8818 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8819 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8820 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8821 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
8822 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8823 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8824 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8825 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8826 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
8827 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8828 case ARM::VLD2LNdAsm_8: Spacing = 1; return ARM::VLD2LNd8;
8829 case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
8830 case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
8831 case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
8832 case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
8833
8834 // VLD3DUP
8835 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8836 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8837 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8838 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
8839 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8840 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8841 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8842 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8843 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8844 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
8845 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8846 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8847 case ARM::VLD3DUPdAsm_8: Spacing = 1; return ARM::VLD3DUPd8;
8848 case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
8849 case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
8850 case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
8851 case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
8852 case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
8853
8854 // VLD3LN
8855 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8856 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8857 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8858 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
8859 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8860 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8861 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8862 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8863 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
8864 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8865 case ARM::VLD3LNdAsm_8: Spacing = 1; return ARM::VLD3LNd8;
8866 case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
8867 case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
8868 case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
8869 case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
8870
8871 // VLD3
8872 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8873 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8874 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8875 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8876 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8877 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8878 case ARM::VLD3dWB_register_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8879 case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8880 case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8881 case ARM::VLD3qWB_register_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8882 case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8883 case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8884 case ARM::VLD3dAsm_8: Spacing = 1; return ARM::VLD3d8;
8885 case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
8886 case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
8887 case ARM::VLD3qAsm_8: Spacing = 2; return ARM::VLD3q8;
8888 case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
8889 case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
8890
8891 // VLD4LN
8892 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8893 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8894 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8895 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8896 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8897 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8898 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8899 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8900 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8901 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8902 case ARM::VLD4LNdAsm_8: Spacing = 1; return ARM::VLD4LNd8;
8903 case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
8904 case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
8905 case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
8906 case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
8907
8908 // VLD4DUP
8909 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8910 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8911 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8912 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
8913 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
8914 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8915 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8916 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8917 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8918 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
8919 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
8920 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8921 case ARM::VLD4DUPdAsm_8: Spacing = 1; return ARM::VLD4DUPd8;
8922 case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
8923 case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
8924 case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
8925 case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
8926 case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
8927
8928 // VLD4
8929 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8930 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8931 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8932 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8933 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8934 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8935 case ARM::VLD4dWB_register_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8936 case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8937 case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8938 case ARM::VLD4qWB_register_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8939 case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8940 case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8941 case ARM::VLD4dAsm_8: Spacing = 1; return ARM::VLD4d8;
8942 case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
8943 case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
8944 case ARM::VLD4qAsm_8: Spacing = 2; return ARM::VLD4q8;
8945 case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
8946 case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
8947 }
8948}
8949
8950bool ARMAsmParser::processInstruction(MCInst &Inst,
8951 const OperandVector &Operands,
8952 unsigned MnemonicOpsEndInd,
8953 MCStreamer &Out) {
8954 // Check if we have the wide qualifier, because if it's present we
8955 // must avoid selecting a 16-bit thumb instruction.
8956 bool HasWideQualifier = false;
8957 for (auto &Op : Operands) {
8958 ARMOperand &ARMOp = static_cast<ARMOperand&>(*Op);
8959 if (ARMOp.isToken() && ARMOp.getToken() == ".w") {
8960 HasWideQualifier = true;
8961 break;
8962 }
8963 }
8964
8965 switch (Inst.getOpcode()) {
8966 case ARM::VLLDM:
8967 case ARM::VLSTM: {
8968 // In some cases both T1 and T2 are valid, causing tablegen pick T1 instead
8969 // of T2
8970 if (Operands.size() ==
8971 MnemonicOpsEndInd + 2) { // a register list has been provided
8972 ARMOperand &Op = static_cast<ARMOperand &>(
8973 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
8974 assert(Op.isDPRRegList());
8975 auto &RegList = Op.getRegList();
8976 // When the register list is {d0-d31} the instruction has to be the T2
8977 // variant
8978 if (RegList.size() == 32) {
8979 const unsigned Opcode =
8980 (Inst.getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8981 MCInst TmpInst;
8982 TmpInst.setOpcode(Opcode);
8983 TmpInst.addOperand(Inst.getOperand(0));
8984 TmpInst.addOperand(Inst.getOperand(1));
8985 TmpInst.addOperand(Inst.getOperand(2));
8986 TmpInst.addOperand(Inst.getOperand(3));
8987 Inst = TmpInst;
8988 return true;
8989 }
8990 }
8991 return false;
8992 }
8993 // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
8994 case ARM::LDRT_POST:
8995 case ARM::LDRBT_POST: {
8996 const unsigned Opcode =
8997 (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8998 : ARM::LDRBT_POST_IMM;
8999 MCInst TmpInst;
9000 TmpInst.setOpcode(Opcode);
9001 TmpInst.addOperand(Inst.getOperand(0));
9002 TmpInst.addOperand(Inst.getOperand(1));
9003 TmpInst.addOperand(Inst.getOperand(1));
9004 TmpInst.addOperand(MCOperand::createReg(0));
9005 TmpInst.addOperand(MCOperand::createImm(0));
9006 TmpInst.addOperand(Inst.getOperand(2));
9007 TmpInst.addOperand(Inst.getOperand(3));
9008 Inst = TmpInst;
9009 return true;
9010 }
9011 // Alias for 'ldr{sb,h,sh}t Rt, [Rn] {, #imm}' for omitted immediate.
9012 case ARM::LDRSBTii:
9013 case ARM::LDRHTii:
9014 case ARM::LDRSHTii: {
9015 MCInst TmpInst;
9016
9017 if (Inst.getOpcode() == ARM::LDRSBTii)
9018 TmpInst.setOpcode(ARM::LDRSBTi);
9019 else if (Inst.getOpcode() == ARM::LDRHTii)
9020 TmpInst.setOpcode(ARM::LDRHTi);
9021 else if (Inst.getOpcode() == ARM::LDRSHTii)
9022 TmpInst.setOpcode(ARM::LDRSHTi);
9023 TmpInst.addOperand(Inst.getOperand(0));
9024 TmpInst.addOperand(Inst.getOperand(1));
9025 TmpInst.addOperand(Inst.getOperand(1));
9026 TmpInst.addOperand(MCOperand::createImm(256));
9027 TmpInst.addOperand(Inst.getOperand(2));
9028 Inst = TmpInst;
9029 return true;
9030 }
9031 // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction.
9032 case ARM::STRT_POST:
9033 case ARM::STRBT_POST: {
9034 const unsigned Opcode =
9035 (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9036 : ARM::STRBT_POST_IMM;
9037 MCInst TmpInst;
9038 TmpInst.setOpcode(Opcode);
9039 TmpInst.addOperand(Inst.getOperand(1));
9040 TmpInst.addOperand(Inst.getOperand(0));
9041 TmpInst.addOperand(Inst.getOperand(1));
9042 TmpInst.addOperand(MCOperand::createReg(0));
9043 TmpInst.addOperand(MCOperand::createImm(0));
9044 TmpInst.addOperand(Inst.getOperand(2));
9045 TmpInst.addOperand(Inst.getOperand(3));
9046 Inst = TmpInst;
9047 return true;
9048 }
9049 // Alias for alternate form of 'ADR Rd, #imm' instruction.
9050 case ARM::ADDri: {
9051 if (Inst.getOperand(1).getReg() != ARM::PC || Inst.getOperand(5).getReg() ||
9052 !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
9053 return false;
9054 MCInst TmpInst;
9055 TmpInst.setOpcode(ARM::ADR);
9056 TmpInst.addOperand(Inst.getOperand(0));
9057 if (Inst.getOperand(2).isImm()) {
9058 // Immediate (mod_imm) will be in its encoded form, we must unencode it
9059 // before passing it to the ADR instruction.
9060 unsigned Enc = Inst.getOperand(2).getImm();
9062 llvm::rotr<uint32_t>(Enc & 0xFF, (Enc & 0xF00) >> 7)));
9063 } else {
9064 // Turn PC-relative expression into absolute expression.
9065 // Reading PC provides the start of the current instruction + 8 and
9066 // the transform to adr is biased by that.
9067 MCSymbol *Dot = getContext().createTempSymbol();
9068 Out.emitLabel(Dot);
9069 const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
9070 const MCExpr *InstPC = MCSymbolRefExpr::create(Dot,
9071 getContext());
9072 const MCExpr *Const8 = MCConstantExpr::create(8, getContext());
9073 const MCExpr *ReadPC = MCBinaryExpr::createAdd(InstPC, Const8,
9074 getContext());
9075 const MCExpr *FixupAddr = MCBinaryExpr::createAdd(ReadPC, OpExpr,
9076 getContext());
9077 TmpInst.addOperand(MCOperand::createExpr(FixupAddr));
9078 }
9079 TmpInst.addOperand(Inst.getOperand(3));
9080 TmpInst.addOperand(Inst.getOperand(4));
9081 Inst = TmpInst;
9082 return true;
9083 }
9084 // Aliases for imm syntax of LDR instructions.
9085 case ARM::t2LDR_PRE_imm:
9086 case ARM::t2LDR_POST_imm: {
9087 MCInst TmpInst;
9088 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDR_PRE_imm ? ARM::t2LDR_PRE
9089 : ARM::t2LDR_POST);
9090 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9091 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9092 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9093 TmpInst.addOperand(Inst.getOperand(2)); // imm
9094 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9095 TmpInst.addOperand(Inst.getOperand(4));
9096 Inst = TmpInst;
9097 return true;
9098 }
9099 // Aliases for imm syntax of STR instructions.
9100 case ARM::t2STR_PRE_imm:
9101 case ARM::t2STR_POST_imm: {
9102 MCInst TmpInst;
9103 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STR_PRE_imm ? ARM::t2STR_PRE
9104 : ARM::t2STR_POST);
9105 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9106 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9107 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9108 TmpInst.addOperand(Inst.getOperand(2)); // imm
9109 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9110 TmpInst.addOperand(Inst.getOperand(4));
9111 Inst = TmpInst;
9112 return true;
9113 }
9114 // Aliases for imm syntax of LDRB instructions.
9115 case ARM::t2LDRB_OFFSET_imm: {
9116 MCInst TmpInst;
9117 TmpInst.setOpcode(ARM::t2LDRBi8);
9118 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9119 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9120 TmpInst.addOperand(Inst.getOperand(2)); // imm
9121 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9122 Inst = TmpInst;
9123 return true;
9124 }
9125 case ARM::t2LDRB_PRE_imm:
9126 case ARM::t2LDRB_POST_imm: {
9127 MCInst TmpInst;
9128 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRB_PRE_imm
9129 ? ARM::t2LDRB_PRE
9130 : ARM::t2LDRB_POST);
9131 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9132 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9133 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9134 TmpInst.addOperand(Inst.getOperand(2)); // imm
9135 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9136 TmpInst.addOperand(Inst.getOperand(4));
9137 Inst = TmpInst;
9138 return true;
9139 }
9140 // Aliases for imm syntax of STRB instructions.
9141 case ARM::t2STRB_OFFSET_imm: {
9142 MCInst TmpInst;
9143 TmpInst.setOpcode(ARM::t2STRBi8);
9144 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9145 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9146 TmpInst.addOperand(Inst.getOperand(2)); // imm
9147 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9148 Inst = TmpInst;
9149 return true;
9150 }
9151 case ARM::t2STRB_PRE_imm:
9152 case ARM::t2STRB_POST_imm: {
9153 MCInst TmpInst;
9154 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRB_PRE_imm
9155 ? ARM::t2STRB_PRE
9156 : ARM::t2STRB_POST);
9157 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9158 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9159 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9160 TmpInst.addOperand(Inst.getOperand(2)); // imm
9161 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9162 TmpInst.addOperand(Inst.getOperand(4));
9163 Inst = TmpInst;
9164 return true;
9165 }
9166 // Aliases for imm syntax of LDRH instructions.
9167 case ARM::t2LDRH_OFFSET_imm: {
9168 MCInst TmpInst;
9169 TmpInst.setOpcode(ARM::t2LDRHi8);
9170 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9171 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9172 TmpInst.addOperand(Inst.getOperand(2)); // imm
9173 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9174 Inst = TmpInst;
9175 return true;
9176 }
9177 case ARM::t2LDRH_PRE_imm:
9178 case ARM::t2LDRH_POST_imm: {
9179 MCInst TmpInst;
9180 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRH_PRE_imm
9181 ? ARM::t2LDRH_PRE
9182 : ARM::t2LDRH_POST);
9183 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9184 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9185 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9186 TmpInst.addOperand(Inst.getOperand(2)); // imm
9187 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9188 TmpInst.addOperand(Inst.getOperand(4));
9189 Inst = TmpInst;
9190 return true;
9191 }
9192 // Aliases for imm syntax of STRH instructions.
9193 case ARM::t2STRH_OFFSET_imm: {
9194 MCInst TmpInst;
9195 TmpInst.setOpcode(ARM::t2STRHi8);
9196 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9197 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9198 TmpInst.addOperand(Inst.getOperand(2)); // imm
9199 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9200 Inst = TmpInst;
9201 return true;
9202 }
9203 case ARM::t2STRH_PRE_imm:
9204 case ARM::t2STRH_POST_imm: {
9205 MCInst TmpInst;
9206 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRH_PRE_imm
9207 ? ARM::t2STRH_PRE
9208 : ARM::t2STRH_POST);
9209 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9210 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9211 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9212 TmpInst.addOperand(Inst.getOperand(2)); // imm
9213 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9214 TmpInst.addOperand(Inst.getOperand(4));
9215 Inst = TmpInst;
9216 return true;
9217 }
9218 // Aliases for imm syntax of LDRSB instructions.
9219 case ARM::t2LDRSB_OFFSET_imm: {
9220 MCInst TmpInst;
9221 TmpInst.setOpcode(ARM::t2LDRSBi8);
9222 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9223 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9224 TmpInst.addOperand(Inst.getOperand(2)); // imm
9225 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9226 Inst = TmpInst;
9227 return true;
9228 }
9229 case ARM::t2LDRSB_PRE_imm:
9230 case ARM::t2LDRSB_POST_imm: {
9231 MCInst TmpInst;
9232 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSB_PRE_imm
9233 ? ARM::t2LDRSB_PRE
9234 : ARM::t2LDRSB_POST);
9235 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9236 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9237 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9238 TmpInst.addOperand(Inst.getOperand(2)); // imm
9239 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9240 TmpInst.addOperand(Inst.getOperand(4));
9241 Inst = TmpInst;
9242 return true;
9243 }
9244 // Aliases for imm syntax of LDRSH instructions.
9245 case ARM::t2LDRSH_OFFSET_imm: {
9246 MCInst TmpInst;
9247 TmpInst.setOpcode(ARM::t2LDRSHi8);
9248 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9249 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9250 TmpInst.addOperand(Inst.getOperand(2)); // imm
9251 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9252 Inst = TmpInst;
9253 return true;
9254 }
9255 case ARM::t2LDRSH_PRE_imm:
9256 case ARM::t2LDRSH_POST_imm: {
9257 MCInst TmpInst;
9258 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSH_PRE_imm
9259 ? ARM::t2LDRSH_PRE
9260 : ARM::t2LDRSH_POST);
9261 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9262 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9263 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9264 TmpInst.addOperand(Inst.getOperand(2)); // imm
9265 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9266 TmpInst.addOperand(Inst.getOperand(4));
9267 Inst = TmpInst;
9268 return true;
9269 }
9270 // Aliases for alternate PC+imm syntax of LDR instructions.
9271 case ARM::t2LDRpcrel:
9272 // Select the narrow version if the immediate will fit.
9273 if (Inst.getOperand(1).getImm() > 0 &&
9274 Inst.getOperand(1).getImm() <= 0xff &&
9275 !HasWideQualifier)
9276 Inst.setOpcode(ARM::tLDRpci);
9277 else
9278 Inst.setOpcode(ARM::t2LDRpci);
9279 return true;
9280 case ARM::t2LDRBpcrel:
9281 Inst.setOpcode(ARM::t2LDRBpci);
9282 return true;
9283 case ARM::t2LDRHpcrel:
9284 Inst.setOpcode(ARM::t2LDRHpci);
9285 return true;
9286 case ARM::t2LDRSBpcrel:
9287 Inst.setOpcode(ARM::t2LDRSBpci);
9288 return true;
9289 case ARM::t2LDRSHpcrel:
9290 Inst.setOpcode(ARM::t2LDRSHpci);
9291 return true;
9292 case ARM::LDRConstPool:
9293 case ARM::tLDRConstPool:
9294 case ARM::t2LDRConstPool: {
9295 // Pseudo instruction ldr rt, =immediate is converted to a
9296 // MOV rt, immediate if immediate is known and representable
9297 // otherwise we create a constant pool entry that we load from.
9298 MCInst TmpInst;
9299 if (Inst.getOpcode() == ARM::LDRConstPool)
9300 TmpInst.setOpcode(ARM::LDRi12);
9301 else if (Inst.getOpcode() == ARM::tLDRConstPool)
9302 TmpInst.setOpcode(ARM::tLDRpci);
9303 else if (Inst.getOpcode() == ARM::t2LDRConstPool)
9304 TmpInst.setOpcode(ARM::t2LDRpci);
9305 const ARMOperand &PoolOperand =
9306 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
9307 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9308 // If SubExprVal is a constant we may be able to use a MOV
9309 if (isa<MCConstantExpr>(SubExprVal) &&
9310 Inst.getOperand(0).getReg() != ARM::PC &&
9311 Inst.getOperand(0).getReg() != ARM::SP) {
9312 int64_t Value = (cast<MCConstantExpr>(SubExprVal))->getValue();
9313 bool UseMov = true;
9314 bool MovHasS = true;
9315 if (Inst.getOpcode() == ARM::LDRConstPool) {
9316 // ARM Constant
9317 if (ARM_AM::getSOImmVal(Value) != -1) {
9319 TmpInst.setOpcode(ARM::MOVi);
9320 }
9321 else if (ARM_AM::getSOImmVal(~Value) != -1) {
9323 TmpInst.setOpcode(ARM::MVNi);
9324 }
9325 else if (hasV6T2Ops() &&
9326 Value >=0 && Value < 65536) {
9327 TmpInst.setOpcode(ARM::MOVi16);
9328 MovHasS = false;
9329 }
9330 else
9331 UseMov = false;
9332 }
9333 else {
9334 // Thumb/Thumb2 Constant
9335 if (hasThumb2() &&
9337 TmpInst.setOpcode(ARM::t2MOVi);
9338 else if (hasThumb2() &&
9339 ARM_AM::getT2SOImmVal(~Value) != -1) {
9340 TmpInst.setOpcode(ARM::t2MVNi);
9341 Value = ~Value;
9342 }
9343 else if (hasV8MBaseline() &&
9344 Value >=0 && Value < 65536) {
9345 TmpInst.setOpcode(ARM::t2MOVi16);
9346 MovHasS = false;
9347 }
9348 else
9349 UseMov = false;
9350 }
9351 if (UseMov) {
9352 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9353 TmpInst.addOperand(MCOperand::createImm(Value)); // Immediate
9354 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9355 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9356 if (MovHasS)
9357 TmpInst.addOperand(MCOperand::createReg(0)); // S
9358 Inst = TmpInst;
9359 return true;
9360 }
9361 }
9362 // No opportunity to use MOV/MVN create constant pool
9363 const MCExpr *CPLoc =
9364 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9365 PoolOperand.getStartLoc());
9366 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9367 TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool
9368 if (TmpInst.getOpcode() == ARM::LDRi12)
9369 TmpInst.addOperand(MCOperand::createImm(0)); // unused offset
9370 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9371 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9372 Inst = TmpInst;
9373 return true;
9374 }
9375 // Handle NEON VST complex aliases.
9376 case ARM::VST1LNdWB_register_Asm_8:
9377 case ARM::VST1LNdWB_register_Asm_16:
9378 case ARM::VST1LNdWB_register_Asm_32: {
9379 MCInst TmpInst;
9380 // Shuffle the operands around so the lane index operand is in the
9381 // right place.
9382 unsigned Spacing;
9383 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9384 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9385 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9386 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9387 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9388 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9389 TmpInst.addOperand(Inst.getOperand(1)); // lane
9390 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9391 TmpInst.addOperand(Inst.getOperand(6));
9392 Inst = TmpInst;
9393 return true;
9394 }
9395
9396 case ARM::VST2LNdWB_register_Asm_8:
9397 case ARM::VST2LNdWB_register_Asm_16:
9398 case ARM::VST2LNdWB_register_Asm_32:
9399 case ARM::VST2LNqWB_register_Asm_16:
9400 case ARM::VST2LNqWB_register_Asm_32: {
9401 MCInst TmpInst;
9402 // Shuffle the operands around so the lane index operand is in the
9403 // right place.
9404 unsigned Spacing;
9405 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9406 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9407 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9408 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9409 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9410 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9412 Spacing));
9413 TmpInst.addOperand(Inst.getOperand(1)); // lane
9414 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9415 TmpInst.addOperand(Inst.getOperand(6));
9416 Inst = TmpInst;
9417 return true;
9418 }
9419
9420 case ARM::VST3LNdWB_register_Asm_8:
9421 case ARM::VST3LNdWB_register_Asm_16:
9422 case ARM::VST3LNdWB_register_Asm_32:
9423 case ARM::VST3LNqWB_register_Asm_16:
9424 case ARM::VST3LNqWB_register_Asm_32: {
9425 MCInst TmpInst;
9426 // Shuffle the operands around so the lane index operand is in the
9427 // right place.
9428 unsigned Spacing;
9429 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9430 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9431 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9432 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9433 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9434 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9436 Spacing));
9438 Spacing * 2));
9439 TmpInst.addOperand(Inst.getOperand(1)); // lane
9440 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9441 TmpInst.addOperand(Inst.getOperand(6));
9442 Inst = TmpInst;
9443 return true;
9444 }
9445
9446 case ARM::VST4LNdWB_register_Asm_8:
9447 case ARM::VST4LNdWB_register_Asm_16:
9448 case ARM::VST4LNdWB_register_Asm_32:
9449 case ARM::VST4LNqWB_register_Asm_16:
9450 case ARM::VST4LNqWB_register_Asm_32: {
9451 MCInst TmpInst;
9452 // Shuffle the operands around so the lane index operand is in the
9453 // right place.
9454 unsigned Spacing;
9455 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9456 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9457 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9458 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9459 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9460 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9462 Spacing));
9464 Spacing * 2));
9466 Spacing * 3));
9467 TmpInst.addOperand(Inst.getOperand(1)); // lane
9468 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9469 TmpInst.addOperand(Inst.getOperand(6));
9470 Inst = TmpInst;
9471 return true;
9472 }
9473
9474 case ARM::VST1LNdWB_fixed_Asm_8:
9475 case ARM::VST1LNdWB_fixed_Asm_16:
9476 case ARM::VST1LNdWB_fixed_Asm_32: {
9477 MCInst TmpInst;
9478 // Shuffle the operands around so the lane index operand is in the
9479 // right place.
9480 unsigned Spacing;
9481 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9482 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9483 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9484 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9485 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9486 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9487 TmpInst.addOperand(Inst.getOperand(1)); // lane
9488 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9489 TmpInst.addOperand(Inst.getOperand(5));
9490 Inst = TmpInst;
9491 return true;
9492 }
9493
9494 case ARM::VST2LNdWB_fixed_Asm_8:
9495 case ARM::VST2LNdWB_fixed_Asm_16:
9496 case ARM::VST2LNdWB_fixed_Asm_32:
9497 case ARM::VST2LNqWB_fixed_Asm_16:
9498 case ARM::VST2LNqWB_fixed_Asm_32: {
9499 MCInst TmpInst;
9500 // Shuffle the operands around so the lane index operand is in the
9501 // right place.
9502 unsigned Spacing;
9503 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9504 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9505 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9506 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9507 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9508 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9510 Spacing));
9511 TmpInst.addOperand(Inst.getOperand(1)); // lane
9512 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9513 TmpInst.addOperand(Inst.getOperand(5));
9514 Inst = TmpInst;
9515 return true;
9516 }
9517
9518 case ARM::VST3LNdWB_fixed_Asm_8:
9519 case ARM::VST3LNdWB_fixed_Asm_16:
9520 case ARM::VST3LNdWB_fixed_Asm_32:
9521 case ARM::VST3LNqWB_fixed_Asm_16:
9522 case ARM::VST3LNqWB_fixed_Asm_32: {
9523 MCInst TmpInst;
9524 // Shuffle the operands around so the lane index operand is in the
9525 // right place.
9526 unsigned Spacing;
9527 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9528 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9529 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9530 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9531 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9532 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9534 Spacing));
9536 Spacing * 2));
9537 TmpInst.addOperand(Inst.getOperand(1)); // lane
9538 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9539 TmpInst.addOperand(Inst.getOperand(5));
9540 Inst = TmpInst;
9541 return true;
9542 }
9543
9544 case ARM::VST4LNdWB_fixed_Asm_8:
9545 case ARM::VST4LNdWB_fixed_Asm_16:
9546 case ARM::VST4LNdWB_fixed_Asm_32:
9547 case ARM::VST4LNqWB_fixed_Asm_16:
9548 case ARM::VST4LNqWB_fixed_Asm_32: {
9549 MCInst TmpInst;
9550 // Shuffle the operands around so the lane index operand is in the
9551 // right place.
9552 unsigned Spacing;
9553 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9554 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9555 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9556 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9557 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9558 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9560 Spacing));
9562 Spacing * 2));
9564 Spacing * 3));
9565 TmpInst.addOperand(Inst.getOperand(1)); // lane
9566 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9567 TmpInst.addOperand(Inst.getOperand(5));
9568 Inst = TmpInst;
9569 return true;
9570 }
9571
9572 case ARM::VST1LNdAsm_8:
9573 case ARM::VST1LNdAsm_16:
9574 case ARM::VST1LNdAsm_32: {
9575 MCInst TmpInst;
9576 // Shuffle the operands around so the lane index operand is in the
9577 // right place.
9578 unsigned Spacing;
9579 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9580 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9581 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9582 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9583 TmpInst.addOperand(Inst.getOperand(1)); // lane
9584 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9585 TmpInst.addOperand(Inst.getOperand(5));
9586 Inst = TmpInst;
9587 return true;
9588 }
9589
9590 case ARM::VST2LNdAsm_8:
9591 case ARM::VST2LNdAsm_16:
9592 case ARM::VST2LNdAsm_32:
9593 case ARM::VST2LNqAsm_16:
9594 case ARM::VST2LNqAsm_32: {
9595 MCInst TmpInst;
9596 // Shuffle the operands around so the lane index operand is in the
9597 // right place.
9598 unsigned Spacing;
9599 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9600 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9601 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9602 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9604 Spacing));
9605 TmpInst.addOperand(Inst.getOperand(1)); // lane
9606 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9607 TmpInst.addOperand(Inst.getOperand(5));
9608 Inst = TmpInst;
9609 return true;
9610 }
9611
9612 case ARM::VST3LNdAsm_8:
9613 case ARM::VST3LNdAsm_16:
9614 case ARM::VST3LNdAsm_32:
9615 case ARM::VST3LNqAsm_16:
9616 case ARM::VST3LNqAsm_32: {
9617 MCInst TmpInst;
9618 // Shuffle the operands around so the lane index operand is in the
9619 // right place.
9620 unsigned Spacing;
9621 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9622 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9623 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9624 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9626 Spacing));
9628 Spacing * 2));
9629 TmpInst.addOperand(Inst.getOperand(1)); // lane
9630 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9631 TmpInst.addOperand(Inst.getOperand(5));
9632 Inst = TmpInst;
9633 return true;
9634 }
9635
9636 case ARM::VST4LNdAsm_8:
9637 case ARM::VST4LNdAsm_16:
9638 case ARM::VST4LNdAsm_32:
9639 case ARM::VST4LNqAsm_16:
9640 case ARM::VST4LNqAsm_32: {
9641 MCInst TmpInst;
9642 // Shuffle the operands around so the lane index operand is in the
9643 // right place.
9644 unsigned Spacing;
9645 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9646 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9647 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9648 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9650 Spacing));
9652 Spacing * 2));
9654 Spacing * 3));
9655 TmpInst.addOperand(Inst.getOperand(1)); // lane
9656 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9657 TmpInst.addOperand(Inst.getOperand(5));
9658 Inst = TmpInst;
9659 return true;
9660 }
9661
9662 // Handle NEON VLD complex aliases.
9663 case ARM::VLD1LNdWB_register_Asm_8:
9664 case ARM::VLD1LNdWB_register_Asm_16:
9665 case ARM::VLD1LNdWB_register_Asm_32: {
9666 MCInst TmpInst;
9667 // Shuffle the operands around so the lane index operand is in the
9668 // right place.
9669 unsigned Spacing;
9670 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9671 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9672 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9673 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9674 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9675 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9676 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9677 TmpInst.addOperand(Inst.getOperand(1)); // lane
9678 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9679 TmpInst.addOperand(Inst.getOperand(6));
9680 Inst = TmpInst;
9681 return true;
9682 }
9683
9684 case ARM::VLD2LNdWB_register_Asm_8:
9685 case ARM::VLD2LNdWB_register_Asm_16:
9686 case ARM::VLD2LNdWB_register_Asm_32:
9687 case ARM::VLD2LNqWB_register_Asm_16:
9688 case ARM::VLD2LNqWB_register_Asm_32: {
9689 MCInst TmpInst;
9690 // Shuffle the operands around so the lane index operand is in the
9691 // right place.
9692 unsigned Spacing;
9693 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9694 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9696 Spacing));
9697 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9698 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9699 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9700 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9701 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9703 Spacing));
9704 TmpInst.addOperand(Inst.getOperand(1)); // lane
9705 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9706 TmpInst.addOperand(Inst.getOperand(6));
9707 Inst = TmpInst;
9708 return true;
9709 }
9710
9711 case ARM::VLD3LNdWB_register_Asm_8:
9712 case ARM::VLD3LNdWB_register_Asm_16:
9713 case ARM::VLD3LNdWB_register_Asm_32:
9714 case ARM::VLD3LNqWB_register_Asm_16:
9715 case ARM::VLD3LNqWB_register_Asm_32: {
9716 MCInst TmpInst;
9717 // Shuffle the operands around so the lane index operand is in the
9718 // right place.
9719 unsigned Spacing;
9720 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9721 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9723 Spacing));
9725 Spacing * 2));
9726 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9727 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9728 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9729 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9730 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9732 Spacing));
9734 Spacing * 2));
9735 TmpInst.addOperand(Inst.getOperand(1)); // lane
9736 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9737 TmpInst.addOperand(Inst.getOperand(6));
9738 Inst = TmpInst;
9739 return true;
9740 }
9741
9742 case ARM::VLD4LNdWB_register_Asm_8:
9743 case ARM::VLD4LNdWB_register_Asm_16:
9744 case ARM::VLD4LNdWB_register_Asm_32:
9745 case ARM::VLD4LNqWB_register_Asm_16:
9746 case ARM::VLD4LNqWB_register_Asm_32: {
9747 MCInst TmpInst;
9748 // Shuffle the operands around so the lane index operand is in the
9749 // right place.
9750 unsigned Spacing;
9751 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9752 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9754 Spacing));
9756 Spacing * 2));
9758 Spacing * 3));
9759 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9760 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9761 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9762 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9763 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9765 Spacing));
9767 Spacing * 2));
9769 Spacing * 3));
9770 TmpInst.addOperand(Inst.getOperand(1)); // lane
9771 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9772 TmpInst.addOperand(Inst.getOperand(6));
9773 Inst = TmpInst;
9774 return true;
9775 }
9776
9777 case ARM::VLD1LNdWB_fixed_Asm_8:
9778 case ARM::VLD1LNdWB_fixed_Asm_16:
9779 case ARM::VLD1LNdWB_fixed_Asm_32: {
9780 MCInst TmpInst;
9781 // Shuffle the operands around so the lane index operand is in the
9782 // right place.
9783 unsigned Spacing;
9784 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9785 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9786 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9787 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9788 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9789 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9790 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9791 TmpInst.addOperand(Inst.getOperand(1)); // lane
9792 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9793 TmpInst.addOperand(Inst.getOperand(5));
9794 Inst = TmpInst;
9795 return true;
9796 }
9797
9798 case ARM::VLD2LNdWB_fixed_Asm_8:
9799 case ARM::VLD2LNdWB_fixed_Asm_16:
9800 case ARM::VLD2LNdWB_fixed_Asm_32:
9801 case ARM::VLD2LNqWB_fixed_Asm_16:
9802 case ARM::VLD2LNqWB_fixed_Asm_32: {
9803 MCInst TmpInst;
9804 // Shuffle the operands around so the lane index operand is in the
9805 // right place.
9806 unsigned Spacing;
9807 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9808 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9810 Spacing));
9811 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9812 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9813 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9814 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9815 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9817 Spacing));
9818 TmpInst.addOperand(Inst.getOperand(1)); // lane
9819 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9820 TmpInst.addOperand(Inst.getOperand(5));
9821 Inst = TmpInst;
9822 return true;
9823 }
9824
9825 case ARM::VLD3LNdWB_fixed_Asm_8:
9826 case ARM::VLD3LNdWB_fixed_Asm_16:
9827 case ARM::VLD3LNdWB_fixed_Asm_32:
9828 case ARM::VLD3LNqWB_fixed_Asm_16:
9829 case ARM::VLD3LNqWB_fixed_Asm_32: {
9830 MCInst TmpInst;
9831 // Shuffle the operands around so the lane index operand is in the
9832 // right place.
9833 unsigned Spacing;
9834 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9835 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9837 Spacing));
9839 Spacing * 2));
9840 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9841 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9842 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9843 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9844 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9846 Spacing));
9848 Spacing * 2));
9849 TmpInst.addOperand(Inst.getOperand(1)); // lane
9850 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9851 TmpInst.addOperand(Inst.getOperand(5));
9852 Inst = TmpInst;
9853 return true;
9854 }
9855
9856 case ARM::VLD4LNdWB_fixed_Asm_8:
9857 case ARM::VLD4LNdWB_fixed_Asm_16:
9858 case ARM::VLD4LNdWB_fixed_Asm_32:
9859 case ARM::VLD4LNqWB_fixed_Asm_16:
9860 case ARM::VLD4LNqWB_fixed_Asm_32: {
9861 MCInst TmpInst;
9862 // Shuffle the operands around so the lane index operand is in the
9863 // right place.
9864 unsigned Spacing;
9865 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9866 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9868 Spacing));
9870 Spacing * 2));
9872 Spacing * 3));
9873 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9874 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9875 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9876 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9877 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9879 Spacing));
9881 Spacing * 2));
9883 Spacing * 3));
9884 TmpInst.addOperand(Inst.getOperand(1)); // lane
9885 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9886 TmpInst.addOperand(Inst.getOperand(5));
9887 Inst = TmpInst;
9888 return true;
9889 }
9890
9891 case ARM::VLD1LNdAsm_8:
9892 case ARM::VLD1LNdAsm_16:
9893 case ARM::VLD1LNdAsm_32: {
9894 MCInst TmpInst;
9895 // Shuffle the operands around so the lane index operand is in the
9896 // right place.
9897 unsigned Spacing;
9898 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9899 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9900 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9901 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9902 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9903 TmpInst.addOperand(Inst.getOperand(1)); // lane
9904 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9905 TmpInst.addOperand(Inst.getOperand(5));
9906 Inst = TmpInst;
9907 return true;
9908 }
9909
9910 case ARM::VLD2LNdAsm_8:
9911 case ARM::VLD2LNdAsm_16:
9912 case ARM::VLD2LNdAsm_32:
9913 case ARM::VLD2LNqAsm_16:
9914 case ARM::VLD2LNqAsm_32: {
9915 MCInst TmpInst;
9916 // Shuffle the operands around so the lane index operand is in the
9917 // right place.
9918 unsigned Spacing;
9919 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9920 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9922 Spacing));
9923 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9924 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9925 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9927 Spacing));
9928 TmpInst.addOperand(Inst.getOperand(1)); // lane
9929 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9930 TmpInst.addOperand(Inst.getOperand(5));
9931 Inst = TmpInst;
9932 return true;
9933 }
9934
9935 case ARM::VLD3LNdAsm_8:
9936 case ARM::VLD3LNdAsm_16:
9937 case ARM::VLD3LNdAsm_32:
9938 case ARM::VLD3LNqAsm_16:
9939 case ARM::VLD3LNqAsm_32: {
9940 MCInst TmpInst;
9941 // Shuffle the operands around so the lane index operand is in the
9942 // right place.
9943 unsigned Spacing;
9944 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9945 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9947 Spacing));
9949 Spacing * 2));
9950 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9951 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9952 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9954 Spacing));
9956 Spacing * 2));
9957 TmpInst.addOperand(Inst.getOperand(1)); // lane
9958 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9959 TmpInst.addOperand(Inst.getOperand(5));
9960 Inst = TmpInst;
9961 return true;
9962 }
9963
9964 case ARM::VLD4LNdAsm_8:
9965 case ARM::VLD4LNdAsm_16:
9966 case ARM::VLD4LNdAsm_32:
9967 case ARM::VLD4LNqAsm_16:
9968 case ARM::VLD4LNqAsm_32: {
9969 MCInst TmpInst;
9970 // Shuffle the operands around so the lane index operand is in the
9971 // right place.
9972 unsigned Spacing;
9973 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9974 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9976 Spacing));
9978 Spacing * 2));
9980 Spacing * 3));
9981 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9982 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9983 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9985 Spacing));
9987 Spacing * 2));
9989 Spacing * 3));
9990 TmpInst.addOperand(Inst.getOperand(1)); // lane
9991 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9992 TmpInst.addOperand(Inst.getOperand(5));
9993 Inst = TmpInst;
9994 return true;
9995 }
9996
9997 // VLD3DUP single 3-element structure to all lanes instructions.
9998 case ARM::VLD3DUPdAsm_8:
9999 case ARM::VLD3DUPdAsm_16:
10000 case ARM::VLD3DUPdAsm_32:
10001 case ARM::VLD3DUPqAsm_8:
10002 case ARM::VLD3DUPqAsm_16:
10003 case ARM::VLD3DUPqAsm_32: {
10004 MCInst TmpInst;
10005 unsigned Spacing;
10006 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10007 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10009 Spacing));
10011 Spacing * 2));
10012 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10013 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10014 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10015 TmpInst.addOperand(Inst.getOperand(4));
10016 Inst = TmpInst;
10017 return true;
10018 }
10019
10020 case ARM::VLD3DUPdWB_fixed_Asm_8:
10021 case ARM::VLD3DUPdWB_fixed_Asm_16:
10022 case ARM::VLD3DUPdWB_fixed_Asm_32:
10023 case ARM::VLD3DUPqWB_fixed_Asm_8:
10024 case ARM::VLD3DUPqWB_fixed_Asm_16:
10025 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10026 MCInst TmpInst;
10027 unsigned Spacing;
10028 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10029 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10031 Spacing));
10033 Spacing * 2));
10034 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10035 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10036 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10037 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10038 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10039 TmpInst.addOperand(Inst.getOperand(4));
10040 Inst = TmpInst;
10041 return true;
10042 }
10043
10044 case ARM::VLD3DUPdWB_register_Asm_8:
10045 case ARM::VLD3DUPdWB_register_Asm_16:
10046 case ARM::VLD3DUPdWB_register_Asm_32:
10047 case ARM::VLD3DUPqWB_register_Asm_8:
10048 case ARM::VLD3DUPqWB_register_Asm_16:
10049 case ARM::VLD3DUPqWB_register_Asm_32: {
10050 MCInst TmpInst;
10051 unsigned Spacing;
10052 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10053 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10055 Spacing));
10057 Spacing * 2));
10058 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10059 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10060 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10061 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10062 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10063 TmpInst.addOperand(Inst.getOperand(5));
10064 Inst = TmpInst;
10065 return true;
10066 }
10067
10068 // VLD3 multiple 3-element structure instructions.
10069 case ARM::VLD3dAsm_8:
10070 case ARM::VLD3dAsm_16:
10071 case ARM::VLD3dAsm_32:
10072 case ARM::VLD3qAsm_8:
10073 case ARM::VLD3qAsm_16:
10074 case ARM::VLD3qAsm_32: {
10075 MCInst TmpInst;
10076 unsigned Spacing;
10077 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10078 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10080 Spacing));
10082 Spacing * 2));
10083 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10084 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10085 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10086 TmpInst.addOperand(Inst.getOperand(4));
10087 Inst = TmpInst;
10088 return true;
10089 }
10090
10091 case ARM::VLD3dWB_fixed_Asm_8:
10092 case ARM::VLD3dWB_fixed_Asm_16:
10093 case ARM::VLD3dWB_fixed_Asm_32:
10094 case ARM::VLD3qWB_fixed_Asm_8:
10095 case ARM::VLD3qWB_fixed_Asm_16:
10096 case ARM::VLD3qWB_fixed_Asm_32: {
10097 MCInst TmpInst;
10098 unsigned Spacing;
10099 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10100 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10102 Spacing));
10104 Spacing * 2));
10105 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10106 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10107 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10108 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10109 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10110 TmpInst.addOperand(Inst.getOperand(4));
10111 Inst = TmpInst;
10112 return true;
10113 }
10114
10115 case ARM::VLD3dWB_register_Asm_8:
10116 case ARM::VLD3dWB_register_Asm_16:
10117 case ARM::VLD3dWB_register_Asm_32:
10118 case ARM::VLD3qWB_register_Asm_8:
10119 case ARM::VLD3qWB_register_Asm_16:
10120 case ARM::VLD3qWB_register_Asm_32: {
10121 MCInst TmpInst;
10122 unsigned Spacing;
10123 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10124 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10126 Spacing));
10128 Spacing * 2));
10129 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10130 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10131 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10132 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10133 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10134 TmpInst.addOperand(Inst.getOperand(5));
10135 Inst = TmpInst;
10136 return true;
10137 }
10138
10139 // VLD4DUP single 3-element structure to all lanes instructions.
10140 case ARM::VLD4DUPdAsm_8:
10141 case ARM::VLD4DUPdAsm_16:
10142 case ARM::VLD4DUPdAsm_32:
10143 case ARM::VLD4DUPqAsm_8:
10144 case ARM::VLD4DUPqAsm_16:
10145 case ARM::VLD4DUPqAsm_32: {
10146 MCInst TmpInst;
10147 unsigned Spacing;
10148 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10149 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10151 Spacing));
10153 Spacing * 2));
10155 Spacing * 3));
10156 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10157 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10158 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10159 TmpInst.addOperand(Inst.getOperand(4));
10160 Inst = TmpInst;
10161 return true;
10162 }
10163
10164 case ARM::VLD4DUPdWB_fixed_Asm_8:
10165 case ARM::VLD4DUPdWB_fixed_Asm_16:
10166 case ARM::VLD4DUPdWB_fixed_Asm_32:
10167 case ARM::VLD4DUPqWB_fixed_Asm_8:
10168 case ARM::VLD4DUPqWB_fixed_Asm_16:
10169 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10170 MCInst TmpInst;
10171 unsigned Spacing;
10172 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10173 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10175 Spacing));
10177 Spacing * 2));
10179 Spacing * 3));
10180 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10181 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10182 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10183 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10184 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10185 TmpInst.addOperand(Inst.getOperand(4));
10186 Inst = TmpInst;
10187 return true;
10188 }
10189
10190 case ARM::VLD4DUPdWB_register_Asm_8:
10191 case ARM::VLD4DUPdWB_register_Asm_16:
10192 case ARM::VLD4DUPdWB_register_Asm_32:
10193 case ARM::VLD4DUPqWB_register_Asm_8:
10194 case ARM::VLD4DUPqWB_register_Asm_16:
10195 case ARM::VLD4DUPqWB_register_Asm_32: {
10196 MCInst TmpInst;
10197 unsigned Spacing;
10198 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10199 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10201 Spacing));
10203 Spacing * 2));
10205 Spacing * 3));
10206 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10207 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10208 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10209 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10210 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10211 TmpInst.addOperand(Inst.getOperand(5));
10212 Inst = TmpInst;
10213 return true;
10214 }
10215
10216 // VLD4 multiple 4-element structure instructions.
10217 case ARM::VLD4dAsm_8:
10218 case ARM::VLD4dAsm_16:
10219 case ARM::VLD4dAsm_32:
10220 case ARM::VLD4qAsm_8:
10221 case ARM::VLD4qAsm_16:
10222 case ARM::VLD4qAsm_32: {
10223 MCInst TmpInst;
10224 unsigned Spacing;
10225 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10226 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10228 Spacing));
10230 Spacing * 2));
10232 Spacing * 3));
10233 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10234 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10235 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10236 TmpInst.addOperand(Inst.getOperand(4));
10237 Inst = TmpInst;
10238 return true;
10239 }
10240
10241 case ARM::VLD4dWB_fixed_Asm_8:
10242 case ARM::VLD4dWB_fixed_Asm_16:
10243 case ARM::VLD4dWB_fixed_Asm_32:
10244 case ARM::VLD4qWB_fixed_Asm_8:
10245 case ARM::VLD4qWB_fixed_Asm_16:
10246 case ARM::VLD4qWB_fixed_Asm_32: {
10247 MCInst TmpInst;
10248 unsigned Spacing;
10249 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10250 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10252 Spacing));
10254 Spacing * 2));
10256 Spacing * 3));
10257 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10258 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10259 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10260 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10261 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10262 TmpInst.addOperand(Inst.getOperand(4));
10263 Inst = TmpInst;
10264 return true;
10265 }
10266
10267 case ARM::VLD4dWB_register_Asm_8:
10268 case ARM::VLD4dWB_register_Asm_16:
10269 case ARM::VLD4dWB_register_Asm_32:
10270 case ARM::VLD4qWB_register_Asm_8:
10271 case ARM::VLD4qWB_register_Asm_16:
10272 case ARM::VLD4qWB_register_Asm_32: {
10273 MCInst TmpInst;
10274 unsigned Spacing;
10275 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10276 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10278 Spacing));
10280 Spacing * 2));
10282 Spacing * 3));
10283 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10284 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10285 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10286 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10287 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10288 TmpInst.addOperand(Inst.getOperand(5));
10289 Inst = TmpInst;
10290 return true;
10291 }
10292
10293 // VST3 multiple 3-element structure instructions.
10294 case ARM::VST3dAsm_8:
10295 case ARM::VST3dAsm_16:
10296 case ARM::VST3dAsm_32:
10297 case ARM::VST3qAsm_8:
10298 case ARM::VST3qAsm_16:
10299 case ARM::VST3qAsm_32: {
10300 MCInst TmpInst;
10301 unsigned Spacing;
10302 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10303 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10304 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10305 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10307 Spacing));
10309 Spacing * 2));
10310 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10311 TmpInst.addOperand(Inst.getOperand(4));
10312 Inst = TmpInst;
10313 return true;
10314 }
10315
10316 case ARM::VST3dWB_fixed_Asm_8:
10317 case ARM::VST3dWB_fixed_Asm_16:
10318 case ARM::VST3dWB_fixed_Asm_32:
10319 case ARM::VST3qWB_fixed_Asm_8:
10320 case ARM::VST3qWB_fixed_Asm_16:
10321 case ARM::VST3qWB_fixed_Asm_32: {
10322 MCInst TmpInst;
10323 unsigned Spacing;
10324 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10325 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10326 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10327 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10328 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10329 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10331 Spacing));
10333 Spacing * 2));
10334 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10335 TmpInst.addOperand(Inst.getOperand(4));
10336 Inst = TmpInst;
10337 return true;
10338 }
10339
10340 case ARM::VST3dWB_register_Asm_8:
10341 case ARM::VST3dWB_register_Asm_16:
10342 case ARM::VST3dWB_register_Asm_32:
10343 case ARM::VST3qWB_register_Asm_8:
10344 case ARM::VST3qWB_register_Asm_16:
10345 case ARM::VST3qWB_register_Asm_32: {
10346 MCInst TmpInst;
10347 unsigned Spacing;
10348 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10349 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10350 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10351 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10352 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10353 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10355 Spacing));
10357 Spacing * 2));
10358 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10359 TmpInst.addOperand(Inst.getOperand(5));
10360 Inst = TmpInst;
10361 return true;
10362 }
10363
10364 // VST4 multiple 3-element structure instructions.
10365 case ARM::VST4dAsm_8:
10366 case ARM::VST4dAsm_16:
10367 case ARM::VST4dAsm_32:
10368 case ARM::VST4qAsm_8:
10369 case ARM::VST4qAsm_16:
10370 case ARM::VST4qAsm_32: {
10371 MCInst TmpInst;
10372 unsigned Spacing;
10373 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10374 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10375 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10376 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10378 Spacing));
10380 Spacing * 2));
10382 Spacing * 3));
10383 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10384 TmpInst.addOperand(Inst.getOperand(4));
10385 Inst = TmpInst;
10386 return true;
10387 }
10388
10389 case ARM::VST4dWB_fixed_Asm_8:
10390 case ARM::VST4dWB_fixed_Asm_16:
10391 case ARM::VST4dWB_fixed_Asm_32:
10392 case ARM::VST4qWB_fixed_Asm_8:
10393 case ARM::VST4qWB_fixed_Asm_16:
10394 case ARM::VST4qWB_fixed_Asm_32: {
10395 MCInst TmpInst;
10396 unsigned Spacing;
10397 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10398 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10399 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10400 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10401 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10402 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10404 Spacing));
10406 Spacing * 2));
10408 Spacing * 3));
10409 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10410 TmpInst.addOperand(Inst.getOperand(4));
10411 Inst = TmpInst;
10412 return true;
10413 }
10414
10415 case ARM::VST4dWB_register_Asm_8:
10416 case ARM::VST4dWB_register_Asm_16:
10417 case ARM::VST4dWB_register_Asm_32:
10418 case ARM::VST4qWB_register_Asm_8:
10419 case ARM::VST4qWB_register_Asm_16:
10420 case ARM::VST4qWB_register_Asm_32: {
10421 MCInst TmpInst;
10422 unsigned Spacing;
10423 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10424 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10425 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10426 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10427 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10428 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10430 Spacing));
10432 Spacing * 2));
10434 Spacing * 3));
10435 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10436 TmpInst.addOperand(Inst.getOperand(5));
10437 Inst = TmpInst;
10438 return true;
10439 }
10440
10441 // Handle encoding choice for the shift-immediate instructions.
10442 case ARM::t2LSLri:
10443 case ARM::t2LSRri:
10444 case ARM::t2ASRri:
10445 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10446 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10447 Inst.getOperand(5).getReg() ==
10448 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10449 !HasWideQualifier) {
10450 unsigned NewOpc;
10451 switch (Inst.getOpcode()) {
10452 default: llvm_unreachable("unexpected opcode");
10453 case ARM::t2LSLri: NewOpc = ARM::tLSLri; break;
10454 case ARM::t2LSRri: NewOpc = ARM::tLSRri; break;
10455 case ARM::t2ASRri: NewOpc = ARM::tASRri; break;
10456 }
10457 // The Thumb1 operands aren't in the same order. Awesome, eh?
10458 MCInst TmpInst;
10459 TmpInst.setOpcode(NewOpc);
10460 TmpInst.addOperand(Inst.getOperand(0));
10461 TmpInst.addOperand(Inst.getOperand(5));
10462 TmpInst.addOperand(Inst.getOperand(1));
10463 TmpInst.addOperand(Inst.getOperand(2));
10464 TmpInst.addOperand(Inst.getOperand(3));
10465 TmpInst.addOperand(Inst.getOperand(4));
10466 Inst = TmpInst;
10467 return true;
10468 }
10469 return false;
10470
10471 // Handle the Thumb2 mode MOV complex aliases.
10472 case ARM::t2MOVsr:
10473 case ARM::t2MOVSsr: {
10474 // Which instruction to expand to depends on the CCOut operand and
10475 // whether we're in an IT block if the register operands are low
10476 // registers.
10477 bool isNarrow = false;
10478 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10479 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10480 isARMLowRegister(Inst.getOperand(2).getReg()) &&
10481 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
10482 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr) &&
10483 !HasWideQualifier)
10484 isNarrow = true;
10485 MCInst TmpInst;
10486 unsigned newOpc;
10487 switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
10488 default: llvm_unreachable("unexpected opcode!");
10489 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
10490 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
10491 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
10492 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break;
10493 }
10494 TmpInst.setOpcode(newOpc);
10495 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10496 if (isNarrow)
10498 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10499 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10500 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10501 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10502 TmpInst.addOperand(Inst.getOperand(5));
10503 if (!isNarrow)
10505 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10506 Inst = TmpInst;
10507 return true;
10508 }
10509 case ARM::t2MOVsi:
10510 case ARM::t2MOVSsi: {
10511 // Which instruction to expand to depends on the CCOut operand and
10512 // whether we're in an IT block if the register operands are low
10513 // registers.
10514 bool isNarrow = false;
10515 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10516 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10517 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi) &&
10518 !HasWideQualifier)
10519 isNarrow = true;
10520 MCInst TmpInst;
10521 unsigned newOpc;
10522 unsigned Shift = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
10523 unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
10524 bool isMov = false;
10525 // MOV rd, rm, LSL #0 is actually a MOV instruction
10526 if (Shift == ARM_AM::lsl && Amount == 0) {
10527 isMov = true;
10528 // The 16-bit encoding of MOV rd, rm, LSL #N is explicitly encoding T2 of
10529 // MOV (register) in the ARMv8-A and ARMv8-M manuals, and immediate 0 is
10530 // unpredictable in an IT block so the 32-bit encoding T3 has to be used
10531 // instead.
10532 if (inITBlock()) {
10533 isNarrow = false;
10534 }
10535 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10536 } else {
10537 switch(Shift) {
10538 default: llvm_unreachable("unexpected opcode!");
10539 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
10540 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
10541 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
10542 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
10543 case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
10544 }
10545 }
10546 if (Amount == 32) Amount = 0;
10547 TmpInst.setOpcode(newOpc);
10548 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10549 if (isNarrow && !isMov)
10551 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10552 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10553 if (newOpc != ARM::t2RRX && !isMov)
10554 TmpInst.addOperand(MCOperand::createImm(Amount));
10555 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10556 TmpInst.addOperand(Inst.getOperand(4));
10557 if (!isNarrow)
10559 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10560 Inst = TmpInst;
10561 return true;
10562 }
10563 // Handle the ARM mode MOV complex aliases.
10564 case ARM::ASRr:
10565 case ARM::LSRr:
10566 case ARM::LSLr:
10567 case ARM::RORr: {
10568 ARM_AM::ShiftOpc ShiftTy;
10569 switch(Inst.getOpcode()) {
10570 default: llvm_unreachable("unexpected opcode!");
10571 case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
10572 case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
10573 case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
10574 case ARM::RORr: ShiftTy = ARM_AM::ror; break;
10575 }
10576 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
10577 MCInst TmpInst;
10578 TmpInst.setOpcode(ARM::MOVsr);
10579 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10580 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10581 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10582 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10583 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10584 TmpInst.addOperand(Inst.getOperand(4));
10585 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10586 Inst = TmpInst;
10587 return true;
10588 }
10589 case ARM::ASRi:
10590 case ARM::LSRi:
10591 case ARM::LSLi:
10592 case ARM::RORi: {
10593 ARM_AM::ShiftOpc ShiftTy;
10594 switch(Inst.getOpcode()) {
10595 default: llvm_unreachable("unexpected opcode!");
10596 case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
10597 case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
10598 case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
10599 case ARM::RORi: ShiftTy = ARM_AM::ror; break;
10600 }
10601 // A shift by zero is a plain MOVr, not a MOVsi.
10602 unsigned Amt = Inst.getOperand(2).getImm();
10603 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10604 // A shift by 32 should be encoded as 0 when permitted
10605 if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
10606 Amt = 0;
10607 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
10608 MCInst TmpInst;
10609 TmpInst.setOpcode(Opc);
10610 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10611 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10612 if (Opc == ARM::MOVsi)
10613 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10614 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10615 TmpInst.addOperand(Inst.getOperand(4));
10616 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10617 Inst = TmpInst;
10618 return true;
10619 }
10620 case ARM::RRXi: {
10621 unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
10622 MCInst TmpInst;
10623 TmpInst.setOpcode(ARM::MOVsi);
10624 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10625 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10626 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10627 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10628 TmpInst.addOperand(Inst.getOperand(3));
10629 TmpInst.addOperand(Inst.getOperand(4)); // cc_out
10630 Inst = TmpInst;
10631 return true;
10632 }
10633 case ARM::t2LDMIA_UPD: {
10634 // If this is a load of a single register, then we should use
10635 // a post-indexed LDR instruction instead, per the ARM ARM.
10636 if (Inst.getNumOperands() != 5)
10637 return false;
10638 MCInst TmpInst;
10639 TmpInst.setOpcode(ARM::t2LDR_POST);
10640 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10641 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10642 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10643 TmpInst.addOperand(MCOperand::createImm(4));
10644 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10645 TmpInst.addOperand(Inst.getOperand(3));
10646 Inst = TmpInst;
10647 return true;
10648 }
10649 case ARM::t2STMDB_UPD: {
10650 // If this is a store of a single register, then we should use
10651 // a pre-indexed STR instruction instead, per the ARM ARM.
10652 if (Inst.getNumOperands() != 5)
10653 return false;
10654 MCInst TmpInst;
10655 TmpInst.setOpcode(ARM::t2STR_PRE);
10656 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10657 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10658 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10659 TmpInst.addOperand(MCOperand::createImm(-4));
10660 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10661 TmpInst.addOperand(Inst.getOperand(3));
10662 Inst = TmpInst;
10663 return true;
10664 }
10665 case ARM::LDMIA_UPD:
10666 // If this is a load of a single register via a 'pop', then we should use
10667 // a post-indexed LDR instruction instead, per the ARM ARM.
10668 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "pop" &&
10669 Inst.getNumOperands() == 5) {
10670 MCInst TmpInst;
10671 TmpInst.setOpcode(ARM::LDR_POST_IMM);
10672 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10673 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10674 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10675 TmpInst.addOperand(MCOperand::createReg(0)); // am2offset
10676 TmpInst.addOperand(MCOperand::createImm(4));
10677 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10678 TmpInst.addOperand(Inst.getOperand(3));
10679 Inst = TmpInst;
10680 return true;
10681 }
10682 break;
10683 case ARM::STMDB_UPD:
10684 // If this is a store of a single register via a 'push', then we should use
10685 // a pre-indexed STR instruction instead, per the ARM ARM.
10686 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "push" &&
10687 Inst.getNumOperands() == 5) {
10688 MCInst TmpInst;
10689 TmpInst.setOpcode(ARM::STR_PRE_IMM);
10690 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10691 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10692 TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
10693 TmpInst.addOperand(MCOperand::createImm(-4));
10694 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10695 TmpInst.addOperand(Inst.getOperand(3));
10696 Inst = TmpInst;
10697 }
10698 break;
10699 case ARM::t2ADDri12:
10700 case ARM::t2SUBri12:
10701 case ARM::t2ADDspImm12:
10702 case ARM::t2SUBspImm12: {
10703 // If the immediate fits for encoding T3 and the generic
10704 // mnemonic was used, encoding T3 is preferred.
10705 const StringRef Token = static_cast<ARMOperand &>(*Operands[0]).getToken();
10706 if ((Token != "add" && Token != "sub") ||
10707 ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
10708 break;
10709 switch (Inst.getOpcode()) {
10710 case ARM::t2ADDri12:
10711 Inst.setOpcode(ARM::t2ADDri);
10712 break;
10713 case ARM::t2SUBri12:
10714 Inst.setOpcode(ARM::t2SUBri);
10715 break;
10716 case ARM::t2ADDspImm12:
10717 Inst.setOpcode(ARM::t2ADDspImm);
10718 break;
10719 case ARM::t2SUBspImm12:
10720 Inst.setOpcode(ARM::t2SUBspImm);
10721 break;
10722 }
10723
10724 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10725 return true;
10726 }
10727 case ARM::tADDi8:
10728 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10729 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10730 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10731 // to encoding T1 if <Rd> is omitted."
10732 if (Inst.getOperand(3).isImm() &&
10733 (unsigned)Inst.getOperand(3).getImm() < 8 &&
10734 Operands.size() == MnemonicOpsEndInd + 3) {
10735 Inst.setOpcode(ARM::tADDi3);
10736 return true;
10737 }
10738 break;
10739 case ARM::tSUBi8:
10740 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10741 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10742 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10743 // to encoding T1 if <Rd> is omitted."
10744 if ((unsigned)Inst.getOperand(3).getImm() < 8 &&
10745 Operands.size() == MnemonicOpsEndInd + 3) {
10746 Inst.setOpcode(ARM::tSUBi3);
10747 return true;
10748 }
10749 break;
10750 case ARM::t2ADDri:
10751 case ARM::t2SUBri: {
10752 // If the destination and first source operand are the same, and
10753 // the flags are compatible with the current IT status, use encoding T2
10754 // instead of T3. For compatibility with the system 'as'. Make sure the
10755 // wide encoding wasn't explicit.
10756 if (HasWideQualifier)
10757 break; // source code has asked for the 32-bit instruction
10758 if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg())
10759 break; // tADDi8 can't take different input and output registers
10760 if (!isARMLowRegister(Inst.getOperand(0).getReg()))
10761 break; // high register that tADDi8 can't access
10762 if (Inst.getOperand(5).getReg() !=
10763 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10764 break; // flag-modification would require overriding the IT state
10765 if (Inst.getOperand(2).isImm()) {
10766 if ((unsigned)Inst.getOperand(2).getImm() > 255)
10767 break; // large immediate that tADDi8 can't contain
10768 } else {
10769 int i = (Operands[MnemonicOpsEndInd + 1]->isImm())
10770 ? MnemonicOpsEndInd + 1
10771 : MnemonicOpsEndInd + 2;
10772 MCParsedAsmOperand &Op = *Operands[i];
10774 break; // a type of non-immediate that tADDi8 can't represent
10775 }
10776 MCInst TmpInst;
10777 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
10778 ARM::tADDi8 : ARM::tSUBi8);
10779 TmpInst.addOperand(Inst.getOperand(0));
10780 TmpInst.addOperand(Inst.getOperand(5));
10781 TmpInst.addOperand(Inst.getOperand(0));
10782 TmpInst.addOperand(Inst.getOperand(2));
10783 TmpInst.addOperand(Inst.getOperand(3));
10784 TmpInst.addOperand(Inst.getOperand(4));
10785 Inst = TmpInst;
10786 return true;
10787 }
10788 case ARM::t2ADDspImm:
10789 case ARM::t2SUBspImm: {
10790 // Prefer T1 encoding if possible
10791 if (Inst.getOperand(5).getReg() || HasWideQualifier)
10792 break;
10793 unsigned V = Inst.getOperand(2).getImm();
10794 if (V & 3 || V > ((1 << 7) - 1) << 2)
10795 break;
10796 MCInst TmpInst;
10797 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDspImm ? ARM::tADDspi
10798 : ARM::tSUBspi);
10799 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // destination reg
10800 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // source reg
10801 TmpInst.addOperand(MCOperand::createImm(V / 4)); // immediate
10802 TmpInst.addOperand(Inst.getOperand(3)); // pred
10803 TmpInst.addOperand(Inst.getOperand(4));
10804 Inst = TmpInst;
10805 return true;
10806 }
10807 case ARM::t2ADDrr: {
10808 // If the destination and first source operand are the same, and
10809 // there's no setting of the flags, use encoding T2 instead of T3.
10810 // Note that this is only for ADD, not SUB. This mirrors the system
10811 // 'as' behaviour. Also take advantage of ADD being commutative.
10812 // Make sure the wide encoding wasn't explicit.
10813 bool Swap = false;
10814 auto DestReg = Inst.getOperand(0).getReg();
10815 bool Transform = DestReg == Inst.getOperand(1).getReg();
10816 if (!Transform && DestReg == Inst.getOperand(2).getReg()) {
10817 Transform = true;
10818 Swap = true;
10819 }
10820 if (!Transform || Inst.getOperand(5).getReg() || HasWideQualifier)
10821 break;
10822 MCInst TmpInst;
10823 TmpInst.setOpcode(ARM::tADDhirr);
10824 TmpInst.addOperand(Inst.getOperand(0));
10825 TmpInst.addOperand(Inst.getOperand(0));
10826 TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2));
10827 TmpInst.addOperand(Inst.getOperand(3));
10828 TmpInst.addOperand(Inst.getOperand(4));
10829 Inst = TmpInst;
10830 return true;
10831 }
10832 case ARM::tADDrSP:
10833 // If the non-SP source operand and the destination operand are not the
10834 // same, we need to use the 32-bit encoding if it's available.
10835 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
10836 Inst.setOpcode(ARM::t2ADDrr);
10837 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10838 return true;
10839 }
10840 break;
10841 case ARM::tB:
10842 // A Thumb conditional branch outside of an IT block is a tBcc.
10843 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
10844 Inst.setOpcode(ARM::tBcc);
10845 return true;
10846 }
10847 break;
10848 case ARM::t2B:
10849 // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
10850 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
10851 Inst.setOpcode(ARM::t2Bcc);
10852 return true;
10853 }
10854 break;
10855 case ARM::t2Bcc:
10856 // If the conditional is AL or we're in an IT block, we really want t2B.
10857 if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
10858 Inst.setOpcode(ARM::t2B);
10859 return true;
10860 }
10861 break;
10862 case ARM::tBcc:
10863 // If the conditional is AL, we really want tB.
10864 if (Inst.getOperand(1).getImm() == ARMCC::AL) {
10865 Inst.setOpcode(ARM::tB);
10866 return true;
10867 }
10868 break;
10869 case ARM::tLDMIA: {
10870 // If the register list contains any high registers, or if the writeback
10871 // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
10872 // instead if we're in Thumb2. Otherwise, this should have generated
10873 // an error in validateInstruction().
10874 MCRegister Rn = Inst.getOperand(0).getReg();
10875 bool hasWritebackToken =
10876 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10877 .isToken() &&
10878 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10879 .getToken() == "!");
10880 bool listContainsBase;
10881 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), listContainsBase) ||
10882 (!listContainsBase && !hasWritebackToken) ||
10883 (listContainsBase && hasWritebackToken)) {
10884 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10885 assert(isThumbTwo());
10886 Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10887 // If we're switching to the updating version, we need to insert
10888 // the writeback tied operand.
10889 if (hasWritebackToken)
10890 Inst.insert(Inst.begin(),
10892 return true;
10893 }
10894 break;
10895 }
10896 case ARM::tSTMIA_UPD: {
10897 // If the register list contains any high registers, we need to use
10898 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10899 // should have generated an error in validateInstruction().
10900 MCRegister Rn = Inst.getOperand(0).getReg();
10901 bool listContainsBase;
10902 if (checkLowRegisterList(Inst, 4, Rn, MCRegister(), listContainsBase)) {
10903 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10904 assert(isThumbTwo());
10905 Inst.setOpcode(ARM::t2STMIA_UPD);
10906 return true;
10907 }
10908 break;
10909 }
10910 case ARM::tPOP: {
10911 bool listContainsBase;
10912 // If the register list contains any high registers, we need to use
10913 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10914 // should have generated an error in validateInstruction().
10915 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC, listContainsBase))
10916 return false;
10917 assert(isThumbTwo());
10918 Inst.setOpcode(ARM::t2LDMIA_UPD);
10919 // Add the base register and writeback operands.
10920 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10921 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10922 return true;
10923 }
10924 case ARM::tPUSH: {
10925 bool listContainsBase;
10926 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR, listContainsBase))
10927 return false;
10928 assert(isThumbTwo());
10929 Inst.setOpcode(ARM::t2STMDB_UPD);
10930 // Add the base register and writeback operands.
10931 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10932 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10933 return true;
10934 }
10935 case ARM::t2MOVi:
10936 // If we can use the 16-bit encoding and the user didn't explicitly
10937 // request the 32-bit variant, transform it here.
10938 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10939 (Inst.getOperand(1).isImm() &&
10940 (unsigned)Inst.getOperand(1).getImm() <= 255) &&
10941 Inst.getOperand(4).getReg() ==
10942 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10943 !HasWideQualifier) {
10944 // The operands aren't in the same order for tMOVi8...
10945 MCInst TmpInst;
10946 TmpInst.setOpcode(ARM::tMOVi8);
10947 TmpInst.addOperand(Inst.getOperand(0));
10948 TmpInst.addOperand(Inst.getOperand(4));
10949 TmpInst.addOperand(Inst.getOperand(1));
10950 TmpInst.addOperand(Inst.getOperand(2));
10951 TmpInst.addOperand(Inst.getOperand(3));
10952 Inst = TmpInst;
10953 return true;
10954 }
10955 break;
10956
10957 case ARM::t2MOVr:
10958 // If we can use the 16-bit encoding and the user didn't explicitly
10959 // request the 32-bit variant, transform it here.
10960 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10961 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10962 Inst.getOperand(2).getImm() == ARMCC::AL &&
10963 Inst.getOperand(4).getReg() == ARM::CPSR &&
10964 !HasWideQualifier) {
10965 // The operands aren't the same for tMOV[S]r... (no cc_out)
10966 MCInst TmpInst;
10967 unsigned Op = Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr;
10968 TmpInst.setOpcode(Op);
10969 TmpInst.addOperand(Inst.getOperand(0));
10970 TmpInst.addOperand(Inst.getOperand(1));
10971 if (Op == ARM::tMOVr) {
10972 TmpInst.addOperand(Inst.getOperand(2));
10973 TmpInst.addOperand(Inst.getOperand(3));
10974 }
10975 Inst = TmpInst;
10976 return true;
10977 }
10978 break;
10979
10980 case ARM::t2SXTH:
10981 case ARM::t2SXTB:
10982 case ARM::t2UXTH:
10983 case ARM::t2UXTB:
10984 // If we can use the 16-bit encoding and the user didn't explicitly
10985 // request the 32-bit variant, transform it here.
10986 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10987 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10988 Inst.getOperand(2).getImm() == 0 &&
10989 !HasWideQualifier) {
10990 unsigned NewOpc;
10991 switch (Inst.getOpcode()) {
10992 default: llvm_unreachable("Illegal opcode!");
10993 case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
10994 case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
10995 case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
10996 case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
10997 }
10998 // The operands aren't the same for thumb1 (no rotate operand).
10999 MCInst TmpInst;
11000 TmpInst.setOpcode(NewOpc);
11001 TmpInst.addOperand(Inst.getOperand(0));
11002 TmpInst.addOperand(Inst.getOperand(1));
11003 TmpInst.addOperand(Inst.getOperand(3));
11004 TmpInst.addOperand(Inst.getOperand(4));
11005 Inst = TmpInst;
11006 return true;
11007 }
11008 break;
11009
11010 case ARM::MOVsi: {
11012 // rrx shifts and asr/lsr of #32 is encoded as 0
11013 if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
11014 return false;
11015 if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
11016 // Shifting by zero is accepted as a vanilla 'MOVr'
11017 MCInst TmpInst;
11018 TmpInst.setOpcode(ARM::MOVr);
11019 TmpInst.addOperand(Inst.getOperand(0));
11020 TmpInst.addOperand(Inst.getOperand(1));
11021 TmpInst.addOperand(Inst.getOperand(3));
11022 TmpInst.addOperand(Inst.getOperand(4));
11023 TmpInst.addOperand(Inst.getOperand(5));
11024 Inst = TmpInst;
11025 return true;
11026 }
11027 return false;
11028 }
11029 case ARM::ANDrsi:
11030 case ARM::ORRrsi:
11031 case ARM::EORrsi:
11032 case ARM::BICrsi:
11033 case ARM::SUBrsi:
11034 case ARM::ADDrsi: {
11035 unsigned newOpc;
11037 if (SOpc == ARM_AM::rrx) return false;
11038 switch (Inst.getOpcode()) {
11039 default: llvm_unreachable("unexpected opcode!");
11040 case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
11041 case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
11042 case ARM::EORrsi: newOpc = ARM::EORrr; break;
11043 case ARM::BICrsi: newOpc = ARM::BICrr; break;
11044 case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
11045 case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
11046 }
11047 // If the shift is by zero, use the non-shifted instruction definition.
11048 // The exception is for right shifts, where 0 == 32
11049 if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 &&
11050 !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) {
11051 MCInst TmpInst;
11052 TmpInst.setOpcode(newOpc);
11053 TmpInst.addOperand(Inst.getOperand(0));
11054 TmpInst.addOperand(Inst.getOperand(1));
11055 TmpInst.addOperand(Inst.getOperand(2));
11056 TmpInst.addOperand(Inst.getOperand(4));
11057 TmpInst.addOperand(Inst.getOperand(5));
11058 TmpInst.addOperand(Inst.getOperand(6));
11059 Inst = TmpInst;
11060 return true;
11061 }
11062 return false;
11063 }
11064 case ARM::ITasm:
11065 case ARM::t2IT: {
11066 // Set up the IT block state according to the IT instruction we just
11067 // matched.
11068 assert(!inITBlock() && "nested IT blocks?!");
11069 startExplicitITBlock(ARMCC::CondCodes(Inst.getOperand(0).getImm()),
11070 Inst.getOperand(1).getImm());
11071 break;
11072 }
11073 case ARM::t2LSLrr:
11074 case ARM::t2LSRrr:
11075 case ARM::t2ASRrr:
11076 case ARM::t2SBCrr:
11077 case ARM::t2RORrr:
11078 case ARM::t2BICrr:
11079 // Assemblers should use the narrow encodings of these instructions when permissible.
11080 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11081 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11082 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
11083 Inst.getOperand(5).getReg() ==
11084 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11085 !HasWideQualifier) {
11086 unsigned NewOpc;
11087 switch (Inst.getOpcode()) {
11088 default: llvm_unreachable("unexpected opcode");
11089 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break;
11090 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break;
11091 case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break;
11092 case ARM::t2SBCrr: NewOpc = ARM::tSBC; break;
11093 case ARM::t2RORrr: NewOpc = ARM::tROR; break;
11094 case ARM::t2BICrr: NewOpc = ARM::tBIC; break;
11095 }
11096 MCInst TmpInst;
11097 TmpInst.setOpcode(NewOpc);
11098 TmpInst.addOperand(Inst.getOperand(0));
11099 TmpInst.addOperand(Inst.getOperand(5));
11100 TmpInst.addOperand(Inst.getOperand(1));
11101 TmpInst.addOperand(Inst.getOperand(2));
11102 TmpInst.addOperand(Inst.getOperand(3));
11103 TmpInst.addOperand(Inst.getOperand(4));
11104 Inst = TmpInst;
11105 return true;
11106 }
11107 return false;
11108
11109 case ARM::t2ANDrr:
11110 case ARM::t2EORrr:
11111 case ARM::t2ADCrr:
11112 case ARM::t2ORRrr:
11113 // Assemblers should use the narrow encodings of these instructions when permissible.
11114 // These instructions are special in that they are commutable, so shorter encodings
11115 // are available more often.
11116 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11117 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11118 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() ||
11119 Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) &&
11120 Inst.getOperand(5).getReg() ==
11121 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11122 !HasWideQualifier) {
11123 unsigned NewOpc;
11124 switch (Inst.getOpcode()) {
11125 default: llvm_unreachable("unexpected opcode");
11126 case ARM::t2ADCrr: NewOpc = ARM::tADC; break;
11127 case ARM::t2ANDrr: NewOpc = ARM::tAND; break;
11128 case ARM::t2EORrr: NewOpc = ARM::tEOR; break;
11129 case ARM::t2ORRrr: NewOpc = ARM::tORR; break;
11130 }
11131 MCInst TmpInst;
11132 TmpInst.setOpcode(NewOpc);
11133 TmpInst.addOperand(Inst.getOperand(0));
11134 TmpInst.addOperand(Inst.getOperand(5));
11135 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) {
11136 TmpInst.addOperand(Inst.getOperand(1));
11137 TmpInst.addOperand(Inst.getOperand(2));
11138 } else {
11139 TmpInst.addOperand(Inst.getOperand(2));
11140 TmpInst.addOperand(Inst.getOperand(1));
11141 }
11142 TmpInst.addOperand(Inst.getOperand(3));
11143 TmpInst.addOperand(Inst.getOperand(4));
11144 Inst = TmpInst;
11145 return true;
11146 }
11147 return false;
11148 case ARM::MVE_VPST:
11149 case ARM::MVE_VPTv16i8:
11150 case ARM::MVE_VPTv8i16:
11151 case ARM::MVE_VPTv4i32:
11152 case ARM::MVE_VPTv16u8:
11153 case ARM::MVE_VPTv8u16:
11154 case ARM::MVE_VPTv4u32:
11155 case ARM::MVE_VPTv16s8:
11156 case ARM::MVE_VPTv8s16:
11157 case ARM::MVE_VPTv4s32:
11158 case ARM::MVE_VPTv4f32:
11159 case ARM::MVE_VPTv8f16:
11160 case ARM::MVE_VPTv16i8r:
11161 case ARM::MVE_VPTv8i16r:
11162 case ARM::MVE_VPTv4i32r:
11163 case ARM::MVE_VPTv16u8r:
11164 case ARM::MVE_VPTv8u16r:
11165 case ARM::MVE_VPTv4u32r:
11166 case ARM::MVE_VPTv16s8r:
11167 case ARM::MVE_VPTv8s16r:
11168 case ARM::MVE_VPTv4s32r:
11169 case ARM::MVE_VPTv4f32r:
11170 case ARM::MVE_VPTv8f16r: {
11171 assert(!inVPTBlock() && "Nested VPT blocks are not allowed");
11172 MCOperand &MO = Inst.getOperand(0);
11173 VPTState.Mask = MO.getImm();
11174 VPTState.CurPosition = 0;
11175 break;
11176 }
11177 }
11178 return false;
11179}
11180
11181unsigned
11182ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11183 const OperandVector &Operands) {
11184 unsigned Opc = Inst.getOpcode();
11185 switch (Opc) {
11186 // Prevent the mov r8 r8 encoding for nop being selected when the v6/thumb 2
11187 // encoding is available.
11188 case ARM::tMOVr: {
11189 if (Operands[0]->isToken() &&
11190 static_cast<ARMOperand &>(*Operands[0]).getToken() == "nop" &&
11191 ((isThumb() && !isThumbOne()) || hasV6MOps())) {
11192 return Match_MnemonicFail;
11193 }
11194 }
11195 [[fallthrough]];
11196 default:
11197 return Match_Success;
11198 }
11199}
11200
11201unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11202 // 16-bit thumb arithmetic instructions either require or preclude the 'S'
11203 // suffix depending on whether they're in an IT block or not.
11204 unsigned Opc = Inst.getOpcode();
11205 const MCInstrDesc &MCID = MII.get(Opc);
11207 assert(MCID.hasOptionalDef() &&
11208 "optionally flag setting instruction missing optional def operand");
11209 assert(MCID.NumOperands == Inst.getNumOperands() &&
11210 "operand count mismatch!");
11211 bool IsCPSR = false;
11212 // Check if the instruction has CPSR set.
11213 for (unsigned OpNo = 0; OpNo < MCID.NumOperands; ++OpNo) {
11214 if (MCID.operands()[OpNo].isOptionalDef() &&
11215 Inst.getOperand(OpNo).isReg() &&
11216 Inst.getOperand(OpNo).getReg() == ARM::CPSR)
11217 IsCPSR = true;
11218 }
11219
11220 // If we're parsing Thumb1, reject it completely.
11221 if (isThumbOne() && !IsCPSR)
11222 return Match_RequiresFlagSetting;
11223 // If we're parsing Thumb2, which form is legal depends on whether we're
11224 // in an IT block.
11225 if (isThumbTwo() && !IsCPSR && !inITBlock())
11226 return Match_RequiresITBlock;
11227 if (isThumbTwo() && IsCPSR && inITBlock())
11228 return Match_RequiresNotITBlock;
11229 // LSL with zero immediate is not allowed in an IT block
11230 if (Opc == ARM::tLSLri && Inst.getOperand(3).getImm() == 0 && inITBlock())
11231 return Match_RequiresNotITBlock;
11232 } else if (isThumbOne()) {
11233 // Some high-register supporting Thumb1 encodings only allow both registers
11234 // to be from r0-r7 when in Thumb2.
11235 if (Opc == ARM::tADDhirr && !hasV6MOps() &&
11236 isARMLowRegister(Inst.getOperand(1).getReg()) &&
11238 return Match_RequiresThumb2;
11239 // Others only require ARMv6 or later.
11240 else if (Opc == ARM::tMOVr && !hasV6Ops() &&
11241 isARMLowRegister(Inst.getOperand(0).getReg()) &&
11243 return Match_RequiresV6;
11244 }
11245
11246 // Before ARMv8 the rules for when SP is allowed in t2MOVr are more complex
11247 // than the loop below can handle, so it uses the GPRnopc register class and
11248 // we do SP handling here.
11249 if (Opc == ARM::t2MOVr && !hasV8Ops())
11250 {
11251 // SP as both source and destination is not allowed
11252 if (Inst.getOperand(0).getReg() == ARM::SP &&
11253 Inst.getOperand(1).getReg() == ARM::SP)
11254 return Match_RequiresV8;
11255 // When flags-setting SP as either source or destination is not allowed
11256 if (Inst.getOperand(4).getReg() == ARM::CPSR &&
11257 (Inst.getOperand(0).getReg() == ARM::SP ||
11258 Inst.getOperand(1).getReg() == ARM::SP))
11259 return Match_RequiresV8;
11260 }
11261
11262 switch (Inst.getOpcode()) {
11263 case ARM::VMRS:
11264 case ARM::VMSR:
11265 case ARM::VMRS_FPCXTS:
11266 case ARM::VMRS_FPCXTNS:
11267 case ARM::VMSR_FPCXTS:
11268 case ARM::VMSR_FPCXTNS:
11269 case ARM::VMRS_FPSCR_NZCVQC:
11270 case ARM::VMSR_FPSCR_NZCVQC:
11271 case ARM::FMSTAT:
11272 case ARM::VMRS_VPR:
11273 case ARM::VMRS_P0:
11274 case ARM::VMSR_VPR:
11275 case ARM::VMSR_P0:
11276 // Use of SP for VMRS/VMSR is only allowed in ARM mode with the exception of
11277 // ARMv8-A.
11278 if (Inst.getOperand(0).isReg() && Inst.getOperand(0).getReg() == ARM::SP &&
11279 (isThumb() && !hasV8Ops()))
11280 return Match_InvalidOperand;
11281 break;
11282 case ARM::t2TBB:
11283 case ARM::t2TBH:
11284 // Rn = sp is only allowed with ARMv8-A
11285 if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP))
11286 return Match_RequiresV8;
11287 break;
11288 case ARM::tMUL:
11289 // The second source operand must be the same register as the destination
11290 // operand.
11291 // FIXME: Ideally this would be handled by ARMGenAsmMatcher and
11292 // emitAsmTiedOperandConstraints.
11293 if (Inst.getOperand(0).getReg() != Inst.getOperand(3).getReg())
11294 return Match_InvalidTiedOperand;
11295 break;
11296 default:
11297 break;
11298 }
11299
11300 for (unsigned I = 0; I < MCID.NumOperands; ++I)
11301 if (MCID.operands()[I].RegClass == ARM::rGPRRegClassID) {
11302 // rGPRRegClass excludes PC, and also excluded SP before ARMv8
11303 const auto &Op = Inst.getOperand(I);
11304 if (!Op.isReg()) {
11305 // This can happen in awkward cases with tied operands, e.g. a
11306 // writeback load/store with a complex addressing mode in
11307 // which there's an output operand corresponding to the
11308 // updated written-back base register: the Tablegen-generated
11309 // AsmMatcher will have written a placeholder operand to that
11310 // slot in the form of an immediate 0, because it can't
11311 // generate the register part of the complex addressing-mode
11312 // operand ahead of time.
11313 continue;
11314 }
11315
11316 MCRegister Reg = Op.getReg();
11317 if ((Reg == ARM::SP) && !hasV8Ops())
11318 return Match_RequiresV8;
11319 else if (Reg == ARM::PC)
11320 return Match_InvalidOperand;
11321 }
11322
11323 return Match_Success;
11324}
11325
11326namespace llvm {
11327
11328template <> inline bool IsCPSRDead<MCInst>(const MCInst *Instr) {
11329 return true; // In an assembly source, no need to second-guess
11330}
11331
11332} // end namespace llvm
11333
11334// Returns true if Inst is unpredictable if it is in and IT block, but is not
11335// the last instruction in the block.
11336bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const {
11337 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11338
11339 // All branch & call instructions terminate IT blocks with the exception of
11340 // SVC.
11341 if (MCID.isTerminator() || (MCID.isCall() && Inst.getOpcode() != ARM::tSVC) ||
11342 MCID.isReturn() || MCID.isBranch() || MCID.isIndirectBranch())
11343 return true;
11344
11345 // Any arithmetic instruction which writes to the PC also terminates the IT
11346 // block.
11347 if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI))
11348 return true;
11349
11350 return false;
11351}
11352
11353unsigned ARMAsmParser::MatchInstruction(OperandVector &Operands, MCInst &Inst,
11354 SmallVectorImpl<NearMissInfo> &NearMisses,
11355 bool MatchingInlineAsm,
11356 bool &EmitInITBlock,
11357 MCStreamer &Out) {
11358 // If we can't use an implicit IT block here, just match as normal.
11359 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11360 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11361
11362 // Try to match the instruction in an extension of the current IT block (if
11363 // there is one).
11364 if (inImplicitITBlock()) {
11365 extendImplicitITBlock(ITState.Cond);
11366 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11367 Match_Success) {
11368 // The match succeeded, but we still have to check that the instruction is
11369 // valid in this implicit IT block.
11370 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11371 if (MCID.isPredicable()) {
11372 ARMCC::CondCodes InstCond =
11374 .getImm();
11375 ARMCC::CondCodes ITCond = currentITCond();
11376 if (InstCond == ITCond) {
11377 EmitInITBlock = true;
11378 return Match_Success;
11379 } else if (InstCond == ARMCC::getOppositeCondition(ITCond)) {
11380 invertCurrentITCondition();
11381 EmitInITBlock = true;
11382 return Match_Success;
11383 }
11384 }
11385 }
11386 rewindImplicitITPosition();
11387 }
11388
11389 // Finish the current IT block, and try to match outside any IT block.
11390 flushPendingInstructions(Out);
11391 unsigned PlainMatchResult =
11392 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11393 if (PlainMatchResult == Match_Success) {
11394 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11395 if (MCID.isPredicable()) {
11396 ARMCC::CondCodes InstCond =
11398 .getImm();
11399 // Some forms of the branch instruction have their own condition code
11400 // fields, so can be conditionally executed without an IT block.
11401 if (Inst.getOpcode() == ARM::tBcc || Inst.getOpcode() == ARM::t2Bcc) {
11402 EmitInITBlock = false;
11403 return Match_Success;
11404 }
11405 if (InstCond == ARMCC::AL) {
11406 EmitInITBlock = false;
11407 return Match_Success;
11408 }
11409 } else {
11410 EmitInITBlock = false;
11411 return Match_Success;
11412 }
11413 }
11414
11415 // Try to match in a new IT block. The matcher doesn't check the actual
11416 // condition, so we create an IT block with a dummy condition, and fix it up
11417 // once we know the actual condition.
11418 startImplicitITBlock();
11419 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11420 Match_Success) {
11421 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11422 if (MCID.isPredicable()) {
11423 ITState.Cond =
11425 .getImm();
11426 EmitInITBlock = true;
11427 return Match_Success;
11428 }
11429 }
11430 discardImplicitITBlock();
11431
11432 // If none of these succeed, return the error we got when trying to match
11433 // outside any IT blocks.
11434 EmitInITBlock = false;
11435 return PlainMatchResult;
11436}
11437
11438static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
11439 unsigned VariantID = 0);
11440
11441static const char *getSubtargetFeatureName(uint64_t Val);
11442bool ARMAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
11445 bool MatchingInlineAsm) {
11446 MCInst Inst;
11447 unsigned MatchResult;
11448 bool PendConditionalInstruction = false;
11449
11451 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
11452 PendConditionalInstruction, Out);
11453
11454 // Find the number of operators that are part of the Mnumonic (LHS).
11455 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
11456
11457 switch (MatchResult) {
11458 case Match_Success:
11459 LLVM_DEBUG(dbgs() << "Parsed as: ";
11460 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11461 dbgs() << "\n");
11462
11463 // Context sensitive operand constraints aren't handled by the matcher,
11464 // so check them here.
11465 if (validateInstruction(Inst, Operands, MnemonicOpsEndInd)) {
11466 // Still progress the IT block, otherwise one wrong condition causes
11467 // nasty cascading errors.
11468 forwardITPosition();
11469 forwardVPTPosition();
11470 return true;
11471 }
11472
11473 {
11474 // Some instructions need post-processing to, for example, tweak which
11475 // encoding is selected. Loop on it while changes happen so the
11476 // individual transformations can chain off each other. E.g.,
11477 // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
11478 while (processInstruction(Inst, Operands, MnemonicOpsEndInd, Out))
11479 LLVM_DEBUG(dbgs() << "Changed to: ";
11480 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11481 dbgs() << "\n");
11482 }
11483
11484 // Only move forward at the very end so that everything in validate
11485 // and process gets a consistent answer about whether we're in an IT
11486 // block.
11487 forwardITPosition();
11488 forwardVPTPosition();
11489
11490 // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
11491 // doesn't actually encode.
11492 if (Inst.getOpcode() == ARM::ITasm)
11493 return false;
11494
11495 Inst.setLoc(IDLoc);
11496 if (PendConditionalInstruction) {
11497 PendingConditionalInsts.push_back(Inst);
11498 if (isITBlockFull() || isITBlockTerminator(Inst))
11499 flushPendingInstructions(Out);
11500 } else {
11501 Out.emitInstruction(Inst, getSTI());
11502 }
11503 return false;
11504 case Match_NearMisses:
11505 ReportNearMisses(NearMisses, IDLoc, Operands);
11506 return true;
11507 case Match_MnemonicFail: {
11508 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11509 std::string Suggestion = ARMMnemonicSpellCheck(
11510 ((ARMOperand &)*Operands[0]).getToken(), FBS);
11511 return Error(IDLoc, "invalid instruction" + Suggestion,
11512 ((ARMOperand &)*Operands[0]).getLocRange());
11513 }
11514 }
11515
11516 llvm_unreachable("Implement any new match types added!");
11517}
11518
11519/// ParseDirective parses the arm specific directives
11520bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11521 const MCContext::Environment Format = getContext().getObjectFileType();
11522 bool IsMachO = Format == MCContext::IsMachO;
11523 bool IsCOFF = Format == MCContext::IsCOFF;
11524
11525 std::string IDVal = DirectiveID.getIdentifier().lower();
11526 if (IDVal == ".word")
11527 parseLiteralValues(4, DirectiveID.getLoc());
11528 else if (IDVal == ".short" || IDVal == ".hword")
11529 parseLiteralValues(2, DirectiveID.getLoc());
11530 else if (IDVal == ".thumb")
11531 parseDirectiveThumb(DirectiveID.getLoc());
11532 else if (IDVal == ".arm")
11533 parseDirectiveARM(DirectiveID.getLoc());
11534 else if (IDVal == ".thumb_func")
11535 parseDirectiveThumbFunc(DirectiveID.getLoc());
11536 else if (IDVal == ".code")
11537 parseDirectiveCode(DirectiveID.getLoc());
11538 else if (IDVal == ".syntax")
11539 parseDirectiveSyntax(DirectiveID.getLoc());
11540 else if (IDVal == ".unreq")
11541 parseDirectiveUnreq(DirectiveID.getLoc());
11542 else if (IDVal == ".fnend")
11543 parseDirectiveFnEnd(DirectiveID.getLoc());
11544 else if (IDVal == ".cantunwind")
11545 parseDirectiveCantUnwind(DirectiveID.getLoc());
11546 else if (IDVal == ".personality")
11547 parseDirectivePersonality(DirectiveID.getLoc());
11548 else if (IDVal == ".handlerdata")
11549 parseDirectiveHandlerData(DirectiveID.getLoc());
11550 else if (IDVal == ".setfp")
11551 parseDirectiveSetFP(DirectiveID.getLoc());
11552 else if (IDVal == ".pad")
11553 parseDirectivePad(DirectiveID.getLoc());
11554 else if (IDVal == ".save")
11555 parseDirectiveRegSave(DirectiveID.getLoc(), false);
11556 else if (IDVal == ".vsave")
11557 parseDirectiveRegSave(DirectiveID.getLoc(), true);
11558 else if (IDVal == ".ltorg" || IDVal == ".pool")
11559 parseDirectiveLtorg(DirectiveID.getLoc());
11560 else if (IDVal == ".even")
11561 parseDirectiveEven(DirectiveID.getLoc());
11562 else if (IDVal == ".personalityindex")
11563 parseDirectivePersonalityIndex(DirectiveID.getLoc());
11564 else if (IDVal == ".unwind_raw")
11565 parseDirectiveUnwindRaw(DirectiveID.getLoc());
11566 else if (IDVal == ".movsp")
11567 parseDirectiveMovSP(DirectiveID.getLoc());
11568 else if (IDVal == ".arch_extension")
11569 parseDirectiveArchExtension(DirectiveID.getLoc());
11570 else if (IDVal == ".align")
11571 return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
11572 else if (IDVal == ".thumb_set")
11573 parseDirectiveThumbSet(DirectiveID.getLoc());
11574 else if (IDVal == ".inst")
11575 parseDirectiveInst(DirectiveID.getLoc());
11576 else if (IDVal == ".inst.n")
11577 parseDirectiveInst(DirectiveID.getLoc(), 'n');
11578 else if (IDVal == ".inst.w")
11579 parseDirectiveInst(DirectiveID.getLoc(), 'w');
11580 else if (!IsMachO && !IsCOFF) {
11581 if (IDVal == ".arch")
11582 parseDirectiveArch(DirectiveID.getLoc());
11583 else if (IDVal == ".cpu")
11584 parseDirectiveCPU(DirectiveID.getLoc());
11585 else if (IDVal == ".eabi_attribute")
11586 parseDirectiveEabiAttr(DirectiveID.getLoc());
11587 else if (IDVal == ".fpu")
11588 parseDirectiveFPU(DirectiveID.getLoc());
11589 else if (IDVal == ".fnstart")
11590 parseDirectiveFnStart(DirectiveID.getLoc());
11591 else if (IDVal == ".object_arch")
11592 parseDirectiveObjectArch(DirectiveID.getLoc());
11593 else if (IDVal == ".tlsdescseq")
11594 parseDirectiveTLSDescSeq(DirectiveID.getLoc());
11595 else
11596 return true;
11597 } else if (IsCOFF) {
11598 if (IDVal == ".seh_stackalloc")
11599 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/false);
11600 else if (IDVal == ".seh_stackalloc_w")
11601 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/true);
11602 else if (IDVal == ".seh_save_regs")
11603 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/false);
11604 else if (IDVal == ".seh_save_regs_w")
11605 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/true);
11606 else if (IDVal == ".seh_save_sp")
11607 parseDirectiveSEHSaveSP(DirectiveID.getLoc());
11608 else if (IDVal == ".seh_save_fregs")
11609 parseDirectiveSEHSaveFRegs(DirectiveID.getLoc());
11610 else if (IDVal == ".seh_save_lr")
11611 parseDirectiveSEHSaveLR(DirectiveID.getLoc());
11612 else if (IDVal == ".seh_endprologue")
11613 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/false);
11614 else if (IDVal == ".seh_endprologue_fragment")
11615 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/true);
11616 else if (IDVal == ".seh_nop")
11617 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/false);
11618 else if (IDVal == ".seh_nop_w")
11619 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/true);
11620 else if (IDVal == ".seh_startepilogue")
11621 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/false);
11622 else if (IDVal == ".seh_startepilogue_cond")
11623 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/true);
11624 else if (IDVal == ".seh_endepilogue")
11625 parseDirectiveSEHEpilogEnd(DirectiveID.getLoc());
11626 else if (IDVal == ".seh_custom")
11627 parseDirectiveSEHCustom(DirectiveID.getLoc());
11628 else
11629 return true;
11630 } else
11631 return true;
11632 return false;
11633}
11634
11635/// parseLiteralValues
11636/// ::= .hword expression [, expression]*
11637/// ::= .short expression [, expression]*
11638/// ::= .word expression [, expression]*
11639bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
11640 auto parseOne = [&]() -> bool {
11641 const MCExpr *Value;
11642 if (getParser().parseExpression(Value))
11643 return true;
11644 getParser().getStreamer().emitValue(Value, Size, L);
11645 return false;
11646 };
11647 return (parseMany(parseOne));
11648}
11649
11650/// parseDirectiveThumb
11651/// ::= .thumb
11652bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11653 if (parseEOL() || check(!hasThumb(), L, "target does not support Thumb mode"))
11654 return true;
11655
11656 if (!isThumb())
11657 SwitchMode();
11658
11659 getTargetStreamer().emitCode16();
11660 getParser().getStreamer().emitCodeAlignment(Align(2), getSTI(), 0);
11661 return false;
11662}
11663
11664/// parseDirectiveARM
11665/// ::= .arm
11666bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11667 if (parseEOL() || check(!hasARM(), L, "target does not support ARM mode"))
11668 return true;
11669
11670 if (isThumb())
11671 SwitchMode();
11672 getTargetStreamer().emitCode32();
11673 getParser().getStreamer().emitCodeAlignment(Align(4), getSTI(), 0);
11674 return false;
11675}
11676
11677void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11678 // We need to flush the current implicit IT block on a label, because it is
11679 // not legal to branch into an IT block.
11680 flushPendingInstructions(getStreamer());
11681}
11682
11683void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11684 if (NextSymbolIsThumb) {
11685 getTargetStreamer().emitThumbFunc(Symbol);
11686 NextSymbolIsThumb = false;
11687 }
11688}
11689
11690/// parseDirectiveThumbFunc
11691/// ::= .thumbfunc symbol_name
11692bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11693 MCAsmParser &Parser = getParser();
11694 const auto Format = getContext().getObjectFileType();
11695 bool IsMachO = Format == MCContext::IsMachO;
11696
11697 // Darwin asm has (optionally) function name after .thumb_func direction
11698 // ELF doesn't
11699
11700 if (IsMachO) {
11701 if (Parser.getTok().is(AsmToken::Identifier) ||
11702 Parser.getTok().is(AsmToken::String)) {
11703 MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
11704 Parser.getTok().getIdentifier());
11705 getTargetStreamer().emitThumbFunc(Func);
11706 Parser.Lex();
11707 if (parseEOL())
11708 return true;
11709 return false;
11710 }
11711 }
11712
11713 if (parseEOL())
11714 return true;
11715
11716 // .thumb_func implies .thumb
11717 if (!isThumb())
11718 SwitchMode();
11719
11720 getTargetStreamer().emitCode16();
11721
11722 NextSymbolIsThumb = true;
11723 return false;
11724}
11725
11726/// parseDirectiveSyntax
11727/// ::= .syntax unified | divided
11728bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11729 MCAsmParser &Parser = getParser();
11730 const AsmToken &Tok = Parser.getTok();
11731 if (Tok.isNot(AsmToken::Identifier)) {
11732 Error(L, "unexpected token in .syntax directive");
11733 return false;
11734 }
11735
11736 StringRef Mode = Tok.getString();
11737 Parser.Lex();
11738 if (check(Mode == "divided" || Mode == "DIVIDED", L,
11739 "'.syntax divided' arm assembly not supported") ||
11740 check(Mode != "unified" && Mode != "UNIFIED", L,
11741 "unrecognized syntax mode in .syntax directive") ||
11742 parseEOL())
11743 return true;
11744
11745 // TODO tell the MC streamer the mode
11746 // getParser().getStreamer().Emit???();
11747 return false;
11748}
11749
11750/// parseDirectiveCode
11751/// ::= .code 16 | 32
11752bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11753 MCAsmParser &Parser = getParser();
11754 const AsmToken &Tok = Parser.getTok();
11755 if (Tok.isNot(AsmToken::Integer))
11756 return Error(L, "unexpected token in .code directive");
11757 int64_t Val = Parser.getTok().getIntVal();
11758 if (Val != 16 && Val != 32) {
11759 Error(L, "invalid operand to .code directive");
11760 return false;
11761 }
11762 Parser.Lex();
11763
11764 if (parseEOL())
11765 return true;
11766
11767 if (Val == 16) {
11768 if (!hasThumb())
11769 return Error(L, "target does not support Thumb mode");
11770
11771 if (!isThumb())
11772 SwitchMode();
11773 getTargetStreamer().emitCode16();
11774 } else {
11775 if (!hasARM())
11776 return Error(L, "target does not support ARM mode");
11777
11778 if (isThumb())
11779 SwitchMode();
11780 getTargetStreamer().emitCode32();
11781 }
11782
11783 return false;
11784}
11785
11786/// parseDirectiveReq
11787/// ::= name .req registername
11788bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11789 MCAsmParser &Parser = getParser();
11790 Parser.Lex(); // Eat the '.req' token.
11791 MCRegister Reg;
11792 SMLoc SRegLoc, ERegLoc;
11793 const bool parseResult = parseRegister(Reg, SRegLoc, ERegLoc);
11794 if (check(parseResult, SRegLoc, "register name expected") || parseEOL())
11795 return true;
11796
11797 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg)
11798 return Error(SRegLoc,
11799 "redefinition of '" + Name + "' does not match original.");
11800
11801 return false;
11802}
11803
11804/// parseDirectiveUneq
11805/// ::= .unreq registername
11806bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11807 MCAsmParser &Parser = getParser();
11808 if (Parser.getTok().isNot(AsmToken::Identifier))
11809 return Error(L, "unexpected input in .unreq directive.");
11810 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
11811 Parser.Lex(); // Eat the identifier.
11812 return parseEOL();
11813}
11814
11815// After changing arch/CPU, try to put the ARM/Thumb mode back to what it was
11816// before, if supported by the new target, or emit mapping symbols for the mode
11817// switch.
11818void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) {
11819 if (WasThumb != isThumb()) {
11820 if (WasThumb && hasThumb()) {
11821 // Stay in Thumb mode
11822 SwitchMode();
11823 } else if (!WasThumb && hasARM()) {
11824 // Stay in ARM mode
11825 SwitchMode();
11826 } else {
11827 // Mode switch forced, because the new arch doesn't support the old mode.
11828 if (isThumb())
11829 getTargetStreamer().emitCode16();
11830 else
11831 getTargetStreamer().emitCode32();
11832 // Warn about the implicit mode switch. GAS does not switch modes here,
11833 // but instead stays in the old mode, reporting an error on any following
11834 // instructions as the mode does not exist on the target.
11835 Warning(Loc, Twine("new target does not support ") +
11836 (WasThumb ? "thumb" : "arm") + " mode, switching to " +
11837 (!WasThumb ? "thumb" : "arm") + " mode");
11838 }
11839 }
11840}
11841
11842/// parseDirectiveArch
11843/// ::= .arch token
11844bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11845 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11847
11848 if (ID == ARM::ArchKind::INVALID)
11849 return Error(L, "Unknown arch name");
11850
11851 bool WasThumb = isThumb();
11852 MCSubtargetInfo &STI = copySTI();
11853 STI.setDefaultFeatures("", /*TuneCPU*/ "",
11854 ("+" + ARM::getArchName(ID)).str());
11855 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11856 FixModeAfterArchChange(WasThumb, L);
11857
11858 getTargetStreamer().emitArch(ID);
11859 return false;
11860}
11861
11862/// parseDirectiveEabiAttr
11863/// ::= .eabi_attribute int, int [, "str"]
11864/// ::= .eabi_attribute Tag_name, int [, "str"]
11865bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11866 MCAsmParser &Parser = getParser();
11867 int64_t Tag;
11868 SMLoc TagLoc;
11869 TagLoc = Parser.getTok().getLoc();
11870 if (Parser.getTok().is(AsmToken::Identifier)) {
11871 StringRef Name = Parser.getTok().getIdentifier();
11872 std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString(
11874 if (!Ret) {
11875 Error(TagLoc, "attribute name not recognised: " + Name);
11876 return false;
11877 }
11878 Tag = *Ret;
11879 Parser.Lex();
11880 } else {
11881 const MCExpr *AttrExpr;
11882
11883 TagLoc = Parser.getTok().getLoc();
11884 if (Parser.parseExpression(AttrExpr))
11885 return true;
11886
11887 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
11888 if (check(!CE, TagLoc, "expected numeric constant"))
11889 return true;
11890
11891 Tag = CE->getValue();
11892 }
11893
11894 if (Parser.parseComma())
11895 return true;
11896
11897 StringRef StringValue = "";
11898 bool IsStringValue = false;
11899
11900 int64_t IntegerValue = 0;
11901 bool IsIntegerValue = false;
11902
11904 IsStringValue = true;
11905 else if (Tag == ARMBuildAttrs::compatibility) {
11906 IsStringValue = true;
11907 IsIntegerValue = true;
11908 } else if (Tag < 32 || Tag % 2 == 0)
11909 IsIntegerValue = true;
11910 else if (Tag % 2 == 1)
11911 IsStringValue = true;
11912 else
11913 llvm_unreachable("invalid tag type");
11914
11915 if (IsIntegerValue) {
11916 const MCExpr *ValueExpr;
11917 SMLoc ValueExprLoc = Parser.getTok().getLoc();
11918 if (Parser.parseExpression(ValueExpr))
11919 return true;
11920
11921 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
11922 if (!CE)
11923 return Error(ValueExprLoc, "expected numeric constant");
11924 IntegerValue = CE->getValue();
11925 }
11926
11928 if (Parser.parseComma())
11929 return true;
11930 }
11931
11932 std::string EscapedValue;
11933 if (IsStringValue) {
11934 if (Parser.getTok().isNot(AsmToken::String))
11935 return Error(Parser.getTok().getLoc(), "bad string constant");
11936
11938 if (Parser.parseEscapedString(EscapedValue))
11939 return Error(Parser.getTok().getLoc(), "bad escaped string constant");
11940
11941 StringValue = EscapedValue;
11942 } else {
11943 StringValue = Parser.getTok().getStringContents();
11944 Parser.Lex();
11945 }
11946 }
11947
11948 if (Parser.parseEOL())
11949 return true;
11950
11951 if (IsIntegerValue && IsStringValue) {
11953 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
11954 } else if (IsIntegerValue)
11955 getTargetStreamer().emitAttribute(Tag, IntegerValue);
11956 else if (IsStringValue)
11957 getTargetStreamer().emitTextAttribute(Tag, StringValue);
11958 return false;
11959}
11960
11961/// parseDirectiveCPU
11962/// ::= .cpu str
11963bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11964 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11965 getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
11966
11967 // FIXME: This is using table-gen data, but should be moved to
11968 // ARMTargetParser once that is table-gen'd.
11969 if (!getSTI().isCPUStringValid(CPU))
11970 return Error(L, "Unknown CPU name");
11971
11972 bool WasThumb = isThumb();
11973 MCSubtargetInfo &STI = copySTI();
11974 STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
11975 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11976 FixModeAfterArchChange(WasThumb, L);
11977
11978 return false;
11979}
11980
11981/// parseDirectiveFPU
11982/// ::= .fpu str
11983bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11984 SMLoc FPUNameLoc = getTok().getLoc();
11985 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11986
11988 std::vector<StringRef> Features;
11989 if (!ARM::getFPUFeatures(ID, Features))
11990 return Error(FPUNameLoc, "Unknown FPU name");
11991
11992 MCSubtargetInfo &STI = copySTI();
11993 for (auto Feature : Features)
11994 STI.ApplyFeatureFlag(Feature);
11995 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11996
11997 getTargetStreamer().emitFPU(ID);
11998 return false;
11999}
12000
12001/// parseDirectiveFnStart
12002/// ::= .fnstart
12003bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
12004 if (parseEOL())
12005 return true;
12006
12007 if (UC.hasFnStart()) {
12008 Error(L, ".fnstart starts before the end of previous one");
12009 UC.emitFnStartLocNotes();
12010 return true;
12011 }
12012
12013 // Reset the unwind directives parser state
12014 UC.reset();
12015
12016 getTargetStreamer().emitFnStart();
12017
12018 UC.recordFnStart(L);
12019 return false;
12020}
12021
12022/// parseDirectiveFnEnd
12023/// ::= .fnend
12024bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12025 if (parseEOL())
12026 return true;
12027 // Check the ordering of unwind directives
12028 if (!UC.hasFnStart())
12029 return Error(L, ".fnstart must precede .fnend directive");
12030
12031 // Reset the unwind directives parser state
12032 getTargetStreamer().emitFnEnd();
12033
12034 UC.reset();
12035 return false;
12036}
12037
12038/// parseDirectiveCantUnwind
12039/// ::= .cantunwind
12040bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12041 if (parseEOL())
12042 return true;
12043
12044 UC.recordCantUnwind(L);
12045 // Check the ordering of unwind directives
12046 if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive"))
12047 return true;
12048
12049 if (UC.hasHandlerData()) {
12050 Error(L, ".cantunwind can't be used with .handlerdata directive");
12051 UC.emitHandlerDataLocNotes();
12052 return true;
12053 }
12054 if (UC.hasPersonality()) {
12055 Error(L, ".cantunwind can't be used with .personality directive");
12056 UC.emitPersonalityLocNotes();
12057 return true;
12058 }
12059
12060 getTargetStreamer().emitCantUnwind();
12061 return false;
12062}
12063
12064/// parseDirectivePersonality
12065/// ::= .personality name
12066bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12067 MCAsmParser &Parser = getParser();
12068 bool HasExistingPersonality = UC.hasPersonality();
12069
12070 // Parse the name of the personality routine
12071 if (Parser.getTok().isNot(AsmToken::Identifier))
12072 return Error(L, "unexpected input in .personality directive.");
12073 StringRef Name(Parser.getTok().getIdentifier());
12074 Parser.Lex();
12075
12076 if (parseEOL())
12077 return true;
12078
12079 UC.recordPersonality(L);
12080
12081 // Check the ordering of unwind directives
12082 if (!UC.hasFnStart())
12083 return Error(L, ".fnstart must precede .personality directive");
12084 if (UC.cantUnwind()) {
12085 Error(L, ".personality can't be used with .cantunwind directive");
12086 UC.emitCantUnwindLocNotes();
12087 return true;
12088 }
12089 if (UC.hasHandlerData()) {
12090 Error(L, ".personality must precede .handlerdata directive");
12091 UC.emitHandlerDataLocNotes();
12092 return true;
12093 }
12094 if (HasExistingPersonality) {
12095 Error(L, "multiple personality directives");
12096 UC.emitPersonalityLocNotes();
12097 return true;
12098 }
12099
12100 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12101 getTargetStreamer().emitPersonality(PR);
12102 return false;
12103}
12104
12105/// parseDirectiveHandlerData
12106/// ::= .handlerdata
12107bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12108 if (parseEOL())
12109 return true;
12110
12111 UC.recordHandlerData(L);
12112 // Check the ordering of unwind directives
12113 if (!UC.hasFnStart())
12114 return Error(L, ".fnstart must precede .personality directive");
12115 if (UC.cantUnwind()) {
12116 Error(L, ".handlerdata can't be used with .cantunwind directive");
12117 UC.emitCantUnwindLocNotes();
12118 return true;
12119 }
12120
12121 getTargetStreamer().emitHandlerData();
12122 return false;
12123}
12124
12125/// parseDirectiveSetFP
12126/// ::= .setfp fpreg, spreg [, offset]
12127bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12128 MCAsmParser &Parser = getParser();
12129 // Check the ordering of unwind directives
12130 if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") ||
12131 check(UC.hasHandlerData(), L,
12132 ".setfp must precede .handlerdata directive"))
12133 return true;
12134
12135 // Parse fpreg
12136 SMLoc FPRegLoc = Parser.getTok().getLoc();
12137 MCRegister FPReg = tryParseRegister();
12138
12139 if (check(!FPReg, FPRegLoc, "frame pointer register expected") ||
12140 Parser.parseComma())
12141 return true;
12142
12143 // Parse spreg
12144 SMLoc SPRegLoc = Parser.getTok().getLoc();
12145 MCRegister SPReg = tryParseRegister();
12146 if (check(!SPReg, SPRegLoc, "stack pointer register expected") ||
12147 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
12148 "register should be either $sp or the latest fp register"))
12149 return true;
12150
12151 // Update the frame pointer register
12152 UC.saveFPReg(FPReg);
12153
12154 // Parse offset
12155 int64_t Offset = 0;
12156 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12157 if (Parser.getTok().isNot(AsmToken::Hash) &&
12158 Parser.getTok().isNot(AsmToken::Dollar))
12159 return Error(Parser.getTok().getLoc(), "'#' expected");
12160 Parser.Lex(); // skip hash token.
12161
12162 const MCExpr *OffsetExpr;
12163 SMLoc ExLoc = Parser.getTok().getLoc();
12164 SMLoc EndLoc;
12165 if (getParser().parseExpression(OffsetExpr, EndLoc))
12166 return Error(ExLoc, "malformed setfp offset");
12167 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12168 if (check(!CE, ExLoc, "setfp offset must be an immediate"))
12169 return true;
12170 Offset = CE->getValue();
12171 }
12172
12173 if (Parser.parseEOL())
12174 return true;
12175
12176 getTargetStreamer().emitSetFP(FPReg, SPReg, Offset);
12177 return false;
12178}
12179
12180/// parseDirectivePad
12181/// ::= .pad offset
12182bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12183 MCAsmParser &Parser = getParser();
12184 // Check the ordering of unwind directives
12185 if (!UC.hasFnStart())
12186 return Error(L, ".fnstart must precede .pad directive");
12187 if (UC.hasHandlerData())
12188 return Error(L, ".pad must precede .handlerdata directive");
12189
12190 // Parse the offset
12191 if (Parser.getTok().isNot(AsmToken::Hash) &&
12192 Parser.getTok().isNot(AsmToken::Dollar))
12193 return Error(Parser.getTok().getLoc(), "'#' expected");
12194 Parser.Lex(); // skip hash token.
12195
12196 const MCExpr *OffsetExpr;
12197 SMLoc ExLoc = Parser.getTok().getLoc();
12198 SMLoc EndLoc;
12199 if (getParser().parseExpression(OffsetExpr, EndLoc))
12200 return Error(ExLoc, "malformed pad offset");
12201 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12202 if (!CE)
12203 return Error(ExLoc, "pad offset must be an immediate");
12204
12205 if (parseEOL())
12206 return true;
12207
12208 getTargetStreamer().emitPad(CE->getValue());
12209 return false;
12210}
12211
12212/// parseDirectiveRegSave
12213/// ::= .save { registers }
12214/// ::= .vsave { registers }
12215bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
12216 // Check the ordering of unwind directives
12217 if (!UC.hasFnStart())
12218 return Error(L, ".fnstart must precede .save or .vsave directives");
12219 if (UC.hasHandlerData())
12220 return Error(L, ".save or .vsave must precede .handlerdata directive");
12221
12222 // RAII object to make sure parsed operands are deleted.
12224
12225 // Parse the register list
12226 if (parseRegisterList(Operands, true, true) || parseEOL())
12227 return true;
12228 ARMOperand &Op = (ARMOperand &)*Operands[0];
12229 if (!IsVector && !Op.isRegList())
12230 return Error(L, ".save expects GPR registers");
12231 if (IsVector && !Op.isDPRRegList())
12232 return Error(L, ".vsave expects DPR registers");
12233
12234 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
12235 return false;
12236}
12237
12238/// parseDirectiveInst
12239/// ::= .inst opcode [, ...]
12240/// ::= .inst.n opcode [, ...]
12241/// ::= .inst.w opcode [, ...]
12242bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
12243 int Width = 4;
12244
12245 if (isThumb()) {
12246 switch (Suffix) {
12247 case 'n':
12248 Width = 2;
12249 break;
12250 case 'w':
12251 break;
12252 default:
12253 Width = 0;
12254 break;
12255 }
12256 } else {
12257 if (Suffix)
12258 return Error(Loc, "width suffixes are invalid in ARM mode");
12259 }
12260
12261 auto parseOne = [&]() -> bool {
12262 const MCExpr *Expr;
12263 if (getParser().parseExpression(Expr))
12264 return true;
12265 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
12266 if (!Value) {
12267 return Error(Loc, "expected constant expression");
12268 }
12269
12270 char CurSuffix = Suffix;
12271 switch (Width) {
12272 case 2:
12273 if (Value->getValue() > 0xffff)
12274 return Error(Loc, "inst.n operand is too big, use inst.w instead");
12275 break;
12276 case 4:
12277 if (Value->getValue() > 0xffffffff)
12278 return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +
12279 " operand is too big");
12280 break;
12281 case 0:
12282 // Thumb mode, no width indicated. Guess from the opcode, if possible.
12283 if (Value->getValue() < 0xe800)
12284 CurSuffix = 'n';
12285 else if (Value->getValue() >= 0xe8000000)
12286 CurSuffix = 'w';
12287 else
12288 return Error(Loc, "cannot determine Thumb instruction size, "
12289 "use inst.n/inst.w instead");
12290 break;
12291 default:
12292 llvm_unreachable("only supported widths are 2 and 4");
12293 }
12294
12295 getTargetStreamer().emitInst(Value->getValue(), CurSuffix);
12296 forwardITPosition();
12297 forwardVPTPosition();
12298 return false;
12299 };
12300
12301 if (parseOptionalToken(AsmToken::EndOfStatement))
12302 return Error(Loc, "expected expression following directive");
12303 if (parseMany(parseOne))
12304 return true;
12305 return false;
12306}
12307
12308/// parseDirectiveLtorg
12309/// ::= .ltorg | .pool
12310bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12311 if (parseEOL())
12312 return true;
12313 getTargetStreamer().emitCurrentConstantPool();
12314 return false;
12315}
12316
12317bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12318 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12319
12320 if (parseEOL())
12321 return true;
12322
12323 if (!Section) {
12324 getStreamer().initSections(getSTI());
12325 Section = getStreamer().getCurrentSectionOnly();
12326 }
12327
12328 assert(Section && "must have section to emit alignment");
12329 if (getContext().getAsmInfo().useCodeAlign(*Section))
12330 getStreamer().emitCodeAlignment(Align(2), getSTI());
12331 else
12332 getStreamer().emitValueToAlignment(Align(2));
12333
12334 return false;
12335}
12336
12337/// parseDirectivePersonalityIndex
12338/// ::= .personalityindex index
12339bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12340 MCAsmParser &Parser = getParser();
12341 bool HasExistingPersonality = UC.hasPersonality();
12342
12343 const MCExpr *IndexExpression;
12344 SMLoc IndexLoc = Parser.getTok().getLoc();
12345 if (Parser.parseExpression(IndexExpression) || parseEOL()) {
12346 return true;
12347 }
12348
12349 UC.recordPersonalityIndex(L);
12350
12351 if (!UC.hasFnStart()) {
12352 return Error(L, ".fnstart must precede .personalityindex directive");
12353 }
12354 if (UC.cantUnwind()) {
12355 Error(L, ".personalityindex cannot be used with .cantunwind");
12356 UC.emitCantUnwindLocNotes();
12357 return true;
12358 }
12359 if (UC.hasHandlerData()) {
12360 Error(L, ".personalityindex must precede .handlerdata directive");
12361 UC.emitHandlerDataLocNotes();
12362 return true;
12363 }
12364 if (HasExistingPersonality) {
12365 Error(L, "multiple personality directives");
12366 UC.emitPersonalityLocNotes();
12367 return true;
12368 }
12369
12370 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression);
12371 if (!CE)
12372 return Error(IndexLoc, "index must be a constant number");
12373 if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX)
12374 return Error(IndexLoc,
12375 "personality routine index should be in range [0-3]");
12376
12377 getTargetStreamer().emitPersonalityIndex(CE->getValue());
12378 return false;
12379}
12380
12381/// parseDirectiveUnwindRaw
12382/// ::= .unwind_raw offset, opcode [, opcode...]
12383bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12384 MCAsmParser &Parser = getParser();
12385 int64_t StackOffset;
12386 const MCExpr *OffsetExpr;
12387 SMLoc OffsetLoc = getLexer().getLoc();
12388
12389 if (!UC.hasFnStart())
12390 return Error(L, ".fnstart must precede .unwind_raw directives");
12391 if (getParser().parseExpression(OffsetExpr))
12392 return Error(OffsetLoc, "expected expression");
12393
12394 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12395 if (!CE)
12396 return Error(OffsetLoc, "offset must be a constant");
12397
12398 StackOffset = CE->getValue();
12399
12400 if (Parser.parseComma())
12401 return true;
12402
12404
12405 auto parseOne = [&]() -> bool {
12406 const MCExpr *OE = nullptr;
12407 SMLoc OpcodeLoc = getLexer().getLoc();
12408 if (check(getLexer().is(AsmToken::EndOfStatement) ||
12409 Parser.parseExpression(OE),
12410 OpcodeLoc, "expected opcode expression"))
12411 return true;
12412 const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE);
12413 if (!OC)
12414 return Error(OpcodeLoc, "opcode value must be a constant");
12415 const int64_t Opcode = OC->getValue();
12416 if (Opcode & ~0xff)
12417 return Error(OpcodeLoc, "invalid opcode");
12418 Opcodes.push_back(uint8_t(Opcode));
12419 return false;
12420 };
12421
12422 // Must have at least 1 element
12423 SMLoc OpcodeLoc = getLexer().getLoc();
12424 if (parseOptionalToken(AsmToken::EndOfStatement))
12425 return Error(OpcodeLoc, "expected opcode expression");
12426 if (parseMany(parseOne))
12427 return true;
12428
12429 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12430 return false;
12431}
12432
12433/// parseDirectiveTLSDescSeq
12434/// ::= .tlsdescseq tls-variable
12435bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12436 MCAsmParser &Parser = getParser();
12437
12438 if (getLexer().isNot(AsmToken::Identifier))
12439 return TokError("expected variable after '.tlsdescseq' directive");
12440
12441 auto *Sym = getContext().getOrCreateSymbol(Parser.getTok().getIdentifier());
12442 const auto *SRE =
12444 Lex();
12445
12446 if (parseEOL())
12447 return true;
12448
12449 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12450 return false;
12451}
12452
12453/// parseDirectiveMovSP
12454/// ::= .movsp reg [, #offset]
12455bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12456 MCAsmParser &Parser = getParser();
12457 if (!UC.hasFnStart())
12458 return Error(L, ".fnstart must precede .movsp directives");
12459 if (UC.getFPReg() != ARM::SP)
12460 return Error(L, "unexpected .movsp directive");
12461
12462 SMLoc SPRegLoc = Parser.getTok().getLoc();
12463 MCRegister SPReg = tryParseRegister();
12464 if (!SPReg)
12465 return Error(SPRegLoc, "register expected");
12466 if (SPReg == ARM::SP || SPReg == ARM::PC)
12467 return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
12468
12469 int64_t Offset = 0;
12470 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12471 if (Parser.parseToken(AsmToken::Hash, "expected #constant"))
12472 return true;
12473
12474 const MCExpr *OffsetExpr;
12475 SMLoc OffsetLoc = Parser.getTok().getLoc();
12476
12477 if (Parser.parseExpression(OffsetExpr))
12478 return Error(OffsetLoc, "malformed offset expression");
12479
12480 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12481 if (!CE)
12482 return Error(OffsetLoc, "offset must be an immediate constant");
12483
12484 Offset = CE->getValue();
12485 }
12486
12487 if (parseEOL())
12488 return true;
12489
12490 getTargetStreamer().emitMovSP(SPReg, Offset);
12491 UC.saveFPReg(SPReg);
12492
12493 return false;
12494}
12495
12496/// parseDirectiveObjectArch
12497/// ::= .object_arch name
12498bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12499 MCAsmParser &Parser = getParser();
12500 if (getLexer().isNot(AsmToken::Identifier))
12501 return Error(getLexer().getLoc(), "unexpected token");
12502
12503 StringRef Arch = Parser.getTok().getString();
12504 SMLoc ArchLoc = Parser.getTok().getLoc();
12505 Lex();
12506
12508
12509 if (ID == ARM::ArchKind::INVALID)
12510 return Error(ArchLoc, "unknown architecture '" + Arch + "'");
12511 if (parseToken(AsmToken::EndOfStatement))
12512 return true;
12513
12514 getTargetStreamer().emitObjectArch(ID);
12515 return false;
12516}
12517
12518/// parseDirectiveAlign
12519/// ::= .align
12520bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12521 // NOTE: if this is not the end of the statement, fall back to the target
12522 // agnostic handling for this directive which will correctly handle this.
12523 if (parseOptionalToken(AsmToken::EndOfStatement)) {
12524 // '.align' is target specifically handled to mean 2**2 byte alignment.
12525 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12526 assert(Section && "must have section to emit alignment");
12527 if (getContext().getAsmInfo().useCodeAlign(*Section))
12528 getStreamer().emitCodeAlignment(Align(4), getSTI(), 0);
12529 else
12530 getStreamer().emitValueToAlignment(Align(4), 0, 1, 0);
12531 return false;
12532 }
12533 return true;
12534}
12535
12536/// parseDirectiveThumbSet
12537/// ::= .thumb_set name, value
12538bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12539 MCAsmParser &Parser = getParser();
12540
12541 StringRef Name;
12542 if (check(Parser.parseIdentifier(Name),
12543 "expected identifier after '.thumb_set'") ||
12544 Parser.parseComma())
12545 return true;
12546
12547 MCSymbol *Sym;
12548 const MCExpr *Value;
12549 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
12550 Parser, Sym, Value))
12551 return true;
12552
12553 getTargetStreamer().emitThumbSet(Sym, Value);
12554 return false;
12555}
12556
12557/// parseDirectiveSEHAllocStack
12558/// ::= .seh_stackalloc
12559/// ::= .seh_stackalloc_w
12560bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L, bool Wide) {
12561 int64_t Size;
12562 if (parseImmExpr(Size))
12563 return true;
12564 getTargetStreamer().emitARMWinCFIAllocStack(Size, Wide);
12565 return false;
12566}
12567
12568/// parseDirectiveSEHSaveRegs
12569/// ::= .seh_save_regs
12570/// ::= .seh_save_regs_w
12571bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L, bool Wide) {
12573
12574 if (parseRegisterList(Operands) || parseEOL())
12575 return true;
12576 ARMOperand &Op = (ARMOperand &)*Operands[0];
12577 if (!Op.isRegList())
12578 return Error(L, ".seh_save_regs{_w} expects GPR registers");
12579 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12580 uint32_t Mask = 0;
12581 for (size_t i = 0; i < RegList.size(); ++i) {
12582 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12583 if (Reg == 15) // pc -> lr
12584 Reg = 14;
12585 if (Reg == 13)
12586 return Error(L, ".seh_save_regs{_w} can't include SP");
12587 assert(Reg < 16U && "Register out of range");
12588 unsigned Bit = (1u << Reg);
12589 Mask |= Bit;
12590 }
12591 if (!Wide && (Mask & 0x1f00) != 0)
12592 return Error(L,
12593 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12594 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12595 return false;
12596}
12597
12598/// parseDirectiveSEHSaveSP
12599/// ::= .seh_save_sp
12600bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12601 MCRegister Reg = tryParseRegister();
12602 if (!Reg || !MRI->getRegClass(ARM::GPRRegClassID).contains(Reg))
12603 return Error(L, "expected GPR");
12604 unsigned Index = MRI->getEncodingValue(Reg);
12605 if (Index > 14 || Index == 13)
12606 return Error(L, "invalid register for .seh_save_sp");
12607 getTargetStreamer().emitARMWinCFISaveSP(Index);
12608 return false;
12609}
12610
12611/// parseDirectiveSEHSaveFRegs
12612/// ::= .seh_save_fregs
12613bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12615
12616 if (parseRegisterList(Operands) || parseEOL())
12617 return true;
12618 ARMOperand &Op = (ARMOperand &)*Operands[0];
12619 if (!Op.isDPRRegList())
12620 return Error(L, ".seh_save_fregs expects DPR registers");
12621 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12622 uint32_t Mask = 0;
12623 for (size_t i = 0; i < RegList.size(); ++i) {
12624 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12625 assert(Reg < 32U && "Register out of range");
12626 unsigned Bit = (1u << Reg);
12627 Mask |= Bit;
12628 }
12629
12630 if (Mask == 0)
12631 return Error(L, ".seh_save_fregs missing registers");
12632
12633 unsigned First = 0;
12634 while ((Mask & 1) == 0) {
12635 First++;
12636 Mask >>= 1;
12637 }
12638 if (((Mask + 1) & Mask) != 0)
12639 return Error(L,
12640 ".seh_save_fregs must take a contiguous range of registers");
12641 unsigned Last = First;
12642 while ((Mask & 2) != 0) {
12643 Last++;
12644 Mask >>= 1;
12645 }
12646 if (First < 16 && Last >= 16)
12647 return Error(L, ".seh_save_fregs must be all d0-d15 or d16-d31");
12648 getTargetStreamer().emitARMWinCFISaveFRegs(First, Last);
12649 return false;
12650}
12651
12652/// parseDirectiveSEHSaveLR
12653/// ::= .seh_save_lr
12654bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12655 int64_t Offset;
12656 if (parseImmExpr(Offset))
12657 return true;
12658 getTargetStreamer().emitARMWinCFISaveLR(Offset);
12659 return false;
12660}
12661
12662/// parseDirectiveSEHPrologEnd
12663/// ::= .seh_endprologue
12664/// ::= .seh_endprologue_fragment
12665bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L, bool Fragment) {
12666 getTargetStreamer().emitARMWinCFIPrologEnd(Fragment);
12667 return false;
12668}
12669
12670/// parseDirectiveSEHNop
12671/// ::= .seh_nop
12672/// ::= .seh_nop_w
12673bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L, bool Wide) {
12674 getTargetStreamer().emitARMWinCFINop(Wide);
12675 return false;
12676}
12677
12678/// parseDirectiveSEHEpilogStart
12679/// ::= .seh_startepilogue
12680/// ::= .seh_startepilogue_cond
12681bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L, bool Condition) {
12682 unsigned CC = ARMCC::AL;
12683 if (Condition) {
12684 MCAsmParser &Parser = getParser();
12685 SMLoc S = Parser.getTok().getLoc();
12686 const AsmToken &Tok = Parser.getTok();
12687 if (!Tok.is(AsmToken::Identifier))
12688 return Error(S, ".seh_startepilogue_cond missing condition");
12690 if (CC == ~0U)
12691 return Error(S, "invalid condition");
12692 Parser.Lex(); // Eat the token.
12693 }
12694
12695 getTargetStreamer().emitARMWinCFIEpilogStart(CC);
12696 return false;
12697}
12698
12699/// parseDirectiveSEHEpilogEnd
12700/// ::= .seh_endepilogue
12701bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12702 getTargetStreamer().emitARMWinCFIEpilogEnd();
12703 return false;
12704}
12705
12706/// parseDirectiveSEHCustom
12707/// ::= .seh_custom
12708bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12709 unsigned Opcode = 0;
12710 do {
12711 int64_t Byte;
12712 if (parseImmExpr(Byte))
12713 return true;
12714 if (Byte > 0xff || Byte < 0)
12715 return Error(L, "Invalid byte value in .seh_custom");
12716 if (Opcode > 0x00ffffff)
12717 return Error(L, "Too many bytes in .seh_custom");
12718 // Store the bytes as one big endian number in Opcode. In a multi byte
12719 // opcode sequence, the first byte can't be zero.
12720 Opcode = (Opcode << 8) | Byte;
12721 } while (parseOptionalToken(AsmToken::Comma));
12722 getTargetStreamer().emitARMWinCFICustom(Opcode);
12723 return false;
12724}
12725
12726/// Force static initialization.
12733
12734#define GET_REGISTER_MATCHER
12735#define GET_SUBTARGET_FEATURE_NAME
12736#define GET_MATCHER_IMPLEMENTATION
12737#define GET_MNEMONIC_SPELL_CHECKER
12738#include "ARMGenAsmMatcher.inc"
12739
12740// Some diagnostics need to vary with subtarget features, so they are handled
12741// here. For example, the DPR class has either 16 or 32 registers, depending
12742// on the FPU available.
12743const char *
12744ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12745 switch (MatchError) {
12746 // rGPR contains sp starting with ARMv8.
12747 case Match_rGPR:
12748 return hasV8Ops() ? "operand must be a register in range [r0, r14]"
12749 : "operand must be a register in range [r0, r12] or r14";
12750 // DPR contains 16 registers for some FPUs, and 32 for others.
12751 case Match_DPR:
12752 return hasD32() ? "operand must be a register in range [d0, d31]"
12753 : "operand must be a register in range [d0, d15]";
12754 case Match_DPR_RegList:
12755 return hasD32() ? "operand must be a list of registers in range [d0, d31]"
12756 : "operand must be a list of registers in range [d0, d15]";
12757
12758 // For all other diags, use the static string from tablegen.
12759 default:
12760 return getMatchKindDiag(MatchError);
12761 }
12762}
12763
12764// Process the list of near-misses, throwing away ones we don't want to report
12765// to the user, and converting the rest to a source location and string that
12766// should be reported.
12767void
12768ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12769 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12770 SMLoc IDLoc, OperandVector &Operands) {
12771 // TODO: If operand didn't match, sub in a dummy one and run target
12772 // predicate, so that we can avoid reporting near-misses that are invalid?
12773 // TODO: Many operand types dont have SuperClasses set, so we report
12774 // redundant ones.
12775 // TODO: Some operands are superclasses of registers (e.g.
12776 // MCK_RegShiftedImm), we don't have any way to represent that currently.
12777 // TODO: This is not all ARM-specific, can some of it be factored out?
12778
12779 // Record some information about near-misses that we have already seen, so
12780 // that we can avoid reporting redundant ones. For example, if there are
12781 // variants of an instruction that take 8- and 16-bit immediates, we want
12782 // to only report the widest one.
12783 std::multimap<unsigned, unsigned> OperandMissesSeen;
12784 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12785 bool ReportedTooFewOperands = false;
12786
12787 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
12788
12789 // Process the near-misses in reverse order, so that we see more general ones
12790 // first, and so can avoid emitting more specific ones.
12791 for (NearMissInfo &I : reverse(NearMissesIn)) {
12792 switch (I.getKind()) {
12794 SMLoc OperandLoc =
12795 ((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
12796 const char *OperandDiag =
12797 getCustomOperandDiag((ARMMatchResultTy)I.getOperandError());
12798
12799 // If we have already emitted a message for a superclass, don't also report
12800 // the sub-class. We consider all operand classes that we don't have a
12801 // specialised diagnostic for to be equal for the propose of this check,
12802 // so that we don't report the generic error multiple times on the same
12803 // operand.
12804 unsigned DupCheckMatchClass = OperandDiag ? I.getOperandClass() : ~0U;
12805 auto PrevReports = OperandMissesSeen.equal_range(I.getOperandIndex());
12806 if (std::any_of(PrevReports.first, PrevReports.second,
12807 [DupCheckMatchClass](
12808 const std::pair<unsigned, unsigned> Pair) {
12809 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12810 return Pair.second == DupCheckMatchClass;
12811 else
12812 return isSubclass((MatchClassKind)DupCheckMatchClass,
12813 (MatchClassKind)Pair.second);
12814 }))
12815 break;
12816 OperandMissesSeen.insert(
12817 std::make_pair(I.getOperandIndex(), DupCheckMatchClass));
12818
12819 NearMissMessage Message;
12820 Message.Loc = OperandLoc;
12821 if (OperandDiag) {
12822 Message.Message = OperandDiag;
12823 } else if (I.getOperandClass() == InvalidMatchClass) {
12824 Message.Message = "too many operands for instruction";
12825 } else {
12826 Message.Message = "invalid operand for instruction";
12827 LLVM_DEBUG(
12828 dbgs() << "Missing diagnostic string for operand class "
12829 << getMatchClassName((MatchClassKind)I.getOperandClass())
12830 << I.getOperandClass() << ", error " << I.getOperandError()
12831 << ", opcode " << MII.getName(I.getOpcode()) << "\n");
12832 }
12833 NearMissesOut.emplace_back(Message);
12834 break;
12835 }
12837 const FeatureBitset &MissingFeatures = I.getFeatures();
12838 // Don't report the same set of features twice.
12839 if (FeatureMissesSeen.count(MissingFeatures))
12840 break;
12841 FeatureMissesSeen.insert(MissingFeatures);
12842
12843 // Special case: don't report a feature set which includes arm-mode for
12844 // targets that don't have ARM mode.
12845 if (MissingFeatures.test(Feature_IsARMBit) && !hasARM())
12846 break;
12847 // Don't report any near-misses that both require switching instruction
12848 // set, and adding other subtarget features.
12849 if (isThumb() && MissingFeatures.test(Feature_IsARMBit) &&
12850 MissingFeatures.count() > 1)
12851 break;
12852 if (!isThumb() && MissingFeatures.test(Feature_IsThumbBit) &&
12853 MissingFeatures.count() > 1)
12854 break;
12855 if (!isThumb() && MissingFeatures.test(Feature_IsThumb2Bit) &&
12856 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12857 Feature_IsThumbBit})).any())
12858 break;
12859 if (isMClass() && MissingFeatures.test(Feature_HasNEONBit))
12860 break;
12861
12862 NearMissMessage Message;
12863 Message.Loc = IDLoc;
12864 raw_svector_ostream OS(Message.Message);
12865
12866 OS << "instruction requires:";
12867 for (unsigned Feature : MissingFeatures)
12868 OS << ' ' << getSubtargetFeatureName(Feature);
12869
12870 NearMissesOut.emplace_back(Message);
12871
12872 break;
12873 }
12875 NearMissMessage Message;
12876 Message.Loc = IDLoc;
12877 switch (I.getPredicateError()) {
12878 case Match_RequiresNotITBlock:
12879 Message.Message = "flag setting instruction only valid outside IT block";
12880 break;
12881 case Match_RequiresITBlock:
12882 Message.Message = "instruction only valid inside IT block";
12883 break;
12884 case Match_RequiresV6:
12885 Message.Message = "instruction variant requires ARMv6 or later";
12886 break;
12887 case Match_RequiresThumb2:
12888 Message.Message = "instruction variant requires Thumb2";
12889 break;
12890 case Match_RequiresV8:
12891 Message.Message = "instruction variant requires ARMv8 or later";
12892 break;
12893 case Match_RequiresFlagSetting:
12894 Message.Message = "no flag-preserving variant of this instruction available";
12895 break;
12896 case Match_InvalidTiedOperand: {
12897 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[0]);
12898 if (Op.isToken() && Op.getToken() == "mul") {
12899 Message.Message = "destination register must match a source register";
12900 Message.Loc = Operands[MnemonicOpsEndInd]->getStartLoc();
12901 } else {
12902 llvm_unreachable("Match_InvalidTiedOperand only used for tMUL.");
12903 }
12904 break;
12905 }
12906 case Match_InvalidOperand:
12907 Message.Message = "invalid operand for instruction";
12908 break;
12909 default:
12910 llvm_unreachable("Unhandled target predicate error");
12911 break;
12912 }
12913 NearMissesOut.emplace_back(Message);
12914 break;
12915 }
12917 if (!ReportedTooFewOperands) {
12918 SMLoc EndLoc = ((ARMOperand &)*Operands.back()).getEndLoc();
12919 NearMissesOut.emplace_back(NearMissMessage{
12920 EndLoc, StringRef("too few operands for instruction")});
12921 ReportedTooFewOperands = true;
12922 }
12923 break;
12924 }
12926 // This should never leave the matcher.
12927 llvm_unreachable("not a near-miss");
12928 break;
12929 }
12930 }
12931}
12932
12933void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
12934 SMLoc IDLoc, OperandVector &Operands) {
12936 FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
12937
12938 if (Messages.size() == 0) {
12939 // No near-misses were found, so the best we can do is "invalid
12940 // instruction".
12941 Error(IDLoc, "invalid instruction");
12942 } else if (Messages.size() == 1) {
12943 // One near miss was found, report it as the sole error.
12944 Error(Messages[0].Loc, Messages[0].Message);
12945 } else {
12946 // More than one near miss, so report a generic "invalid instruction"
12947 // error, followed by notes for each of the near-misses.
12948 Error(IDLoc, "invalid instruction, any one of the following would fix this:");
12949 for (auto &M : Messages) {
12950 Note(M.Loc, M.Message);
12951 }
12952 }
12953}
12954
12955bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
12956 // FIXME: This structure should be moved inside ARMTargetParser
12957 // when we start to table-generate them, and we can use the ARM
12958 // flags below, that were generated by table-gen.
12959 static const struct {
12960 const uint64_t Kind;
12961 const FeatureBitset ArchCheck;
12962 const FeatureBitset Features;
12963 } Extensions[] = {
12964 {ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}},
12965 {ARM::AEK_AES,
12966 {Feature_HasV8Bit},
12967 {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12969 {Feature_HasV8Bit},
12970 {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12972 {Feature_HasV8Bit},
12973 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12975 {Feature_HasV8_1MMainlineBit},
12976 {ARM::HasMVEFloatOps}},
12977 {ARM::AEK_FP,
12978 {Feature_HasV8Bit},
12979 {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12981 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12982 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}},
12983 {ARM::AEK_MP,
12984 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12985 {ARM::FeatureMP}},
12987 {Feature_HasV8Bit},
12988 {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12989 {ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}},
12990 // FIXME: Only available in A-class, isel not predicated
12991 {ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}},
12993 {Feature_HasV8_2aBit},
12994 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
12995 {ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
12996 {ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
12997 {ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI}},
12998 // FIXME: Unsupported extensions.
12999 {ARM::AEK_OS, {}, {}},
13000 {ARM::AEK_IWMMXT, {}, {}},
13001 {ARM::AEK_IWMMXT2, {}, {}},
13002 {ARM::AEK_MAVERICK, {}, {}},
13003 {ARM::AEK_XSCALE, {}, {}},
13004 };
13005 bool EnableFeature = !Name.consume_front_insensitive("no");
13007 if (FeatureKind == ARM::AEK_INVALID)
13008 return Error(ExtLoc, "unknown architectural extension: " + Name);
13009
13010 for (const auto &Extension : Extensions) {
13011 if (Extension.Kind != FeatureKind)
13012 continue;
13013
13014 if (Extension.Features.none())
13015 return Error(ExtLoc, "unsupported architectural extension: " + Name);
13016
13017 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck)
13018 return Error(ExtLoc, "architectural extension '" + Name +
13019 "' is not "
13020 "allowed for the current base architecture");
13021
13022 MCSubtargetInfo &STI = copySTI();
13023 if (EnableFeature) {
13025 } else {
13027 }
13028 FeatureBitset Features = ComputeAvailableFeatures(STI.getFeatureBits());
13029 setAvailableFeatures(Features);
13030 return true;
13031 }
13032 return false;
13033}
13034
13035/// parseDirectiveArchExtension
13036/// ::= .arch_extension [no]feature
13037bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
13038
13039 MCAsmParser &Parser = getParser();
13040
13041 if (getLexer().isNot(AsmToken::Identifier))
13042 return Error(getLexer().getLoc(), "expected architecture extension name");
13043
13044 StringRef Name = Parser.getTok().getString();
13045 SMLoc ExtLoc = Parser.getTok().getLoc();
13046 Lex();
13047
13048 if (parseEOL())
13049 return true;
13050
13051 if (Name == "nocrypto") {
13052 enableArchExtFeature("nosha2", ExtLoc);
13053 enableArchExtFeature("noaes", ExtLoc);
13054 }
13055
13056 if (enableArchExtFeature(Name, ExtLoc))
13057 return false;
13058
13059 return Error(ExtLoc, "unknown architectural extension: " + Name);
13060}
13061
13062// Define this matcher function after the auto-generated include so we
13063// have the match class enum definitions.
13064unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13065 unsigned Kind) {
13066 ARMOperand &Op = static_cast<ARMOperand &>(AsmOp);
13067 // If the kind is a token for a literal immediate, check if our asm
13068 // operand matches. This is for InstAliases which have a fixed-value
13069 // immediate in the syntax.
13070 switch (Kind) {
13071 default: break;
13072 case MCK__HASH_0:
13073 if (Op.isImm())
13074 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13075 if (CE->getValue() == 0)
13076 return Match_Success;
13077 break;
13078 case MCK__HASH_8:
13079 if (Op.isImm())
13080 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13081 if (CE->getValue() == 8)
13082 return Match_Success;
13083 break;
13084 case MCK__HASH_16:
13085 if (Op.isImm())
13086 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13087 if (CE->getValue() == 16)
13088 return Match_Success;
13089 break;
13090 case MCK_ModImm:
13091 if (Op.isImm()) {
13092 const MCExpr *SOExpr = Op.getImm();
13093 int64_t Value;
13094 if (!SOExpr->evaluateAsAbsolute(Value))
13095 return Match_Success;
13096 assert((Value >= std::numeric_limits<int32_t>::min() &&
13097 Value <= std::numeric_limits<uint32_t>::max()) &&
13098 "expression value must be representable in 32 bits");
13099 }
13100 break;
13101 case MCK_rGPR:
13102 if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP)
13103 return Match_Success;
13104 return Match_rGPR;
13105 }
13106 return Match_InvalidOperand;
13107}
13108
13109bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic,
13110 StringRef ExtraToken) {
13111 if (!hasMVE())
13112 return false;
13113
13114 if (MS.isVPTPredicableCDEInstr(Mnemonic) ||
13115 (Mnemonic.starts_with("vldrh") && Mnemonic != "vldrhi") ||
13116 (Mnemonic.starts_with("vmov") &&
13117 !(ExtraToken == ".f16" || ExtraToken == ".32" || ExtraToken == ".16" ||
13118 ExtraToken == ".8")) ||
13119 (Mnemonic.starts_with("vrint") && Mnemonic != "vrintr") ||
13120 (Mnemonic.starts_with("vstrh") && Mnemonic != "vstrhi"))
13121 return true;
13122
13123 const char *predicable_prefixes[] = {
13124 "vabav", "vabd", "vabs", "vadc", "vadd",
13125 "vaddlv", "vaddv", "vand", "vbic", "vbrsr",
13126 "vcadd", "vcls", "vclz", "vcmla", "vcmp",
13127 "vcmul", "vctp", "vcvt", "vddup", "vdup",
13128 "vdwdup", "veor", "vfma", "vfmas", "vfms",
13129 "vhadd", "vhcadd", "vhsub", "vidup", "viwdup",
13130 "vldrb", "vldrd", "vldrw", "vmax", "vmaxa",
13131 "vmaxav", "vmaxnm", "vmaxnma", "vmaxnmav", "vmaxnmv",
13132 "vmaxv", "vmin", "vminav", "vminnm", "vminnmav",
13133 "vminnmv", "vminv", "vmla", "vmladav", "vmlaldav",
13134 "vmlalv", "vmlas", "vmlav", "vmlsdav", "vmlsldav",
13135 "vmovlb", "vmovlt", "vmovnb", "vmovnt", "vmul",
13136 "vmvn", "vneg", "vorn", "vorr", "vpnot",
13137 "vpsel", "vqabs", "vqadd", "vqdmladh", "vqdmlah",
13138 "vqdmlash", "vqdmlsdh", "vqdmulh", "vqdmull", "vqmovn",
13139 "vqmovun", "vqneg", "vqrdmladh", "vqrdmlah", "vqrdmlash",
13140 "vqrdmlsdh", "vqrdmulh", "vqrshl", "vqrshrn", "vqrshrun",
13141 "vqshl", "vqshrn", "vqshrun", "vqsub", "vrev16",
13142 "vrev32", "vrev64", "vrhadd", "vrmlaldavh", "vrmlalvh",
13143 "vrmlsldavh", "vrmulh", "vrshl", "vrshr", "vrshrn",
13144 "vsbc", "vshl", "vshlc", "vshll", "vshr",
13145 "vshrn", "vsli", "vsri", "vstrb", "vstrd",
13146 "vstrw", "vsub"};
13147
13148 return any_of(predicable_prefixes, [&Mnemonic](const char *prefix) {
13149 return Mnemonic.starts_with(prefix);
13150 });
13151}
13152
13153std::unique_ptr<ARMOperand> ARMAsmParser::defaultCondCodeOp() {
13154 return ARMOperand::CreateCondCode(ARMCC::AL, SMLoc(), *this);
13155}
13156
13157std::unique_ptr<ARMOperand> ARMAsmParser::defaultCCOutOp() {
13158 return ARMOperand::CreateCCOut(0, SMLoc(), *this);
13159}
13160
13161std::unique_ptr<ARMOperand> ARMAsmParser::defaultVPTPredOp() {
13162 return ARMOperand::CreateVPTPred(ARMVCC::None, SMLoc(), *this);
13163}
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.
SDValue Pred
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)
uint64_t uint64_t
uint64_t Imm
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:665
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 Register getFPReg(const CSKYSubtarget &STI)
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_ABI
Definition Compiler.h:211
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
static cl::opt< bool > AddBuildAttributes("hexagon-add-build-attributes")
#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
SmallVector< MachineOperand, 4 > Cond
RISCVCC::CondCode CC
MachineRegisterInfo & MRI
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
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:479
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:283
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...
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
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
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:27
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition StringSet.h:41
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:183
#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:881
#define N
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...