LLVM 23.0.0git
ARMAsmParser.cpp
Go to the documentation of this file.
1//===- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ARMBaseInstrInfo.h"
10#include "ARMFeatures.h"
17#include "Utils/ARMBaseInfo.h"
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/SmallSet.h"
24#include "llvm/ADT/StringMap.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/ADT/StringSet.h"
28#include "llvm/ADT/Twine.h"
29#include "llvm/MC/MCContext.h"
30#include "llvm/MC/MCExpr.h"
31#include "llvm/MC/MCInst.h"
32#include "llvm/MC/MCInstrDesc.h"
33#include "llvm/MC/MCInstrInfo.h"
41#include "llvm/MC/MCSection.h"
42#include "llvm/MC/MCStreamer.h"
44#include "llvm/MC/MCSymbol.h"
51#include "llvm/Support/Debug.h"
54#include "llvm/Support/SMLoc.h"
58#include <algorithm>
59#include <cassert>
60#include <cstddef>
61#include <cstdint>
62#include <iterator>
63#include <limits>
64#include <memory>
65#include <optional>
66#include <string>
67#include <utility>
68#include <vector>
69
70#define DEBUG_TYPE "asm-parser"
71
72using namespace llvm;
73
74namespace {
75class ARMOperand;
76
77enum class ImplicitItModeTy { Always, Never, ARMOnly, ThumbOnly };
78
79static cl::opt<ImplicitItModeTy> ImplicitItMode(
80 "arm-implicit-it", cl::init(ImplicitItModeTy::ARMOnly),
81 cl::desc("Allow conditional instructions outside of an IT block"),
82 cl::values(clEnumValN(ImplicitItModeTy::Always, "always",
83 "Accept in both ISAs, emit implicit ITs in Thumb"),
84 clEnumValN(ImplicitItModeTy::Never, "never",
85 "Warn in ARM, reject in Thumb"),
86 clEnumValN(ImplicitItModeTy::ARMOnly, "arm",
87 "Accept in ARM, reject in Thumb"),
88 clEnumValN(ImplicitItModeTy::ThumbOnly, "thumb",
89 "Warn in ARM, emit implicit ITs in Thumb")));
90
91static cl::opt<bool> AddBuildAttributes("arm-add-build-attributes",
92 cl::init(false));
93
94enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
95
96static inline unsigned extractITMaskBit(unsigned Mask, unsigned Position) {
97 // Position==0 means we're not in an IT block at all. Position==1
98 // means we want the first state bit, which is always 0 (Then).
99 // Position==2 means we want the second state bit, stored at bit 3
100 // of Mask, and so on downwards. So (5 - Position) will shift the
101 // right bit down to bit 0, including the always-0 bit at bit 4 for
102 // the mandatory initial Then.
103 return (Mask >> (5 - Position) & 1);
104}
105
106class UnwindContext {
107 using Locs = SmallVector<SMLoc, 4>;
108
109 MCAsmParser &Parser;
110 Locs FnStartLocs;
111 Locs CantUnwindLocs;
112 Locs PersonalityLocs;
113 Locs PersonalityIndexLocs;
114 Locs HandlerDataLocs;
116
117public:
118 UnwindContext(MCAsmParser &P) : Parser(P), FPReg(ARM::SP) {}
119
120 bool hasFnStart() const { return !FnStartLocs.empty(); }
121 bool cantUnwind() const { return !CantUnwindLocs.empty(); }
122 bool hasHandlerData() const { return !HandlerDataLocs.empty(); }
123
124 bool hasPersonality() const {
125 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
126 }
127
128 void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); }
129 void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); }
130 void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); }
131 void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); }
132 void recordPersonalityIndex(SMLoc L) { PersonalityIndexLocs.push_back(L); }
133
134 void saveFPReg(MCRegister Reg) { FPReg = Reg; }
135 MCRegister getFPReg() const { return FPReg; }
136
137 void emitFnStartLocNotes() const {
138 for (SMLoc Loc : FnStartLocs)
139 Parser.Note(Loc, ".fnstart was specified here");
140 }
141
142 void emitCantUnwindLocNotes() const {
143 for (SMLoc Loc : CantUnwindLocs)
144 Parser.Note(Loc, ".cantunwind was specified here");
145 }
146
147 void emitHandlerDataLocNotes() const {
148 for (SMLoc Loc : HandlerDataLocs)
149 Parser.Note(Loc, ".handlerdata was specified here");
150 }
151
152 void emitPersonalityLocNotes() const {
153 for (Locs::const_iterator PI = PersonalityLocs.begin(),
154 PE = PersonalityLocs.end(),
155 PII = PersonalityIndexLocs.begin(),
156 PIE = PersonalityIndexLocs.end();
157 PI != PE || PII != PIE;) {
158 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
159 Parser.Note(*PI++, ".personality was specified here");
160 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
161 Parser.Note(*PII++, ".personalityindex was specified here");
162 else
163 llvm_unreachable(".personality and .personalityindex cannot be "
164 "at the same location");
165 }
166 }
167
168 void reset() {
169 FnStartLocs = Locs();
170 CantUnwindLocs = Locs();
171 PersonalityLocs = Locs();
172 HandlerDataLocs = Locs();
173 PersonalityIndexLocs = Locs();
174 FPReg = ARM::SP;
175 }
176};
177
178// Various sets of ARM instruction mnemonics which are used by the asm parser
179class ARMMnemonicSets {
180 StringSet<> CDE;
181 StringSet<> CDEWithVPTSuffix;
182public:
183 ARMMnemonicSets(const MCSubtargetInfo &STI);
184
185 /// Returns true iff a given mnemonic is a CDE instruction
186 bool isCDEInstr(StringRef Mnemonic) {
187 // Quick check before searching the set
188 if (!Mnemonic.starts_with("cx") && !Mnemonic.starts_with("vcx"))
189 return false;
190 return CDE.count(Mnemonic);
191 }
192
193 /// Returns true iff a given mnemonic is a VPT-predicable CDE instruction
194 /// (possibly with a predication suffix "e" or "t")
195 bool isVPTPredicableCDEInstr(StringRef Mnemonic) {
196 if (!Mnemonic.starts_with("vcx"))
197 return false;
198 return CDEWithVPTSuffix.count(Mnemonic);
199 }
200
201 /// Returns true iff a given mnemonic is an IT-predicable CDE instruction
202 /// (possibly with a condition suffix)
203 bool isITPredicableCDEInstr(StringRef Mnemonic) {
204 if (!Mnemonic.starts_with("cx"))
205 return false;
206 return Mnemonic.starts_with("cx1a") || Mnemonic.starts_with("cx1da") ||
207 Mnemonic.starts_with("cx2a") || Mnemonic.starts_with("cx2da") ||
208 Mnemonic.starts_with("cx3a") || Mnemonic.starts_with("cx3da");
209 }
210
211 /// Return true iff a given mnemonic is an integer CDE instruction with
212 /// dual-register destination
213 bool isCDEDualRegInstr(StringRef Mnemonic) {
214 if (!Mnemonic.starts_with("cx"))
215 return false;
216 return Mnemonic == "cx1d" || Mnemonic == "cx1da" ||
217 Mnemonic == "cx2d" || Mnemonic == "cx2da" ||
218 Mnemonic == "cx3d" || Mnemonic == "cx3da";
219 }
220};
221
222ARMMnemonicSets::ARMMnemonicSets(const MCSubtargetInfo &STI) {
223 for (StringRef Mnemonic: { "cx1", "cx1a", "cx1d", "cx1da",
224 "cx2", "cx2a", "cx2d", "cx2da",
225 "cx3", "cx3a", "cx3d", "cx3da", })
226 CDE.insert(Mnemonic);
227 for (StringRef Mnemonic :
228 {"vcx1", "vcx1a", "vcx2", "vcx2a", "vcx3", "vcx3a"}) {
229 CDE.insert(Mnemonic);
230 CDEWithVPTSuffix.insert(Mnemonic);
231 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "t");
232 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "e");
233 }
234}
235
236class ARMAsmParser : public MCTargetAsmParser {
237 const MCRegisterInfo *MRI;
238 UnwindContext UC;
239 ARMMnemonicSets MS;
240
241 ARMTargetStreamer &getTargetStreamer() {
242 assert(getParser().getStreamer().getTargetStreamer() &&
243 "do not have a target streamer");
244 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
245 return static_cast<ARMTargetStreamer &>(TS);
246 }
247
248 // Map of register aliases registers via the .req directive.
249 StringMap<MCRegister> RegisterReqs;
250
251 bool NextSymbolIsThumb;
252
253 bool useImplicitITThumb() const {
254 return ImplicitItMode == ImplicitItModeTy::Always ||
255 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
256 }
257
258 bool useImplicitITARM() const {
259 return ImplicitItMode == ImplicitItModeTy::Always ||
260 ImplicitItMode == ImplicitItModeTy::ARMOnly;
261 }
262
263 struct {
264 ARMCC::CondCodes Cond; // Condition for IT block.
265 unsigned Mask:4; // Condition mask for instructions.
266 // Starting at first 1 (from lsb).
267 // '1' condition as indicated in IT.
268 // '0' inverse of condition (else).
269 // Count of instructions in IT block is
270 // 4 - trailingzeroes(mask)
271 // Note that this does not have the same encoding
272 // as in the IT instruction, which also depends
273 // on the low bit of the condition code.
274
275 unsigned CurPosition; // Current position in parsing of IT
276 // block. In range [0,4], with 0 being the IT
277 // instruction itself. Initialized according to
278 // count of instructions in block. ~0U if no
279 // active IT block.
280
281 bool IsExplicit; // true - The IT instruction was present in the
282 // input, we should not modify it.
283 // false - The IT instruction was added
284 // implicitly, we can extend it if that
285 // would be legal.
286 } ITState;
287
288 SmallVector<MCInst, 4> PendingConditionalInsts;
289
290 void onEndOfFile() override {
291 flushPendingInstructions(getParser().getStreamer());
292 }
293
294 void flushPendingInstructions(MCStreamer &Out) override {
295 if (!inImplicitITBlock()) {
296 assert(PendingConditionalInsts.size() == 0);
297 return;
298 }
299
300 // Emit the IT instruction
301 MCInst ITInst;
302 ITInst.setOpcode(ARM::t2IT);
303 ITInst.addOperand(MCOperand::createImm(ITState.Cond));
304 ITInst.addOperand(MCOperand::createImm(ITState.Mask));
305 Out.emitInstruction(ITInst, getSTI());
306
307 // Emit the conditional instructions
308 assert(PendingConditionalInsts.size() <= 4);
309 for (const MCInst &Inst : PendingConditionalInsts) {
310 Out.emitInstruction(Inst, getSTI());
311 }
312 PendingConditionalInsts.clear();
313
314 // Clear the IT state
315 ITState.Mask = 0;
316 ITState.CurPosition = ~0U;
317 }
318
319 bool inITBlock() { return ITState.CurPosition != ~0U; }
320 bool inExplicitITBlock() { return inITBlock() && ITState.IsExplicit; }
321 bool inImplicitITBlock() { return inITBlock() && !ITState.IsExplicit; }
322
323 bool lastInITBlock() {
324 return ITState.CurPosition == 4 - (unsigned)llvm::countr_zero(ITState.Mask);
325 }
326
327 void forwardITPosition() {
328 if (!inITBlock()) return;
329 // Move to the next instruction in the IT block, if there is one. If not,
330 // mark the block as done, except for implicit IT blocks, which we leave
331 // open until we find an instruction that can't be added to it.
332 unsigned TZ = llvm::countr_zero(ITState.Mask);
333 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
334 ITState.CurPosition = ~0U; // Done with the IT block after this.
335 }
336
337 // Rewind the state of the current IT block, removing the last slot from it.
338 void rewindImplicitITPosition() {
339 assert(inImplicitITBlock());
340 assert(ITState.CurPosition > 1);
341 ITState.CurPosition--;
342 unsigned TZ = llvm::countr_zero(ITState.Mask);
343 unsigned NewMask = 0;
344 NewMask |= ITState.Mask & (0xC << TZ);
345 NewMask |= 0x2 << TZ;
346 ITState.Mask = NewMask;
347 }
348
349 // Rewind the state of the current IT block, removing the last slot from it.
350 // If we were at the first slot, this closes the IT block.
351 void discardImplicitITBlock() {
352 assert(inImplicitITBlock());
353 assert(ITState.CurPosition == 1);
354 ITState.CurPosition = ~0U;
355 }
356
357 // Get the condition code corresponding to the current IT block slot.
358 ARMCC::CondCodes currentITCond() {
359 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
360 return MaskBit ? ARMCC::getOppositeCondition(ITState.Cond) : ITState.Cond;
361 }
362
363 // Invert the condition of the current IT block slot without changing any
364 // other slots in the same block.
365 void invertCurrentITCondition() {
366 if (ITState.CurPosition == 1) {
367 ITState.Cond = ARMCC::getOppositeCondition(ITState.Cond);
368 } else {
369 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
370 }
371 }
372
373 // Returns true if the current IT block is full (all 4 slots used).
374 bool isITBlockFull() {
375 return inITBlock() && (ITState.Mask & 1);
376 }
377
378 // Extend the current implicit IT block to have one more slot with the given
379 // condition code.
380 void extendImplicitITBlock(ARMCC::CondCodes Cond) {
381 assert(inImplicitITBlock());
382 assert(!isITBlockFull());
383 assert(Cond == ITState.Cond ||
384 Cond == ARMCC::getOppositeCondition(ITState.Cond));
385 unsigned TZ = llvm::countr_zero(ITState.Mask);
386 unsigned NewMask = 0;
387 // Keep any existing condition bits.
388 NewMask |= ITState.Mask & (0xE << TZ);
389 // Insert the new condition bit.
390 NewMask |= (Cond != ITState.Cond) << TZ;
391 // Move the trailing 1 down one bit.
392 NewMask |= 1 << (TZ - 1);
393 ITState.Mask = NewMask;
394 }
395
396 // Create a new implicit IT block with a dummy condition code.
397 void startImplicitITBlock() {
398 assert(!inITBlock());
399 ITState.Cond = ARMCC::AL;
400 ITState.Mask = 8;
401 ITState.CurPosition = 1;
402 ITState.IsExplicit = false;
403 }
404
405 // Create a new explicit IT block with the given condition and mask.
406 // The mask should be in the format used in ARMOperand and
407 // MCOperand, with a 1 implying 'e', regardless of the low bit of
408 // the condition.
409 void startExplicitITBlock(ARMCC::CondCodes Cond, unsigned Mask) {
410 assert(!inITBlock());
411 ITState.Cond = Cond;
412 ITState.Mask = Mask;
413 ITState.CurPosition = 0;
414 ITState.IsExplicit = true;
415 }
416
417 struct {
418 unsigned Mask : 4;
419 unsigned CurPosition;
420 } VPTState;
421 bool inVPTBlock() { return VPTState.CurPosition != ~0U; }
422 void forwardVPTPosition() {
423 if (!inVPTBlock()) return;
424 unsigned TZ = llvm::countr_zero(VPTState.Mask);
425 if (++VPTState.CurPosition == 5 - TZ)
426 VPTState.CurPosition = ~0U;
427 }
428
429 void Note(SMLoc L, const Twine &Msg, SMRange Range = {}) {
430 return getParser().Note(L, Msg, Range);
431 }
432
433 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = {}) {
434 return getParser().Warning(L, Msg, Range);
435 }
436
437 bool Error(SMLoc L, const Twine &Msg, SMRange Range = {}) {
438 return getParser().Error(L, Msg, Range);
439 }
440
441 bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
442 unsigned MnemonicOpsEndInd, unsigned ListIndex,
443 bool IsARPop = false);
444 bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands,
445 unsigned MnemonicOpsEndInd, unsigned ListIndex);
446
447 MCRegister tryParseRegister(bool AllowOutofBoundReg = false);
448 bool tryParseRegisterWithWriteBack(OperandVector &);
449 int tryParseShiftRegister(OperandVector &);
450 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
451 bool parseRegisterList(OperandVector &, bool EnforceOrder = true,
452 bool AllowRAAC = false, bool IsLazyLoadStore = false,
453 bool IsVSCCLRM = false);
454 bool parseMemory(OperandVector &);
455 bool parseOperand(OperandVector &, StringRef Mnemonic);
456 bool parseImmExpr(int64_t &Out);
457 bool parsePrefix(ARM::Specifier &);
458 bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
459 unsigned &ShiftAmount);
460 bool parseLiteralValues(unsigned Size, SMLoc L);
461 bool parseDirectiveThumb(SMLoc L);
462 bool parseDirectiveARM(SMLoc L);
463 bool parseDirectiveThumbFunc(SMLoc L);
464 bool parseDirectiveCode(SMLoc L);
465 bool parseDirectiveSyntax(SMLoc L);
466 bool parseDirectiveReq(StringRef Name, SMLoc L);
467 bool parseDirectiveUnreq(SMLoc L);
468 bool parseDirectiveArch(SMLoc L);
469 bool parseDirectiveEabiAttr(SMLoc L);
470 bool parseDirectiveCPU(SMLoc L);
471 bool parseDirectiveFPU(SMLoc L);
472 bool parseDirectiveFnStart(SMLoc L);
473 bool parseDirectiveFnEnd(SMLoc L);
474 bool parseDirectiveCantUnwind(SMLoc L);
475 bool parseDirectivePersonality(SMLoc L);
476 bool parseDirectiveHandlerData(SMLoc L);
477 bool parseDirectiveSetFP(SMLoc L);
478 bool parseDirectivePad(SMLoc L);
479 bool parseDirectiveRegSave(SMLoc L, bool IsVector);
480 bool parseDirectiveInst(SMLoc L, char Suffix = '\0');
481 bool parseDirectiveLtorg(SMLoc L);
482 bool parseDirectiveEven(SMLoc L);
483 bool parseDirectivePersonalityIndex(SMLoc L);
484 bool parseDirectiveUnwindRaw(SMLoc L);
485 bool parseDirectiveTLSDescSeq(SMLoc L);
486 bool parseDirectiveMovSP(SMLoc L);
487 bool parseDirectiveObjectArch(SMLoc L);
488 bool parseDirectiveArchExtension(SMLoc L);
489 bool parseDirectiveAlign(SMLoc L);
490 bool parseDirectiveThumbSet(SMLoc L);
491
492 bool parseDirectiveSEHAllocStack(SMLoc L, bool Wide);
493 bool parseDirectiveSEHSaveRegs(SMLoc L, bool Wide);
494 bool parseDirectiveSEHSaveSP(SMLoc L);
495 bool parseDirectiveSEHSaveFRegs(SMLoc L);
496 bool parseDirectiveSEHSaveLR(SMLoc L);
497 bool parseDirectiveSEHPrologEnd(SMLoc L, bool Fragment);
498 bool parseDirectiveSEHNop(SMLoc L, bool Wide);
499 bool parseDirectiveSEHEpilogStart(SMLoc L, bool Condition);
500 bool parseDirectiveSEHEpilogEnd(SMLoc L);
501 bool parseDirectiveSEHCustom(SMLoc L);
502
503 std::unique_ptr<ARMOperand> defaultCondCodeOp();
504 std::unique_ptr<ARMOperand> defaultCCOutOp();
505 std::unique_ptr<ARMOperand> defaultVPTPredOp();
506
507 bool isMnemonicVPTPredicable(StringRef Mnemonic, StringRef ExtraToken);
508 StringRef splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
509 ARMCC::CondCodes &PredicationCode,
510 ARMVCC::VPTCodes &VPTPredicationCode,
511 bool &CarrySetting, unsigned &ProcessorIMod,
512 StringRef &ITMask);
513 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef ExtraToken,
514 StringRef FullInst, bool &CanAcceptCarrySet,
515 bool &CanAcceptPredicationCode,
516 bool &CanAcceptVPTPredicationCode);
517 bool enableArchExtFeature(StringRef Name, SMLoc &ExtLoc);
518
519 void tryConvertingToTwoOperandForm(StringRef Mnemonic,
520 ARMCC::CondCodes PredicationCode,
521 bool CarrySetting, OperandVector &Operands,
522 unsigned MnemonicOpsEndInd);
523
524 bool CDEConvertDualRegOperand(StringRef Mnemonic, OperandVector &Operands,
525 unsigned MnemonicOpsEndInd);
526
527 bool isThumb() const {
528 // FIXME: Can tablegen auto-generate this?
529 return getSTI().hasFeature(ARM::ModeThumb);
530 }
531
532 bool isThumbOne() const {
533 return isThumb() && !getSTI().hasFeature(ARM::FeatureThumb2);
534 }
535
536 bool isThumbTwo() const {
537 return isThumb() && getSTI().hasFeature(ARM::FeatureThumb2);
538 }
539
540 bool hasThumb() const {
541 return getSTI().hasFeature(ARM::HasV4TOps);
542 }
543
544 bool hasThumb2() const {
545 return getSTI().hasFeature(ARM::FeatureThumb2);
546 }
547
548 bool hasV6Ops() const {
549 return getSTI().hasFeature(ARM::HasV6Ops);
550 }
551
552 bool hasV6T2Ops() const {
553 return getSTI().hasFeature(ARM::HasV6T2Ops);
554 }
555
556 bool hasV6MOps() const {
557 return getSTI().hasFeature(ARM::HasV6MOps);
558 }
559
560 bool hasV7Ops() const {
561 return getSTI().hasFeature(ARM::HasV7Ops);
562 }
563
564 bool hasV8Ops() const {
565 return getSTI().hasFeature(ARM::HasV8Ops);
566 }
567
568 bool hasV8MBaseline() const {
569 return getSTI().hasFeature(ARM::HasV8MBaselineOps);
570 }
571
572 bool hasV8MMainline() const {
573 return getSTI().hasFeature(ARM::HasV8MMainlineOps);
574 }
575 bool hasV8_1MMainline() const {
576 return getSTI().hasFeature(ARM::HasV8_1MMainlineOps);
577 }
578 bool hasMVEFloat() const {
579 return getSTI().hasFeature(ARM::HasMVEFloatOps);
580 }
581 bool hasCDE() const {
582 return getSTI().hasFeature(ARM::HasCDEOps);
583 }
584 bool has8MSecExt() const {
585 return getSTI().hasFeature(ARM::Feature8MSecExt);
586 }
587
588 bool hasARM() const {
589 return !getSTI().hasFeature(ARM::FeatureNoARM);
590 }
591
592 bool hasDSP() const {
593 return getSTI().hasFeature(ARM::FeatureDSP);
594 }
595
596 bool hasD32() const {
597 return getSTI().hasFeature(ARM::FeatureD32);
598 }
599
600 bool hasV8_1aOps() const {
601 return getSTI().hasFeature(ARM::HasV8_1aOps);
602 }
603
604 bool hasRAS() const {
605 return getSTI().hasFeature(ARM::FeatureRAS);
606 }
607
608 void SwitchMode() {
609 MCSubtargetInfo &STI = copySTI();
610 auto FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
611 setAvailableFeatures(FB);
612 }
613
614 void FixModeAfterArchChange(bool WasThumb, SMLoc Loc);
615
616 bool isMClass() const {
617 return getSTI().hasFeature(ARM::FeatureMClass);
618 }
619
620 /// @name Auto-generated Match Functions
621 /// {
622
623#define GET_ASSEMBLER_HEADER
624#include "ARMGenAsmMatcher.inc"
625
626 /// }
627
628 ParseStatus parseITCondCode(OperandVector &);
629 ParseStatus parseCoprocNumOperand(OperandVector &);
630 ParseStatus parseCoprocRegOperand(OperandVector &);
631 ParseStatus parseCoprocOptionOperand(OperandVector &);
632 ParseStatus parseMemBarrierOptOperand(OperandVector &);
633 ParseStatus parseTraceSyncBarrierOptOperand(OperandVector &);
634 ParseStatus parseInstSyncBarrierOptOperand(OperandVector &);
635 ParseStatus parseProcIFlagsOperand(OperandVector &);
636 ParseStatus parseMSRMaskOperand(OperandVector &);
637 ParseStatus parseBankedRegOperand(OperandVector &);
638 ParseStatus parsePKHImm(OperandVector &O, ARM_AM::ShiftOpc, int Low,
639 int High);
640 ParseStatus parsePKHLSLImm(OperandVector &O) {
641 return parsePKHImm(O, ARM_AM::lsl, 0, 31);
642 }
643 ParseStatus parsePKHASRImm(OperandVector &O) {
644 return parsePKHImm(O, ARM_AM::asr, 1, 32);
645 }
646 ParseStatus parseSetEndImm(OperandVector &);
647 ParseStatus parseShifterImm(OperandVector &);
648 ParseStatus parseRotImm(OperandVector &);
649 ParseStatus parseModImm(OperandVector &);
650 ParseStatus parseBitfield(OperandVector &);
651 ParseStatus parsePostIdxReg(OperandVector &);
652 ParseStatus parseAM3Offset(OperandVector &);
653 ParseStatus parseFPImm(OperandVector &);
654 ParseStatus parseVectorList(OperandVector &);
655 ParseStatus parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index,
656 SMLoc &EndLoc);
657
658 // Asm Match Converter Methods
659 void cvtThumbMultiply(MCInst &Inst, const OperandVector &);
660 void cvtThumbBranches(MCInst &Inst, const OperandVector &);
661 void cvtMVEVMOVQtoDReg(MCInst &Inst, const OperandVector &);
662
663 bool validateInstruction(MCInst &Inst, const OperandVector &Ops,
664 unsigned MnemonicOpsEndInd);
665 bool processInstruction(MCInst &Inst, const OperandVector &Ops,
666 unsigned MnemonicOpsEndInd, MCStreamer &Out);
667 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic,
668 OperandVector &Operands,
669 unsigned MnemonicOpsEndInd);
670 bool isITBlockTerminator(MCInst &Inst) const;
671
672 void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands,
673 unsigned MnemonicOpsEndInd);
674 bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands, bool Load,
675 bool ARMMode, bool Writeback,
676 unsigned MnemonicOpsEndInd);
677
678public:
679 enum ARMMatchResultTy {
680 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
681 Match_RequiresNotITBlock,
682 Match_RequiresV6,
683 Match_RequiresThumb2,
684 Match_RequiresV8,
685 Match_RequiresFlagSetting,
686#define GET_OPERAND_DIAGNOSTIC_TYPES
687#include "ARMGenAsmMatcher.inc"
688
689 };
690
691 ARMAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
692 const MCInstrInfo &MII)
693 : MCTargetAsmParser(STI, MII), UC(Parser), MS(STI) {
695
696 // Cache the MCRegisterInfo.
697 MRI = getContext().getRegisterInfo();
698
699 // Initialize the set of available features.
700 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
701
702 // Add build attributes based on the selected target.
704 getTargetStreamer().emitTargetAttributes(STI);
705
706 // Not in an ITBlock to start with.
707 ITState.CurPosition = ~0U;
708
709 VPTState.CurPosition = ~0U;
710
711 NextSymbolIsThumb = false;
712 }
713
714 // Implementation of the MCTargetAsmParser interface:
715 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
716 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
717 SMLoc &EndLoc) override;
718 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
719 SMLoc NameLoc, OperandVector &Operands) override;
720 bool ParseDirective(AsmToken DirectiveID) override;
721
722 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
723 unsigned Kind) override;
724 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
725 unsigned
726 checkEarlyTargetMatchPredicate(MCInst &Inst,
727 const OperandVector &Operands) override;
728
729 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
730 OperandVector &Operands, MCStreamer &Out,
731 uint64_t &ErrorInfo,
732 bool MatchingInlineAsm) override;
733 unsigned MatchInstruction(OperandVector &Operands, MCInst &Inst,
734 SmallVectorImpl<NearMissInfo> &NearMisses,
735 bool MatchingInlineAsm, bool &EmitInITBlock,
736 MCStreamer &Out);
737
738 struct NearMissMessage {
739 SMLoc Loc;
740 SmallString<128> Message;
741 };
742
743 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
744
745 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
746 SmallVectorImpl<NearMissMessage> &NearMissesOut,
747 SMLoc IDLoc, OperandVector &Operands);
748 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
749 OperandVector &Operands);
750
751 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) override;
752
753 void onLabelParsed(MCSymbol *Symbol) override;
754
755 const MCInstrDesc &getInstrDesc(unsigned int Opcode) const {
756 return MII.get(Opcode);
757 }
758
759 bool hasMVE() const { return getSTI().hasFeature(ARM::HasMVEIntegerOps); }
760
761 // Return the low-subreg of a given Q register.
762 MCRegister getDRegFromQReg(MCRegister QReg) const {
763 return MRI->getSubReg(QReg, ARM::dsub_0);
764 }
765
766 const MCRegisterInfo *getMRI() const { return MRI; }
767};
768
769/// ARMOperand - Instances of this class represent a parsed ARM machine
770/// operand.
771class ARMOperand : public MCParsedAsmOperand {
772 enum KindTy {
773 k_CondCode,
774 k_VPTPred,
775 k_CCOut,
776 k_ITCondMask,
777 k_CoprocNum,
778 k_CoprocReg,
779 k_CoprocOption,
780 k_Immediate,
781 k_MemBarrierOpt,
782 k_InstSyncBarrierOpt,
783 k_TraceSyncBarrierOpt,
784 k_Memory,
785 k_PostIndexRegister,
786 k_MSRMask,
787 k_BankedReg,
788 k_ProcIFlags,
789 k_VectorIndex,
790 k_Register,
791 k_RegisterList,
792 k_RegisterListWithAPSR,
793 k_DPRRegisterList,
794 k_SPRRegisterList,
795 k_FPSRegisterListWithVPR,
796 k_FPDRegisterListWithVPR,
797 k_VectorList,
798 k_VectorListAllLanes,
799 k_VectorListIndexed,
800 k_ShiftedRegister,
801 k_ShiftedImmediate,
802 k_ShifterImmediate,
803 k_RotateImmediate,
804 k_ModifiedImmediate,
805 k_ConstantPoolImmediate,
806 k_BitfieldDescriptor,
807 k_Token,
808 } Kind;
809
810 SMLoc StartLoc, EndLoc, AlignmentLoc;
812
813 ARMAsmParser *Parser;
814
815 struct CCOp {
817 };
818
819 struct VCCOp {
821 };
822
823 struct CopOp {
824 unsigned Val;
825 };
826
827 struct CoprocOptionOp {
828 unsigned Val;
829 };
830
831 struct ITMaskOp {
832 unsigned Mask:4;
833 };
834
835 struct MBOptOp {
836 ARM_MB::MemBOpt Val;
837 };
838
839 struct ISBOptOp {
841 };
842
843 struct TSBOptOp {
845 };
846
847 struct IFlagsOp {
849 };
850
851 struct MMaskOp {
852 unsigned Val;
853 };
854
855 struct BankedRegOp {
856 unsigned Val;
857 };
858
859 struct TokOp {
860 const char *Data;
861 unsigned Length;
862 };
863
864 struct RegOp {
865 MCRegister RegNum;
866 };
867
868 // A vector register list is a sequential list of 1 to 4 registers.
869 struct VectorListOp {
870 MCRegister RegNum;
871 unsigned Count;
872 unsigned LaneIndex;
873 bool isDoubleSpaced;
874 };
875
876 struct VectorIndexOp {
877 unsigned Val;
878 };
879
880 struct ImmOp {
881 const MCExpr *Val;
882 };
883
884 /// Combined record for all forms of ARM address expressions.
885 struct MemoryOp {
886 MCRegister BaseRegNum;
887 // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
888 // was specified.
889 const MCExpr *OffsetImm; // Offset immediate value
890 MCRegister OffsetRegNum; // Offset register num, when OffsetImm == NULL
891 ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
892 unsigned ShiftImm; // shift for OffsetReg.
893 unsigned Alignment; // 0 = no alignment specified
894 // n = alignment in bytes (2, 4, 8, 16, or 32)
895 unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit)
896 };
897
898 struct PostIdxRegOp {
899 MCRegister RegNum;
900 bool isAdd;
901 ARM_AM::ShiftOpc ShiftTy;
902 unsigned ShiftImm;
903 };
904
905 struct ShifterImmOp {
906 bool isASR;
907 unsigned Imm;
908 };
909
910 struct RegShiftedRegOp {
911 ARM_AM::ShiftOpc ShiftTy;
912 MCRegister SrcReg;
913 MCRegister ShiftReg;
914 unsigned ShiftImm;
915 };
916
917 struct RegShiftedImmOp {
918 ARM_AM::ShiftOpc ShiftTy;
919 MCRegister SrcReg;
920 unsigned ShiftImm;
921 };
922
923 struct RotImmOp {
924 unsigned Imm;
925 };
926
927 struct ModImmOp {
928 unsigned Bits;
929 unsigned Rot;
930 };
931
932 struct BitfieldOp {
933 unsigned LSB;
934 unsigned Width;
935 };
936
937 union {
938 struct CCOp CC;
939 struct VCCOp VCC;
940 struct CopOp Cop;
941 struct CoprocOptionOp CoprocOption;
942 struct MBOptOp MBOpt;
943 struct ISBOptOp ISBOpt;
944 struct TSBOptOp TSBOpt;
945 struct ITMaskOp ITMask;
946 struct IFlagsOp IFlags;
947 struct MMaskOp MMask;
948 struct BankedRegOp BankedReg;
949 struct TokOp Tok;
950 struct RegOp Reg;
951 struct VectorListOp VectorList;
952 struct VectorIndexOp VectorIndex;
953 struct ImmOp Imm;
954 struct MemoryOp Memory;
955 struct PostIdxRegOp PostIdxReg;
956 struct ShifterImmOp ShifterImm;
957 struct RegShiftedRegOp RegShiftedReg;
958 struct RegShiftedImmOp RegShiftedImm;
959 struct RotImmOp RotImm;
960 struct ModImmOp ModImm;
961 struct BitfieldOp Bitfield;
962 };
963
964public:
965 ARMOperand(KindTy K, ARMAsmParser &Parser) : Kind(K), Parser(&Parser) {}
966
967 /// getStartLoc - Get the location of the first token of this operand.
968 SMLoc getStartLoc() const override { return StartLoc; }
969
970 /// getEndLoc - Get the location of the last token of this operand.
971 SMLoc getEndLoc() const override { return EndLoc; }
972
973 /// getLocRange - Get the range between the first and last token of this
974 /// operand.
975 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
976
977 /// getAlignmentLoc - Get the location of the Alignment token of this operand.
978 SMLoc getAlignmentLoc() const {
979 assert(Kind == k_Memory && "Invalid access!");
980 return AlignmentLoc;
981 }
982
984 assert(Kind == k_CondCode && "Invalid access!");
985 return CC.Val;
986 }
987
988 ARMVCC::VPTCodes getVPTPred() const {
989 assert(isVPTPred() && "Invalid access!");
990 return VCC.Val;
991 }
992
993 unsigned getCoproc() const {
994 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
995 return Cop.Val;
996 }
997
998 StringRef getToken() const {
999 assert(Kind == k_Token && "Invalid access!");
1000 return StringRef(Tok.Data, Tok.Length);
1001 }
1002
1003 MCRegister getReg() const override {
1004 assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
1005 return Reg.RegNum;
1006 }
1007
1008 const SmallVectorImpl<MCRegister> &getRegList() const {
1009 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
1010 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
1011 Kind == k_FPSRegisterListWithVPR ||
1012 Kind == k_FPDRegisterListWithVPR) &&
1013 "Invalid access!");
1014 return Registers;
1015 }
1016
1017 const MCExpr *getImm() const {
1018 assert(isImm() && "Invalid access!");
1019 return Imm.Val;
1020 }
1021
1022 const MCExpr *getConstantPoolImm() const {
1023 assert(isConstantPoolImm() && "Invalid access!");
1024 return Imm.Val;
1025 }
1026
1027 unsigned getVectorIndex() const {
1028 assert(Kind == k_VectorIndex && "Invalid access!");
1029 return VectorIndex.Val;
1030 }
1031
1032 ARM_MB::MemBOpt getMemBarrierOpt() const {
1033 assert(Kind == k_MemBarrierOpt && "Invalid access!");
1034 return MBOpt.Val;
1035 }
1036
1037 ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const {
1038 assert(Kind == k_InstSyncBarrierOpt && "Invalid access!");
1039 return ISBOpt.Val;
1040 }
1041
1042 ARM_TSB::TraceSyncBOpt getTraceSyncBarrierOpt() const {
1043 assert(Kind == k_TraceSyncBarrierOpt && "Invalid access!");
1044 return TSBOpt.Val;
1045 }
1046
1047 ARM_PROC::IFlags getProcIFlags() const {
1048 assert(Kind == k_ProcIFlags && "Invalid access!");
1049 return IFlags.Val;
1050 }
1051
1052 unsigned getMSRMask() const {
1053 assert(Kind == k_MSRMask && "Invalid access!");
1054 return MMask.Val;
1055 }
1056
1057 unsigned getBankedReg() const {
1058 assert(Kind == k_BankedReg && "Invalid access!");
1059 return BankedReg.Val;
1060 }
1061
1062 bool isCoprocNum() const { return Kind == k_CoprocNum; }
1063 bool isCoprocReg() const { return Kind == k_CoprocReg; }
1064 bool isCoprocOption() const { return Kind == k_CoprocOption; }
1065 bool isCondCode() const { return Kind == k_CondCode; }
1066 bool isVPTPred() const { return Kind == k_VPTPred; }
1067 bool isCCOut() const { return Kind == k_CCOut; }
1068 bool isITMask() const { return Kind == k_ITCondMask; }
1069 bool isITCondCode() const { return Kind == k_CondCode; }
1070 bool isImm() const override {
1071 return Kind == k_Immediate;
1072 }
1073
1074 bool isARMBranchTarget() const {
1075 if (!isImm()) return false;
1076
1077 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1078 return CE->getValue() % 4 == 0;
1079 return true;
1080 }
1081
1082
1083 bool isThumbBranchTarget() const {
1084 if (!isImm()) return false;
1085
1086 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1087 return CE->getValue() % 2 == 0;
1088 return true;
1089 }
1090
1091 // checks whether this operand is an unsigned offset which fits is a field
1092 // of specified width and scaled by a specific number of bits
1093 template<unsigned width, unsigned scale>
1094 bool isUnsignedOffset() const {
1095 if (!isImm()) return false;
1096 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1097 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1098 int64_t Val = CE->getValue();
1099 int64_t Align = 1LL << scale;
1100 int64_t Max = Align * ((1LL << width) - 1);
1101 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
1102 }
1103 return false;
1104 }
1105
1106 // checks whether this operand is an signed offset which fits is a field
1107 // of specified width and scaled by a specific number of bits
1108 template<unsigned width, unsigned scale>
1109 bool isSignedOffset() const {
1110 if (!isImm()) return false;
1111 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1112 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1113 int64_t Val = CE->getValue();
1114 int64_t Align = 1LL << scale;
1115 int64_t Max = Align * ((1LL << (width-1)) - 1);
1116 int64_t Min = -Align * (1LL << (width-1));
1117 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
1118 }
1119 return false;
1120 }
1121
1122 // checks whether this operand is an offset suitable for the LE /
1123 // LETP instructions in Arm v8.1M
1124 bool isLEOffset() const {
1125 if (!isImm()) return false;
1126 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1127 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1128 int64_t Val = CE->getValue();
1129 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1130 }
1131 return false;
1132 }
1133
1134 // checks whether this operand is a memory operand computed as an offset
1135 // applied to PC. the offset may have 8 bits of magnitude and is represented
1136 // with two bits of shift. textually it may be either [pc, #imm], #imm or
1137 // relocable expression...
1138 bool isThumbMemPC() const {
1139 int64_t Val = 0;
1140 if (isImm()) {
1141 if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
1142 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val);
1143 if (!CE) return false;
1144 Val = CE->getValue();
1145 }
1146 else if (isGPRMem()) {
1147 if(!Memory.OffsetImm || Memory.OffsetRegNum) return false;
1148 if(Memory.BaseRegNum != ARM::PC) return false;
1149 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
1150 Val = CE->getValue();
1151 else
1152 return false;
1153 }
1154 else return false;
1155 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1156 }
1157
1158 bool isFPImm() const {
1159 if (!isImm()) return false;
1160 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1161 if (!CE || !isUInt<32>(CE->getValue()))
1162 return false;
1163 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
1164 return Val != -1;
1165 }
1166
1167 template<int64_t N, int64_t M>
1168 bool isImmediate() const {
1169 if (!isImm()) return false;
1170 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1171 if (!CE) return false;
1172 int64_t Value = CE->getValue();
1173 return Value >= N && Value <= M;
1174 }
1175
1176 template<int64_t N, int64_t M>
1177 bool isImmediateS4() const {
1178 if (!isImm()) return false;
1179 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1180 if (!CE) return false;
1181 int64_t Value = CE->getValue();
1182 // ARM assembly uses #-0 to request the subtract-zero encoding,
1183 // which is distinct from the add-zero spelling even though both
1184 // have zero magnitude. The rather odd std::numeric_limits
1185 // invocation gives us this.
1186 return (((Value & 3) == 0) && Value >= N && Value <= M) ||
1187 Value == std::numeric_limits<int32_t>::min();
1188 }
1189 template<int64_t N, int64_t M>
1190 bool isImmediateS2() const {
1191 if (!isImm()) return false;
1192 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1193 if (!CE) return false;
1194 int64_t Value = CE->getValue();
1195 return ((Value & 1) == 0) && Value >= N && Value <= M;
1196 }
1197 bool isFBits16() const {
1198 return isImmediate<0, 17>();
1199 }
1200 bool isFBits32() const {
1201 return isImmediate<1, 33>();
1202 }
1203 bool isImm8s4() const {
1204 return isImmediateS4<-1020, 1020>();
1205 }
1206 bool isImm7s4() const {
1207 return isImmediateS4<-508, 508>();
1208 }
1209 bool isImm7Shift0() const {
1210 return isImmediate<-127, 127>();
1211 }
1212 bool isImm7Shift1() const {
1213 return isImmediateS2<-255, 255>();
1214 }
1215 bool isImm7Shift2() const {
1216 return isImmediateS4<-511, 511>();
1217 }
1218 bool isImm7() const {
1219 return isImmediate<-127, 127>();
1220 }
1221 bool isImm0_1020s4() const {
1222 return isImmediateS4<0, 1020>();
1223 }
1224 bool isImm0_508s4() const {
1225 return isImmediateS4<0, 508>();
1226 }
1227 bool isImm0_508s4Neg() const {
1228 if (!isImm()) return false;
1229 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1230 if (!CE) return false;
1231 int64_t Value = -CE->getValue();
1232 // explicitly exclude zero. we want that to use the normal 0_508 version.
1233 return ((Value & 3) == 0) && Value > 0 && Value <= 508;
1234 }
1235
1236 bool isImm0_4095Neg() const {
1237 if (!isImm()) return false;
1238 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1239 if (!CE) return false;
1240 // isImm0_4095Neg is used with 32-bit immediates only.
1241 // 32-bit immediates are zero extended to 64-bit when parsed,
1242 // thus simple -CE->getValue() results in a big negative number,
1243 // not a small positive number as intended
1244 if ((CE->getValue() >> 32) > 0) return false;
1245 uint32_t Value = -static_cast<uint32_t>(CE->getValue());
1246 return Value > 0 && Value < 4096;
1247 }
1248
1249 bool isImm0_7() const {
1250 return isImmediate<0, 7>();
1251 }
1252
1253 bool isImm1_16() const {
1254 return isImmediate<1, 16>();
1255 }
1256
1257 bool isImm1_32() const {
1258 return isImmediate<1, 32>();
1259 }
1260
1261 bool isImm8_255() const {
1262 return isImmediate<8, 255>();
1263 }
1264
1265 bool isImm0_255Expr() const {
1266 if (!isImm())
1267 return false;
1268 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1269 // If it's not a constant expression, it'll generate a fixup and be
1270 // handled later.
1271 if (!CE)
1272 return true;
1273 int64_t Value = CE->getValue();
1274 return isUInt<8>(Value);
1275 }
1276
1277 bool isImm256_65535Expr() const {
1278 if (!isImm()) return false;
1279 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1280 // If it's not a constant expression, it'll generate a fixup and be
1281 // handled later.
1282 if (!CE) return true;
1283 int64_t Value = CE->getValue();
1284 return Value >= 256 && Value < 65536;
1285 }
1286
1287 bool isImm0_65535Expr() const {
1288 if (!isImm()) return false;
1289 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1290 // If it's not a constant expression, it'll generate a fixup and be
1291 // handled later.
1292 if (!CE) return true;
1293 int64_t Value = CE->getValue();
1294 return Value >= 0 && Value < 65536;
1295 }
1296
1297 bool isImm24bit() const {
1298 return isImmediate<0, 0xffffff + 1>();
1299 }
1300
1301 bool isImmThumbSR() const {
1302 return isImmediate<1, 33>();
1303 }
1304
1305 bool isPKHLSLImm() const {
1306 return isImmediate<0, 32>();
1307 }
1308
1309 bool isPKHASRImm() const {
1310 return isImmediate<0, 33>();
1311 }
1312
1313 bool isAdrLabel() const {
1314 // If we have an immediate that's not a constant, treat it as a label
1315 // reference needing a fixup.
1316 if (isImm() && !isa<MCConstantExpr>(getImm()))
1317 return true;
1318
1319 // If it is a constant, it must fit into a modified immediate encoding.
1320 if (!isImm()) return false;
1321 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1322 if (!CE) return false;
1323 int64_t Value = CE->getValue();
1324 return (ARM_AM::getSOImmVal(Value) != -1 ||
1325 ARM_AM::getSOImmVal(-Value) != -1);
1326 }
1327
1328 bool isT2SOImm() const {
1329 // If we have an immediate that's not a constant, treat it as an expression
1330 // needing a fixup.
1331 if (isImm() && !isa<MCConstantExpr>(getImm())) {
1332 // We want to avoid matching :upper16: and :lower16: as we want these
1333 // expressions to match in isImm0_65535Expr()
1334 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(getImm());
1335 return (!ARM16Expr || (ARM16Expr->getSpecifier() != ARM::S_HI16 &&
1336 ARM16Expr->getSpecifier() != ARM::S_LO16));
1337 }
1338 if (!isImm()) return false;
1339 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1340 if (!CE) return false;
1341 int64_t Value = CE->getValue();
1342 return ARM_AM::getT2SOImmVal(Value) != -1;
1343 }
1344
1345 bool isT2SOImmNot() const {
1346 if (!isImm()) return false;
1347 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1348 if (!CE) return false;
1349 int64_t Value = CE->getValue();
1350 return ARM_AM::getT2SOImmVal(Value) == -1 &&
1352 }
1353
1354 bool isT2SOImmNeg() const {
1355 if (!isImm()) return false;
1356 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1357 if (!CE) return false;
1358 int64_t Value = CE->getValue();
1359 // Only use this when not representable as a plain so_imm.
1360 return ARM_AM::getT2SOImmVal(Value) == -1 &&
1362 }
1363
1364 bool isSetEndImm() const {
1365 if (!isImm()) return false;
1366 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1367 if (!CE) return false;
1368 int64_t Value = CE->getValue();
1369 return Value == 1 || Value == 0;
1370 }
1371
1372 bool isReg() const override { return Kind == k_Register; }
1373 bool isRegList() const { return Kind == k_RegisterList; }
1374 bool isRegListWithAPSR() const {
1375 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1376 }
1377 bool isDReg() const {
1378 return isReg() &&
1379 ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg.RegNum);
1380 }
1381 bool isQReg() const {
1382 return isReg() &&
1383 ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg.RegNum);
1384 }
1385 bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
1386 bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
1387 bool isFPSRegListWithVPR() const { return Kind == k_FPSRegisterListWithVPR; }
1388 bool isFPDRegListWithVPR() const { return Kind == k_FPDRegisterListWithVPR; }
1389 bool isToken() const override { return Kind == k_Token; }
1390 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
1391 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
1392 bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; }
1393 bool isMem() const override {
1394 return isGPRMem() || isMVEMem();
1395 }
1396 bool isMVEMem() const {
1397 if (Kind != k_Memory)
1398 return false;
1399 if (Memory.BaseRegNum &&
1400 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum) &&
1401 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Memory.BaseRegNum))
1402 return false;
1403 if (Memory.OffsetRegNum &&
1404 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1405 Memory.OffsetRegNum))
1406 return false;
1407 return true;
1408 }
1409 bool isGPRMem() const {
1410 if (Kind != k_Memory)
1411 return false;
1412 if (Memory.BaseRegNum &&
1413 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum))
1414 return false;
1415 if (Memory.OffsetRegNum &&
1416 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.OffsetRegNum))
1417 return false;
1418 return true;
1419 }
1420 bool isShifterImm() const { return Kind == k_ShifterImmediate; }
1421 bool isRegShiftedReg() const {
1422 return Kind == k_ShiftedRegister &&
1423 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1424 RegShiftedReg.SrcReg) &&
1425 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1426 RegShiftedReg.ShiftReg);
1427 }
1428 bool isRegShiftedImm() const {
1429 return Kind == k_ShiftedImmediate &&
1430 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1431 RegShiftedImm.SrcReg);
1432 }
1433 bool isRotImm() const { return Kind == k_RotateImmediate; }
1434
1435 template<unsigned Min, unsigned Max>
1436 bool isPowerTwoInRange() const {
1437 if (!isImm()) return false;
1438 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1439 if (!CE) return false;
1440 int64_t Value = CE->getValue();
1441 return Value > 0 && llvm::popcount((uint64_t)Value) == 1 && Value >= Min &&
1442 Value <= Max;
1443 }
1444 bool isModImm() const { return Kind == k_ModifiedImmediate; }
1445
1446 bool isModImmNot() const {
1447 if (!isImm()) return false;
1448 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1449 if (!CE) return false;
1450 int64_t Value = CE->getValue();
1451 return ARM_AM::getSOImmVal(~Value) != -1;
1452 }
1453
1454 bool isModImmNeg() const {
1455 if (!isImm()) return false;
1456 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1457 if (!CE) return false;
1458 int64_t Value = CE->getValue();
1459 return ARM_AM::getSOImmVal(Value) == -1 &&
1460 ARM_AM::getSOImmVal(-Value) != -1;
1461 }
1462
1463 bool isThumbModImmNeg1_7() const {
1464 if (!isImm()) return false;
1465 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1466 if (!CE) return false;
1467 int32_t Value = -(int32_t)CE->getValue();
1468 return 0 < Value && Value < 8;
1469 }
1470
1471 bool isThumbModImmNeg8_255() const {
1472 if (!isImm()) return false;
1473 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1474 if (!CE) return false;
1475 int32_t Value = -(int32_t)CE->getValue();
1476 return 7 < Value && Value < 256;
1477 }
1478
1479 bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
1480 bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
1481 bool isPostIdxRegShifted() const {
1482 return Kind == k_PostIndexRegister &&
1483 ARMMCRegisterClasses[ARM::GPRRegClassID].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 (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1500 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 (!ARMMCRegisterClasses[ARM::rGPRRegClassID].contains(
1512 Memory.BaseRegNum))
1513 return false;
1514
1515 // No offset of any kind.
1516 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1517 (alignOK || Memory.Alignment == Alignment);
1518 }
1519 bool isMemNoOffsetT(bool alignOK = false, unsigned Alignment = 0) const {
1520 if (!isGPRMem())
1521 return false;
1522
1523 if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].contains(
1524 Memory.BaseRegNum))
1525 return false;
1526
1527 // No offset of any kind.
1528 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1529 (alignOK || Memory.Alignment == Alignment);
1530 }
1531 bool isMemPCRelImm12() const {
1532 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1533 return false;
1534 // Base register must be PC.
1535 if (Memory.BaseRegNum != ARM::PC)
1536 return false;
1537 // Immediate offset in range [-4095, 4095].
1538 if (!Memory.OffsetImm) return true;
1539 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1540 int64_t Val = CE->getValue();
1541 return (Val > -4096 && Val < 4096) ||
1542 (Val == std::numeric_limits<int32_t>::min());
1543 }
1544 return false;
1545 }
1546
1547 bool isAlignedMemory() const {
1548 return isMemNoOffset(true);
1549 }
1550
1551 bool isAlignedMemoryNone() const {
1552 return isMemNoOffset(false, 0);
1553 }
1554
1555 bool isDupAlignedMemoryNone() const {
1556 return isMemNoOffset(false, 0);
1557 }
1558
1559 bool isAlignedMemory16() const {
1560 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1561 return true;
1562 return isMemNoOffset(false, 0);
1563 }
1564
1565 bool isDupAlignedMemory16() const {
1566 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1567 return true;
1568 return isMemNoOffset(false, 0);
1569 }
1570
1571 bool isAlignedMemory32() const {
1572 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1573 return true;
1574 return isMemNoOffset(false, 0);
1575 }
1576
1577 bool isDupAlignedMemory32() const {
1578 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1579 return true;
1580 return isMemNoOffset(false, 0);
1581 }
1582
1583 bool isAlignedMemory64() const {
1584 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1585 return true;
1586 return isMemNoOffset(false, 0);
1587 }
1588
1589 bool isDupAlignedMemory64() const {
1590 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1591 return true;
1592 return isMemNoOffset(false, 0);
1593 }
1594
1595 bool isAlignedMemory64or128() const {
1596 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1597 return true;
1598 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1599 return true;
1600 return isMemNoOffset(false, 0);
1601 }
1602
1603 bool isDupAlignedMemory64or128() const {
1604 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1605 return true;
1606 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1607 return true;
1608 return isMemNoOffset(false, 0);
1609 }
1610
1611 bool isAlignedMemory64or128or256() const {
1612 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1613 return true;
1614 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1615 return true;
1616 if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32.
1617 return true;
1618 return isMemNoOffset(false, 0);
1619 }
1620
1621 bool isAddrMode2() const {
1622 if (!isGPRMem() || Memory.Alignment != 0) return false;
1623 // Check for register offset.
1624 if (Memory.OffsetRegNum) return true;
1625 // Immediate offset in range [-4095, 4095].
1626 if (!Memory.OffsetImm) return true;
1627 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1628 int64_t Val = CE->getValue();
1629 return Val > -4096 && Val < 4096;
1630 }
1631 return false;
1632 }
1633
1634 bool isAM2OffsetImm() const {
1635 if (!isImm()) return false;
1636 // Immediate offset in range [-4095, 4095].
1637 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1638 if (!CE) return false;
1639 int64_t Val = CE->getValue();
1640 return (Val == std::numeric_limits<int32_t>::min()) ||
1641 (Val > -4096 && Val < 4096);
1642 }
1643
1644 bool isAddrMode3() const {
1645 // If we have an immediate that's not a constant, treat it as a label
1646 // reference needing a fixup. If it is a constant, it's something else
1647 // and we reject it.
1648 if (isImm() && !isa<MCConstantExpr>(getImm()))
1649 return true;
1650 if (!isGPRMem() || Memory.Alignment != 0) return false;
1651 // No shifts are legal for AM3.
1652 if (Memory.ShiftType != ARM_AM::no_shift) return false;
1653 // Check for register offset.
1654 if (Memory.OffsetRegNum) return true;
1655 // Immediate offset in range [-255, 255].
1656 if (!Memory.OffsetImm) return true;
1657 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1658 int64_t Val = CE->getValue();
1659 // The #-0 offset is encoded as std::numeric_limits<int32_t>::min(), and
1660 // we have to check for this too.
1661 return (Val > -256 && Val < 256) ||
1662 Val == std::numeric_limits<int32_t>::min();
1663 }
1664 return false;
1665 }
1666
1667 bool isAM3Offset() const {
1668 if (isPostIdxReg())
1669 return true;
1670 if (!isImm())
1671 return false;
1672 // Immediate offset in range [-255, 255].
1673 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1674 if (!CE) return false;
1675 int64_t Val = CE->getValue();
1676 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1677 return (Val > -256 && Val < 256) ||
1678 Val == std::numeric_limits<int32_t>::min();
1679 }
1680
1681 bool isAddrMode5() const {
1682 // If we have an immediate that's not a constant, treat it as a label
1683 // reference needing a fixup. If it is a constant, it's something else
1684 // and we reject it.
1685 if (isImm() && !isa<MCConstantExpr>(getImm()))
1686 return true;
1687 if (!isGPRMem() || Memory.Alignment != 0) return false;
1688 // Check for register offset.
1689 if (Memory.OffsetRegNum) return false;
1690 // Immediate offset in range [-1020, 1020] and a multiple of 4.
1691 if (!Memory.OffsetImm) return true;
1692 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1693 int64_t Val = CE->getValue();
1694 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1695 Val == std::numeric_limits<int32_t>::min();
1696 }
1697 return false;
1698 }
1699
1700 bool isAddrMode5FP16() const {
1701 // If we have an immediate that's not a constant, treat it as a label
1702 // reference needing a fixup. If it is a constant, it's something else
1703 // and we reject it.
1704 if (isImm() && !isa<MCConstantExpr>(getImm()))
1705 return true;
1706 if (!isGPRMem() || Memory.Alignment != 0) return false;
1707 // Check for register offset.
1708 if (Memory.OffsetRegNum) return false;
1709 // Immediate offset in range [-510, 510] and a multiple of 2.
1710 if (!Memory.OffsetImm) return true;
1711 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1712 int64_t Val = CE->getValue();
1713 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1714 Val == std::numeric_limits<int32_t>::min();
1715 }
1716 return false;
1717 }
1718
1719 bool isMemTBB() const {
1720 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1721 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1722 return false;
1723 return true;
1724 }
1725
1726 bool isMemTBH() const {
1727 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1728 Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
1729 Memory.Alignment != 0 )
1730 return false;
1731 return true;
1732 }
1733
1734 bool isMemRegOffset() const {
1735 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1736 return false;
1737 return true;
1738 }
1739
1740 bool isT2MemRegOffset() const {
1741 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1742 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1743 return false;
1744 // Only lsl #{0, 1, 2, 3} allowed.
1745 if (Memory.ShiftType == ARM_AM::no_shift)
1746 return true;
1747 if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
1748 return false;
1749 return true;
1750 }
1751
1752 bool isMemThumbRR() const {
1753 // Thumb reg+reg addressing is simple. Just two registers, a base and
1754 // an offset. No shifts, negations or any other complicating factors.
1755 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1756 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1757 return false;
1758 return isARMLowRegister(Memory.BaseRegNum) &&
1759 (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
1760 }
1761
1762 bool isMemThumbRIs4() const {
1763 if (!isGPRMem() || Memory.OffsetRegNum ||
1764 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1765 return false;
1766 // Immediate offset, multiple of 4 in range [0, 124].
1767 if (!Memory.OffsetImm) return true;
1768 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1769 int64_t Val = CE->getValue();
1770 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1771 }
1772 return false;
1773 }
1774
1775 bool isMemThumbRIs2() const {
1776 if (!isGPRMem() || Memory.OffsetRegNum ||
1777 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1778 return false;
1779 // Immediate offset, multiple of 4 in range [0, 62].
1780 if (!Memory.OffsetImm) return true;
1781 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1782 int64_t Val = CE->getValue();
1783 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1784 }
1785 return false;
1786 }
1787
1788 bool isMemThumbRIs1() const {
1789 if (!isGPRMem() || Memory.OffsetRegNum ||
1790 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1791 return false;
1792 // Immediate offset in range [0, 31].
1793 if (!Memory.OffsetImm) return true;
1794 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1795 int64_t Val = CE->getValue();
1796 return Val >= 0 && Val <= 31;
1797 }
1798 return false;
1799 }
1800
1801 bool isMemThumbSPI() const {
1802 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1803 Memory.Alignment != 0)
1804 return false;
1805 // Immediate offset, multiple of 4 in range [0, 1020].
1806 if (!Memory.OffsetImm) return true;
1807 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1808 int64_t Val = CE->getValue();
1809 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1810 }
1811 return false;
1812 }
1813
1814 bool isMemImm8s4Offset() const {
1815 // If we have an immediate that's not a constant, treat it as a label
1816 // reference needing a fixup. If it is a constant, it's something else
1817 // and we reject it.
1818 if (isImm() && !isa<MCConstantExpr>(getImm()))
1819 return true;
1820 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1821 return false;
1822 // Immediate offset a multiple of 4 in range [-1020, 1020].
1823 if (!Memory.OffsetImm) return true;
1824 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1825 int64_t Val = CE->getValue();
1826 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1827 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1828 Val == std::numeric_limits<int32_t>::min();
1829 }
1830 return false;
1831 }
1832
1833 bool isMemImm7s4Offset() const {
1834 // If we have an immediate that's not a constant, treat it as a label
1835 // reference needing a fixup. If it is a constant, it's something else
1836 // and we reject it.
1837 if (isImm() && !isa<MCConstantExpr>(getImm()))
1838 return true;
1839 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1840 !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1841 Memory.BaseRegNum))
1842 return false;
1843 // Immediate offset a multiple of 4 in range [-508, 508].
1844 if (!Memory.OffsetImm) return true;
1845 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1846 int64_t Val = CE->getValue();
1847 // Special case, #-0 is INT32_MIN.
1848 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1849 }
1850 return false;
1851 }
1852
1853 bool isMemImm0_1020s4Offset() const {
1854 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1855 return false;
1856 // Immediate offset a multiple of 4 in range [0, 1020].
1857 if (!Memory.OffsetImm) return true;
1858 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1859 int64_t Val = CE->getValue();
1860 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1861 }
1862 return false;
1863 }
1864
1865 bool isMemImm8Offset() const {
1866 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1867 return false;
1868 // Base reg of PC isn't allowed for these encodings.
1869 if (Memory.BaseRegNum == ARM::PC) return false;
1870 // Immediate offset in range [-255, 255].
1871 if (!Memory.OffsetImm) return true;
1872 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1873 int64_t Val = CE->getValue();
1874 return (Val == std::numeric_limits<int32_t>::min()) ||
1875 (Val > -256 && Val < 256);
1876 }
1877 return false;
1878 }
1879
1880 template<unsigned Bits, unsigned RegClassID>
1881 bool isMemImm7ShiftedOffset() const {
1882 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1883 !ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum))
1884 return false;
1885
1886 // Expect an immediate offset equal to an element of the range
1887 // [-127, 127], shifted left by Bits.
1888
1889 if (!Memory.OffsetImm) return true;
1890 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1891 int64_t Val = CE->getValue();
1892
1893 // INT32_MIN is a special-case value (indicating the encoding with
1894 // zero offset and the subtract bit set)
1895 if (Val == INT32_MIN)
1896 return true;
1897
1898 unsigned Divisor = 1U << Bits;
1899
1900 // Check that the low bits are zero
1901 if (Val % Divisor != 0)
1902 return false;
1903
1904 // Check that the remaining offset is within range.
1905 Val /= Divisor;
1906 return (Val >= -127 && Val <= 127);
1907 }
1908 return false;
1909 }
1910
1911 template <int shift> bool isMemRegRQOffset() const {
1912 if (!isMVEMem() || Memory.OffsetImm != nullptr || Memory.Alignment != 0)
1913 return false;
1914
1915 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1916 Memory.BaseRegNum))
1917 return false;
1918 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1919 Memory.OffsetRegNum))
1920 return false;
1921
1922 if (shift == 0 && Memory.ShiftType != ARM_AM::no_shift)
1923 return false;
1924
1925 if (shift > 0 &&
1926 (Memory.ShiftType != ARM_AM::uxtw || Memory.ShiftImm != shift))
1927 return false;
1928
1929 return true;
1930 }
1931
1932 template <int shift> bool isMemRegQOffset() const {
1933 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1934 return false;
1935
1936 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1937 Memory.BaseRegNum))
1938 return false;
1939
1940 if (!Memory.OffsetImm)
1941 return true;
1942 static_assert(shift < 56,
1943 "Such that we dont shift by a value higher than 62");
1944 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1945 int64_t Val = CE->getValue();
1946
1947 // The value must be a multiple of (1 << shift)
1948 if ((Val & ((1U << shift) - 1)) != 0)
1949 return false;
1950
1951 // And be in the right range, depending on the amount that it is shifted
1952 // by. Shift 0, is equal to 7 unsigned bits, the sign bit is set
1953 // separately.
1954 int64_t Range = (1U << (7 + shift)) - 1;
1955 return (Val == INT32_MIN) || (Val > -Range && Val < Range);
1956 }
1957 return false;
1958 }
1959
1960 bool isMemPosImm8Offset() const {
1961 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1962 return false;
1963 // Immediate offset in range [0, 255].
1964 if (!Memory.OffsetImm) return true;
1965 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1966 int64_t Val = CE->getValue();
1967 return Val >= 0 && Val < 256;
1968 }
1969 return false;
1970 }
1971
1972 bool isMemNegImm8Offset() const {
1973 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1974 return false;
1975 // Base reg of PC isn't allowed for these encodings.
1976 if (Memory.BaseRegNum == ARM::PC) return false;
1977 // Immediate offset in range [-255, -1].
1978 if (!Memory.OffsetImm) return false;
1979 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1980 int64_t Val = CE->getValue();
1981 return (Val == std::numeric_limits<int32_t>::min()) ||
1982 (Val > -256 && Val < 0);
1983 }
1984 return false;
1985 }
1986
1987 bool isMemUImm12Offset() const {
1988 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1989 return false;
1990 // Immediate offset in range [0, 4095].
1991 if (!Memory.OffsetImm) return true;
1992 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1993 int64_t Val = CE->getValue();
1994 return (Val >= 0 && Val < 4096);
1995 }
1996 return false;
1997 }
1998
1999 bool isMemImm12Offset() const {
2000 // If we have an immediate that's not a constant, treat it as a label
2001 // reference needing a fixup. If it is a constant, it's something else
2002 // and we reject it.
2003
2004 if (isImm() && !isa<MCConstantExpr>(getImm()))
2005 return true;
2006
2007 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2008 return false;
2009 // Immediate offset in range [-4095, 4095].
2010 if (!Memory.OffsetImm) return true;
2011 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
2012 int64_t Val = CE->getValue();
2013 return (Val > -4096 && Val < 4096) ||
2014 (Val == std::numeric_limits<int32_t>::min());
2015 }
2016 // If we have an immediate that's not a constant, treat it as a
2017 // symbolic expression needing a fixup.
2018 return true;
2019 }
2020
2021 bool isConstPoolAsmImm() const {
2022 // Delay processing of Constant Pool Immediate, this will turn into
2023 // a constant. Match no other operand
2024 return (isConstantPoolImm());
2025 }
2026
2027 bool isPostIdxImm8() const {
2028 if (!isImm()) return false;
2029 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2030 if (!CE) return false;
2031 int64_t Val = CE->getValue();
2032 return (Val > -256 && Val < 256) ||
2033 (Val == std::numeric_limits<int32_t>::min());
2034 }
2035
2036 bool isPostIdxImm8s4() const {
2037 if (!isImm()) return false;
2038 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2039 if (!CE) return false;
2040 int64_t Val = CE->getValue();
2041 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2042 (Val == std::numeric_limits<int32_t>::min());
2043 }
2044
2045 bool isMSRMask() const { return Kind == k_MSRMask; }
2046 bool isBankedReg() const { return Kind == k_BankedReg; }
2047 bool isProcIFlags() const { return Kind == k_ProcIFlags; }
2048
2049 // NEON operands.
2050 bool isAnyVectorList() const {
2051 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2052 Kind == k_VectorListIndexed;
2053 }
2054
2055 bool isVectorList() const { return Kind == k_VectorList; }
2056
2057 bool isSingleSpacedVectorList() const {
2058 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2059 }
2060
2061 bool isDoubleSpacedVectorList() const {
2062 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2063 }
2064
2065 bool isVecListOneD() const {
2066 // We convert a single D reg to a list containing a D reg
2067 if (isDReg() && !Parser->hasMVE())
2068 return true;
2069 if (!isSingleSpacedVectorList()) return false;
2070 return VectorList.Count == 1;
2071 }
2072
2073 bool isVecListTwoMQ() const {
2074 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2075 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2076 VectorList.RegNum);
2077 }
2078
2079 bool isVecListDPair() const {
2080 // We convert a single Q reg to a list with the two corresponding D
2081 // registers
2082 if (isQReg() && !Parser->hasMVE())
2083 return true;
2084 if (!isSingleSpacedVectorList()) return false;
2085 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2086 .contains(VectorList.RegNum));
2087 }
2088
2089 bool isVecListThreeD() const {
2090 if (!isSingleSpacedVectorList()) return false;
2091 return VectorList.Count == 3;
2092 }
2093
2094 bool isVecListFourD() const {
2095 if (!isSingleSpacedVectorList()) return false;
2096 return VectorList.Count == 4;
2097 }
2098
2099 bool isVecListDPairSpaced() const {
2100 if (Kind != k_VectorList) return false;
2101 if (isSingleSpacedVectorList()) return false;
2102 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
2103 .contains(VectorList.RegNum));
2104 }
2105
2106 bool isVecListThreeQ() const {
2107 if (!isDoubleSpacedVectorList()) return false;
2108 return VectorList.Count == 3;
2109 }
2110
2111 bool isVecListFourQ() const {
2112 if (!isDoubleSpacedVectorList()) return false;
2113 return VectorList.Count == 4;
2114 }
2115
2116 bool isVecListFourMQ() const {
2117 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2118 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2119 VectorList.RegNum);
2120 }
2121
2122 bool isSingleSpacedVectorAllLanes() const {
2123 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2124 }
2125
2126 bool isDoubleSpacedVectorAllLanes() const {
2127 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2128 }
2129
2130 bool isVecListOneDAllLanes() const {
2131 if (!isSingleSpacedVectorAllLanes()) return false;
2132 return VectorList.Count == 1;
2133 }
2134
2135 bool isVecListDPairAllLanes() const {
2136 if (!isSingleSpacedVectorAllLanes()) return false;
2137 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2138 .contains(VectorList.RegNum));
2139 }
2140
2141 bool isVecListDPairSpacedAllLanes() const {
2142 if (!isDoubleSpacedVectorAllLanes()) return false;
2143 return VectorList.Count == 2;
2144 }
2145
2146 bool isVecListThreeDAllLanes() const {
2147 if (!isSingleSpacedVectorAllLanes()) return false;
2148 return VectorList.Count == 3;
2149 }
2150
2151 bool isVecListThreeQAllLanes() const {
2152 if (!isDoubleSpacedVectorAllLanes()) return false;
2153 return VectorList.Count == 3;
2154 }
2155
2156 bool isVecListFourDAllLanes() const {
2157 if (!isSingleSpacedVectorAllLanes()) return false;
2158 return VectorList.Count == 4;
2159 }
2160
2161 bool isVecListFourQAllLanes() const {
2162 if (!isDoubleSpacedVectorAllLanes()) return false;
2163 return VectorList.Count == 4;
2164 }
2165
2166 bool isSingleSpacedVectorIndexed() const {
2167 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2168 }
2169
2170 bool isDoubleSpacedVectorIndexed() const {
2171 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2172 }
2173
2174 bool isVecListOneDByteIndexed() const {
2175 if (!isSingleSpacedVectorIndexed()) return false;
2176 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2177 }
2178
2179 bool isVecListOneDHWordIndexed() const {
2180 if (!isSingleSpacedVectorIndexed()) return false;
2181 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2182 }
2183
2184 bool isVecListOneDWordIndexed() const {
2185 if (!isSingleSpacedVectorIndexed()) return false;
2186 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2187 }
2188
2189 bool isVecListTwoDByteIndexed() const {
2190 if (!isSingleSpacedVectorIndexed()) return false;
2191 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2192 }
2193
2194 bool isVecListTwoDHWordIndexed() const {
2195 if (!isSingleSpacedVectorIndexed()) return false;
2196 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2197 }
2198
2199 bool isVecListTwoQWordIndexed() const {
2200 if (!isDoubleSpacedVectorIndexed()) return false;
2201 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2202 }
2203
2204 bool isVecListTwoQHWordIndexed() const {
2205 if (!isDoubleSpacedVectorIndexed()) return false;
2206 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2207 }
2208
2209 bool isVecListTwoDWordIndexed() const {
2210 if (!isSingleSpacedVectorIndexed()) return false;
2211 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2212 }
2213
2214 bool isVecListThreeDByteIndexed() const {
2215 if (!isSingleSpacedVectorIndexed()) return false;
2216 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2217 }
2218
2219 bool isVecListThreeDHWordIndexed() const {
2220 if (!isSingleSpacedVectorIndexed()) return false;
2221 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2222 }
2223
2224 bool isVecListThreeQWordIndexed() const {
2225 if (!isDoubleSpacedVectorIndexed()) return false;
2226 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2227 }
2228
2229 bool isVecListThreeQHWordIndexed() const {
2230 if (!isDoubleSpacedVectorIndexed()) return false;
2231 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2232 }
2233
2234 bool isVecListThreeDWordIndexed() const {
2235 if (!isSingleSpacedVectorIndexed()) return false;
2236 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2237 }
2238
2239 bool isVecListFourDByteIndexed() const {
2240 if (!isSingleSpacedVectorIndexed()) return false;
2241 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2242 }
2243
2244 bool isVecListFourDHWordIndexed() const {
2245 if (!isSingleSpacedVectorIndexed()) return false;
2246 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2247 }
2248
2249 bool isVecListFourQWordIndexed() const {
2250 if (!isDoubleSpacedVectorIndexed()) return false;
2251 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2252 }
2253
2254 bool isVecListFourQHWordIndexed() const {
2255 if (!isDoubleSpacedVectorIndexed()) return false;
2256 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2257 }
2258
2259 bool isVecListFourDWordIndexed() const {
2260 if (!isSingleSpacedVectorIndexed()) return false;
2261 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2262 }
2263
2264 bool isVectorIndex() const { return Kind == k_VectorIndex; }
2265
2266 template <unsigned NumLanes>
2267 bool isVectorIndexInRange() const {
2268 if (Kind != k_VectorIndex) return false;
2269 return VectorIndex.Val < NumLanes;
2270 }
2271
2272 bool isVectorIndex8() const { return isVectorIndexInRange<8>(); }
2273 bool isVectorIndex16() const { return isVectorIndexInRange<4>(); }
2274 bool isVectorIndex32() const { return isVectorIndexInRange<2>(); }
2275 bool isVectorIndex64() const { return isVectorIndexInRange<1>(); }
2276
2277 template<int PermittedValue, int OtherPermittedValue>
2278 bool isMVEPairVectorIndex() const {
2279 if (Kind != k_VectorIndex) return false;
2280 return VectorIndex.Val == PermittedValue ||
2281 VectorIndex.Val == OtherPermittedValue;
2282 }
2283
2284 bool isNEONi8splat() const {
2285 if (!isImm()) return false;
2286 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2287 // Must be a constant.
2288 if (!CE) return false;
2289 int64_t Value = CE->getValue();
2290 // i8 value splatted across 8 bytes. The immediate is just the 8 byte
2291 // value.
2292 return Value >= 0 && Value < 256;
2293 }
2294
2295 bool isNEONi16splat() const {
2296 if (isNEONByteReplicate(2))
2297 return false; // Leave that for bytes replication and forbid by default.
2298 if (!isImm())
2299 return false;
2300 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2301 // Must be a constant.
2302 if (!CE) return false;
2303 unsigned Value = CE->getValue();
2305 }
2306
2307 bool isNEONi16splatNot() const {
2308 if (!isImm())
2309 return false;
2310 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2311 // Must be a constant.
2312 if (!CE) return false;
2313 unsigned Value = CE->getValue();
2314 return ARM_AM::isNEONi16splat(~Value & 0xffff);
2315 }
2316
2317 bool isNEONi32splat() const {
2318 if (isNEONByteReplicate(4))
2319 return false; // Leave that for bytes replication and forbid by default.
2320 if (!isImm())
2321 return false;
2322 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2323 // Must be a constant.
2324 if (!CE) return false;
2325 unsigned Value = CE->getValue();
2327 }
2328
2329 bool isNEONi32splatNot() const {
2330 if (!isImm())
2331 return false;
2332 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2333 // Must be a constant.
2334 if (!CE) return false;
2335 unsigned Value = CE->getValue();
2337 }
2338
2339 static bool isValidNEONi32vmovImm(int64_t Value) {
2340 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
2341 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
2342 return ((Value & 0xffffffffffffff00) == 0) ||
2343 ((Value & 0xffffffffffff00ff) == 0) ||
2344 ((Value & 0xffffffffff00ffff) == 0) ||
2345 ((Value & 0xffffffff00ffffff) == 0) ||
2346 ((Value & 0xffffffffffff00ff) == 0xff) ||
2347 ((Value & 0xffffffffff00ffff) == 0xffff);
2348 }
2349
2350 bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const {
2351 assert((Width == 8 || Width == 16 || Width == 32) &&
2352 "Invalid element width");
2353 assert(NumElems * Width <= 64 && "Invalid result width");
2354
2355 if (!isImm())
2356 return false;
2357 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2358 // Must be a constant.
2359 if (!CE)
2360 return false;
2361 int64_t Value = CE->getValue();
2362 if (!Value)
2363 return false; // Don't bother with zero.
2364 if (Inv)
2365 Value = ~Value;
2366
2367 uint64_t Mask = (1ull << Width) - 1;
2368 uint64_t Elem = Value & Mask;
2369 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2370 return false;
2371 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2372 return false;
2373
2374 for (unsigned i = 1; i < NumElems; ++i) {
2375 Value >>= Width;
2376 if ((Value & Mask) != Elem)
2377 return false;
2378 }
2379 return true;
2380 }
2381
2382 bool isNEONByteReplicate(unsigned NumBytes) const {
2383 return isNEONReplicate(8, NumBytes, false);
2384 }
2385
2386 static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
2387 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2388 "Invalid source width");
2389 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2390 "Invalid destination width");
2391 assert(FromW < ToW && "ToW is not less than FromW");
2392 }
2393
2394 template<unsigned FromW, unsigned ToW>
2395 bool isNEONmovReplicate() const {
2396 checkNeonReplicateArgs(FromW, ToW);
2397 if (ToW == 64 && isNEONi64splat())
2398 return false;
2399 return isNEONReplicate(FromW, ToW / FromW, false);
2400 }
2401
2402 template<unsigned FromW, unsigned ToW>
2403 bool isNEONinvReplicate() const {
2404 checkNeonReplicateArgs(FromW, ToW);
2405 return isNEONReplicate(FromW, ToW / FromW, true);
2406 }
2407
2408 bool isNEONi32vmov() const {
2409 if (isNEONByteReplicate(4))
2410 return false; // Let it to be classified as byte-replicate case.
2411 if (!isImm())
2412 return false;
2413 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2414 // Must be a constant.
2415 if (!CE)
2416 return false;
2417 return isValidNEONi32vmovImm(CE->getValue());
2418 }
2419
2420 bool isNEONi32vmovNeg() const {
2421 if (!isImm()) return false;
2422 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2423 // Must be a constant.
2424 if (!CE) return false;
2425 return isValidNEONi32vmovImm(~CE->getValue());
2426 }
2427
2428 bool isNEONi64splat() const {
2429 if (!isImm()) return false;
2430 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2431 // Must be a constant.
2432 if (!CE) return false;
2433 uint64_t Value = CE->getValue();
2434 // i64 value with each byte being either 0 or 0xff.
2435 for (unsigned i = 0; i < 8; ++i, Value >>= 8)
2436 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
2437 return true;
2438 }
2439
2440 template<int64_t Angle, int64_t Remainder>
2441 bool isComplexRotation() const {
2442 if (!isImm()) return false;
2443
2444 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2445 if (!CE) return false;
2446 uint64_t Value = CE->getValue();
2447
2448 return (Value % Angle == Remainder && Value <= 270);
2449 }
2450
2451 bool isMVELongShift() const {
2452 if (!isImm()) return false;
2453 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2454 // Must be a constant.
2455 if (!CE) return false;
2456 uint64_t Value = CE->getValue();
2457 return Value >= 1 && Value <= 32;
2458 }
2459
2460 bool isMveSaturateOp() const {
2461 if (!isImm()) return false;
2462 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2463 if (!CE) return false;
2464 uint64_t Value = CE->getValue();
2465 return Value == 48 || Value == 64;
2466 }
2467
2468 bool isITCondCodeNoAL() const {
2469 if (!isITCondCode()) return false;
2471 return CC != ARMCC::AL;
2472 }
2473
2474 bool isITCondCodeRestrictedI() const {
2475 if (!isITCondCode())
2476 return false;
2478 return CC == ARMCC::EQ || CC == ARMCC::NE;
2479 }
2480
2481 bool isITCondCodeRestrictedS() const {
2482 if (!isITCondCode())
2483 return false;
2485 return CC == ARMCC::LT || CC == ARMCC::GT || CC == ARMCC::LE ||
2486 CC == ARMCC::GE;
2487 }
2488
2489 bool isITCondCodeRestrictedU() const {
2490 if (!isITCondCode())
2491 return false;
2493 return CC == ARMCC::HS || CC == ARMCC::HI;
2494 }
2495
2496 bool isITCondCodeRestrictedFP() const {
2497 if (!isITCondCode())
2498 return false;
2500 return CC == ARMCC::EQ || CC == ARMCC::NE || CC == ARMCC::LT ||
2501 CC == ARMCC::GT || CC == ARMCC::LE || CC == ARMCC::GE;
2502 }
2503
2504 void setVecListDPair(unsigned int DPair) {
2505 Kind = k_VectorList;
2506 VectorList.RegNum = DPair;
2507 VectorList.Count = 2;
2508 VectorList.isDoubleSpaced = false;
2509 }
2510
2511 void setVecListOneD(unsigned int DReg) {
2512 Kind = k_VectorList;
2513 VectorList.RegNum = DReg;
2514 VectorList.Count = 1;
2515 VectorList.isDoubleSpaced = false;
2516 }
2517
2518 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2519 // Add as immediates when possible. Null MCExpr = 0.
2520 if (!Expr)
2522 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2523 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2524 else
2526 }
2527
2528 void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const {
2529 assert(N == 1 && "Invalid number of operands!");
2530 addExpr(Inst, getImm());
2531 }
2532
2533 void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const {
2534 assert(N == 1 && "Invalid number of operands!");
2535 addExpr(Inst, getImm());
2536 }
2537
2538 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
2539 assert(N == 2 && "Invalid number of operands!");
2540 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2541 unsigned RegNum = getCondCode() == ARMCC::AL ? ARM::NoRegister : ARM::CPSR;
2542 Inst.addOperand(MCOperand::createReg(RegNum));
2543 }
2544
2545 void addVPTPredNOperands(MCInst &Inst, unsigned N) const {
2546 assert(N == 3 && "Invalid number of operands!");
2547 Inst.addOperand(MCOperand::createImm(unsigned(getVPTPred())));
2548 unsigned RegNum = getVPTPred() == ARMVCC::None ? ARM::NoRegister : ARM::P0;
2549 Inst.addOperand(MCOperand::createReg(RegNum));
2551 }
2552
2553 void addVPTPredROperands(MCInst &Inst, unsigned N) const {
2554 assert(N == 4 && "Invalid number of operands!");
2555 addVPTPredNOperands(Inst, N-1);
2556 MCRegister RegNum;
2557 if (getVPTPred() == ARMVCC::None) {
2558 RegNum = ARM::NoRegister;
2559 } else {
2560 unsigned NextOpIndex = Inst.getNumOperands();
2561 auto &MCID = Parser->getInstrDesc(Inst.getOpcode());
2562 int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO);
2563 assert(TiedOp >= 0 &&
2564 "Inactive register in vpred_r is not tied to an output!");
2565 RegNum = Inst.getOperand(TiedOp).getReg();
2566 }
2567 Inst.addOperand(MCOperand::createReg(RegNum));
2568 }
2569
2570 void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
2571 assert(N == 1 && "Invalid number of operands!");
2572 Inst.addOperand(MCOperand::createImm(getCoproc()));
2573 }
2574
2575 void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
2576 assert(N == 1 && "Invalid number of operands!");
2577 Inst.addOperand(MCOperand::createImm(getCoproc()));
2578 }
2579
2580 void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
2581 assert(N == 1 && "Invalid number of operands!");
2582 Inst.addOperand(MCOperand::createImm(CoprocOption.Val));
2583 }
2584
2585 void addITMaskOperands(MCInst &Inst, unsigned N) const {
2586 assert(N == 1 && "Invalid number of operands!");
2587 Inst.addOperand(MCOperand::createImm(ITMask.Mask));
2588 }
2589
2590 void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
2591 assert(N == 1 && "Invalid number of operands!");
2592 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2593 }
2594
2595 void addITCondCodeInvOperands(MCInst &Inst, unsigned N) const {
2596 assert(N == 1 && "Invalid number of operands!");
2598 }
2599
2600 void addCCOutOperands(MCInst &Inst, unsigned N) const {
2601 assert(N == 1 && "Invalid number of operands!");
2603 }
2604
2605 void addRegOperands(MCInst &Inst, unsigned N) const {
2606 assert(N == 1 && "Invalid number of operands!");
2608 }
2609
2610 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
2611 assert(N == 3 && "Invalid number of operands!");
2612 assert(isRegShiftedReg() &&
2613 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2614 Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg));
2615 Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg));
2617 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
2618 }
2619
2620 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
2621 assert(N == 2 && "Invalid number of operands!");
2622 assert(isRegShiftedImm() &&
2623 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2624 Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg));
2625 // Shift of #32 is encoded as 0 where permitted
2626 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2628 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
2629 }
2630
2631 void addShifterImmOperands(MCInst &Inst, unsigned N) const {
2632 assert(N == 1 && "Invalid number of operands!");
2633 Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) |
2634 ShifterImm.Imm));
2635 }
2636
2637 void addRegListOperands(MCInst &Inst, unsigned N) const {
2638 assert(N == 1 && "Invalid number of operands!");
2639 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2640 for (MCRegister Reg : RegList)
2642 }
2643
2644 void addRegListWithAPSROperands(MCInst &Inst, unsigned N) const {
2645 assert(N == 1 && "Invalid number of operands!");
2646 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2647 for (MCRegister Reg : RegList)
2649 }
2650
2651 void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
2652 addRegListOperands(Inst, N);
2653 }
2654
2655 void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
2656 addRegListOperands(Inst, N);
2657 }
2658
2659 void addFPSRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2660 addRegListOperands(Inst, N);
2661 }
2662
2663 void addFPDRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2664 addRegListOperands(Inst, N);
2665 }
2666
2667 void addRotImmOperands(MCInst &Inst, unsigned N) const {
2668 assert(N == 1 && "Invalid number of operands!");
2669 // Encoded as val>>3. The printer handles display as 8, 16, 24.
2670 Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3));
2671 }
2672
2673 void addModImmOperands(MCInst &Inst, unsigned N) const {
2674 assert(N == 1 && "Invalid number of operands!");
2675
2676 // Support for fixups (MCFixup)
2677 if (isImm())
2678 return addImmOperands(Inst, N);
2679
2680 Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7)));
2681 }
2682
2683 void addModImmNotOperands(MCInst &Inst, unsigned N) const {
2684 assert(N == 1 && "Invalid number of operands!");
2685 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2686 uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue());
2688 }
2689
2690 void addModImmNegOperands(MCInst &Inst, unsigned N) const {
2691 assert(N == 1 && "Invalid number of operands!");
2692 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2693 uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue());
2695 }
2696
2697 void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const {
2698 assert(N == 1 && "Invalid number of operands!");
2699 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2700 uint32_t Val = -CE->getValue();
2702 }
2703
2704 void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const {
2705 assert(N == 1 && "Invalid number of operands!");
2706 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2707 uint32_t Val = -CE->getValue();
2709 }
2710
2711 void addBitfieldOperands(MCInst &Inst, unsigned N) const {
2712 assert(N == 1 && "Invalid number of operands!");
2713 // Munge the lsb/width into a bitfield mask.
2714 unsigned lsb = Bitfield.LSB;
2715 unsigned width = Bitfield.Width;
2716 // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
2717 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2718 (32 - (lsb + width)));
2719 Inst.addOperand(MCOperand::createImm(Mask));
2720 }
2721
2722 void addImmOperands(MCInst &Inst, unsigned N) const {
2723 assert(N == 1 && "Invalid number of operands!");
2724 addExpr(Inst, getImm());
2725 }
2726
2727 void addFBits16Operands(MCInst &Inst, unsigned N) const {
2728 assert(N == 1 && "Invalid number of operands!");
2729 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2730 Inst.addOperand(MCOperand::createImm(16 - CE->getValue()));
2731 }
2732
2733 void addFBits32Operands(MCInst &Inst, unsigned N) const {
2734 assert(N == 1 && "Invalid number of operands!");
2735 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2736 Inst.addOperand(MCOperand::createImm(32 - CE->getValue()));
2737 }
2738
2739 void addFPImmOperands(MCInst &Inst, unsigned N) const {
2740 assert(N == 1 && "Invalid number of operands!");
2741 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2742 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
2744 }
2745
2746 void addImm8s4Operands(MCInst &Inst, unsigned N) const {
2747 assert(N == 1 && "Invalid number of operands!");
2748 // FIXME: We really want to scale the value here, but the LDRD/STRD
2749 // instruction don't encode operands that way yet.
2750 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2751 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2752 }
2753
2754 void addImm7s4Operands(MCInst &Inst, unsigned N) const {
2755 assert(N == 1 && "Invalid number of operands!");
2756 // FIXME: We really want to scale the value here, but the VSTR/VLDR_VSYSR
2757 // instruction don't encode operands that way yet.
2758 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2759 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2760 }
2761
2762 void addImm7Shift0Operands(MCInst &Inst, unsigned N) const {
2763 assert(N == 1 && "Invalid number of operands!");
2764 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2765 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2766 }
2767
2768 void addImm7Shift1Operands(MCInst &Inst, unsigned N) const {
2769 assert(N == 1 && "Invalid number of operands!");
2770 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2771 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2772 }
2773
2774 void addImm7Shift2Operands(MCInst &Inst, unsigned N) const {
2775 assert(N == 1 && "Invalid number of operands!");
2776 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2777 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2778 }
2779
2780 void addImm7Operands(MCInst &Inst, unsigned N) const {
2781 assert(N == 1 && "Invalid number of operands!");
2782 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2783 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2784 }
2785
2786 void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
2787 assert(N == 1 && "Invalid number of operands!");
2788 // The immediate is scaled by four in the encoding and is stored
2789 // in the MCInst as such. Lop off the low two bits here.
2790 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2791 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2792 }
2793
2794 void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
2795 assert(N == 1 && "Invalid number of operands!");
2796 // The immediate is scaled by four in the encoding and is stored
2797 // in the MCInst as such. Lop off the low two bits here.
2798 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2799 Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4)));
2800 }
2801
2802 void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
2803 assert(N == 1 && "Invalid number of operands!");
2804 // The immediate is scaled by four in the encoding and is stored
2805 // in the MCInst as such. Lop off the low two bits here.
2806 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2807 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2808 }
2809
2810 void addImm1_16Operands(MCInst &Inst, unsigned N) const {
2811 assert(N == 1 && "Invalid number of operands!");
2812 // The constant encodes as the immediate-1, and we store in the instruction
2813 // the bits as encoded, so subtract off one here.
2814 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2815 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2816 }
2817
2818 void addImm1_32Operands(MCInst &Inst, unsigned N) const {
2819 assert(N == 1 && "Invalid number of operands!");
2820 // The constant encodes as the immediate-1, and we store in the instruction
2821 // the bits as encoded, so subtract off one here.
2822 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2823 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2824 }
2825
2826 void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
2827 assert(N == 1 && "Invalid number of operands!");
2828 // The constant encodes as the immediate, except for 32, which encodes as
2829 // zero.
2830 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2831 unsigned Imm = CE->getValue();
2832 Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm)));
2833 }
2834
2835 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
2836 assert(N == 1 && "Invalid number of operands!");
2837 // An ASR value of 32 encodes as 0, so that's how we want to add it to
2838 // the instruction as well.
2839 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2840 int Val = CE->getValue();
2841 Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val));
2842 }
2843
2844 void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
2845 assert(N == 1 && "Invalid number of operands!");
2846 // The operand is actually a t2_so_imm, but we have its bitwise
2847 // negation in the assembly source, so twiddle it here.
2848 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2849 Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue()));
2850 }
2851
2852 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
2853 assert(N == 1 && "Invalid number of operands!");
2854 // The operand is actually a t2_so_imm, but we have its
2855 // negation in the assembly source, so twiddle it here.
2856 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2857 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2858 }
2859
2860 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
2861 assert(N == 1 && "Invalid number of operands!");
2862 // The operand is actually an imm0_4095, but we have its
2863 // negation in the assembly source, so twiddle it here.
2864 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2865 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2866 }
2867
2868 void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
2869 if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2870 Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2));
2871 return;
2872 }
2873 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2875 }
2876
2877 void addThumbMemPCOperands(MCInst &Inst, unsigned N) const {
2878 assert(N == 1 && "Invalid number of operands!");
2879 if (isImm()) {
2880 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2881 if (CE) {
2882 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2883 return;
2884 }
2885 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2887 return;
2888 }
2889
2890 assert(isGPRMem() && "Unknown value type!");
2891 assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!");
2892 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
2893 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2894 else
2895 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
2896 }
2897
2898 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
2899 assert(N == 1 && "Invalid number of operands!");
2900 Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt())));
2901 }
2902
2903 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2904 assert(N == 1 && "Invalid number of operands!");
2905 Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
2906 }
2907
2908 void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2909 assert(N == 1 && "Invalid number of operands!");
2910 Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt())));
2911 }
2912
2913 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
2914 assert(N == 1 && "Invalid number of operands!");
2915 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2916 }
2917
2918 void addMemNoOffsetT2Operands(MCInst &Inst, unsigned N) const {
2919 assert(N == 1 && "Invalid number of operands!");
2920 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2921 }
2922
2923 void addMemNoOffsetT2NoSpOperands(MCInst &Inst, unsigned N) const {
2924 assert(N == 1 && "Invalid number of operands!");
2925 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2926 }
2927
2928 void addMemNoOffsetTOperands(MCInst &Inst, unsigned N) const {
2929 assert(N == 1 && "Invalid number of operands!");
2930 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2931 }
2932
2933 void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
2934 assert(N == 1 && "Invalid number of operands!");
2935 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
2936 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2937 else
2938 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
2939 }
2940
2941 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
2942 assert(N == 1 && "Invalid number of operands!");
2943 assert(isImm() && "Not an immediate!");
2944
2945 // If we have an immediate that's not a constant, treat it as a label
2946 // reference needing a fixup.
2947 if (!isa<MCConstantExpr>(getImm())) {
2949 return;
2950 }
2951
2952 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2953 int Val = CE->getValue();
2955 }
2956
2957 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
2958 assert(N == 2 && "Invalid number of operands!");
2959 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2960 Inst.addOperand(MCOperand::createImm(Memory.Alignment));
2961 }
2962
2963 void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2964 addAlignedMemoryOperands(Inst, N);
2965 }
2966
2967 void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2968 addAlignedMemoryOperands(Inst, N);
2969 }
2970
2971 void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2972 addAlignedMemoryOperands(Inst, N);
2973 }
2974
2975 void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2976 addAlignedMemoryOperands(Inst, N);
2977 }
2978
2979 void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2980 addAlignedMemoryOperands(Inst, N);
2981 }
2982
2983 void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2984 addAlignedMemoryOperands(Inst, N);
2985 }
2986
2987 void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2988 addAlignedMemoryOperands(Inst, N);
2989 }
2990
2991 void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2992 addAlignedMemoryOperands(Inst, N);
2993 }
2994
2995 void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2996 addAlignedMemoryOperands(Inst, N);
2997 }
2998
2999 void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
3000 addAlignedMemoryOperands(Inst, N);
3001 }
3002
3003 void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const {
3004 addAlignedMemoryOperands(Inst, N);
3005 }
3006
3007 void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
3008 assert(N == 3 && "Invalid number of operands!");
3009 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3010 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3011 if (!Memory.OffsetRegNum) {
3012 if (!Memory.OffsetImm)
3014 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3015 int32_t Val = CE->getValue();
3017 // Special case for #-0
3018 if (Val == std::numeric_limits<int32_t>::min())
3019 Val = 0;
3020 if (Val < 0)
3021 Val = -Val;
3022 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
3024 } else
3025 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3026 } else {
3027 // For register offset, we encode the shift type and negation flag
3028 // here.
3029 int32_t Val =
3030 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3031 Memory.ShiftImm, Memory.ShiftType);
3033 }
3034 }
3035
3036 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
3037 assert(N == 2 && "Invalid number of operands!");
3038 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3039 assert(CE && "non-constant AM2OffsetImm operand!");
3040 int32_t Val = CE->getValue();
3042 // Special case for #-0
3043 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3044 if (Val < 0) Val = -Val;
3045 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
3048 }
3049
3050 void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
3051 assert(N == 3 && "Invalid number of operands!");
3052 // If we have an immediate that's not a constant, treat it as a label
3053 // reference needing a fixup. If it is a constant, it's something else
3054 // and we reject it.
3055 if (isImm()) {
3059 return;
3060 }
3061
3062 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3063 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3064 if (!Memory.OffsetRegNum) {
3065 if (!Memory.OffsetImm)
3067 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3068 int32_t Val = CE->getValue();
3070 // Special case for #-0
3071 if (Val == std::numeric_limits<int32_t>::min())
3072 Val = 0;
3073 if (Val < 0)
3074 Val = -Val;
3075 Val = ARM_AM::getAM3Opc(AddSub, Val);
3077 } else
3078 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3079 } else {
3080 // For register offset, we encode the shift type and negation flag
3081 // here.
3082 int32_t Val =
3083 ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
3085 }
3086 }
3087
3088 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
3089 assert(N == 2 && "Invalid number of operands!");
3090 if (Kind == k_PostIndexRegister) {
3091 int32_t Val =
3092 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
3093 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3095 return;
3096 }
3097
3098 // Constant offset.
3099 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
3100 int32_t Val = CE->getValue();
3102 // Special case for #-0
3103 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3104 if (Val < 0) Val = -Val;
3105 Val = ARM_AM::getAM3Opc(AddSub, Val);
3108 }
3109
3110 void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
3111 assert(N == 2 && "Invalid number of operands!");
3112 // If we have an immediate that's not a constant, treat it as a label
3113 // reference needing a fixup. If it is a constant, it's something else
3114 // and we reject it.
3115 if (isImm()) {
3118 return;
3119 }
3120
3121 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3122 if (!Memory.OffsetImm)
3124 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3125 // The lower two bits are always zero and as such are not encoded.
3126 int32_t Val = CE->getValue() / 4;
3128 // Special case for #-0
3129 if (Val == std::numeric_limits<int32_t>::min())
3130 Val = 0;
3131 if (Val < 0)
3132 Val = -Val;
3133 Val = ARM_AM::getAM5Opc(AddSub, Val);
3135 } else
3136 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3137 }
3138
3139 void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const {
3140 assert(N == 2 && "Invalid number of operands!");
3141 // If we have an immediate that's not a constant, treat it as a label
3142 // reference needing a fixup. If it is a constant, it's something else
3143 // and we reject it.
3144 if (isImm()) {
3147 return;
3148 }
3149
3150 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3151 // The lower bit is always zero and as such is not encoded.
3152 if (!Memory.OffsetImm)
3154 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3155 int32_t Val = CE->getValue() / 2;
3157 // Special case for #-0
3158 if (Val == std::numeric_limits<int32_t>::min())
3159 Val = 0;
3160 if (Val < 0)
3161 Val = -Val;
3162 Val = ARM_AM::getAM5FP16Opc(AddSub, Val);
3164 } else
3165 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3166 }
3167
3168 void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
3169 assert(N == 2 && "Invalid number of operands!");
3170 // If we have an immediate that's not a constant, treat it as a label
3171 // reference needing a fixup. If it is a constant, it's something else
3172 // and we reject it.
3173 if (isImm()) {
3176 return;
3177 }
3178
3179 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3180 addExpr(Inst, Memory.OffsetImm);
3181 }
3182
3183 void addMemImm7s4OffsetOperands(MCInst &Inst, unsigned N) const {
3184 assert(N == 2 && "Invalid number of operands!");
3185 // If we have an immediate that's not a constant, treat it as a label
3186 // reference needing a fixup. If it is a constant, it's something else
3187 // and we reject it.
3188 if (isImm()) {
3191 return;
3192 }
3193
3194 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3195 addExpr(Inst, Memory.OffsetImm);
3196 }
3197
3198 void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
3199 assert(N == 2 && "Invalid number of operands!");
3200 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3201 if (!Memory.OffsetImm)
3203 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3204 // The lower two bits are always zero and as such are not encoded.
3205 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3206 else
3207 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3208 }
3209
3210 void addMemImmOffsetOperands(MCInst &Inst, unsigned N) const {
3211 assert(N == 2 && "Invalid number of operands!");
3212 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3213 addExpr(Inst, Memory.OffsetImm);
3214 }
3215
3216 void addMemRegRQOffsetOperands(MCInst &Inst, unsigned N) const {
3217 assert(N == 2 && "Invalid number of operands!");
3218 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3219 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3220 }
3221
3222 void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3223 assert(N == 2 && "Invalid number of operands!");
3224 // If this is an immediate, it's a label reference.
3225 if (isImm()) {
3226 addExpr(Inst, getImm());
3228 return;
3229 }
3230
3231 // Otherwise, it's a normal memory reg+offset.
3232 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3233 addExpr(Inst, Memory.OffsetImm);
3234 }
3235
3236 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3237 assert(N == 2 && "Invalid number of operands!");
3238 // If this is an immediate, it's a label reference.
3239 if (isImm()) {
3240 addExpr(Inst, getImm());
3242 return;
3243 }
3244
3245 // Otherwise, it's a normal memory reg+offset.
3246 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3247 addExpr(Inst, Memory.OffsetImm);
3248 }
3249
3250 void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const {
3251 assert(N == 1 && "Invalid number of operands!");
3252 // This is container for the immediate that we will create the constant
3253 // pool from
3254 addExpr(Inst, getConstantPoolImm());
3255 }
3256
3257 void addMemTBBOperands(MCInst &Inst, unsigned N) const {
3258 assert(N == 2 && "Invalid number of operands!");
3259 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3260 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3261 }
3262
3263 void addMemTBHOperands(MCInst &Inst, unsigned N) const {
3264 assert(N == 2 && "Invalid number of operands!");
3265 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3266 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3267 }
3268
3269 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3270 assert(N == 3 && "Invalid number of operands!");
3271 unsigned Val =
3272 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3273 Memory.ShiftImm, Memory.ShiftType);
3274 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3275 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3277 }
3278
3279 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3280 assert(N == 3 && "Invalid number of operands!");
3281 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3282 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3283 Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
3284 }
3285
3286 void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
3287 assert(N == 2 && "Invalid number of operands!");
3288 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3289 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3290 }
3291
3292 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
3293 assert(N == 2 && "Invalid number of operands!");
3294 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3295 if (!Memory.OffsetImm)
3297 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3298 // The lower two bits are always zero and as such are not encoded.
3299 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3300 else
3301 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3302 }
3303
3304 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
3305 assert(N == 2 && "Invalid number of operands!");
3306 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3307 if (!Memory.OffsetImm)
3309 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3310 Inst.addOperand(MCOperand::createImm(CE->getValue() / 2));
3311 else
3312 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3313 }
3314
3315 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
3316 assert(N == 2 && "Invalid number of operands!");
3317 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3318 addExpr(Inst, Memory.OffsetImm);
3319 }
3320
3321 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
3322 assert(N == 2 && "Invalid number of operands!");
3323 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3324 if (!Memory.OffsetImm)
3326 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3327 // The lower two bits are always zero and as such are not encoded.
3328 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3329 else
3330 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3331 }
3332
3333 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
3334 assert(N == 1 && "Invalid number of operands!");
3335 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3336 assert(CE && "non-constant post-idx-imm8 operand!");
3337 int Imm = CE->getValue();
3338 bool isAdd = Imm >= 0;
3339 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3340 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
3342 }
3343
3344 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
3345 assert(N == 1 && "Invalid number of operands!");
3346 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3347 assert(CE && "non-constant post-idx-imm8s4 operand!");
3348 int Imm = CE->getValue();
3349 bool isAdd = Imm >= 0;
3350 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3351 // Immediate is scaled by 4.
3352 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
3354 }
3355
3356 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
3357 assert(N == 2 && "Invalid number of operands!");
3358 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3359 Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
3360 }
3361
3362 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
3363 assert(N == 2 && "Invalid number of operands!");
3364 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3365 // The sign, shift type, and shift amount are encoded in a single operand
3366 // using the AM2 encoding helpers.
3367 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
3368 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
3369 PostIdxReg.ShiftTy);
3371 }
3372
3373 void addPowerTwoOperands(MCInst &Inst, unsigned N) const {
3374 assert(N == 1 && "Invalid number of operands!");
3375 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3376 Inst.addOperand(MCOperand::createImm(CE->getValue()));
3377 }
3378
3379 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
3380 assert(N == 1 && "Invalid number of operands!");
3381 Inst.addOperand(MCOperand::createImm(getMSRMask()));
3382 }
3383
3384 void addBankedRegOperands(MCInst &Inst, unsigned N) const {
3385 assert(N == 1 && "Invalid number of operands!");
3386 Inst.addOperand(MCOperand::createImm(getBankedReg()));
3387 }
3388
3389 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
3390 assert(N == 1 && "Invalid number of operands!");
3391 Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
3392 }
3393
3394 void addVecListOperands(MCInst &Inst, unsigned N) const {
3395 assert(N == 1 && "Invalid number of operands!");
3396
3397 if (isAnyVectorList())
3398 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3399 else if (isDReg() && !Parser->hasMVE()) {
3400 Inst.addOperand(MCOperand::createReg(Reg.RegNum));
3401 } else if (isQReg() && !Parser->hasMVE()) {
3402 MCRegister DPair = Parser->getDRegFromQReg(Reg.RegNum);
3403 DPair = Parser->getMRI()->getMatchingSuperReg(
3404 DPair, ARM::dsub_0, &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3405 Inst.addOperand(MCOperand::createReg(DPair));
3406 } else {
3407 LLVM_DEBUG(dbgs() << "TYPE: " << Kind << "\n");
3409 "attempted to add a vector list register with wrong type!");
3410 }
3411 }
3412
3413 void addMVEVecListOperands(MCInst &Inst, unsigned N) const {
3414 assert(N == 1 && "Invalid number of operands!");
3415
3416 // When we come here, the VectorList field will identify a range
3417 // of q-registers by its base register and length, and it will
3418 // have already been error-checked to be the expected length of
3419 // range and contain only q-regs in the range q0-q7. So we can
3420 // count on the base register being in the range q0-q6 (for 2
3421 // regs) or q0-q4 (for 4)
3422 //
3423 // The MVE instructions taking a register range of this kind will
3424 // need an operand in the MQQPR or MQQQQPR class, representing the
3425 // entire range as a unit. So we must translate into that class,
3426 // by finding the index of the base register in the MQPR reg
3427 // class, and returning the super-register at the corresponding
3428 // index in the target class.
3429
3430 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3431 const MCRegisterClass *RC_out =
3432 (VectorList.Count == 2) ? &ARMMCRegisterClasses[ARM::MQQPRRegClassID]
3433 : &ARMMCRegisterClasses[ARM::MQQQQPRRegClassID];
3434
3435 unsigned I, E = RC_out->getNumRegs();
3436 for (I = 0; I < E; I++)
3437 if (RC_in->getRegister(I) == VectorList.RegNum)
3438 break;
3439 assert(I < E && "Invalid vector list start register!");
3440
3442 }
3443
3444 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
3445 assert(N == 2 && "Invalid number of operands!");
3446 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3447 Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
3448 }
3449
3450 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
3451 assert(N == 1 && "Invalid number of operands!");
3452 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3453 }
3454
3455 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
3456 assert(N == 1 && "Invalid number of operands!");
3457 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3458 }
3459
3460 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
3461 assert(N == 1 && "Invalid number of operands!");
3462 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3463 }
3464
3465 void addVectorIndex64Operands(MCInst &Inst, unsigned N) const {
3466 assert(N == 1 && "Invalid number of operands!");
3467 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3468 }
3469
3470 void addMVEVectorIndexOperands(MCInst &Inst, unsigned N) const {
3471 assert(N == 1 && "Invalid number of operands!");
3472 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3473 }
3474
3475 void addMVEPairVectorIndexOperands(MCInst &Inst, unsigned N) const {
3476 assert(N == 1 && "Invalid number of operands!");
3477 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3478 }
3479
3480 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
3481 assert(N == 1 && "Invalid number of operands!");
3482 // The immediate encodes the type of constant as well as the value.
3483 // Mask in that this is an i8 splat.
3484 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3485 Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
3486 }
3487
3488 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
3489 assert(N == 1 && "Invalid number of operands!");
3490 // The immediate encodes the type of constant as well as the value.
3491 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3492 unsigned Value = CE->getValue();
3495 }
3496
3497 void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
3498 assert(N == 1 && "Invalid number of operands!");
3499 // The immediate encodes the type of constant as well as the value.
3500 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3501 unsigned Value = CE->getValue();
3504 }
3505
3506 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
3507 assert(N == 1 && "Invalid number of operands!");
3508 // The immediate encodes the type of constant as well as the value.
3509 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3510 unsigned Value = CE->getValue();
3513 }
3514
3515 void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
3516 assert(N == 1 && "Invalid number of operands!");
3517 // The immediate encodes the type of constant as well as the value.
3518 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3519 unsigned Value = CE->getValue();
3522 }
3523
3524 void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
3525 // The immediate encodes the type of constant as well as the value.
3526 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3527 assert((Inst.getOpcode() == ARM::VMOVv8i8 ||
3528 Inst.getOpcode() == ARM::VMOVv16i8) &&
3529 "All instructions that wants to replicate non-zero byte "
3530 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3531 unsigned Value = CE->getValue();
3532 if (Inv)
3533 Value = ~Value;
3534 unsigned B = Value & 0xff;
3535 B |= 0xe00; // cmode = 0b1110
3537 }
3538
3539 void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3540 assert(N == 1 && "Invalid number of operands!");
3541 addNEONi8ReplicateOperands(Inst, true);
3542 }
3543
3544 static unsigned encodeNeonVMOVImmediate(unsigned Value) {
3545 if (Value >= 256 && Value <= 0xffff)
3546 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
3547 else if (Value > 0xffff && Value <= 0xffffff)
3548 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
3549 else if (Value > 0xffffff)
3550 Value = (Value >> 24) | 0x600;
3551 return Value;
3552 }
3553
3554 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
3555 assert(N == 1 && "Invalid number of operands!");
3556 // The immediate encodes the type of constant as well as the value.
3557 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3558 unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
3560 }
3561
3562 void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3563 assert(N == 1 && "Invalid number of operands!");
3564 addNEONi8ReplicateOperands(Inst, false);
3565 }
3566
3567 void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
3568 assert(N == 1 && "Invalid number of operands!");
3569 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3570 assert((Inst.getOpcode() == ARM::VMOVv4i16 ||
3571 Inst.getOpcode() == ARM::VMOVv8i16 ||
3572 Inst.getOpcode() == ARM::VMVNv4i16 ||
3573 Inst.getOpcode() == ARM::VMVNv8i16) &&
3574 "All instructions that want to replicate non-zero half-word "
3575 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3576 uint64_t Value = CE->getValue();
3577 unsigned Elem = Value & 0xffff;
3578 if (Elem >= 256)
3579 Elem = (Elem >> 8) | 0x200;
3580 Inst.addOperand(MCOperand::createImm(Elem));
3581 }
3582
3583 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
3584 assert(N == 1 && "Invalid number of operands!");
3585 // The immediate encodes the type of constant as well as the value.
3586 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3587 unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
3589 }
3590
3591 void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
3592 assert(N == 1 && "Invalid number of operands!");
3593 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3594 assert((Inst.getOpcode() == ARM::VMOVv2i32 ||
3595 Inst.getOpcode() == ARM::VMOVv4i32 ||
3596 Inst.getOpcode() == ARM::VMVNv2i32 ||
3597 Inst.getOpcode() == ARM::VMVNv4i32) &&
3598 "All instructions that want to replicate non-zero word "
3599 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3600 uint64_t Value = CE->getValue();
3601 unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
3602 Inst.addOperand(MCOperand::createImm(Elem));
3603 }
3604
3605 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
3606 assert(N == 1 && "Invalid number of operands!");
3607 // The immediate encodes the type of constant as well as the value.
3608 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3609 uint64_t Value = CE->getValue();
3610 unsigned Imm = 0;
3611 for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
3612 Imm |= (Value & 1) << i;
3613 }
3614 Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
3615 }
3616
3617 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
3618 assert(N == 1 && "Invalid number of operands!");
3619 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3620 Inst.addOperand(MCOperand::createImm(CE->getValue() / 90));
3621 }
3622
3623 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
3624 assert(N == 1 && "Invalid number of operands!");
3625 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3626 Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
3627 }
3628
3629 void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
3630 assert(N == 1 && "Invalid number of operands!");
3631 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3632 unsigned Imm = CE->getValue();
3633 assert((Imm == 48 || Imm == 64) && "Invalid saturate operand");
3634 Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0));
3635 }
3636
3637 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;
3638
3639 static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S,
3640 ARMAsmParser &Parser) {
3641 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3642 Op->ITMask.Mask = Mask;
3643 Op->StartLoc = S;
3644 Op->EndLoc = S;
3645 return Op;
3646 }
3647
3648 static std::unique_ptr<ARMOperand>
3649 CreateCondCode(ARMCC::CondCodes CC, SMLoc S, ARMAsmParser &Parser) {
3650 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3651 Op->CC.Val = CC;
3652 Op->StartLoc = S;
3653 Op->EndLoc = S;
3654 return Op;
3655 }
3656
3657 static std::unique_ptr<ARMOperand> CreateVPTPred(ARMVCC::VPTCodes CC, SMLoc S,
3658 ARMAsmParser &Parser) {
3659 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3660 Op->VCC.Val = CC;
3661 Op->StartLoc = S;
3662 Op->EndLoc = S;
3663 return Op;
3664 }
3665
3666 static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S,
3667 ARMAsmParser &Parser) {
3668 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3669 Op->Cop.Val = CopVal;
3670 Op->StartLoc = S;
3671 Op->EndLoc = S;
3672 return Op;
3673 }
3674
3675 static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S,
3676 ARMAsmParser &Parser) {
3677 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3678 Op->Cop.Val = CopVal;
3679 Op->StartLoc = S;
3680 Op->EndLoc = S;
3681 return Op;
3682 }
3683
3684 static std::unique_ptr<ARMOperand>
3685 CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3686 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3687 Op->Cop.Val = Val;
3688 Op->StartLoc = S;
3689 Op->EndLoc = E;
3690 return Op;
3691 }
3692
3693 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister Reg, SMLoc S,
3694 ARMAsmParser &Parser) {
3695 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3696 Op->Reg.RegNum = Reg;
3697 Op->StartLoc = S;
3698 Op->EndLoc = S;
3699 return Op;
3700 }
3701
3702 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3703 ARMAsmParser &Parser) {
3704 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3705 Op->Tok.Data = Str.data();
3706 Op->Tok.Length = Str.size();
3707 Op->StartLoc = S;
3708 Op->EndLoc = S;
3709 return Op;
3710 }
3711
3712 static std::unique_ptr<ARMOperand> CreateReg(MCRegister Reg, SMLoc S, SMLoc E,
3713 ARMAsmParser &Parser) {
3714 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3715 Op->Reg.RegNum = Reg;
3716 Op->StartLoc = S;
3717 Op->EndLoc = E;
3718 return Op;
3719 }
3720
3721 static std::unique_ptr<ARMOperand>
3722 CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, MCRegister SrcReg,
3723 MCRegister ShiftReg, unsigned ShiftImm, SMLoc S,
3724 SMLoc E, ARMAsmParser &Parser) {
3725 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3726 Op->RegShiftedReg.ShiftTy = ShTy;
3727 Op->RegShiftedReg.SrcReg = SrcReg;
3728 Op->RegShiftedReg.ShiftReg = ShiftReg;
3729 Op->RegShiftedReg.ShiftImm = ShiftImm;
3730 Op->StartLoc = S;
3731 Op->EndLoc = E;
3732 return Op;
3733 }
3734
3735 static std::unique_ptr<ARMOperand>
3736 CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, MCRegister SrcReg,
3737 unsigned ShiftImm, SMLoc S, SMLoc E,
3738 ARMAsmParser &Parser) {
3739 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3740 Op->RegShiftedImm.ShiftTy = ShTy;
3741 Op->RegShiftedImm.SrcReg = SrcReg;
3742 Op->RegShiftedImm.ShiftImm = ShiftImm;
3743 Op->StartLoc = S;
3744 Op->EndLoc = E;
3745 return Op;
3746 }
3747
3748 static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm,
3749 SMLoc S, SMLoc E,
3750 ARMAsmParser &Parser) {
3751 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3752 Op->ShifterImm.isASR = isASR;
3753 Op->ShifterImm.Imm = Imm;
3754 Op->StartLoc = S;
3755 Op->EndLoc = E;
3756 return Op;
3757 }
3758
3759 static std::unique_ptr<ARMOperand>
3760 CreateRotImm(unsigned Imm, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3761 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3762 Op->RotImm.Imm = Imm;
3763 Op->StartLoc = S;
3764 Op->EndLoc = E;
3765 return Op;
3766 }
3767
3768 static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
3769 SMLoc S, SMLoc E,
3770 ARMAsmParser &Parser) {
3771 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3772 Op->ModImm.Bits = Bits;
3773 Op->ModImm.Rot = Rot;
3774 Op->StartLoc = S;
3775 Op->EndLoc = E;
3776 return Op;
3777 }
3778
3779 static std::unique_ptr<ARMOperand>
3780 CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E,
3781 ARMAsmParser &Parser) {
3782 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3783 Op->Imm.Val = Val;
3784 Op->StartLoc = S;
3785 Op->EndLoc = E;
3786 return Op;
3787 }
3788
3789 static std::unique_ptr<ARMOperand> CreateBitfield(unsigned LSB,
3790 unsigned Width, SMLoc S,
3791 SMLoc E,
3792 ARMAsmParser &Parser) {
3793 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3794 Op->Bitfield.LSB = LSB;
3795 Op->Bitfield.Width = Width;
3796 Op->StartLoc = S;
3797 Op->EndLoc = E;
3798 return Op;
3799 }
3800
3801 static std::unique_ptr<ARMOperand>
3802 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3803 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3804 assert(Regs.size() > 0 && "RegList contains no registers?");
3805 KindTy Kind = k_RegisterList;
3806
3807 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
3808 Regs.front().second)) {
3809 if (Regs.back().second == ARM::VPR)
3810 Kind = k_FPDRegisterListWithVPR;
3811 else
3812 Kind = k_DPRRegisterList;
3813 } else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(
3814 Regs.front().second)) {
3815 if (Regs.back().second == ARM::VPR)
3816 Kind = k_FPSRegisterListWithVPR;
3817 else
3818 Kind = k_SPRRegisterList;
3819 } else if (Regs.front().second == ARM::VPR) {
3820 assert(Regs.size() == 1 &&
3821 "Register list starting with VPR expected to only contain VPR");
3822 Kind = k_FPSRegisterListWithVPR;
3823 }
3824
3825 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3826 Kind = k_RegisterListWithAPSR;
3827
3828 assert(llvm::is_sorted(Regs) && "Register list must be sorted by encoding");
3829
3830 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3831 for (const auto &P : Regs)
3832 Op->Registers.push_back(P.second);
3833
3834 Op->StartLoc = StartLoc;
3835 Op->EndLoc = EndLoc;
3836 return Op;
3837 }
3838
3839 static std::unique_ptr<ARMOperand>
3840 CreateVectorList(MCRegister Reg, unsigned Count, bool isDoubleSpaced, SMLoc S,
3841 SMLoc E, ARMAsmParser &Parser) {
3842 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3843 Op->VectorList.RegNum = Reg;
3844 Op->VectorList.Count = Count;
3845 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3846 Op->StartLoc = S;
3847 Op->EndLoc = E;
3848 return Op;
3849 }
3850
3851 static std::unique_ptr<ARMOperand>
3852 CreateVectorListAllLanes(MCRegister Reg, unsigned Count, bool isDoubleSpaced,
3853 SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3854 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3855 Op->VectorList.RegNum = Reg;
3856 Op->VectorList.Count = Count;
3857 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3858 Op->StartLoc = S;
3859 Op->EndLoc = E;
3860 return Op;
3861 }
3862
3863 static std::unique_ptr<ARMOperand>
3864 CreateVectorListIndexed(MCRegister Reg, unsigned Count, unsigned Index,
3865 bool isDoubleSpaced, SMLoc S, SMLoc E,
3866 ARMAsmParser &Parser) {
3867 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3868 Op->VectorList.RegNum = Reg;
3869 Op->VectorList.Count = Count;
3870 Op->VectorList.LaneIndex = Index;
3871 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3872 Op->StartLoc = S;
3873 Op->EndLoc = E;
3874 return Op;
3875 }
3876
3877 static std::unique_ptr<ARMOperand> CreateVectorIndex(unsigned Idx, SMLoc S,
3878 SMLoc E, MCContext &Ctx,
3879 ARMAsmParser &Parser) {
3880 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3881 Op->VectorIndex.Val = Idx;
3882 Op->StartLoc = S;
3883 Op->EndLoc = E;
3884 return Op;
3885 }
3886
3887 static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S,
3888 SMLoc E, ARMAsmParser &Parser) {
3889 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3890 Op->Imm.Val = Val;
3891 Op->StartLoc = S;
3892 Op->EndLoc = E;
3893 return Op;
3894 }
3895
3896 static std::unique_ptr<ARMOperand>
3897 CreateMem(MCRegister BaseReg, const MCExpr *OffsetImm, MCRegister OffsetReg,
3898 ARM_AM::ShiftOpc ShiftType, unsigned ShiftImm, unsigned Alignment,
3899 bool isNegative, SMLoc S, SMLoc E, ARMAsmParser &Parser,
3900 SMLoc AlignmentLoc = SMLoc()) {
3901 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3902 Op->Memory.BaseRegNum = BaseReg;
3903 Op->Memory.OffsetImm = OffsetImm;
3904 Op->Memory.OffsetRegNum = OffsetReg;
3905 Op->Memory.ShiftType = ShiftType;
3906 Op->Memory.ShiftImm = ShiftImm;
3907 Op->Memory.Alignment = Alignment;
3908 Op->Memory.isNegative = isNegative;
3909 Op->StartLoc = S;
3910 Op->EndLoc = E;
3911 Op->AlignmentLoc = AlignmentLoc;
3912 return Op;
3913 }
3914
3915 static std::unique_ptr<ARMOperand>
3916 CreatePostIdxReg(MCRegister Reg, bool isAdd, ARM_AM::ShiftOpc ShiftTy,
3917 unsigned ShiftImm, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3918 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3919 Op->PostIdxReg.RegNum = Reg;
3920 Op->PostIdxReg.isAdd = isAdd;
3921 Op->PostIdxReg.ShiftTy = ShiftTy;
3922 Op->PostIdxReg.ShiftImm = ShiftImm;
3923 Op->StartLoc = S;
3924 Op->EndLoc = E;
3925 return Op;
3926 }
3927
3928 static std::unique_ptr<ARMOperand>
3929 CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3930 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3931 Op->MBOpt.Val = Opt;
3932 Op->StartLoc = S;
3933 Op->EndLoc = S;
3934 return Op;
3935 }
3936
3937 static std::unique_ptr<ARMOperand>
3938 CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S,
3939 ARMAsmParser &Parser) {
3940 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3941 Op->ISBOpt.Val = Opt;
3942 Op->StartLoc = S;
3943 Op->EndLoc = S;
3944 return Op;
3945 }
3946
3947 static std::unique_ptr<ARMOperand>
3948 CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S,
3949 ARMAsmParser &Parser) {
3950 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3951 Op->TSBOpt.Val = Opt;
3952 Op->StartLoc = S;
3953 Op->EndLoc = S;
3954 return Op;
3955 }
3956
3957 static std::unique_ptr<ARMOperand>
3958 CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S, ARMAsmParser &Parser) {
3959 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3960 Op->IFlags.Val = IFlags;
3961 Op->StartLoc = S;
3962 Op->EndLoc = S;
3963 return Op;
3964 }
3965
3966 static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S,
3967 ARMAsmParser &Parser) {
3968 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3969 Op->MMask.Val = MMask;
3970 Op->StartLoc = S;
3971 Op->EndLoc = S;
3972 return Op;
3973 }
3974
3975 static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S,
3976 ARMAsmParser &Parser) {
3977 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3978 Op->BankedReg.Val = Reg;
3979 Op->StartLoc = S;
3980 Op->EndLoc = S;
3981 return Op;
3982 }
3983};
3984
3985} // end anonymous namespace.
3986
3987void ARMOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
3988 auto RegName = [](MCRegister Reg) {
3989 if (Reg)
3991 else
3992 return "noreg";
3993 };
3994
3995 switch (Kind) {
3996 case k_CondCode:
3997 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
3998 break;
3999 case k_VPTPred:
4000 OS << "<ARMVCC::" << ARMVPTPredToString(getVPTPred()) << ">";
4001 break;
4002 case k_CCOut:
4003 OS << "<ccout " << RegName(getReg()) << ">";
4004 break;
4005 case k_ITCondMask: {
4006 static const char *const MaskStr[] = {
4007 "(invalid)", "(tttt)", "(ttt)", "(ttte)",
4008 "(tt)", "(ttet)", "(tte)", "(ttee)",
4009 "(t)", "(tett)", "(tet)", "(tete)",
4010 "(te)", "(teet)", "(tee)", "(teee)",
4011 };
4012 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4013 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
4014 break;
4015 }
4016 case k_CoprocNum:
4017 OS << "<coprocessor number: " << getCoproc() << ">";
4018 break;
4019 case k_CoprocReg:
4020 OS << "<coprocessor register: " << getCoproc() << ">";
4021 break;
4022 case k_CoprocOption:
4023 OS << "<coprocessor option: " << CoprocOption.Val << ">";
4024 break;
4025 case k_MSRMask:
4026 OS << "<mask: " << getMSRMask() << ">";
4027 break;
4028 case k_BankedReg:
4029 OS << "<banked reg: " << getBankedReg() << ">";
4030 break;
4031 case k_Immediate:
4032 MAI.printExpr(OS, *getImm());
4033 break;
4034 case k_MemBarrierOpt:
4035 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
4036 break;
4037 case k_InstSyncBarrierOpt:
4038 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
4039 break;
4040 case k_TraceSyncBarrierOpt:
4041 OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
4042 break;
4043 case k_Memory:
4044 OS << "<memory";
4045 if (Memory.BaseRegNum)
4046 OS << " base:" << RegName(Memory.BaseRegNum);
4047 if (Memory.OffsetImm) {
4048 OS << " offset-imm:";
4049 MAI.printExpr(OS, *Memory.OffsetImm);
4050 }
4051 if (Memory.OffsetRegNum)
4052 OS << " offset-reg:" << (Memory.isNegative ? "-" : "")
4053 << RegName(Memory.OffsetRegNum);
4054 if (Memory.ShiftType != ARM_AM::no_shift) {
4055 OS << " shift-type:" << ARM_AM::getShiftOpcStr(Memory.ShiftType);
4056 OS << " shift-imm:" << Memory.ShiftImm;
4057 }
4058 if (Memory.Alignment)
4059 OS << " alignment:" << Memory.Alignment;
4060 OS << ">";
4061 break;
4062 case k_PostIndexRegister:
4063 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
4064 << RegName(PostIdxReg.RegNum);
4065 if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
4066 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
4067 << PostIdxReg.ShiftImm;
4068 OS << ">";
4069 break;
4070 case k_ProcIFlags: {
4071 OS << "<ARM_PROC::";
4072 unsigned IFlags = getProcIFlags();
4073 for (int i=2; i >= 0; --i)
4074 if (IFlags & (1 << i))
4075 OS << ARM_PROC::IFlagsToString(1 << i);
4076 OS << ">";
4077 break;
4078 }
4079 case k_Register:
4080 OS << "<register " << RegName(getReg()) << ">";
4081 break;
4082 case k_ShifterImmediate:
4083 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
4084 << " #" << ShifterImm.Imm << ">";
4085 break;
4086 case k_ShiftedRegister:
4087 OS << "<so_reg_reg " << RegName(RegShiftedReg.SrcReg) << " "
4088 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) << " "
4089 << RegName(RegShiftedReg.ShiftReg) << ">";
4090 break;
4091 case k_ShiftedImmediate:
4092 OS << "<so_reg_imm " << RegName(RegShiftedImm.SrcReg) << " "
4093 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) << " #"
4094 << RegShiftedImm.ShiftImm << ">";
4095 break;
4096 case k_RotateImmediate:
4097 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
4098 break;
4099 case k_ModifiedImmediate:
4100 OS << "<mod_imm #" << ModImm.Bits << ", #"
4101 << ModImm.Rot << ")>";
4102 break;
4103 case k_ConstantPoolImmediate:
4104 OS << "<constant_pool_imm #";
4105 MAI.printExpr(OS, *getConstantPoolImm());
4106 break;
4107 case k_BitfieldDescriptor:
4108 OS << "<bitfield " << "lsb: " << Bitfield.LSB
4109 << ", width: " << Bitfield.Width << ">";
4110 break;
4111 case k_RegisterList:
4112 case k_RegisterListWithAPSR:
4113 case k_DPRRegisterList:
4114 case k_SPRRegisterList:
4115 case k_FPSRegisterListWithVPR:
4116 case k_FPDRegisterListWithVPR: {
4117 OS << "<register_list ";
4118
4119 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4120 for (auto I = RegList.begin(), E = RegList.end(); I != E;) {
4121 OS << RegName(*I);
4122 if (++I < E) OS << ", ";
4123 }
4124
4125 OS << ">";
4126 break;
4127 }
4128 case k_VectorList:
4129 OS << "<vector_list " << VectorList.Count << " * "
4130 << RegName(VectorList.RegNum) << ">";
4131 break;
4132 case k_VectorListAllLanes:
4133 OS << "<vector_list(all lanes) " << VectorList.Count << " * "
4134 << RegName(VectorList.RegNum) << ">";
4135 break;
4136 case k_VectorListIndexed:
4137 OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
4138 << VectorList.Count << " * " << RegName(VectorList.RegNum) << ">";
4139 break;
4140 case k_Token:
4141 OS << "'" << getToken() << "'";
4142 break;
4143 case k_VectorIndex:
4144 OS << "<vectorindex " << getVectorIndex() << ">";
4145 break;
4146 }
4147}
4148
4149/// @name Auto-generated Match Functions
4150/// {
4151
4153
4154/// }
4155
4156static bool isDataTypeToken(StringRef Tok) {
4157 static const DenseSet<StringRef> DataTypes{
4158 ".8", ".16", ".32", ".64", ".i8", ".i16", ".i32", ".i64",
4159 ".u8", ".u16", ".u32", ".u64", ".s8", ".s16", ".s32", ".s64",
4160 ".p8", ".p16", ".f32", ".f64", ".f", ".d"};
4161 return DataTypes.contains(Tok);
4162}
4163
4164static unsigned getMnemonicOpsEndInd(const OperandVector &Operands) {
4165 unsigned MnemonicOpsEndInd = 1;
4166 // Special case for CPS which has a Mnemonic side token for possibly storing
4167 // ie/id variant
4168 if (Operands[0]->isToken() &&
4169 static_cast<ARMOperand &>(*Operands[0]).getToken() == "cps") {
4170 if (Operands.size() > 1 && Operands[1]->isImm() &&
4171 static_cast<ARMOperand &>(*Operands[1]).getImm()->getKind() ==
4174 static_cast<ARMOperand &>(*Operands[1]).getImm())
4175 ->getValue() == ARM_PROC::IE ||
4177 static_cast<ARMOperand &>(*Operands[1]).getImm())
4178 ->getValue() == ARM_PROC::ID))
4179 ++MnemonicOpsEndInd;
4180 }
4181
4182 // In some circumstances the condition code moves to the right
4183 bool RHSCondCode = false;
4184 while (MnemonicOpsEndInd < Operands.size()) {
4185 auto Op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
4186 // Special case for it instructions which have a condition code on the RHS
4187 if (Op.isITMask()) {
4188 RHSCondCode = true;
4189 MnemonicOpsEndInd++;
4190 } else if (Op.isToken() &&
4191 (
4192 // There are several special cases not covered by
4193 // isDataTypeToken
4194 Op.getToken() == ".w" || Op.getToken() == ".bf16" ||
4195 Op.getToken() == ".p64" || Op.getToken() == ".f16" ||
4196 isDataTypeToken(Op.getToken()))) {
4197 // In the mnemonic operators the cond code must always precede the data
4198 // type. So we can now safely assume any subsequent cond code is on the
4199 // RHS. As is the case for VCMP and VPT.
4200 RHSCondCode = true;
4201 MnemonicOpsEndInd++;
4202 }
4203 // Skip all mnemonic operator types
4204 else if (Op.isCCOut() || (Op.isCondCode() && !RHSCondCode) ||
4205 Op.isVPTPred() || (Op.isToken() && Op.getToken() == ".w"))
4206 MnemonicOpsEndInd++;
4207 else
4208 break;
4209 }
4210 return MnemonicOpsEndInd;
4211}
4212
4213bool ARMAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
4214 SMLoc &EndLoc) {
4215 const AsmToken &Tok = getParser().getTok();
4216 StartLoc = Tok.getLoc();
4217 EndLoc = Tok.getEndLoc();
4218 Reg = tryParseRegister();
4219
4220 return !Reg;
4221}
4222
4223ParseStatus ARMAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
4224 SMLoc &EndLoc) {
4225 if (parseRegister(Reg, StartLoc, EndLoc))
4226 return ParseStatus::NoMatch;
4227 return ParseStatus::Success;
4228}
4229
4230/// Try to parse a register name. The token must be an Identifier when called,
4231/// and if it is a register name the token is eaten and the register is
4232/// returned. Otherwise return an invalid MCRegister.
4233MCRegister ARMAsmParser::tryParseRegister(bool AllowOutOfBoundReg) {
4234 MCAsmParser &Parser = getParser();
4235 const AsmToken &Tok = Parser.getTok();
4236 if (Tok.isNot(AsmToken::Identifier))
4237 return MCRegister();
4238
4239 std::string lowerCase = Tok.getString().lower();
4240 MCRegister Reg = MatchRegisterName(lowerCase);
4241 if (!Reg) {
4242 Reg = StringSwitch<MCRegister>(lowerCase)
4243 .Case("r13", ARM::SP)
4244 .Case("r14", ARM::LR)
4245 .Case("r15", ARM::PC)
4246 .Case("ip", ARM::R12)
4247 // Additional register name aliases for 'gas' compatibility.
4248 .Case("a1", ARM::R0)
4249 .Case("a2", ARM::R1)
4250 .Case("a3", ARM::R2)
4251 .Case("a4", ARM::R3)
4252 .Case("v1", ARM::R4)
4253 .Case("v2", ARM::R5)
4254 .Case("v3", ARM::R6)
4255 .Case("v4", ARM::R7)
4256 .Case("v5", ARM::R8)
4257 .Case("v6", ARM::R9)
4258 .Case("v7", ARM::R10)
4259 .Case("v8", ARM::R11)
4260 .Case("sb", ARM::R9)
4261 .Case("sl", ARM::R10)
4262 .Case("fp", ARM::R11)
4263 .Default(MCRegister());
4264 }
4265 if (!Reg) {
4266 // Check for aliases registered via .req. Canonicalize to lower case.
4267 // That's more consistent since register names are case insensitive, and
4268 // it's how the original entry was passed in from MC/MCParser/AsmParser.
4269 auto Entry = RegisterReqs.find(lowerCase);
4270 // If no match, return failure.
4271 if (Entry == RegisterReqs.end())
4272 return MCRegister();
4273 Parser.Lex(); // Eat identifier token.
4274 return Entry->getValue();
4275 }
4276
4277 // Some FPUs only have 16 D registers, so D16-D31 are invalid
4278 if (!AllowOutOfBoundReg && !hasD32() && Reg >= ARM::D16 && Reg <= ARM::D31)
4279 return MCRegister();
4280
4281 Parser.Lex(); // Eat identifier token.
4282
4283 return Reg;
4284}
4285
4286std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4287 MCAsmParser &Parser = getParser();
4288 const AsmToken &Tok = Parser.getTok();
4289 if (Tok.isNot(AsmToken::Identifier))
4290 return std::nullopt;
4291
4292 std::string lowerCase = Tok.getString().lower();
4293 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4294 .Case("asl", ARM_AM::lsl)
4295 .Case("lsl", ARM_AM::lsl)
4296 .Case("lsr", ARM_AM::lsr)
4297 .Case("asr", ARM_AM::asr)
4298 .Case("ror", ARM_AM::ror)
4299 .Case("rrx", ARM_AM::rrx)
4300 .Default(std::nullopt);
4301}
4302
4303// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0.
4304// If a recoverable error occurs, return 1. If an irrecoverable error
4305// occurs, return -1. An irrecoverable error is one where tokens have been
4306// consumed in the process of trying to parse the shifter (i.e., when it is
4307// indeed a shifter operand, but malformed).
4308int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
4309 MCAsmParser &Parser = getParser();
4310 SMLoc S = Parser.getTok().getLoc();
4311
4312 auto ShiftTyOpt = tryParseShiftToken();
4313 if (ShiftTyOpt == std::nullopt)
4314 return 1;
4315 auto ShiftTy = ShiftTyOpt.value();
4316
4317 Parser.Lex(); // Eat the operator.
4318
4319 // The source register for the shift has already been added to the
4320 // operand list, so we need to pop it off and combine it into the shifted
4321 // register operand instead.
4322 std::unique_ptr<ARMOperand> PrevOp(
4323 (ARMOperand *)Operands.pop_back_val().release());
4324 if (!PrevOp->isReg())
4325 return Error(PrevOp->getStartLoc(), "shift must be of a register");
4326 MCRegister SrcReg = PrevOp->getReg();
4327
4328 SMLoc EndLoc;
4329 int64_t Imm = 0;
4330 MCRegister ShiftReg;
4331 if (ShiftTy == ARM_AM::rrx) {
4332 // RRX Doesn't have an explicit shift amount. The encoder expects
4333 // the shift register to be the same as the source register. Seems odd,
4334 // but OK.
4335 ShiftReg = SrcReg;
4336 } else {
4337 // Figure out if this is shifted by a constant or a register (for non-RRX).
4338 if (Parser.getTok().is(AsmToken::Hash) ||
4339 Parser.getTok().is(AsmToken::Dollar)) {
4340 Parser.Lex(); // Eat hash.
4341 SMLoc ImmLoc = Parser.getTok().getLoc();
4342 const MCExpr *ShiftExpr = nullptr;
4343 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4344 Error(ImmLoc, "invalid immediate shift value");
4345 return -1;
4346 }
4347 // The expression must be evaluatable as an immediate.
4348 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
4349 if (!CE) {
4350 Error(ImmLoc, "invalid immediate shift value");
4351 return -1;
4352 }
4353 // Range check the immediate.
4354 // lsl, ror: 0 <= imm <= 31
4355 // lsr, asr: 0 <= imm <= 32
4356 Imm = CE->getValue();
4357 if (Imm < 0 ||
4358 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
4359 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
4360 Error(ImmLoc, "immediate shift value out of range");
4361 return -1;
4362 }
4363 // shift by zero is a nop. Always send it through as lsl.
4364 // ('as' compatibility)
4365 if (Imm == 0)
4366 ShiftTy = ARM_AM::lsl;
4367 } else if (Parser.getTok().is(AsmToken::Identifier)) {
4368 SMLoc L = Parser.getTok().getLoc();
4369 EndLoc = Parser.getTok().getEndLoc();
4370 ShiftReg = tryParseRegister();
4371 if (!ShiftReg) {
4372 Error(L, "expected immediate or register in shift operand");
4373 return -1;
4374 }
4375 } else {
4376 Error(Parser.getTok().getLoc(),
4377 "expected immediate or register in shift operand");
4378 return -1;
4379 }
4380 }
4381
4382 if (ShiftReg && ShiftTy != ARM_AM::rrx)
4383 Operands.push_back(ARMOperand::CreateShiftedRegister(
4384 ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *this));
4385 else
4386 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4387 S, EndLoc, *this));
4388
4389 return 0;
4390}
4391
4392/// Try to parse a register name. The token must be an Identifier when called.
4393/// If it's a register, an AsmOperand is created. Another AsmOperand is created
4394/// if there is a "writeback". 'true' if it's not a register.
4395///
4396/// TODO this is likely to change to allow different register types and or to
4397/// parse for a specific register type.
4398bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) {
4399 MCAsmParser &Parser = getParser();
4400 SMLoc RegStartLoc = Parser.getTok().getLoc();
4401 SMLoc RegEndLoc = Parser.getTok().getEndLoc();
4402 MCRegister Reg = tryParseRegister();
4403 if (!Reg)
4404 return true;
4405
4406 Operands.push_back(ARMOperand::CreateReg(Reg, RegStartLoc, RegEndLoc, *this));
4407
4408 const AsmToken &ExclaimTok = Parser.getTok();
4409 if (ExclaimTok.is(AsmToken::Exclaim)) {
4410 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
4411 ExclaimTok.getLoc(), *this));
4412 Parser.Lex(); // Eat exclaim token
4413 return false;
4414 }
4415
4416 // Also check for an index operand. This is only legal for vector registers,
4417 // but that'll get caught OK in operand matching, so we don't need to
4418 // explicitly filter everything else out here.
4419 if (Parser.getTok().is(AsmToken::LBrac)) {
4420 SMLoc SIdx = Parser.getTok().getLoc();
4421 Parser.Lex(); // Eat left bracket token.
4422
4423 const MCExpr *ImmVal;
4424 if (getParser().parseExpression(ImmVal))
4425 return true;
4426 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
4427 if (!MCE)
4428 return TokError("immediate value expected for vector index");
4429
4430 if (Parser.getTok().isNot(AsmToken::RBrac))
4431 return Error(Parser.getTok().getLoc(), "']' expected");
4432
4433 SMLoc E = Parser.getTok().getEndLoc();
4434 Parser.Lex(); // Eat right bracket token.
4435
4436 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), SIdx, E,
4437 getContext(), *this));
4438 }
4439
4440 return false;
4441}
4442
4443/// MatchCoprocessorOperandName - Try to parse an coprocessor related
4444/// instruction with a symbolic operand name.
4445/// We accept "crN" syntax for GAS compatibility.
4446/// <operand-name> ::= <prefix><number>
4447/// If CoprocOp is 'c', then:
4448/// <prefix> ::= c | cr
4449/// If CoprocOp is 'p', then :
4450/// <prefix> ::= p
4451/// <number> ::= integer in range [0, 15]
4452static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
4453 // Use the same layout as the tablegen'erated register name matcher. Ugly,
4454 // but efficient.
4455 if (Name.size() < 2 || Name[0] != CoprocOp)
4456 return -1;
4457 Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front();
4458
4459 switch (Name.size()) {
4460 default: return -1;
4461 case 1:
4462 switch (Name[0]) {
4463 default: return -1;
4464 case '0': return 0;
4465 case '1': return 1;
4466 case '2': return 2;
4467 case '3': return 3;
4468 case '4': return 4;
4469 case '5': return 5;
4470 case '6': return 6;
4471 case '7': return 7;
4472 case '8': return 8;
4473 case '9': return 9;
4474 }
4475 case 2:
4476 if (Name[0] != '1')
4477 return -1;
4478 switch (Name[1]) {
4479 default: return -1;
4480 // CP10 and CP11 are VFP/NEON and so vector instructions should be used.
4481 // However, old cores (v5/v6) did use them in that way.
4482 case '0': return 10;
4483 case '1': return 11;
4484 case '2': return 12;
4485 case '3': return 13;
4486 case '4': return 14;
4487 case '5': return 15;
4488 }
4489 }
4490}
4491
4492/// parseITCondCode - Try to parse a condition code for an IT instruction.
4493ParseStatus ARMAsmParser::parseITCondCode(OperandVector &Operands) {
4494 MCAsmParser &Parser = getParser();
4495 SMLoc S = Parser.getTok().getLoc();
4496 const AsmToken &Tok = Parser.getTok();
4497 if (!Tok.is(AsmToken::Identifier))
4498 return ParseStatus::NoMatch;
4499 unsigned CC = ARMCondCodeFromString(Tok.getString());
4500 if (CC == ~0U)
4501 return ParseStatus::NoMatch;
4502 Parser.Lex(); // Eat the token.
4503
4504 Operands.push_back(
4505 ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S, *this));
4506
4507 return ParseStatus::Success;
4508}
4509
4510/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
4511/// token must be an Identifier when called, and if it is a coprocessor
4512/// number, the token is eaten and the operand is added to the operand list.
4513ParseStatus ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
4514 MCAsmParser &Parser = getParser();
4515 SMLoc S = Parser.getTok().getLoc();
4516 const AsmToken &Tok = Parser.getTok();
4517 if (Tok.isNot(AsmToken::Identifier))
4518 return ParseStatus::NoMatch;
4519
4520 int Num = MatchCoprocessorOperandName(Tok.getString().lower(), 'p');
4521 if (Num == -1)
4522 return ParseStatus::NoMatch;
4523 if (!isValidCoprocessorNumber(Num, getSTI().getFeatureBits()))
4524 return ParseStatus::NoMatch;
4525
4526 Parser.Lex(); // Eat identifier token.
4527 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *this));
4528 return ParseStatus::Success;
4529}
4530
4531/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
4532/// token must be an Identifier when called, and if it is a coprocessor
4533/// number, the token is eaten and the operand is added to the operand list.
4534ParseStatus ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) {
4535 MCAsmParser &Parser = getParser();
4536 SMLoc S = Parser.getTok().getLoc();
4537 const AsmToken &Tok = Parser.getTok();
4538 if (Tok.isNot(AsmToken::Identifier))
4539 return ParseStatus::NoMatch;
4540
4541 int Reg = MatchCoprocessorOperandName(Tok.getString().lower(), 'c');
4542 if (Reg == -1)
4543 return ParseStatus::NoMatch;
4544
4545 Parser.Lex(); // Eat identifier token.
4546 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S, *this));
4547 return ParseStatus::Success;
4548}
4549
4550/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
4551/// coproc_option : '{' imm0_255 '}'
4552ParseStatus ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) {
4553 MCAsmParser &Parser = getParser();
4554 SMLoc S = Parser.getTok().getLoc();
4555
4556 // If this isn't a '{', this isn't a coprocessor immediate operand.
4557 if (Parser.getTok().isNot(AsmToken::LCurly))
4558 return ParseStatus::NoMatch;
4559 Parser.Lex(); // Eat the '{'
4560
4561 const MCExpr *Expr;
4562 SMLoc Loc = Parser.getTok().getLoc();
4563 if (getParser().parseExpression(Expr))
4564 return Error(Loc, "illegal expression");
4565 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
4566 if (!CE || CE->getValue() < 0 || CE->getValue() > 255)
4567 return Error(Loc,
4568 "coprocessor option must be an immediate in range [0, 255]");
4569 int Val = CE->getValue();
4570
4571 // Check for and consume the closing '}'
4572 if (Parser.getTok().isNot(AsmToken::RCurly))
4573 return ParseStatus::Failure;
4574 SMLoc E = Parser.getTok().getEndLoc();
4575 Parser.Lex(); // Eat the '}'
4576
4577 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E, *this));
4578 return ParseStatus::Success;
4579}
4580
4581// For register list parsing, we need to map from raw GPR register numbering
4582// to the enumeration values. The enumeration values aren't sorted by
4583// register number due to our using "sp", "lr" and "pc" as canonical names.
4585 // If this is a GPR, we need to do it manually, otherwise we can rely
4586 // on the sort ordering of the enumeration since the other reg-classes
4587 // are sane.
4588 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4589 return Reg + 1;
4590 switch (Reg.id()) {
4591 default: llvm_unreachable("Invalid GPR number!");
4592 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2;
4593 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4;
4594 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6;
4595 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8;
4596 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10;
4597 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
4598 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR;
4599 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0;
4600 }
4601}
4602
4603// Insert an <Encoding, Register> pair in an ordered vector. Return true on
4604// success, or false, if duplicate encoding found.
4605static bool
4606insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
4607 unsigned Enc, MCRegister Reg) {
4608 Regs.emplace_back(Enc, Reg);
4609 for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
4610 if (J->first == Enc) {
4611 Regs.erase(J.base());
4612 return false;
4613 }
4614 if (J->first < Enc)
4615 break;
4616 std::swap(*I, *J);
4617 }
4618 return true;
4619}
4620
4621/// Parse a register list.
4622bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
4623 bool AllowRAAC, bool IsLazyLoadStore,
4624 bool IsVSCCLRM) {
4625 MCAsmParser &Parser = getParser();
4626 if (Parser.getTok().isNot(AsmToken::LCurly))
4627 return TokError("Token is not a Left Curly Brace");
4628 SMLoc S = Parser.getTok().getLoc();
4629 Parser.Lex(); // Eat '{' token.
4630 SMLoc RegLoc = Parser.getTok().getLoc();
4631
4632 // Check the first register in the list to see what register class
4633 // this is a list of.
4634 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4635 MCRegister Reg = tryParseRegister(AllowOutOfBoundReg);
4636 if (!Reg)
4637 return Error(RegLoc, "register expected");
4638 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
4639 return Error(RegLoc, "pseudo-register not allowed");
4640 // The reglist instructions have at most 32 registers, so reserve
4641 // space for that many.
4642 int EReg = 0;
4644
4645 // Single-precision VSCCLRM can have double-precision registers in the
4646 // register list. When VSCCLRMAdjustEncoding is true then we've switched from
4647 // single-precision to double-precision and we pretend that these registers
4648 // are encoded as S32 onwards, which we can do by adding 16 to the encoding
4649 // value.
4650 bool VSCCLRMAdjustEncoding = false;
4651
4652 // Allow Q regs and just interpret them as the two D sub-registers.
4653 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4654 Reg = getDRegFromQReg(Reg);
4655 EReg = MRI->getEncodingValue(Reg);
4656 Registers.emplace_back(EReg, Reg);
4657 Reg = Reg + 1;
4658 }
4659 const MCRegisterClass *RC;
4660 if (Reg == ARM::RA_AUTH_CODE ||
4661 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4662 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
4663 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
4664 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
4665 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
4666 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
4667 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
4668 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4669 else if (Reg == ARM::VPR)
4670 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4671 else
4672 return Error(RegLoc, "invalid register in register list");
4673
4674 // Store the register.
4675 EReg = MRI->getEncodingValue(Reg);
4676 Registers.emplace_back(EReg, Reg);
4677
4678 // This starts immediately after the first register token in the list,
4679 // so we can see either a comma or a minus (range separator) as a legal
4680 // next token.
4681 while (Parser.getTok().is(AsmToken::Comma) ||
4682 Parser.getTok().is(AsmToken::Minus)) {
4683 if (Parser.getTok().is(AsmToken::Minus)) {
4684 if (Reg == ARM::RA_AUTH_CODE)
4685 return Error(RegLoc, "pseudo-register not allowed");
4686 Parser.Lex(); // Eat the minus.
4687 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4688 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4689 if (!EndReg)
4690 return Error(AfterMinusLoc, "register expected");
4691 if (EndReg == ARM::RA_AUTH_CODE)
4692 return Error(AfterMinusLoc, "pseudo-register not allowed");
4693 // Allow Q regs and just interpret them as the two D sub-registers.
4694 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
4695 EndReg = getDRegFromQReg(EndReg) + 1;
4696 // If the register is the same as the start reg, there's nothing
4697 // more to do.
4698 if (Reg == EndReg)
4699 continue;
4700 // The register must be in the same register class as the first.
4701 if (!RC->contains(Reg))
4702 return Error(AfterMinusLoc, "invalid register in register list");
4703 // Ranges must go from low to high.
4704 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
4705 return Error(AfterMinusLoc, "bad range in register list");
4706
4707 // Add all the registers in the range to the register list.
4708 while (Reg != EndReg) {
4710 EReg = MRI->getEncodingValue(Reg);
4711 if (VSCCLRMAdjustEncoding)
4712 EReg += 16;
4713 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4714 Warning(AfterMinusLoc, StringRef("duplicated register (") +
4716 ") in register list");
4717 }
4718 }
4719 continue;
4720 }
4721 Parser.Lex(); // Eat the comma.
4722 RegLoc = Parser.getTok().getLoc();
4723 MCRegister OldReg = Reg;
4724 int EOldReg = EReg;
4725 const AsmToken RegTok = Parser.getTok();
4726 Reg = tryParseRegister(AllowOutOfBoundReg);
4727 if (!Reg)
4728 return Error(RegLoc, "register expected");
4729 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
4730 return Error(RegLoc, "pseudo-register not allowed");
4731 // Allow Q regs and just interpret them as the two D sub-registers.
4732 bool isQReg = false;
4733 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4734 Reg = getDRegFromQReg(Reg);
4735 isQReg = true;
4736 }
4737 if (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg) &&
4738 RC->getID() == ARMMCRegisterClasses[ARM::GPRRegClassID].getID() &&
4739 ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg)) {
4740 // switch the register classes, as GPRwithAPSRnospRegClassID is a partial
4741 // subset of GPRRegClassId except it contains APSR as well.
4742 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4743 }
4744 if (Reg == ARM::VPR &&
4745 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4746 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4747 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
4748 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4749 EReg = MRI->getEncodingValue(Reg);
4750 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4751 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4752 ") in register list");
4753 }
4754 continue;
4755 }
4756 // VSCCLRM can switch from single-precision to double-precision only when
4757 // S31 is followed by D16.
4758 if (IsVSCCLRM && OldReg == ARM::S31 && Reg == ARM::D16) {
4759 VSCCLRMAdjustEncoding = true;
4760 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4761 }
4762 // The register must be in the same register class as the first.
4763 if ((Reg == ARM::RA_AUTH_CODE &&
4764 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) ||
4765 (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg)))
4766 return Error(RegLoc, "invalid register in register list");
4767 // In most cases, the list must be monotonically increasing. An
4768 // exception is CLRM, which is order-independent anyway, so
4769 // there's no potential for confusion if you write clrm {r2,r1}
4770 // instead of clrm {r1,r2}.
4771 EReg = MRI->getEncodingValue(Reg);
4772 if (VSCCLRMAdjustEncoding)
4773 EReg += 16;
4774 if (EnforceOrder && EReg < EOldReg) {
4775 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
4776 Warning(RegLoc, "register list not in ascending order");
4777 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
4778 return Error(RegLoc, "register list not in ascending order");
4779 }
4780 // VFP register lists must also be contiguous.
4781 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
4782 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
4783 EReg != EOldReg + 1)
4784 return Error(RegLoc, "non-contiguous register range");
4785
4786 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4787 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4788 ") in register list");
4789 }
4790 if (isQReg) {
4791 Reg = Reg + 1;
4792 EReg = MRI->getEncodingValue(Reg);
4793 Registers.emplace_back(EReg, Reg);
4794 }
4795 }
4796
4797 if (Parser.getTok().isNot(AsmToken::RCurly))
4798 return Error(Parser.getTok().getLoc(), "'}' expected");
4799 SMLoc E = Parser.getTok().getEndLoc();
4800 Parser.Lex(); // Eat '}' token.
4801
4802 // Push the register list operand.
4803 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E, *this));
4804
4805 // The ARM system instruction variants for LDM/STM have a '^' token here.
4806 if (Parser.getTok().is(AsmToken::Caret)) {
4807 Operands.push_back(
4808 ARMOperand::CreateToken("^", Parser.getTok().getLoc(), *this));
4809 Parser.Lex(); // Eat '^' token.
4810 }
4811
4812 return false;
4813}
4814
4815// Helper function to parse the lane index for vector lists.
4816ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4817 unsigned &Index, SMLoc &EndLoc) {
4818 MCAsmParser &Parser = getParser();
4819 Index = 0; // Always return a defined index value.
4820 if (Parser.getTok().is(AsmToken::LBrac)) {
4821 Parser.Lex(); // Eat the '['.
4822 if (Parser.getTok().is(AsmToken::RBrac)) {
4823 // "Dn[]" is the 'all lanes' syntax.
4824 LaneKind = AllLanes;
4825 EndLoc = Parser.getTok().getEndLoc();
4826 Parser.Lex(); // Eat the ']'.
4827 return ParseStatus::Success;
4828 }
4829
4830 // There's an optional '#' token here. Normally there wouldn't be, but
4831 // inline assemble puts one in, and it's friendly to accept that.
4832 if (Parser.getTok().is(AsmToken::Hash))
4833 Parser.Lex(); // Eat '#' or '$'.
4834
4835 const MCExpr *LaneIndex;
4836 SMLoc Loc = Parser.getTok().getLoc();
4837 if (getParser().parseExpression(LaneIndex))
4838 return Error(Loc, "illegal expression");
4839 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
4840 if (!CE)
4841 return Error(Loc, "lane index must be empty or an integer");
4842 if (Parser.getTok().isNot(AsmToken::RBrac))
4843 return Error(Parser.getTok().getLoc(), "']' expected");
4844 EndLoc = Parser.getTok().getEndLoc();
4845 Parser.Lex(); // Eat the ']'.
4846 int64_t Val = CE->getValue();
4847
4848 // FIXME: Make this range check context sensitive for .8, .16, .32.
4849 if (Val < 0 || Val > 7)
4850 return Error(Parser.getTok().getLoc(), "lane index out of range");
4851 Index = Val;
4852 LaneKind = IndexedLane;
4853 return ParseStatus::Success;
4854 }
4855 LaneKind = NoLanes;
4856 return ParseStatus::Success;
4857}
4858
4859// parse a vector register list
4860ParseStatus ARMAsmParser::parseVectorList(OperandVector &Operands) {
4861 MCAsmParser &Parser = getParser();
4862 VectorLaneTy LaneKind;
4863 unsigned LaneIndex;
4864 SMLoc S = Parser.getTok().getLoc();
4865 // As an extension (to match gas), support a plain D register or Q register
4866 // (without encosing curly braces) as a single or double entry list,
4867 // respectively.
4868 // If there is no lane supplied, just parse as a register and
4869 // use the custom matcher to convert to list if necessary
4870 if (!hasMVE() && Parser.getTok().is(AsmToken::Identifier)) {
4871 SMLoc E = Parser.getTok().getEndLoc();
4872 MCRegister Reg = tryParseRegister();
4873 if (!Reg)
4874 return ParseStatus::NoMatch;
4875 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
4876 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex, E);
4877 if (!Res.isSuccess())
4878 return Res;
4879 switch (LaneKind) {
4880 case NoLanes:
4881 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4882 break;
4883 case AllLanes:
4884 Operands.push_back(
4885 ARMOperand::CreateVectorListAllLanes(Reg, 1, false, S, E, *this));
4886 break;
4887 case IndexedLane:
4888 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4889 Reg, 1, LaneIndex, false, S, E, *this));
4890 break;
4891 }
4892 return ParseStatus::Success;
4893 }
4894 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4895 Reg = getDRegFromQReg(Reg);
4896 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex, E);
4897 if (!Res.isSuccess())
4898 return Res;
4899 switch (LaneKind) {
4900 case NoLanes:
4901 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4902 break;
4903 case AllLanes:
4904 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
4905 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
4906 Operands.push_back(
4907 ARMOperand::CreateVectorListAllLanes(Reg, 2, false, S, E, *this));
4908 break;
4909 case IndexedLane:
4910 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4911 Reg, 2, LaneIndex, false, S, E, *this));
4912 break;
4913 }
4914 return ParseStatus::Success;
4915 }
4916 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4917 return ParseStatus::Success;
4918 }
4919
4920 if (Parser.getTok().isNot(AsmToken::LCurly))
4921 return ParseStatus::NoMatch;
4922
4923 Parser.Lex(); // Eat '{' token.
4924 SMLoc RegLoc = Parser.getTok().getLoc();
4925
4926 MCRegister Reg = tryParseRegister();
4927 if (!Reg)
4928 return Error(RegLoc, "register expected");
4929 unsigned Count = 1;
4930 int Spacing = 0;
4931 MCRegister FirstReg = Reg;
4932
4933 if (hasMVE() && !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg))
4934 return Error(Parser.getTok().getLoc(),
4935 "vector register in range Q0-Q7 expected");
4936 // The list is of D registers, but we also allow Q regs and just interpret
4937 // them as the two D sub-registers.
4938 else if (!hasMVE() && ARMMCRegisterClasses[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() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
4965 EndReg = getDRegFromQReg(EndReg) + 1;
4966 // If the register is the same as the start reg, there's nothing
4967 // more to do.
4968 if (Reg == EndReg)
4969 continue;
4970 // The register must be in the same register class as the first.
4971 if ((hasMVE() &&
4972 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(EndReg)) ||
4973 (!hasMVE() &&
4974 !ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)))
4975 return Error(AfterMinusLoc, "invalid register in register list");
4976 // Ranges must go from low to high.
4977 if (Reg > EndReg)
4978 return Error(AfterMinusLoc, "bad range in register list");
4979 // Parse the lane specifier if present.
4980 VectorLaneTy NextLaneKind;
4981 unsigned NextLaneIndex;
4982 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
4983 return ParseStatus::Failure;
4984 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4985 return Error(AfterMinusLoc, "mismatched lane index in register list");
4986
4987 // Add all the registers in the range to the register list.
4988 Count += EndReg - Reg;
4989 Reg = EndReg;
4990 continue;
4991 }
4992 Parser.Lex(); // Eat the comma.
4993 RegLoc = Parser.getTok().getLoc();
4994 MCRegister OldReg = Reg;
4995 Reg = tryParseRegister();
4996 if (!Reg)
4997 return Error(RegLoc, "register expected");
4998
4999 if (hasMVE()) {
5000 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg))
5001 return Error(RegLoc, "vector register in range Q0-Q7 expected");
5002 Spacing = 1;
5003 }
5004 // vector register lists must be contiguous.
5005 // It's OK to use the enumeration values directly here rather, as the
5006 // VFP register classes have the enum sorted properly.
5007 //
5008 // The list is of D registers, but we also allow Q regs and just interpret
5009 // them as the two D sub-registers.
5010 else if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
5011 if (!Spacing)
5012 Spacing = 1; // Register range implies a single spaced list.
5013 else if (Spacing == 2)
5014 return Error(
5015 RegLoc,
5016 "invalid register in double-spaced list (must be 'D' register')");
5017 Reg = getDRegFromQReg(Reg);
5018 if (Reg != OldReg + 1)
5019 return Error(RegLoc, "non-contiguous register range");
5020 Reg = Reg + 1;
5021 Count += 2;
5022 // Parse the lane specifier if present.
5023 VectorLaneTy NextLaneKind;
5024 unsigned NextLaneIndex;
5025 SMLoc LaneLoc = Parser.getTok().getLoc();
5026 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
5027 return ParseStatus::Failure;
5028 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5029 return Error(LaneLoc, "mismatched lane index in register list");
5030 continue;
5031 }
5032 // Normal D register.
5033 // Figure out the register spacing (single or double) of the list if
5034 // we don't know it already.
5035 if (!Spacing)
5036 Spacing = 1 + (Reg == OldReg + 2);
5037
5038 // Just check that it's contiguous and keep going.
5039 if (Reg != OldReg + Spacing)
5040 return Error(RegLoc, "non-contiguous register range");
5041 ++Count;
5042 // Parse the lane specifier if present.
5043 VectorLaneTy NextLaneKind;
5044 unsigned NextLaneIndex;
5045 SMLoc EndLoc = Parser.getTok().getLoc();
5046 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
5047 return ParseStatus::Failure;
5048 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5049 return Error(EndLoc, "mismatched lane index in register list");
5050 }
5051
5052 if (Parser.getTok().isNot(AsmToken::RCurly))
5053 return Error(Parser.getTok().getLoc(), "'}' expected");
5054 E = Parser.getTok().getEndLoc();
5055 Parser.Lex(); // Eat '}' token.
5056
5057 switch (LaneKind) {
5058 case NoLanes:
5059 case AllLanes: {
5060 // Two-register operands have been converted to the
5061 // composite register classes.
5062 if (Count == 2 && !hasMVE()) {
5063 const MCRegisterClass *RC = (Spacing == 1) ?
5064 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
5065 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
5066 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
5067 }
5068 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5069 ARMOperand::CreateVectorListAllLanes);
5070 Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E, *this));
5071 break;
5072 }
5073 case IndexedLane:
5074 Operands.push_back(ARMOperand::CreateVectorListIndexed(
5075 FirstReg, Count, LaneIndex, (Spacing == 2), S, E, *this));
5076 break;
5077 }
5078 return ParseStatus::Success;
5079}
5080
5081/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
5082ParseStatus ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
5083 MCAsmParser &Parser = getParser();
5084 SMLoc S = Parser.getTok().getLoc();
5085 const AsmToken &Tok = Parser.getTok();
5086 unsigned Opt;
5087
5088 if (Tok.is(AsmToken::Identifier)) {
5089 StringRef OptStr = Tok.getString();
5090
5091 Opt = StringSwitch<unsigned>(OptStr.lower())
5092 .Case("sy", ARM_MB::SY)
5093 .Case("st", ARM_MB::ST)
5094 .Case("ld", ARM_MB::LD)
5095 .Case("sh", ARM_MB::ISH)
5096 .Case("ish", ARM_MB::ISH)
5097 .Case("shst", ARM_MB::ISHST)
5098 .Case("ishst", ARM_MB::ISHST)
5099 .Case("ishld", ARM_MB::ISHLD)
5100 .Case("nsh", ARM_MB::NSH)
5101 .Case("un", ARM_MB::NSH)
5102 .Case("nshst", ARM_MB::NSHST)
5103 .Case("nshld", ARM_MB::NSHLD)
5104 .Case("unst", ARM_MB::NSHST)
5105 .Case("osh", ARM_MB::OSH)
5106 .Case("oshst", ARM_MB::OSHST)
5107 .Case("oshld", ARM_MB::OSHLD)
5108 .Default(~0U);
5109
5110 // ishld, oshld, nshld and ld are only available from ARMv8.
5111 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD ||
5112 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD))
5113 Opt = ~0U;
5114
5115 if (Opt == ~0U)
5116 return ParseStatus::NoMatch;
5117
5118 Parser.Lex(); // Eat identifier token.
5119 } else if (Tok.is(AsmToken::Hash) ||
5120 Tok.is(AsmToken::Dollar) ||
5121 Tok.is(AsmToken::Integer)) {
5122 if (Parser.getTok().isNot(AsmToken::Integer))
5123 Parser.Lex(); // Eat '#' or '$'.
5124 SMLoc Loc = Parser.getTok().getLoc();
5125
5126 const MCExpr *MemBarrierID;
5127 if (getParser().parseExpression(MemBarrierID))
5128 return Error(Loc, "illegal expression");
5129
5130 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
5131 if (!CE)
5132 return Error(Loc, "constant expression expected");
5133
5134 int Val = CE->getValue();
5135 if (Val & ~0xf)
5136 return Error(Loc, "immediate value out of range");
5137
5138 Opt = ARM_MB::RESERVED_0 + Val;
5139 } else
5140 return Error(Parser.getTok().getLoc(),
5141 "expected an immediate or barrier type");
5142
5143 Operands.push_back(
5144 ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S, *this));
5145 return ParseStatus::Success;
5146}
5147
5148ParseStatus
5149ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) {
5150 MCAsmParser &Parser = getParser();
5151 SMLoc S = Parser.getTok().getLoc();
5152 const AsmToken &Tok = Parser.getTok();
5153
5154 if (Tok.isNot(AsmToken::Identifier))
5155 return ParseStatus::NoMatch;
5156
5157 if (!Tok.getString().equals_insensitive("csync"))
5158 return ParseStatus::NoMatch;
5159
5160 Parser.Lex(); // Eat identifier token.
5161
5162 Operands.push_back(
5163 ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S, *this));
5164 return ParseStatus::Success;
5165}
5166
5167/// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
5168ParseStatus
5169ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
5170 MCAsmParser &Parser = getParser();
5171 SMLoc S = Parser.getTok().getLoc();
5172 const AsmToken &Tok = Parser.getTok();
5173 unsigned Opt;
5174
5175 if (Tok.is(AsmToken::Identifier)) {
5176 StringRef OptStr = Tok.getString();
5177
5178 if (OptStr.equals_insensitive("sy"))
5179 Opt = ARM_ISB::SY;
5180 else
5181 return ParseStatus::NoMatch;
5182
5183 Parser.Lex(); // Eat identifier token.
5184 } else if (Tok.is(AsmToken::Hash) ||
5185 Tok.is(AsmToken::Dollar) ||
5186 Tok.is(AsmToken::Integer)) {
5187 if (Parser.getTok().isNot(AsmToken::Integer))
5188 Parser.Lex(); // Eat '#' or '$'.
5189 SMLoc Loc = Parser.getTok().getLoc();
5190
5191 const MCExpr *ISBarrierID;
5192 if (getParser().parseExpression(ISBarrierID))
5193 return Error(Loc, "illegal expression");
5194
5195 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID);
5196 if (!CE)
5197 return Error(Loc, "constant expression expected");
5198
5199 int Val = CE->getValue();
5200 if (Val & ~0xf)
5201 return Error(Loc, "immediate value out of range");
5202
5203 Opt = ARM_ISB::RESERVED_0 + Val;
5204 } else
5205 return Error(Parser.getTok().getLoc(),
5206 "expected an immediate or barrier type");
5207
5208 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
5209 (ARM_ISB::InstSyncBOpt)Opt, S, *this));
5210 return ParseStatus::Success;
5211}
5212
5213/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
5214ParseStatus ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {
5215 MCAsmParser &Parser = getParser();
5216 SMLoc S = Parser.getTok().getLoc();
5217 const AsmToken &Tok = Parser.getTok();
5218 if (!Tok.is(AsmToken::Identifier))
5219 return ParseStatus::NoMatch;
5220 StringRef IFlagsStr = Tok.getString();
5221
5222 // An iflags string of "none" is interpreted to mean that none of the AIF
5223 // bits are set. Not a terribly useful instruction, but a valid encoding.
5224 unsigned IFlags = 0;
5225 if (IFlagsStr != "none") {
5226 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
5227 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1).lower())
5228 .Case("a", ARM_PROC::A)
5229 .Case("i", ARM_PROC::I)
5230 .Case("f", ARM_PROC::F)
5231 .Default(~0U);
5232
5233 // If some specific iflag is already set, it means that some letter is
5234 // present more than once, this is not acceptable.
5235 if (Flag == ~0U || (IFlags & Flag))
5236 return ParseStatus::NoMatch;
5237
5238 IFlags |= Flag;
5239 }
5240 }
5241
5242 Parser.Lex(); // Eat identifier token.
5243 Operands.push_back(
5244 ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S, *this));
5245 return ParseStatus::Success;
5246}
5247
5248/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
5249ParseStatus ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {
5250 // Don't parse two MSR registers in a row
5251 if (static_cast<ARMOperand &>(*Operands.back()).isMSRMask() ||
5252 static_cast<ARMOperand &>(*Operands.back()).isBankedReg())
5253 return ParseStatus::NoMatch;
5254 MCAsmParser &Parser = getParser();
5255 SMLoc S = Parser.getTok().getLoc();
5256 const AsmToken &Tok = Parser.getTok();
5257
5258 if (Tok.is(AsmToken::Integer)) {
5259 int64_t Val = Tok.getIntVal();
5260 if (Val > 255 || Val < 0) {
5261 return ParseStatus::NoMatch;
5262 }
5263 unsigned SYSmvalue = Val & 0xFF;
5264 Parser.Lex();
5265 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this));
5266 return ParseStatus::Success;
5267 }
5268
5269 if (!Tok.is(AsmToken::Identifier))
5270 return ParseStatus::NoMatch;
5271 StringRef Mask = Tok.getString();
5272
5273 if (isMClass()) {
5274 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower());
5275 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5276 return ParseStatus::NoMatch;
5277
5278 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5279
5280 Parser.Lex(); // Eat identifier token.
5281 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this));
5282 return ParseStatus::Success;
5283 }
5284
5285 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
5286 size_t Start = 0, Next = Mask.find('_');
5287 StringRef Flags = "";
5288 std::string SpecReg = Mask.slice(Start, Next).lower();
5289 if (Next != StringRef::npos)
5290 Flags = Mask.substr(Next + 1);
5291
5292 // FlagsVal contains the complete mask:
5293 // 3-0: Mask
5294 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5295 unsigned FlagsVal = 0;
5296
5297 if (SpecReg == "apsr") {
5298 FlagsVal = StringSwitch<unsigned>(Flags)
5299 .Case("nzcvq", 0x8) // same as CPSR_f
5300 .Case("g", 0x4) // same as CPSR_s
5301 .Case("nzcvqg", 0xc) // same as CPSR_fs
5302 .Default(~0U);
5303
5304 if (FlagsVal == ~0U) {
5305 if (!Flags.empty())
5306 return ParseStatus::NoMatch;
5307 else
5308 FlagsVal = 8; // No flag
5309 }
5310 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
5311 // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
5312 if (Flags == "all" || Flags == "")
5313 Flags = "fc";
5314 for (int i = 0, e = Flags.size(); i != e; ++i) {
5315 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
5316 .Case("c", 1)
5317 .Case("x", 2)
5318 .Case("s", 4)
5319 .Case("f", 8)
5320 .Default(~0U);
5321
5322 // If some specific flag is already set, it means that some letter is
5323 // present more than once, this is not acceptable.
5324 if (Flag == ~0U || (FlagsVal & Flag))
5325 return ParseStatus::NoMatch;
5326 FlagsVal |= Flag;
5327 }
5328 } else // No match for special register.
5329 return ParseStatus::NoMatch;
5330
5331 // Special register without flags is NOT equivalent to "fc" flags.
5332 // NOTE: This is a divergence from gas' behavior. Uncommenting the following
5333 // two lines would enable gas compatibility at the expense of breaking
5334 // round-tripping.
5335 //
5336 // if (!FlagsVal)
5337 // FlagsVal = 0x9;
5338
5339 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5340 if (SpecReg == "spsr")
5341 FlagsVal |= 16;
5342
5343 Parser.Lex(); // Eat identifier token.
5344 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *this));
5345 return ParseStatus::Success;
5346}
5347
5348/// parseBankedRegOperand - Try to parse a banked register (e.g. "lr_irq") for
5349/// use in the MRS/MSR instructions added to support virtualization.
5350ParseStatus ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
5351 // Don't parse two Banked registers in a row
5352 if (static_cast<ARMOperand &>(*Operands.back()).isBankedReg() ||
5353 static_cast<ARMOperand &>(*Operands.back()).isMSRMask())
5354 return ParseStatus::NoMatch;
5355 MCAsmParser &Parser = getParser();
5356 SMLoc S = Parser.getTok().getLoc();
5357 const AsmToken &Tok = Parser.getTok();
5358 if (!Tok.is(AsmToken::Identifier))
5359 return ParseStatus::NoMatch;
5360 StringRef RegName = Tok.getString();
5361
5362 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.lower());
5363 if (!TheReg)
5364 return ParseStatus::NoMatch;
5365 unsigned Encoding = TheReg->Encoding;
5366
5367 Parser.Lex(); // Eat identifier token.
5368 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S, *this));
5369 return ParseStatus::Success;
5370}
5371
5372// FIXME: Unify the different methods for handling shift operators
5373// and use TableGen matching mechanisms to do the validation rather than
5374// separate parsing paths.
5375ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands,
5376 ARM_AM::ShiftOpc Op, int Low, int High) {
5377 MCAsmParser &Parser = getParser();
5378 auto ShiftCodeOpt = tryParseShiftToken();
5379
5380 if (!ShiftCodeOpt.has_value())
5381 return ParseStatus::NoMatch;
5382 auto ShiftCode = ShiftCodeOpt.value();
5383
5384 // The wrong shift code has been provided. Can error here as has matched the
5385 // correct operand in this case.
5386 if (ShiftCode != Op)
5387 return Error(Parser.getTok().getLoc(),
5388 ARM_AM::getShiftOpcStr(Op) + " operand expected.");
5389
5390 Parser.Lex(); // Eat shift type token.
5391
5392 // There must be a '#' and a shift amount.
5393 if (Parser.getTok().isNot(AsmToken::Hash) &&
5394 Parser.getTok().isNot(AsmToken::Dollar))
5395 return ParseStatus::NoMatch;
5396 Parser.Lex(); // Eat hash token.
5397
5398 const MCExpr *ShiftAmount;
5399 SMLoc Loc = Parser.getTok().getLoc();
5400 SMLoc EndLoc;
5401 if (getParser().parseExpression(ShiftAmount, EndLoc))
5402 return Error(Loc, "illegal expression");
5403 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5404 if (!CE)
5405 return Error(Loc, "constant expression expected");
5406 int Val = CE->getValue();
5407 if (Val < Low || Val > High)
5408 return Error(Loc, "immediate value out of range");
5409
5410 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *this));
5411
5412 return ParseStatus::Success;
5413}
5414
5415ParseStatus ARMAsmParser::parseSetEndImm(OperandVector &Operands) {
5416 MCAsmParser &Parser = getParser();
5417 const AsmToken &Tok = Parser.getTok();
5418 SMLoc S = Tok.getLoc();
5419 if (Tok.isNot(AsmToken::Identifier))
5420 return Error(S, "'be' or 'le' operand expected");
5421 int Val = StringSwitch<int>(Tok.getString().lower())
5422 .Case("be", 1)
5423 .Case("le", 0)
5424 .Default(-1);
5425 Parser.Lex(); // Eat the token.
5426
5427 if (Val == -1)
5428 return Error(S, "'be' or 'le' operand expected");
5429 Operands.push_back(ARMOperand::CreateImm(
5430 MCConstantExpr::create(Val, getContext()), S, Tok.getEndLoc(), *this));
5431 return ParseStatus::Success;
5432}
5433
5434/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
5435/// instructions. Legal values are:
5436/// lsl #n 'n' in [0,31]
5437/// asr #n 'n' in [1,32]
5438/// n == 32 encoded as n == 0.
5439ParseStatus ARMAsmParser::parseShifterImm(OperandVector &Operands) {
5440 MCAsmParser &Parser = getParser();
5441 const AsmToken &Tok = Parser.getTok();
5442 SMLoc S = Tok.getLoc();
5443 if (Tok.isNot(AsmToken::Identifier))
5444 return ParseStatus::NoMatch;
5445 StringRef ShiftName = Tok.getString();
5446 bool isASR;
5447 if (ShiftName == "lsl" || ShiftName == "LSL")
5448 isASR = false;
5449 else if (ShiftName == "asr" || ShiftName == "ASR")
5450 isASR = true;
5451 else
5452 return ParseStatus::NoMatch;
5453 Parser.Lex(); // Eat the operator.
5454
5455 // A '#' and a shift amount.
5456 if (Parser.getTok().isNot(AsmToken::Hash) &&
5457 Parser.getTok().isNot(AsmToken::Dollar))
5458 return Error(Parser.getTok().getLoc(), "'#' expected");
5459 Parser.Lex(); // Eat hash token.
5460 SMLoc ExLoc = Parser.getTok().getLoc();
5461
5462 const MCExpr *ShiftAmount;
5463 SMLoc EndLoc;
5464 if (getParser().parseExpression(ShiftAmount, EndLoc))
5465 return Error(ExLoc, "malformed shift expression");
5466 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5467 if (!CE)
5468 return Error(ExLoc, "shift amount must be an immediate");
5469
5470 int64_t Val = CE->getValue();
5471 if (isASR) {
5472 // Shift amount must be in [1,32]
5473 if (Val < 1 || Val > 32)
5474 return Error(ExLoc, "'asr' shift amount must be in range [1,32]");
5475 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
5476 if (isThumb() && Val == 32)
5477 return Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode");
5478 if (Val == 32) Val = 0;
5479 } else {
5480 // Shift amount must be in [1,32]
5481 if (Val < 0 || Val > 31)
5482 return Error(ExLoc, "'lsr' shift amount must be in range [0,31]");
5483 }
5484
5485 Operands.push_back(
5486 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *this));
5487
5488 return ParseStatus::Success;
5489}
5490
5491/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
5492/// of instructions. Legal values are:
5493/// ror #n 'n' in {0, 8, 16, 24}
5494ParseStatus ARMAsmParser::parseRotImm(OperandVector &Operands) {
5495 MCAsmParser &Parser = getParser();
5496 const AsmToken &Tok = Parser.getTok();
5497 SMLoc S = Tok.getLoc();
5498 if (Tok.isNot(AsmToken::Identifier))
5499 return ParseStatus::NoMatch;
5500 StringRef ShiftName = Tok.getString();
5501 if (ShiftName != "ror" && ShiftName != "ROR")
5502 return ParseStatus::NoMatch;
5503 Parser.Lex(); // Eat the operator.
5504
5505 // A '#' and a rotate amount.
5506 if (Parser.getTok().isNot(AsmToken::Hash) &&
5507 Parser.getTok().isNot(AsmToken::Dollar))
5508 return Error(Parser.getTok().getLoc(), "'#' expected");
5509 Parser.Lex(); // Eat hash token.
5510 SMLoc ExLoc = Parser.getTok().getLoc();
5511
5512 const MCExpr *ShiftAmount;
5513 SMLoc EndLoc;
5514 if (getParser().parseExpression(ShiftAmount, EndLoc))
5515 return Error(ExLoc, "malformed rotate expression");
5516 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5517 if (!CE)
5518 return Error(ExLoc, "rotate amount must be an immediate");
5519
5520 int64_t Val = CE->getValue();
5521 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
5522 // normally, zero is represented in asm by omitting the rotate operand
5523 // entirely.
5524 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5525 return Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24");
5526
5527 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *this));
5528
5529 return ParseStatus::Success;
5530}
5531
5532ParseStatus ARMAsmParser::parseModImm(OperandVector &Operands) {
5533 MCAsmParser &Parser = getParser();
5534 AsmLexer &Lexer = getLexer();
5535 int64_t Imm1, Imm2;
5536
5537 SMLoc S = Parser.getTok().getLoc();
5538
5539 // 1) A mod_imm operand can appear in the place of a register name:
5540 // add r0, #mod_imm
5541 // add r0, r0, #mod_imm
5542 // to correctly handle the latter, we bail out as soon as we see an
5543 // identifier.
5544 //
5545 // 2) Similarly, we do not want to parse into complex operands:
5546 // mov r0, #mod_imm
5547 // mov r0, :lower16:(_foo)
5548 if (Parser.getTok().is(AsmToken::Identifier) ||
5549 Parser.getTok().is(AsmToken::Colon))
5550 return ParseStatus::NoMatch;
5551
5552 // Hash (dollar) is optional as per the ARMARM
5553 if (Parser.getTok().is(AsmToken::Hash) ||
5554 Parser.getTok().is(AsmToken::Dollar)) {
5555 // Avoid parsing into complex operands (#:)
5556 if (Lexer.peekTok().is(AsmToken::Colon))
5557 return ParseStatus::NoMatch;
5558
5559 // Eat the hash (dollar)
5560 Parser.Lex();
5561 }
5562
5563 SMLoc Sx1, Ex1;
5564 Sx1 = Parser.getTok().getLoc();
5565 const MCExpr *Imm1Exp;
5566 if (getParser().parseExpression(Imm1Exp, Ex1))
5567 return Error(Sx1, "malformed expression");
5568
5569 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
5570
5571 if (CE) {
5572 // Immediate must fit within 32-bits
5573 Imm1 = CE->getValue();
5574 int Enc = ARM_AM::getSOImmVal(Imm1);
5575 if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) {
5576 // We have a match!
5577 Operands.push_back(ARMOperand::CreateModImm(
5578 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *this));
5579 return ParseStatus::Success;
5580 }
5581
5582 // We have parsed an immediate which is not for us, fallback to a plain
5583 // immediate. This can happen for instruction aliases. For an example,
5584 // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
5585 // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
5586 // instruction with a mod_imm operand. The alias is defined such that the
5587 // parser method is shared, that's why we have to do this here.
5588 if (Parser.getTok().is(AsmToken::EndOfStatement)) {
5589 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this));
5590 return ParseStatus::Success;
5591 }
5592 } else {
5593 // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
5594 // MCFixup). Fallback to a plain immediate.
5595 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this));
5596 return ParseStatus::Success;
5597 }
5598
5599 // From this point onward, we expect the input to be a (#bits, #rot) pair
5600 if (Parser.getTok().isNot(AsmToken::Comma))
5601 return Error(Sx1,
5602 "expected modified immediate operand: #[0, 255], #even[0-30]");
5603
5604 if (Imm1 & ~0xFF)
5605 return Error(Sx1, "immediate operand must a number in the range [0, 255]");
5606
5607 // Eat the comma
5608 Parser.Lex();
5609
5610 // Repeat for #rot
5611 SMLoc Sx2, Ex2;
5612 Sx2 = Parser.getTok().getLoc();
5613
5614 // Eat the optional hash (dollar)
5615 if (Parser.getTok().is(AsmToken::Hash) ||
5616 Parser.getTok().is(AsmToken::Dollar))
5617 Parser.Lex();
5618
5619 const MCExpr *Imm2Exp;
5620 if (getParser().parseExpression(Imm2Exp, Ex2))
5621 return Error(Sx2, "malformed expression");
5622
5623 CE = dyn_cast<MCConstantExpr>(Imm2Exp);
5624
5625 if (CE) {
5626 Imm2 = CE->getValue();
5627 if (!(Imm2 & ~0x1E)) {
5628 // We have a match!
5629 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *this));
5630 return ParseStatus::Success;
5631 }
5632 return Error(Sx2,
5633 "immediate operand must an even number in the range [0, 30]");
5634 } else {
5635 return Error(Sx2, "constant expression expected");
5636 }
5637}
5638
5639ParseStatus ARMAsmParser::parseBitfield(OperandVector &Operands) {
5640 MCAsmParser &Parser = getParser();
5641 SMLoc S = Parser.getTok().getLoc();
5642 // The bitfield descriptor is really two operands, the LSB and the width.
5643 if (Parser.getTok().isNot(AsmToken::Hash) &&
5644 Parser.getTok().isNot(AsmToken::Dollar))
5645 return ParseStatus::NoMatch;
5646 Parser.Lex(); // Eat hash token.
5647
5648 const MCExpr *LSBExpr;
5649 SMLoc E = Parser.getTok().getLoc();
5650 if (getParser().parseExpression(LSBExpr))
5651 return Error(E, "malformed immediate expression");
5652 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
5653 if (!CE)
5654 return Error(E, "'lsb' operand must be an immediate");
5655
5656 int64_t LSB = CE->getValue();
5657 // The LSB must be in the range [0,31]
5658 if (LSB < 0 || LSB > 31)
5659 return Error(E, "'lsb' operand must be in the range [0,31]");
5660 E = Parser.getTok().getLoc();
5661
5662 // Expect another immediate operand.
5663 if (Parser.getTok().isNot(AsmToken::Comma))
5664 return Error(Parser.getTok().getLoc(), "too few operands");
5665 Parser.Lex(); // Eat hash token.
5666 if (Parser.getTok().isNot(AsmToken::Hash) &&
5667 Parser.getTok().isNot(AsmToken::Dollar))
5668 return Error(Parser.getTok().getLoc(), "'#' expected");
5669 Parser.Lex(); // Eat hash token.
5670
5671 const MCExpr *WidthExpr;
5672 SMLoc EndLoc;
5673 if (getParser().parseExpression(WidthExpr, EndLoc))
5674 return Error(E, "malformed immediate expression");
5675 CE = dyn_cast<MCConstantExpr>(WidthExpr);
5676 if (!CE)
5677 return Error(E, "'width' operand must be an immediate");
5678
5679 int64_t Width = CE->getValue();
5680 // The LSB must be in the range [1,32-lsb]
5681 if (Width < 1 || Width > 32 - LSB)
5682 return Error(E, "'width' operand must be in the range [1,32-lsb]");
5683
5684 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *this));
5685
5686 return ParseStatus::Success;
5687}
5688
5689ParseStatus ARMAsmParser::parsePostIdxReg(OperandVector &Operands) {
5690 // Check for a post-index addressing register operand. Specifically:
5691 // postidx_reg := '+' register {, shift}
5692 // | '-' register {, shift}
5693 // | register {, shift}
5694
5695 // This method must return ParseStatus::NoMatch without consuming any tokens
5696 // in the case where there is no match, as other alternatives take other
5697 // parse methods.
5698 MCAsmParser &Parser = getParser();
5699 AsmToken Tok = Parser.getTok();
5700 SMLoc S = Tok.getLoc();
5701 bool haveEaten = false;
5702 bool isAdd = true;
5703 if (Tok.is(AsmToken::Plus)) {
5704 Parser.Lex(); // Eat the '+' token.
5705 haveEaten = true;
5706 } else if (Tok.is(AsmToken::Minus)) {
5707 Parser.Lex(); // Eat the '-' token.
5708 isAdd = false;
5709 haveEaten = true;
5710 }
5711
5712 SMLoc E = Parser.getTok().getEndLoc();
5713 MCRegister Reg = tryParseRegister();
5714 if (!Reg) {
5715 if (!haveEaten)
5716 return ParseStatus::NoMatch;
5717 return Error(Parser.getTok().getLoc(), "register expected");
5718 }
5719
5721 unsigned ShiftImm = 0;
5722 if (Parser.getTok().is(AsmToken::Comma)) {
5723 Parser.Lex(); // Eat the ','.
5724 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5725 return ParseStatus::Failure;
5726
5727 // FIXME: Only approximates end...may include intervening whitespace.
5728 E = Parser.getTok().getLoc();
5729 }
5730
5731 Operands.push_back(
5732 ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, ShiftImm, S, E, *this));
5733
5734 return ParseStatus::Success;
5735}
5736
5737ParseStatus ARMAsmParser::parseAM3Offset(OperandVector &Operands) {
5738 // Check for a post-index addressing register operand. Specifically:
5739 // am3offset := '+' register
5740 // | '-' register
5741 // | register
5742 // | # imm
5743 // | # + imm
5744 // | # - imm
5745
5746 // This method must return ParseStatus::NoMatch without consuming any tokens
5747 // in the case where there is no match, as other alternatives take other
5748 // parse methods.
5749 MCAsmParser &Parser = getParser();
5750 AsmToken Tok = Parser.getTok();
5751 SMLoc S = Tok.getLoc();
5752
5753 // Do immediates first, as we always parse those if we have a '#'.
5754 if (Parser.getTok().is(AsmToken::Hash) ||
5755 Parser.getTok().is(AsmToken::Dollar)) {
5756 Parser.Lex(); // Eat '#' or '$'.
5757 // Explicitly look for a '-', as we need to encode negative zero
5758 // differently.
5759 bool isNegative = Parser.getTok().is(AsmToken::Minus);
5760 const MCExpr *Offset;
5761 SMLoc E;
5762 if (getParser().parseExpression(Offset, E))
5763 return ParseStatus::Failure;
5764 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
5765 if (!CE)
5766 return Error(S, "constant expression expected");
5767 // Negative zero is encoded as the flag value
5768 // std::numeric_limits<int32_t>::min().
5769 int32_t Val = CE->getValue();
5770 if (isNegative && Val == 0)
5771 Val = std::numeric_limits<int32_t>::min();
5772
5773 Operands.push_back(ARMOperand::CreateImm(
5774 MCConstantExpr::create(Val, getContext()), S, E, *this));
5775
5776 return ParseStatus::Success;
5777 }
5778
5779 bool haveEaten = false;
5780 bool isAdd = true;
5781 if (Tok.is(AsmToken::Plus)) {
5782 Parser.Lex(); // Eat the '+' token.
5783 haveEaten = true;
5784 } else if (Tok.is(AsmToken::Minus)) {
5785 Parser.Lex(); // Eat the '-' token.
5786 isAdd = false;
5787 haveEaten = true;
5788 }
5789
5790 Tok = Parser.getTok();
5791 MCRegister Reg = tryParseRegister();
5792 if (!Reg) {
5793 if (!haveEaten)
5794 return ParseStatus::NoMatch;
5795 return Error(Tok.getLoc(), "register expected");
5796 }
5797
5798 Operands.push_back(ARMOperand::CreatePostIdxReg(
5799 Reg, isAdd, ARM_AM::no_shift, 0, S, Tok.getEndLoc(), *this));
5800
5801 return ParseStatus::Success;
5802}
5803
5804// Finds the index of the first CondCode operator, if there is none returns 0
5805unsigned findCondCodeInd(const OperandVector &Operands,
5806 unsigned MnemonicOpsEndInd) {
5807 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
5808 auto Op = static_cast<ARMOperand &>(*Operands[I]);
5809 if (Op.isCondCode())
5810 return I;
5811 }
5812 return 0;
5813}
5814
5815unsigned findCCOutInd(const OperandVector &Operands,
5816 unsigned MnemonicOpsEndInd) {
5817 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
5818 auto Op = static_cast<ARMOperand &>(*Operands[I]);
5819 if (Op.isCCOut())
5820 return I;
5821 }
5822 return 0;
5823}
5824
5825/// Convert parsed operands to MCInst. Needed here because this instruction
5826/// only has two register operands, but multiplication is commutative so
5827/// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN".
5828void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5829 const OperandVector &Operands) {
5830 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5831 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5832 unsigned CondOutI = findCCOutInd(Operands, MnemonicOpsEndInd);
5833
5834 // 2 operand form
5835 unsigned RegRd = MnemonicOpsEndInd;
5836 unsigned RegRn = MnemonicOpsEndInd + 1;
5837 unsigned RegRm = MnemonicOpsEndInd;
5838
5839 if (Operands.size() == MnemonicOpsEndInd + 3) {
5840 // If we have a three-operand form, make sure to set Rn to be the operand
5841 // that isn't the same as Rd.
5842 if (((ARMOperand &)*Operands[RegRd]).getReg() ==
5843 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1]).getReg()) {
5844 RegRn = MnemonicOpsEndInd + 2;
5845 RegRm = MnemonicOpsEndInd + 1;
5846 } else {
5847 RegRn = MnemonicOpsEndInd + 1;
5848 RegRm = MnemonicOpsEndInd + 2;
5849 }
5850 }
5851
5852 // Rd
5853 ((ARMOperand &)*Operands[RegRd]).addRegOperands(Inst, 1);
5854 // CCOut
5855 if (CondOutI != 0) {
5856 ((ARMOperand &)*Operands[CondOutI]).addCCOutOperands(Inst, 1);
5857 } else {
5858 ARMOperand Op =
5859 *ARMOperand::CreateCCOut(0, Operands[0]->getEndLoc(), *this);
5860 Op.addCCOutOperands(Inst, 1);
5861 }
5862 // Rn
5863 ((ARMOperand &)*Operands[RegRn]).addRegOperands(Inst, 1);
5864 // Rm
5865 ((ARMOperand &)*Operands[RegRm]).addRegOperands(Inst, 1);
5866
5867 // Cond code
5868 if (CondI != 0) {
5869 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5870 } else {
5871 ARMOperand Op = *ARMOperand::CreateCondCode(
5872 llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this);
5873 Op.addCondCodeOperands(Inst, 2);
5874 }
5875}
5876
5877void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5878 const OperandVector &Operands) {
5879 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5880 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5881 unsigned Cond =
5882 (CondI == 0 ? ARMCC::AL
5883 : static_cast<ARMOperand &>(*Operands[CondI]).getCondCode());
5884
5885 // first decide whether or not the branch should be conditional
5886 // by looking at it's location relative to an IT block
5887 if(inITBlock()) {
5888 // inside an IT block we cannot have any conditional branches. any
5889 // such instructions needs to be converted to unconditional form
5890 switch(Inst.getOpcode()) {
5891 case ARM::tBcc: Inst.setOpcode(ARM::tB); break;
5892 case ARM::t2Bcc: Inst.setOpcode(ARM::t2B); break;
5893 }
5894 } else {
5895 switch(Inst.getOpcode()) {
5896 case ARM::tB:
5897 case ARM::tBcc:
5898 Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc);
5899 break;
5900 case ARM::t2B:
5901 case ARM::t2Bcc:
5902 Inst.setOpcode(Cond == ARMCC::AL ? ARM::t2B : ARM::t2Bcc);
5903 break;
5904 }
5905 }
5906
5907 // now decide on encoding size based on branch target range
5908 switch(Inst.getOpcode()) {
5909 // classify tB as either t2B or t1B based on range of immediate operand
5910 case ARM::tB: {
5911 ARMOperand &op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
5912 if (!op.isSignedOffset<11, 1>() && isThumb() && hasV8MBaseline())
5913 Inst.setOpcode(ARM::t2B);
5914 break;
5915 }
5916 // classify tBcc as either t2Bcc or t1Bcc based on range of immediate operand
5917 case ARM::tBcc: {
5918 ARMOperand &op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
5919 if (!op.isSignedOffset<8, 1>() && isThumb() && hasV8MBaseline())
5920 Inst.setOpcode(ARM::t2Bcc);
5921 break;
5922 }
5923 }
5924 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5925 if (CondI != 0) {
5926 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5927 } else {
5928 ARMOperand Op = *ARMOperand::CreateCondCode(
5929 llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this);
5930 Op.addCondCodeOperands(Inst, 2);
5931 }
5932}
5933
5934void ARMAsmParser::cvtMVEVMOVQtoDReg(
5935 MCInst &Inst, const OperandVector &Operands) {
5936
5937 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5938 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5939
5940 // mnemonic, condition code, Rt, Rt2, Qd, idx, Qd again, idx2
5941 assert(Operands.size() == MnemonicOpsEndInd + 6);
5942
5943 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1); // Rt
5944 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1])
5945 .addRegOperands(Inst, 1); // Rt2
5946 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 2])
5947 .addRegOperands(Inst, 1); // Qd
5948 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 3])
5949 .addMVEPairVectorIndexOperands(Inst, 1); // idx
5950 // skip second copy of Qd in Operands[6]
5951 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 5])
5952 .addMVEPairVectorIndexOperands(Inst, 1); // idx2
5953 if (CondI != 0) {
5954 ((ARMOperand &)*Operands[CondI])
5955 .addCondCodeOperands(Inst, 2); // condition code
5956 } else {
5957 ARMOperand Op =
5958 *ARMOperand::CreateCondCode(ARMCC::AL, Operands[0]->getEndLoc(), *this);
5959 Op.addCondCodeOperands(Inst, 2);
5960 }
5961}
5962
5963/// Parse an ARM memory expression, return false if successful else return true
5964/// or an error. The first token must be a '[' when called.
5965bool ARMAsmParser::parseMemory(OperandVector &Operands) {
5966 MCAsmParser &Parser = getParser();
5967 SMLoc S, E;
5968 if (Parser.getTok().isNot(AsmToken::LBrac))
5969 return TokError("Token is not a Left Bracket");
5970 S = Parser.getTok().getLoc();
5971 Parser.Lex(); // Eat left bracket token.
5972
5973 const AsmToken &BaseRegTok = Parser.getTok();
5974 MCRegister BaseReg = tryParseRegister();
5975 if (!BaseReg)
5976 return Error(BaseRegTok.getLoc(), "register expected");
5977
5978 // The next token must either be a comma, a colon or a closing bracket.
5979 const AsmToken &Tok = Parser.getTok();
5980 if (!Tok.is(AsmToken::Colon) && !Tok.is(AsmToken::Comma) &&
5981 !Tok.is(AsmToken::RBrac))
5982 return Error(Tok.getLoc(), "malformed memory operand");
5983
5984 if (Tok.is(AsmToken::RBrac)) {
5985 E = Tok.getEndLoc();
5986 Parser.Lex(); // Eat right bracket token.
5987
5988 Operands.push_back(ARMOperand::CreateMem(
5989 BaseReg, nullptr, 0, ARM_AM::no_shift, 0, 0, false, S, E, *this));
5990
5991 // If there's a pre-indexing writeback marker, '!', just add it as a token
5992 // operand. It's rather odd, but syntactically valid.
5993 if (Parser.getTok().is(AsmToken::Exclaim)) {
5994 Operands.push_back(
5995 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
5996 Parser.Lex(); // Eat the '!'.
5997 }
5998
5999 return false;
6000 }
6001
6002 assert((Tok.is(AsmToken::Colon) || Tok.is(AsmToken::Comma)) &&
6003 "Lost colon or comma in memory operand?!");
6004 if (Tok.is(AsmToken::Comma)) {
6005 Parser.Lex(); // Eat the comma.
6006 }
6007
6008 // If we have a ':', it's an alignment specifier.
6009 if (Parser.getTok().is(AsmToken::Colon)) {
6010 Parser.Lex(); // Eat the ':'.
6011 E = Parser.getTok().getLoc();
6012 SMLoc AlignmentLoc = Tok.getLoc();
6013
6014 const MCExpr *Expr;
6015 if (getParser().parseExpression(Expr))
6016 return true;
6017
6018 // The expression has to be a constant. Memory references with relocations
6019 // don't come through here, as they use the <label> forms of the relevant
6020 // instructions.
6021 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
6022 if (!CE)
6023 return Error (E, "constant expression expected");
6024
6025 unsigned Align = 0;
6026 switch (CE->getValue()) {
6027 default:
6028 return Error(E,
6029 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6030 case 16: Align = 2; break;
6031 case 32: Align = 4; break;
6032 case 64: Align = 8; break;
6033 case 128: Align = 16; break;
6034 case 256: Align = 32; break;
6035 }
6036
6037 // Now we should have the closing ']'
6038 if (Parser.getTok().isNot(AsmToken::RBrac))
6039 return Error(Parser.getTok().getLoc(), "']' expected");
6040 E = Parser.getTok().getEndLoc();
6041 Parser.Lex(); // Eat right bracket token.
6042
6043 // Don't worry about range checking the value here. That's handled by
6044 // the is*() predicates.
6045 Operands.push_back(ARMOperand::CreateMem(BaseReg, nullptr, 0,
6046 ARM_AM::no_shift, 0, Align, false,
6047 S, E, *this, AlignmentLoc));
6048
6049 // If there's a pre-indexing writeback marker, '!', just add it as a token
6050 // operand.
6051 if (Parser.getTok().is(AsmToken::Exclaim)) {
6052 Operands.push_back(
6053 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6054 Parser.Lex(); // Eat the '!'.
6055 }
6056
6057 return false;
6058 }
6059
6060 // If we have a '#' or '$', it's an immediate offset, else assume it's a
6061 // register offset. Be friendly and also accept a plain integer or expression
6062 // (without a leading hash) for gas compatibility.
6063 if (Parser.getTok().is(AsmToken::Hash) ||
6064 Parser.getTok().is(AsmToken::Dollar) ||
6065 Parser.getTok().is(AsmToken::LParen) ||
6066 Parser.getTok().is(AsmToken::Integer)) {
6067 if (Parser.getTok().is(AsmToken::Hash) ||
6068 Parser.getTok().is(AsmToken::Dollar))
6069 Parser.Lex(); // Eat '#' or '$'
6070 E = Parser.getTok().getLoc();
6071
6072 bool isNegative = getParser().getTok().is(AsmToken::Minus);
6073 const MCExpr *Offset, *AdjustedOffset;
6074 if (getParser().parseExpression(Offset))
6075 return true;
6076
6077 if (const auto *CE = dyn_cast<MCConstantExpr>(Offset)) {
6078 // If the constant was #-0, represent it as
6079 // std::numeric_limits<int32_t>::min().
6080 int32_t Val = CE->getValue();
6081 if (isNegative && Val == 0)
6082 CE = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
6083 getContext());
6084 // Don't worry about range checking the value here. That's handled by
6085 // the is*() predicates.
6086 AdjustedOffset = CE;
6087 } else
6088 AdjustedOffset = Offset;
6089 Operands.push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6090 ARM_AM::no_shift, 0, 0, false, S,
6091 E, *this));
6092
6093 // Now we should have the closing ']'
6094 if (Parser.getTok().isNot(AsmToken::RBrac))
6095 return Error(Parser.getTok().getLoc(), "']' expected");
6096 E = Parser.getTok().getEndLoc();
6097 Parser.Lex(); // Eat right bracket token.
6098
6099 // If there's a pre-indexing writeback marker, '!', just add it as a token
6100 // operand.
6101 if (Parser.getTok().is(AsmToken::Exclaim)) {
6102 Operands.push_back(
6103 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6104 Parser.Lex(); // Eat the '!'.
6105 }
6106
6107 return false;
6108 }
6109
6110 // The register offset is optionally preceded by a '+' or '-'
6111 bool isNegative = false;
6112 if (Parser.getTok().is(AsmToken::Minus)) {
6113 isNegative = true;
6114 Parser.Lex(); // Eat the '-'.
6115 } else if (Parser.getTok().is(AsmToken::Plus)) {
6116 // Nothing to do.
6117 Parser.Lex(); // Eat the '+'.
6118 }
6119
6120 E = Parser.getTok().getLoc();
6121 MCRegister OffsetReg = tryParseRegister();
6122 if (!OffsetReg)
6123 return Error(E, "register expected");
6124
6125 // If there's a shift operator, handle it.
6127 unsigned ShiftImm = 0;
6128 if (Parser.getTok().is(AsmToken::Comma)) {
6129 Parser.Lex(); // Eat the ','.
6130 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6131 return true;
6132 }
6133
6134 // Now we should have the closing ']'
6135 if (Parser.getTok().isNot(AsmToken::RBrac))
6136 return Error(Parser.getTok().getLoc(), "']' expected");
6137 E = Parser.getTok().getEndLoc();
6138 Parser.Lex(); // Eat right bracket token.
6139
6140 Operands.push_back(ARMOperand::CreateMem(BaseReg, nullptr, OffsetReg,
6141 ShiftType, ShiftImm, 0, isNegative,
6142 S, E, *this));
6143
6144 // If there's a pre-indexing writeback marker, '!', just add it as a token
6145 // operand.
6146 if (Parser.getTok().is(AsmToken::Exclaim)) {
6147 Operands.push_back(
6148 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6149 Parser.Lex(); // Eat the '!'.
6150 }
6151
6152 return false;
6153}
6154
6155/// parseMemRegOffsetShift - one of these two:
6156/// ( lsl | lsr | asr | ror ) , # shift_amount
6157/// rrx
6158/// return true if it parses a shift otherwise it returns false.
6159bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
6160 unsigned &Amount) {
6161 MCAsmParser &Parser = getParser();
6162 SMLoc Loc = Parser.getTok().getLoc();
6163 const AsmToken &Tok = Parser.getTok();
6164 if (Tok.isNot(AsmToken::Identifier))
6165 return Error(Loc, "illegal shift operator");
6166 StringRef ShiftName = Tok.getString();
6167 if (ShiftName == "lsl" || ShiftName == "LSL" ||
6168 ShiftName == "asl" || ShiftName == "ASL")
6169 St = ARM_AM::lsl;
6170 else if (ShiftName == "lsr" || ShiftName == "LSR")
6171 St = ARM_AM::lsr;
6172 else if (ShiftName == "asr" || ShiftName == "ASR")
6173 St = ARM_AM::asr;
6174 else if (ShiftName == "ror" || ShiftName == "ROR")
6175 St = ARM_AM::ror;
6176 else if (ShiftName == "rrx" || ShiftName == "RRX")
6177 St = ARM_AM::rrx;
6178 else if (ShiftName == "uxtw" || ShiftName == "UXTW")
6179 St = ARM_AM::uxtw;
6180 else
6181 return Error(Loc, "illegal shift operator");
6182 Parser.Lex(); // Eat shift type token.
6183
6184 // rrx stands alone.
6185 Amount = 0;
6186 if (St != ARM_AM::rrx) {
6187 Loc = Parser.getTok().getLoc();
6188 // A '#' and a shift amount.
6189 const AsmToken &HashTok = Parser.getTok();
6190 if (HashTok.isNot(AsmToken::Hash) &&
6191 HashTok.isNot(AsmToken::Dollar))
6192 return Error(HashTok.getLoc(), "'#' expected");
6193 Parser.Lex(); // Eat hash token.
6194
6195 const MCExpr *Expr;
6196 if (getParser().parseExpression(Expr))
6197 return true;
6198 // Range check the immediate.
6199 // lsl, ror: 0 <= imm <= 31
6200 // lsr, asr: 0 <= imm <= 32
6201 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
6202 if (!CE)
6203 return Error(Loc, "shift amount must be an immediate");
6204 int64_t Imm = CE->getValue();
6205 if (Imm < 0 ||
6206 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
6207 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
6208 return Error(Loc, "immediate shift value out of range");
6209 // If <ShiftTy> #0, turn it into a no_shift.
6210 if (Imm == 0)
6211 St = ARM_AM::lsl;
6212 // For consistency, treat lsr #32 and asr #32 as having immediate value 0.
6213 if (Imm == 32)
6214 Imm = 0;
6215 Amount = Imm;
6216 }
6217
6218 return false;
6219}
6220
6221/// parseFPImm - A floating point immediate expression operand.
6222ParseStatus ARMAsmParser::parseFPImm(OperandVector &Operands) {
6223 LLVM_DEBUG(dbgs() << "PARSE FPImm, Ops: " << Operands.size());
6224
6225 MCAsmParser &Parser = getParser();
6226 // Anything that can accept a floating point constant as an operand
6227 // needs to go through here, as the regular parseExpression is
6228 // integer only.
6229 //
6230 // This routine still creates a generic Immediate operand, containing
6231 // a bitcast of the 64-bit floating point value. The various operands
6232 // that accept floats can check whether the value is valid for them
6233 // via the standard is*() predicates.
6234
6235 SMLoc S = Parser.getTok().getLoc();
6236
6237 if (Parser.getTok().isNot(AsmToken::Hash) &&
6238 Parser.getTok().isNot(AsmToken::Dollar))
6239 return ParseStatus::NoMatch;
6240
6241 // Disambiguate the VMOV forms that can accept an FP immediate.
6242 // vmov.f32 <sreg>, #imm
6243 // vmov.f64 <dreg>, #imm
6244 // vmov.f32 <dreg>, #imm @ vector f32x2
6245 // vmov.f32 <qreg>, #imm @ vector f32x4
6246 //
6247 // There are also the NEON VMOV instructions which expect an
6248 // integer constant. Make sure we don't try to parse an FPImm
6249 // for these:
6250 // vmov.i{8|16|32|64} <dreg|qreg>, #imm
6251
6252 bool isVmovf = false;
6253 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
6254 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
6255 ARMOperand &TyOp = static_cast<ARMOperand &>(*Operands[I]);
6256 if (TyOp.isToken() &&
6257 (TyOp.getToken() == ".f32" || TyOp.getToken() == ".f64" ||
6258 TyOp.getToken() == ".f16")) {
6259 isVmovf = true;
6260 break;
6261 }
6262 }
6263
6264 ARMOperand &Mnemonic = static_cast<ARMOperand &>(*Operands[0]);
6265 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() == "fconstd" ||
6266 Mnemonic.getToken() == "fconsts");
6267 if (!(isVmovf || isFconst))
6268 return ParseStatus::NoMatch;
6269
6270 Parser.Lex(); // Eat '#' or '$'.
6271
6272 // Handle negation, as that still comes through as a separate token.
6273 bool isNegative = false;
6274 if (Parser.getTok().is(AsmToken::Minus)) {
6275 isNegative = true;
6276 Parser.Lex();
6277 }
6278 const AsmToken &Tok = Parser.getTok();
6279 SMLoc Loc = Tok.getLoc();
6280 if (Tok.is(AsmToken::Real) && isVmovf) {
6281 APFloat RealVal(APFloat::IEEEsingle(), Tok.getString());
6282 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
6283 // If we had a '-' in front, toggle the sign bit.
6284 IntVal ^= (uint64_t)isNegative << 31;
6285 Parser.Lex(); // Eat the token.
6286 Operands.push_back(
6287 ARMOperand::CreateImm(MCConstantExpr::create(IntVal, getContext()), S,
6288 Parser.getTok().getLoc(), *this));
6289 return ParseStatus::Success;
6290 }
6291 // Also handle plain integers. Instructions which allow floating point
6292 // immediates also allow a raw encoded 8-bit value.
6293 if (Tok.is(AsmToken::Integer) && isFconst) {
6294 int64_t Val = Tok.getIntVal();
6295 Parser.Lex(); // Eat the token.
6296 if (Val > 255 || Val < 0)
6297 return Error(Loc, "encoded floating point value out of range");
6298 float RealVal = ARM_AM::getFPImmFloat(Val);
6299 Val = APFloat(RealVal).bitcastToAPInt().getZExtValue();
6300
6301 Operands.push_back(
6302 ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S,
6303 Parser.getTok().getLoc(), *this));
6304 return ParseStatus::Success;
6305 }
6306
6307 return Error(Loc, "invalid floating point immediate");
6308}
6309
6310/// Parse a arm instruction operand. For now this parses the operand regardless
6311/// of the mnemonic.
6312bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6313 MCAsmParser &Parser = getParser();
6314 SMLoc S, E;
6315
6316 // Check if the current operand has a custom associated parser, if so, try to
6317 // custom parse the operand, or fallback to the general approach.
6318 ParseStatus ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6319 if (ResTy.isSuccess())
6320 return false;
6321 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6322 // there was a match, but an error occurred, in which case, just return that
6323 // the operand parsing failed.
6324 if (ResTy.isFailure())
6325 return true;
6326
6327 switch (getLexer().getKind()) {
6328 default:
6329 Error(Parser.getTok().getLoc(), "unexpected token in operand");
6330 return true;
6331 case AsmToken::Identifier: {
6332 // If we've seen a branch mnemonic, the next operand must be a label. This
6333 // is true even if the label is a register name. So "br r1" means branch to
6334 // label "r1".
6335 bool ExpectLabel = Mnemonic == "b" || Mnemonic == "bl";
6336 if (!ExpectLabel) {
6337 if (!tryParseRegisterWithWriteBack(Operands))
6338 return false;
6339 int Res = tryParseShiftRegister(Operands);
6340 if (Res == 0) // success
6341 return false;
6342 else if (Res == -1) // irrecoverable error
6343 return true;
6344 // If this is VMRS, check for the apsr_nzcv operand.
6345 if (Mnemonic == "vmrs" &&
6346 Parser.getTok().getString().equals_insensitive("apsr_nzcv")) {
6347 S = Parser.getTok().getLoc();
6348 Parser.Lex();
6349 Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S, *this));
6350 return false;
6351 }
6352 }
6353
6354 // Fall though for the Identifier case that is not a register or a
6355 // special name.
6356 [[fallthrough]];
6357 }
6358 case AsmToken::LParen: // parenthesized expressions like (_strcmp-4)
6359 case AsmToken::Integer: // things like 1f and 2b as a branch targets
6360 case AsmToken::String: // quoted label names.
6361 case AsmToken::Dot: { // . as a branch target
6362 // This was not a register so parse other operands that start with an
6363 // identifier (like labels) as expressions and create them as immediates.
6364 const MCExpr *IdVal;
6365 S = Parser.getTok().getLoc();
6366 if (getParser().parseExpression(IdVal))
6367 return true;
6368 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6369 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E, *this));
6370 return false;
6371 }
6372 case AsmToken::LBrac:
6373 return parseMemory(Operands);
6374 case AsmToken::LCurly: {
6375 bool IsLazyLoadStore = Mnemonic == "vlldm" || Mnemonic == "vlstm";
6376 bool IsVSCCLRM = Mnemonic == "vscclrm";
6377 return parseRegisterList(Operands, !Mnemonic.starts_with("clr"), false,
6378 IsLazyLoadStore, IsVSCCLRM);
6379 }
6380 case AsmToken::Dollar:
6381 case AsmToken::Hash: {
6382 // #42 -> immediate
6383 // $ 42 -> immediate
6384 // $foo -> symbol name
6385 // $42 -> symbol name
6386 S = Parser.getTok().getLoc();
6387
6388 // Favor the interpretation of $-prefixed operands as symbol names.
6389 // Cases where immediates are explicitly expected are handled by their
6390 // specific ParseMethod implementations.
6391 auto AdjacentToken = getLexer().peekTok(/*ShouldSkipSpace=*/false);
6392 bool ExpectIdentifier = Parser.getTok().is(AsmToken::Dollar) &&
6393 (AdjacentToken.is(AsmToken::Identifier) ||
6394 AdjacentToken.is(AsmToken::Integer));
6395 if (!ExpectIdentifier) {
6396 // Token is not part of identifier. Drop leading $ or # before parsing
6397 // expression.
6398 Parser.Lex();
6399 }
6400
6401 if (Parser.getTok().isNot(AsmToken::Colon)) {
6402 bool IsNegative = Parser.getTok().is(AsmToken::Minus);
6403 const MCExpr *ImmVal;
6404 if (getParser().parseExpression(ImmVal))
6405 return true;
6406 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
6407 if (CE) {
6408 int32_t Val = CE->getValue();
6409 if (IsNegative && Val == 0)
6410 ImmVal = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
6411 getContext());
6412 }
6413 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6414 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E, *this));
6415
6416 // There can be a trailing '!' on operands that we want as a separate
6417 // '!' Token operand. Handle that here. For example, the compatibility
6418 // alias for 'srsdb sp!, #imm' is 'srsdb #imm!'.
6419 if (Parser.getTok().is(AsmToken::Exclaim)) {
6420 Operands.push_back(ARMOperand::CreateToken(
6421 Parser.getTok().getString(), Parser.getTok().getLoc(), *this));
6422 Parser.Lex(); // Eat exclaim token
6423 }
6424 return false;
6425 }
6426 // w/ a ':' after the '#', it's just like a plain ':'.
6427 [[fallthrough]];
6428 }
6429 case AsmToken::Colon: {
6430 S = Parser.getTok().getLoc();
6431 // ":lower16:", ":upper16:", ":lower0_7:", ":lower8_15:", ":upper0_7:" and
6432 // ":upper8_15:", expression prefixes
6433 // FIXME: Check it's an expression prefix,
6434 // e.g. (FOO - :lower16:BAR) isn't legal.
6435 ARM::Specifier Spec;
6436 if (parsePrefix(Spec))
6437 return true;
6438
6439 const MCExpr *SubExprVal;
6440 if (getParser().parseExpression(SubExprVal))
6441 return true;
6442
6443 const auto *ExprVal =
6444 MCSpecifierExpr::create(SubExprVal, Spec, getContext(), S);
6445 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6446 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E, *this));
6447 return false;
6448 }
6449 case AsmToken::Equal: {
6450 S = Parser.getTok().getLoc();
6451 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
6452 return Error(S, "unexpected token in operand");
6453 Parser.Lex(); // Eat '='
6454 const MCExpr *SubExprVal;
6455 if (getParser().parseExpression(SubExprVal))
6456 return true;
6457 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6458
6459 // execute-only: we assume that assembly programmers know what they are
6460 // doing and allow literal pool creation here
6461 Operands.push_back(
6462 ARMOperand::CreateConstantPoolImm(SubExprVal, S, E, *this));
6463 return false;
6464 }
6465 }
6466}
6467
6468bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6469 const MCExpr *Expr = nullptr;
6470 SMLoc L = getParser().getTok().getLoc();
6471 if (check(getParser().parseExpression(Expr), L, "expected expression"))
6472 return true;
6473 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
6474 if (check(!Value, L, "expected constant expression"))
6475 return true;
6476 Out = Value->getValue();
6477 return false;
6478}
6479
6480// parsePrefix - Parse ARM 16-bit relocations expression prefixes, i.e.
6481// :lower16: and :upper16: and Thumb 8-bit relocation expression prefixes, i.e.
6482// :upper8_15:, :upper0_7:, :lower8_15: and :lower0_7:
6483bool ARMAsmParser::parsePrefix(ARM::Specifier &Spec) {
6484 MCAsmParser &Parser = getParser();
6485 Spec = ARM::S_None;
6486
6487 // consume an optional '#' (GNU compatibility)
6488 if (getLexer().is(AsmToken::Hash))
6489 Parser.Lex();
6490
6491 assert(getLexer().is(AsmToken::Colon) && "expected a :");
6492 Parser.Lex(); // Eat ':'
6493
6494 if (getLexer().isNot(AsmToken::Identifier)) {
6495 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
6496 return true;
6497 }
6498
6499 enum {
6500 COFF = (1 << MCContext::IsCOFF),
6501 ELF = (1 << MCContext::IsELF),
6502 MACHO = (1 << MCContext::IsMachO),
6503 WASM = (1 << MCContext::IsWasm),
6504 };
6505 static const struct PrefixEntry {
6506 const char *Spelling;
6507 ARM::Specifier Spec;
6508 uint8_t SupportedFormats;
6509 } PrefixEntries[] = {
6510 {"upper16", ARM::S_HI16, COFF | ELF | MACHO},
6511 {"lower16", ARM::S_LO16, COFF | ELF | MACHO},
6512 {"upper8_15", ARM::S_HI_8_15, ELF},
6513 {"upper0_7", ARM::S_HI_0_7, ELF},
6514 {"lower8_15", ARM::S_LO_8_15, ELF},
6515 {"lower0_7", ARM::S_LO_0_7, ELF},
6516 };
6517
6518 StringRef IDVal = Parser.getTok().getIdentifier();
6519
6520 const auto &Prefix =
6521 llvm::find_if(PrefixEntries, [&IDVal](const PrefixEntry &PE) {
6522 return PE.Spelling == IDVal;
6523 });
6524 if (Prefix == std::end(PrefixEntries)) {
6525 Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
6526 return true;
6527 }
6528
6529 uint8_t CurrentFormat;
6530 switch (getContext().getObjectFileType()) {
6531 case MCContext::IsMachO:
6532 CurrentFormat = MACHO;
6533 break;
6534 case MCContext::IsELF:
6535 CurrentFormat = ELF;
6536 break;
6537 case MCContext::IsCOFF:
6538 CurrentFormat = COFF;
6539 break;
6540 case MCContext::IsWasm:
6541 CurrentFormat = WASM;
6542 break;
6543 case MCContext::IsGOFF:
6544 case MCContext::IsSPIRV:
6545 case MCContext::IsXCOFF:
6547 llvm_unreachable("unexpected object format");
6548 break;
6549 }
6550
6551 if (~Prefix->SupportedFormats & CurrentFormat) {
6552 Error(Parser.getTok().getLoc(),
6553 "cannot represent relocation in the current file format");
6554 return true;
6555 }
6556
6557 Spec = Prefix->Spec;
6558 Parser.Lex();
6559
6560 if (getLexer().isNot(AsmToken::Colon)) {
6561 Error(Parser.getTok().getLoc(), "unexpected token after prefix");
6562 return true;
6563 }
6564 Parser.Lex(); // Eat the last ':'
6565
6566 // consume an optional trailing '#' (GNU compatibility) bla
6567 parseOptionalToken(AsmToken::Hash);
6568
6569 return false;
6570}
6571
6572/// Given a mnemonic, split out possible predication code and carry
6573/// setting letters to form a canonical mnemonic and flags.
6574//
6575// FIXME: Would be nice to autogen this.
6576// FIXME: This is a bit of a maze of special cases.
6577StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6578 ARMCC::CondCodes &PredicationCode,
6579 ARMVCC::VPTCodes &VPTPredicationCode,
6580 bool &CarrySetting,
6581 unsigned &ProcessorIMod,
6582 StringRef &ITMask) {
6583 PredicationCode = ARMCC::AL;
6584 VPTPredicationCode = ARMVCC::None;
6585 CarrySetting = false;
6586 ProcessorIMod = 0;
6587
6588 // Ignore some mnemonics we know aren't predicated forms.
6589 //
6590 // FIXME: Would be nice to autogen this.
6591 if ((Mnemonic == "movs" && isThumb()) || Mnemonic == "teq" ||
6592 Mnemonic == "vceq" || Mnemonic == "svc" || Mnemonic == "mls" ||
6593 Mnemonic == "smmls" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
6594 Mnemonic == "vnmls" || Mnemonic == "vacge" || Mnemonic == "vcge" ||
6595 Mnemonic == "vclt" || Mnemonic == "vacgt" || Mnemonic == "vaclt" ||
6596 Mnemonic == "vacle" || Mnemonic == "hlt" || Mnemonic == "vcgt" ||
6597 Mnemonic == "vcle" || Mnemonic == "smlal" || Mnemonic == "umaal" ||
6598 Mnemonic == "umlal" || Mnemonic == "vabal" || Mnemonic == "vmlal" ||
6599 Mnemonic == "vpadal" || Mnemonic == "vqdmlal" || Mnemonic == "fmuls" ||
6600 Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" ||
6601 Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" ||
6602 Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" ||
6603 Mnemonic == "vrintm" || Mnemonic == "hvc" ||
6604 Mnemonic.starts_with("vsel") || Mnemonic == "vins" ||
6605 Mnemonic == "vmovx" || Mnemonic == "bxns" || Mnemonic == "blxns" ||
6606 Mnemonic == "vdot" || Mnemonic == "vmmla" || Mnemonic == "vudot" ||
6607 Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
6608 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || Mnemonic == "wls" ||
6609 Mnemonic == "le" || Mnemonic == "dls" || Mnemonic == "csel" ||
6610 Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" ||
6611 Mnemonic == "cinc" || Mnemonic == "cinv" || Mnemonic == "cneg" ||
6612 Mnemonic == "cset" || Mnemonic == "csetm" || Mnemonic == "aut" ||
6613 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "bti")
6614 return Mnemonic;
6615
6616 // First, split out any predication code. Ignore mnemonics we know aren't
6617 // predicated but do have a carry-set and so weren't caught above.
6618 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
6619 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
6620 Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
6621 Mnemonic != "sbcs" && Mnemonic != "rscs" &&
6622 !(hasMVE() &&
6623 (Mnemonic == "vmine" || Mnemonic == "vshle" || Mnemonic == "vshlt" ||
6624 Mnemonic == "vshllt" || Mnemonic == "vrshle" || Mnemonic == "vrshlt" ||
6625 Mnemonic == "vmvne" || Mnemonic == "vorne" || Mnemonic == "vnege" ||
6626 Mnemonic == "vnegt" || Mnemonic == "vmule" || Mnemonic == "vmult" ||
6627 Mnemonic == "vrintne" || Mnemonic == "vcmult" ||
6628 Mnemonic == "vcmule" || Mnemonic == "vpsele" || Mnemonic == "vpselt" ||
6629 Mnemonic.starts_with("vq")))) {
6630 unsigned CC = ARMCondCodeFromString(Mnemonic.substr(Mnemonic.size()-2));
6631 if (CC != ~0U) {
6632 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
6633 PredicationCode = static_cast<ARMCC::CondCodes>(CC);
6634 }
6635 }
6636
6637 // Next, determine if we have a carry setting bit. We explicitly ignore all
6638 // the instructions we know end in 's'.
6639 if (Mnemonic.ends_with("s") &&
6640 !(Mnemonic == "cps" || Mnemonic == "mls" || Mnemonic == "mrs" ||
6641 Mnemonic == "smmls" || Mnemonic == "vabs" || Mnemonic == "vcls" ||
6642 Mnemonic == "vmls" || Mnemonic == "vmrs" || Mnemonic == "vnmls" ||
6643 Mnemonic == "vqabs" || Mnemonic == "vrecps" || Mnemonic == "vrsqrts" ||
6644 Mnemonic == "srs" || Mnemonic == "flds" || Mnemonic == "fmrs" ||
6645 Mnemonic == "fsqrts" || Mnemonic == "fsubs" || Mnemonic == "fsts" ||
6646 Mnemonic == "fcpys" || Mnemonic == "fdivs" || Mnemonic == "fmuls" ||
6647 Mnemonic == "fcmps" || Mnemonic == "fcmpzs" || Mnemonic == "vfms" ||
6648 Mnemonic == "vfnms" || Mnemonic == "fconsts" || Mnemonic == "bxns" ||
6649 Mnemonic == "blxns" || Mnemonic == "vfmas" || Mnemonic == "vmlas" ||
6650 (Mnemonic == "movs" && isThumb()))) {
6651 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
6652 CarrySetting = true;
6653 }
6654
6655 // The "cps" instruction can have a interrupt mode operand which is glued into
6656 // the mnemonic. Check if this is the case, split it and parse the imod op
6657 if (Mnemonic.starts_with("cps")) {
6658 // Split out any imod code.
6659 unsigned IMod =
6660 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
6661 .Case("ie", ARM_PROC::IE)
6662 .Case("id", ARM_PROC::ID)
6663 .Default(~0U);
6664 if (IMod != ~0U) {
6665 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
6666 ProcessorIMod = IMod;
6667 }
6668 }
6669
6670 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic != "vmovlt" &&
6671 Mnemonic != "vshllt" && Mnemonic != "vrshrnt" && Mnemonic != "vshrnt" &&
6672 Mnemonic != "vqrshrunt" && Mnemonic != "vqshrunt" &&
6673 Mnemonic != "vqrshrnt" && Mnemonic != "vqshrnt" && Mnemonic != "vmullt" &&
6674 Mnemonic != "vqmovnt" && Mnemonic != "vqmovunt" && Mnemonic != "vmovnt" &&
6675 Mnemonic != "vqdmullt" && Mnemonic != "vpnot" && Mnemonic != "vcvtt" &&
6676 Mnemonic != "vcvt") {
6677 unsigned VCC =
6678 ARMVectorCondCodeFromString(Mnemonic.substr(Mnemonic.size() - 1));
6679 if (VCC != ~0U) {
6680 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-1);
6681 VPTPredicationCode = static_cast<ARMVCC::VPTCodes>(VCC);
6682 }
6683 return Mnemonic;
6684 }
6685
6686 // The "it" instruction has the condition mask on the end of the mnemonic.
6687 if (Mnemonic.starts_with("it")) {
6688 ITMask = Mnemonic.substr(2);
6689 Mnemonic = Mnemonic.slice(0, 2);
6690 }
6691
6692 if (Mnemonic.starts_with("vpst")) {
6693 ITMask = Mnemonic.substr(4);
6694 Mnemonic = Mnemonic.slice(0, 4);
6695 } else if (Mnemonic.starts_with("vpt")) {
6696 ITMask = Mnemonic.substr(3);
6697 Mnemonic = Mnemonic.slice(0, 3);
6698 }
6699
6700 return Mnemonic;
6701}
6702
6703/// Given a canonical mnemonic, determine if the instruction ever allows
6704/// inclusion of carry set or predication code operands.
6705//
6706// FIXME: It would be nice to autogen this.
6707void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6708 StringRef ExtraToken,
6709 StringRef FullInst,
6710 bool &CanAcceptCarrySet,
6711 bool &CanAcceptPredicationCode,
6712 bool &CanAcceptVPTPredicationCode) {
6713 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6714
6715 CanAcceptCarrySet =
6716 Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
6717 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
6718 Mnemonic == "add" || Mnemonic == "adc" || Mnemonic == "mul" ||
6719 Mnemonic == "bic" || Mnemonic == "asr" || Mnemonic == "orr" ||
6720 Mnemonic == "mvn" || Mnemonic == "rsb" || Mnemonic == "rsc" ||
6721 Mnemonic == "orn" || Mnemonic == "sbc" || Mnemonic == "eor" ||
6722 Mnemonic == "neg" || Mnemonic == "vfm" || Mnemonic == "vfnm" ||
6723 (!isThumb() &&
6724 (Mnemonic == "smull" || Mnemonic == "mov" || Mnemonic == "mla" ||
6725 Mnemonic == "smlal" || Mnemonic == "umlal" || Mnemonic == "umull"));
6726
6727 if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
6728 Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
6729 Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic == "udf" ||
6730 Mnemonic.starts_with("crc32") || Mnemonic.starts_with("cps") ||
6731 Mnemonic.starts_with("vsel") || Mnemonic == "vmaxnm" ||
6732 Mnemonic == "vminnm" || Mnemonic == "vcvta" || Mnemonic == "vcvtn" ||
6733 Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || Mnemonic == "vrinta" ||
6734 Mnemonic == "vrintn" || Mnemonic == "vrintp" || Mnemonic == "vrintm" ||
6735 Mnemonic.starts_with("aes") || Mnemonic == "hvc" ||
6736 Mnemonic == "setpan" || Mnemonic.starts_with("sha1") ||
6737 Mnemonic.starts_with("sha256") ||
6738 (FullInst.starts_with("vmull") && FullInst.ends_with(".p64")) ||
6739 Mnemonic == "vmovx" || Mnemonic == "vins" || Mnemonic == "vudot" ||
6740 Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
6741 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || Mnemonic == "vfmat" ||
6742 Mnemonic == "vfmab" || Mnemonic == "vdot" || Mnemonic == "vmmla" ||
6743 Mnemonic == "sb" || Mnemonic == "ssbb" || Mnemonic == "pssbb" ||
6744 Mnemonic == "vsmmla" || Mnemonic == "vummla" || Mnemonic == "vusmmla" ||
6745 Mnemonic == "vusdot" || Mnemonic == "vsudot" || Mnemonic == "bfcsel" ||
6746 Mnemonic == "wls" || Mnemonic == "dls" || Mnemonic == "le" ||
6747 Mnemonic == "csel" || Mnemonic == "csinc" || Mnemonic == "csinv" ||
6748 Mnemonic == "csneg" || Mnemonic == "cinc" || Mnemonic == "cinv" ||
6749 Mnemonic == "cneg" || Mnemonic == "cset" || Mnemonic == "csetm" ||
6750 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6751 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6752 Mnemonic.starts_with("vpt") || Mnemonic.starts_with("vpst") ||
6753 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "aut" ||
6754 Mnemonic == "bti" ||
6755 (hasMVE() &&
6756 (Mnemonic.starts_with("vst2") || Mnemonic.starts_with("vld2") ||
6757 Mnemonic.starts_with("vst4") || Mnemonic.starts_with("vld4") ||
6758 Mnemonic.starts_with("wlstp") || Mnemonic.starts_with("dlstp") ||
6759 Mnemonic.starts_with("letp")))) {
6760 // These mnemonics are never predicable
6761 CanAcceptPredicationCode = false;
6762 } else if (!isThumb()) {
6763 // Some instructions are only predicable in Thumb mode
6764 CanAcceptPredicationCode =
6765 Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" &&
6766 Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" &&
6767 Mnemonic != "dmb" && Mnemonic != "dfb" && Mnemonic != "dsb" &&
6768 Mnemonic != "isb" && Mnemonic != "pld" && Mnemonic != "pli" &&
6769 Mnemonic != "pldw" && Mnemonic != "ldc2" && Mnemonic != "ldc2l" &&
6770 Mnemonic != "stc2" && Mnemonic != "stc2l" && Mnemonic != "tsb" &&
6771 !Mnemonic.starts_with("rfe") && !Mnemonic.starts_with("srs");
6772 } else if (isThumbOne()) {
6773 if (hasV6MOps())
6774 CanAcceptPredicationCode = Mnemonic != "movs";
6775 else
6776 CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs";
6777 } else
6778 CanAcceptPredicationCode = true;
6779}
6780
6781bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6782 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I) {
6783 auto &Op = static_cast<ARMOperand &>(*Operands[I]);
6784 if (Op.isToken() && Op.getToken() == ".w")
6785 return true;
6786 }
6787 return false;
6788}
6789
6790// Some Thumb instructions have two operand forms that are not
6791// available as three operand, convert to two operand form if possible.
6792//
6793// FIXME: We would really like to be able to tablegen'erate this.
6794void ARMAsmParser::tryConvertingToTwoOperandForm(
6795 StringRef Mnemonic, ARMCC::CondCodes PredicationCode, bool CarrySetting,
6796 OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6797
6798 if (operandsContainWide(Operands, MnemonicOpsEndInd))
6799 return;
6800 if (Operands.size() != MnemonicOpsEndInd + 3)
6801 return;
6802
6803 const auto &Op3 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
6804 auto &Op4 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
6805 if (!Op3.isReg() || !Op4.isReg())
6806 return;
6807
6808 auto Op3Reg = Op3.getReg();
6809 auto Op4Reg = Op4.getReg();
6810
6811 // For most Thumb2 cases we just generate the 3 operand form and reduce
6812 // it in processInstruction(), but the 3 operand form of ADD (t2ADDrr)
6813 // won't accept SP or PC so we do the transformation here taking care
6814 // with immediate range in the 'add sp, sp #imm' case.
6815 auto &Op5 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 2]);
6816 if (isThumbTwo()) {
6817 if (Mnemonic != "add")
6818 return;
6819 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6820 (Op5.isReg() && Op5.getReg() == ARM::PC);
6821 if (!TryTransform) {
6822 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6823 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6824 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6825 Op5.isImm() && !Op5.isImm0_508s4());
6826 }
6827 if (!TryTransform)
6828 return;
6829 } else if (!isThumbOne())
6830 return;
6831
6832 if (!(Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
6833 Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
6834 Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
6835 Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic"))
6836 return;
6837
6838 // If first 2 operands of a 3 operand instruction are the same
6839 // then transform to 2 operand version of the same instruction
6840 // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
6841 bool Transform = Op3Reg == Op4Reg;
6842
6843 // For communtative operations, we might be able to transform if we swap
6844 // Op4 and Op5. The 'ADD Rdm, SP, Rdm' form is already handled specially
6845 // as tADDrsp.
6846 const ARMOperand *LastOp = &Op5;
6847 bool Swap = false;
6848 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6849 ((Mnemonic == "add" && Op4Reg != ARM::SP) ||
6850 Mnemonic == "and" || Mnemonic == "eor" ||
6851 Mnemonic == "adc" || Mnemonic == "orr")) {
6852 Swap = true;
6853 LastOp = &Op4;
6854 Transform = true;
6855 }
6856
6857 // If both registers are the same then remove one of them from
6858 // the operand list, with certain exceptions.
6859 if (Transform) {
6860 // Don't transform 'adds Rd, Rd, Rm' or 'sub{s} Rd, Rd, Rm' because the
6861 // 2 operand forms don't exist.
6862 if (((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub") &&
6863 LastOp->isReg())
6864 Transform = false;
6865
6866 // Don't transform 'add/sub{s} Rd, Rd, #imm' if the immediate fits into
6867 // 3-bits because the ARMARM says not to.
6868 if ((Mnemonic == "add" || Mnemonic == "sub") && LastOp->isImm0_7())
6869 Transform = false;
6870 }
6871
6872 if (Transform) {
6873 if (Swap)
6874 std::swap(Op4, Op5);
6875 Operands.erase(Operands.begin() + MnemonicOpsEndInd);
6876 }
6877}
6878
6879static bool isARMMCExpr(MCParsedAsmOperand &MCOp);
6880// this function returns true if the operand is one of the following
6881// relocations: :upper8_15:, :upper0_7:, :lower8_15: or :lower0_7:
6883 assert(isARMMCExpr(MCOp));
6884 ARMOperand &Op = static_cast<ARMOperand &>(MCOp);
6885 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(Op.getImm());
6886 if (ARM16Expr && (ARM16Expr->getSpecifier() == ARM::S_HI_8_15 ||
6887 ARM16Expr->getSpecifier() == ARM::S_HI_0_7 ||
6888 ARM16Expr->getSpecifier() == ARM::S_LO_8_15 ||
6889 ARM16Expr->getSpecifier() == ARM::S_LO_0_7))
6890 return true;
6891 return false;
6892}
6893
6894bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6895 StringRef Mnemonic, OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6896 if (!hasMVE() || Operands.size() <= MnemonicOpsEndInd)
6897 return true;
6898
6899 if (Mnemonic.starts_with("vld2") || Mnemonic.starts_with("vld4") ||
6900 Mnemonic.starts_with("vst2") || Mnemonic.starts_with("vst4"))
6901 return true;
6902
6903 if (Mnemonic.starts_with("vctp") || Mnemonic.starts_with("vpnot"))
6904 return false;
6905
6906 if (Mnemonic.starts_with("vmov") &&
6907 !(Mnemonic.starts_with("vmovl") || Mnemonic.starts_with("vmovn") ||
6908 Mnemonic.starts_with("vmovx"))) {
6909 for (auto &Operand : Operands) {
6910 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() ||
6911 ((*Operand).isReg() &&
6912 (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(
6913 (*Operand).getReg()) ||
6914 ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
6915 (*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,
6954 OperandVector &Operands,
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,
7003 OperandVector &Operands,
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 the original name "subs" and delete the predicate
7472 // operand so it will match the table entry.
7473 if (isThumbTwo() && Mnemonic == "sub" &&
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(Name, 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
7528unsigned getRegListInd(const OperandVector &Operands,
7529 unsigned MnemonicOpsEndInd) {
7530 for (unsigned I = MnemonicOpsEndInd; I < Operands.size(); ++I) {
7531 const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[I]);
7532 if (Op.isRegList()) {
7533 return I;
7534 }
7535 }
7536 return 0;
7537}
7538
7539bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst,
7540 const OperandVector &Operands,
7541 unsigned MnemonicOpsEndInd,
7542 unsigned ListIndex, bool IsARPop) {
7543 bool ListContainsSP = listContainsReg(Inst, ListIndex, ARM::SP);
7544 bool ListContainsLR = listContainsReg(Inst, ListIndex, ARM::LR);
7545 bool ListContainsPC = listContainsReg(Inst, ListIndex, ARM::PC);
7546
7547 if (!IsARPop && ListContainsSP)
7548 return Error(
7549 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7550 "SP may not be in the register list");
7551 if (ListContainsPC && ListContainsLR)
7552 return Error(
7553 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7554 "PC and LR may not be in the register list simultaneously");
7555 return false;
7556}
7557
7558bool ARMAsmParser::validatetSTMRegList(const MCInst &Inst,
7559 const OperandVector &Operands,
7560 unsigned MnemonicOpsEndInd,
7561 unsigned ListIndex) {
7562 bool ListContainsSP = listContainsReg(Inst, ListIndex, ARM::SP);
7563 bool ListContainsPC = listContainsReg(Inst, ListIndex, ARM::PC);
7564
7565 if (ListContainsSP && ListContainsPC)
7566 return Error(
7567 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7568 "SP and PC may not be in the register list");
7569 if (ListContainsSP)
7570 return Error(
7571 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7572 "SP may not be in the register list");
7573 if (ListContainsPC)
7574 return Error(
7575 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7576 "PC may not be in the register list");
7577 return false;
7578}
7579
7580bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
7581 bool Load, bool ARMMode, bool Writeback,
7582 unsigned MnemonicOpsEndInd) {
7583 unsigned RtIndex = Load || !Writeback ? 0 : 1;
7584 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(RtIndex).getReg());
7585 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(RtIndex + 1).getReg());
7586
7587 if (ARMMode) {
7588 // Rt can't be R14.
7589 if (Rt == 14)
7590 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7591 "Rt can't be R14");
7592
7593 // Rt must be even-numbered.
7594 if ((Rt & 1) == 1)
7595 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7596 "Rt must be even-numbered");
7597
7598 // Rt2 must be Rt + 1.
7599 if (Rt2 != Rt + 1) {
7600 if (Load)
7601 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7602 "destination operands must be sequential");
7603 else
7604 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7605 "source operands must be sequential");
7606 }
7607
7608 // FIXME: Diagnose m == 15
7609 // FIXME: Diagnose ldrd with m == t || m == t2.
7610 }
7611
7612 if (!ARMMode && Load) {
7613 if (Rt2 == Rt)
7614 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7615 "destination operands can't be identical");
7616 }
7617
7618 if (Writeback) {
7619 unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg());
7620
7621 if (Rn == Rt || Rn == Rt2) {
7622 if (Load)
7623 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7624 "base register needs to be different from destination "
7625 "registers");
7626 else
7627 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7628 "source register and base register can't be identical");
7629 }
7630
7631 // FIXME: Diagnose ldrd/strd with writeback and n == 15.
7632 // (Except the immediate form of ldrd?)
7633 }
7634
7635 return false;
7636}
7637
7639 for (unsigned i = 0; i < MCID.NumOperands; ++i) {
7640 if (ARM::isVpred(MCID.operands()[i].OperandType))
7641 return i;
7642 }
7643 return -1;
7644}
7645
7647 return findFirstVectorPredOperandIdx(MCID) != -1;
7648}
7649
7651 ARMOperand &Op = static_cast<ARMOperand &>(MCOp);
7652 if (!Op.isImm())
7653 return false;
7654 return !isa<MCConstantExpr>(Op.getImm());
7655}
7656
7657// FIXME: We would really like to be able to tablegen'erate this.
7658bool ARMAsmParser::validateInstruction(MCInst &Inst,
7659 const OperandVector &Operands,
7660 unsigned MnemonicOpsEndInd) {
7661 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
7662 SMLoc Loc = Operands[0]->getStartLoc();
7663
7664 // Check the IT block state first.
7665 // NOTE: BKPT and HLT instructions have the interesting property of being
7666 // allowed in IT blocks, but not being predicable. They just always execute.
7667 if (inITBlock() && !instIsBreakpoint(Inst)) {
7668 // The instruction must be predicable.
7669 if (!MCID.isPredicable())
7670 return Error(Loc, "instructions in IT block must be predicable");
7673 if (Cond != currentITCond()) {
7674 // Find the condition code Operand to get its SMLoc information.
7675 SMLoc CondLoc = Operands[0]->getEndLoc();
7676 for (unsigned I = 1; I < Operands.size(); ++I)
7677 if (static_cast<ARMOperand &>(*Operands[I]).isCondCode())
7678 CondLoc = Operands[I]->getStartLoc();
7679 return Error(CondLoc, "incorrect condition in IT block; got '" +
7680 StringRef(ARMCondCodeToString(Cond)) +
7681 "', but expected '" +
7682 ARMCondCodeToString(currentITCond()) + "'");
7683 }
7684 // Check for non-'al' condition codes outside of the IT block.
7685 } else if (isThumbTwo() && MCID.isPredicable() &&
7686 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
7687 ARMCC::AL && Inst.getOpcode() != ARM::tBcc &&
7688 Inst.getOpcode() != ARM::t2Bcc &&
7689 Inst.getOpcode() != ARM::t2BFic) {
7690 return Error(Loc, "predicated instructions must be in IT block");
7691 } else if (!isThumb() && !useImplicitITARM() && MCID.isPredicable() &&
7692 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
7693 ARMCC::AL) {
7694 return Warning(Loc, "predicated instructions should be in IT block");
7695 } else if (!MCID.isPredicable()) {
7696 // Check the instruction doesn't have a predicate operand anyway
7697 // that it's not allowed to use. Sometimes this happens in order
7698 // to keep instructions the same shape even though one cannot
7699 // legally be predicated, e.g. vmul.f16 vs vmul.f32.
7700 for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i) {
7701 if (MCID.operands()[i].isPredicate()) {
7702 if (Inst.getOperand(i).getImm() != ARMCC::AL)
7703 return Error(Loc, "instruction is not predicable");
7704 break;
7705 }
7706 }
7707 }
7708
7709 // PC-setting instructions in an IT block, but not the last instruction of
7710 // the block, are UNPREDICTABLE.
7711 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
7712 return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block");
7713 }
7714
7715 if (inVPTBlock() && !instIsBreakpoint(Inst)) {
7716 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
7717 if (!isVectorPredicable(MCID))
7718 return Error(Loc, "instruction in VPT block must be predicable");
7719 unsigned Pred = Inst.getOperand(findFirstVectorPredOperandIdx(MCID)).getImm();
7720 unsigned VPTPred = Bit ? ARMVCC::Else : ARMVCC::Then;
7721 if (Pred != VPTPred) {
7722 SMLoc PredLoc;
7723 for (unsigned I = 1; I < Operands.size(); ++I)
7724 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred())
7725 PredLoc = Operands[I]->getStartLoc();
7726 return Error(PredLoc, "incorrect predication in VPT block; got '" +
7727 StringRef(ARMVPTPredToString(ARMVCC::VPTCodes(Pred))) +
7728 "', but expected '" +
7729 ARMVPTPredToString(ARMVCC::VPTCodes(VPTPred)) + "'");
7730 }
7731 }
7732 else if (isVectorPredicable(MCID) &&
7735 return Error(Loc, "VPT predicated instructions must be in VPT block");
7736
7737 const unsigned Opcode = Inst.getOpcode();
7738 switch (Opcode) {
7739 case ARM::VLLDM:
7740 case ARM::VLLDM_T2:
7741 case ARM::VLSTM:
7742 case ARM::VLSTM_T2: {
7743 // Since in some cases both T1 and T2 are valid, tablegen can not always
7744 // pick the correct instruction.
7745 if (Operands.size() ==
7746 MnemonicOpsEndInd + 2) { // a register list has been provided
7747 ARMOperand &Op = static_cast<ARMOperand &>(
7748 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
7749 assert(Op.isDPRRegList());
7750 auto &RegList = Op.getRegList();
7751 // T2 requires v8.1-M.Main (cannot be handled by tablegen)
7752 if (RegList.size() == 32 && !hasV8_1MMainline()) {
7753 return Error(Op.getEndLoc(), "T2 version requires v8.1-M.Main");
7754 }
7755 // When target has 32 D registers, T1 is undefined.
7756 if (hasD32() && RegList.size() != 32) {
7757 return Error(Op.getEndLoc(), "operand must be exactly {d0-d31}");
7758 }
7759 // When target has 16 D registers, both T1 and T2 are valid.
7760 if (!hasD32() && (RegList.size() != 16 && RegList.size() != 32)) {
7761 return Error(Op.getEndLoc(),
7762 "operand must be exactly {d0-d15} (T1) or {d0-d31} (T2)");
7763 }
7764 }
7765 return false;
7766 }
7767 case ARM::t2IT: {
7768 // Encoding is unpredictable if it ever results in a notional 'NV'
7769 // predicate. Since we don't parse 'NV' directly this means an 'AL'
7770 // predicate with an "else" mask bit.
7771 unsigned Cond = Inst.getOperand(0).getImm();
7772 unsigned Mask = Inst.getOperand(1).getImm();
7773
7774 // Conditions only allowing a 't' are those with no set bit except
7775 // the lowest-order one that indicates the end of the sequence. In
7776 // other words, powers of 2.
7777 if (Cond == ARMCC::AL && llvm::popcount(Mask) != 1)
7778 return Error(Loc, "unpredictable IT predicate sequence");
7779 break;
7780 }
7781 case ARM::LDRD:
7782 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ true,
7783 /*Writeback*/ false, MnemonicOpsEndInd))
7784 return true;
7785 break;
7786 case ARM::LDRD_PRE:
7787 case ARM::LDRD_POST:
7788 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ true,
7789 /*Writeback*/ true, MnemonicOpsEndInd))
7790 return true;
7791 break;
7792 case ARM::t2LDRDi8:
7793 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ false,
7794 /*Writeback*/ false, MnemonicOpsEndInd))
7795 return true;
7796 break;
7797 case ARM::t2LDRD_PRE:
7798 case ARM::t2LDRD_POST:
7799 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ false,
7800 /*Writeback*/ true, MnemonicOpsEndInd))
7801 return true;
7802 break;
7803 case ARM::t2BXJ: {
7804 const MCRegister RmReg = Inst.getOperand(0).getReg();
7805 // Rm = SP is no longer unpredictable in v8-A
7806 if (RmReg == ARM::SP && !hasV8Ops())
7807 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7808 "r13 (SP) is an unpredictable operand to BXJ");
7809 return false;
7810 }
7811 case ARM::STRD:
7812 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ true,
7813 /*Writeback*/ false, MnemonicOpsEndInd))
7814 return true;
7815 break;
7816 case ARM::STRD_PRE:
7817 case ARM::STRD_POST:
7818 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ true,
7819 /*Writeback*/ true, MnemonicOpsEndInd))
7820 return true;
7821 break;
7822 case ARM::t2STRD_PRE:
7823 case ARM::t2STRD_POST:
7824 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ false,
7825 /*Writeback*/ true, MnemonicOpsEndInd))
7826 return true;
7827 break;
7828 case ARM::STR_PRE_IMM:
7829 case ARM::STR_PRE_REG:
7830 case ARM::t2STR_PRE:
7831 case ARM::STR_POST_IMM:
7832 case ARM::STR_POST_REG:
7833 case ARM::t2STR_POST:
7834 case ARM::STRH_PRE:
7835 case ARM::t2STRH_PRE:
7836 case ARM::STRH_POST:
7837 case ARM::t2STRH_POST:
7838 case ARM::STRB_PRE_IMM:
7839 case ARM::STRB_PRE_REG:
7840 case ARM::t2STRB_PRE:
7841 case ARM::STRB_POST_IMM:
7842 case ARM::STRB_POST_REG:
7843 case ARM::t2STRB_POST: {
7844 // Rt must be different from Rn.
7845 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7846 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
7847
7848 if (Rt == Rn)
7849 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7850 "source register and base register can't be identical");
7851 return false;
7852 }
7853 case ARM::t2LDR_PRE_imm:
7854 case ARM::t2LDR_POST_imm:
7855 case ARM::t2STR_PRE_imm:
7856 case ARM::t2STR_POST_imm: {
7857 // Rt must be different from Rn.
7858 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
7859 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7860
7861 if (Rt == Rn)
7862 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7863 "destination register and base register can't be identical");
7864 if (Inst.getOpcode() == ARM::t2LDR_POST_imm ||
7865 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7866 int Imm = Inst.getOperand(2).getImm();
7867 if (Imm > 255 || Imm < -255)
7868 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7869 "operand must be in range [-255, 255]");
7870 }
7871 if (Inst.getOpcode() == ARM::t2STR_PRE_imm ||
7872 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7873 if (Inst.getOperand(0).getReg() == ARM::PC) {
7874 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7875 "operand must be a register in range [r0, r14]");
7876 }
7877 }
7878 return false;
7879 }
7880
7881 case ARM::t2LDRB_OFFSET_imm:
7882 case ARM::t2LDRB_PRE_imm:
7883 case ARM::t2LDRB_POST_imm:
7884 case ARM::t2STRB_OFFSET_imm:
7885 case ARM::t2STRB_PRE_imm:
7886 case ARM::t2STRB_POST_imm: {
7887 if (Inst.getOpcode() == ARM::t2LDRB_POST_imm ||
7888 Inst.getOpcode() == ARM::t2STRB_POST_imm ||
7889 Inst.getOpcode() == ARM::t2LDRB_PRE_imm ||
7890 Inst.getOpcode() == ARM::t2STRB_PRE_imm) {
7891 int Imm = Inst.getOperand(2).getImm();
7892 if (Imm > 255 || Imm < -255)
7893 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7894 "operand must be in range [-255, 255]");
7895 } else if (Inst.getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7896 Inst.getOpcode() == ARM::t2STRB_OFFSET_imm) {
7897 int Imm = Inst.getOperand(2).getImm();
7898 if (Imm > 0 || Imm < -255)
7899 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7900 "operand must be in range [0, 255] with a negative sign");
7901 }
7902 if (Inst.getOperand(0).getReg() == ARM::PC) {
7903 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7904 "if operand is PC, should call the LDRB (literal)");
7905 }
7906 return false;
7907 }
7908
7909 case ARM::t2LDRH_OFFSET_imm:
7910 case ARM::t2LDRH_PRE_imm:
7911 case ARM::t2LDRH_POST_imm:
7912 case ARM::t2STRH_OFFSET_imm:
7913 case ARM::t2STRH_PRE_imm:
7914 case ARM::t2STRH_POST_imm: {
7915 if (Inst.getOpcode() == ARM::t2LDRH_POST_imm ||
7916 Inst.getOpcode() == ARM::t2STRH_POST_imm ||
7917 Inst.getOpcode() == ARM::t2LDRH_PRE_imm ||
7918 Inst.getOpcode() == ARM::t2STRH_PRE_imm) {
7919 int Imm = Inst.getOperand(2).getImm();
7920 if (Imm > 255 || Imm < -255)
7921 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7922 "operand must be in range [-255, 255]");
7923 } else if (Inst.getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7924 Inst.getOpcode() == ARM::t2STRH_OFFSET_imm) {
7925 int Imm = Inst.getOperand(2).getImm();
7926 if (Imm > 0 || Imm < -255)
7927 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7928 "operand must be in range [0, 255] with a negative sign");
7929 }
7930 if (Inst.getOperand(0).getReg() == ARM::PC) {
7931 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7932 "if operand is PC, should call the LDRH (literal)");
7933 }
7934 return false;
7935 }
7936
7937 case ARM::t2LDRSB_OFFSET_imm:
7938 case ARM::t2LDRSB_PRE_imm:
7939 case ARM::t2LDRSB_POST_imm: {
7940 if (Inst.getOpcode() == ARM::t2LDRSB_POST_imm ||
7941 Inst.getOpcode() == ARM::t2LDRSB_PRE_imm) {
7942 int Imm = Inst.getOperand(2).getImm();
7943 if (Imm > 255 || Imm < -255)
7944 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7945 "operand must be in range [-255, 255]");
7946 } else if (Inst.getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7947 int Imm = Inst.getOperand(2).getImm();
7948 if (Imm > 0 || Imm < -255)
7949 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7950 "operand must be in range [0, 255] with a negative sign");
7951 }
7952 if (Inst.getOperand(0).getReg() == ARM::PC) {
7953 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7954 "if operand is PC, should call the LDRH (literal)");
7955 }
7956 return false;
7957 }
7958
7959 case ARM::t2LDRSH_OFFSET_imm:
7960 case ARM::t2LDRSH_PRE_imm:
7961 case ARM::t2LDRSH_POST_imm: {
7962 if (Inst.getOpcode() == ARM::t2LDRSH_POST_imm ||
7963 Inst.getOpcode() == ARM::t2LDRSH_PRE_imm) {
7964 int Imm = Inst.getOperand(2).getImm();
7965 if (Imm > 255 || Imm < -255)
7966 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7967 "operand must be in range [-255, 255]");
7968 } else if (Inst.getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7969 int Imm = Inst.getOperand(2).getImm();
7970 if (Imm > 0 || Imm < -255)
7971 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7972 "operand must be in range [0, 255] with a negative sign");
7973 }
7974 if (Inst.getOperand(0).getReg() == ARM::PC) {
7975 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7976 "if operand is PC, should call the LDRH (literal)");
7977 }
7978 return false;
7979 }
7980
7981 case ARM::LDR_PRE_IMM:
7982 case ARM::LDR_PRE_REG:
7983 case ARM::t2LDR_PRE:
7984 case ARM::LDR_POST_IMM:
7985 case ARM::LDR_POST_REG:
7986 case ARM::t2LDR_POST:
7987 case ARM::LDRH_PRE:
7988 case ARM::t2LDRH_PRE:
7989 case ARM::LDRH_POST:
7990 case ARM::t2LDRH_POST:
7991 case ARM::LDRSH_PRE:
7992 case ARM::t2LDRSH_PRE:
7993 case ARM::LDRSH_POST:
7994 case ARM::t2LDRSH_POST:
7995 case ARM::LDRB_PRE_IMM:
7996 case ARM::LDRB_PRE_REG:
7997 case ARM::t2LDRB_PRE:
7998 case ARM::LDRB_POST_IMM:
7999 case ARM::LDRB_POST_REG:
8000 case ARM::t2LDRB_POST:
8001 case ARM::LDRSB_PRE:
8002 case ARM::t2LDRSB_PRE:
8003 case ARM::LDRSB_POST:
8004 case ARM::t2LDRSB_POST: {
8005 // Rt must be different from Rn.
8006 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8007 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8008
8009 if (Rt == Rn)
8010 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8011 "destination register and base register can't be identical");
8012 return false;
8013 }
8014
8015 case ARM::MVE_VLDRBU8_rq:
8016 case ARM::MVE_VLDRBU16_rq:
8017 case ARM::MVE_VLDRBS16_rq:
8018 case ARM::MVE_VLDRBU32_rq:
8019 case ARM::MVE_VLDRBS32_rq:
8020 case ARM::MVE_VLDRHU16_rq:
8021 case ARM::MVE_VLDRHU16_rq_u:
8022 case ARM::MVE_VLDRHU32_rq:
8023 case ARM::MVE_VLDRHU32_rq_u:
8024 case ARM::MVE_VLDRHS32_rq:
8025 case ARM::MVE_VLDRHS32_rq_u:
8026 case ARM::MVE_VLDRWU32_rq:
8027 case ARM::MVE_VLDRWU32_rq_u:
8028 case ARM::MVE_VLDRDU64_rq:
8029 case ARM::MVE_VLDRDU64_rq_u:
8030 case ARM::MVE_VLDRWU32_qi:
8031 case ARM::MVE_VLDRWU32_qi_pre:
8032 case ARM::MVE_VLDRDU64_qi:
8033 case ARM::MVE_VLDRDU64_qi_pre: {
8034 // Qd must be different from Qm.
8035 unsigned QdIdx = 0, QmIdx = 2;
8036 bool QmIsPointer = false;
8037 switch (Opcode) {
8038 case ARM::MVE_VLDRWU32_qi:
8039 case ARM::MVE_VLDRDU64_qi:
8040 QmIdx = 1;
8041 QmIsPointer = true;
8042 break;
8043 case ARM::MVE_VLDRWU32_qi_pre:
8044 case ARM::MVE_VLDRDU64_qi_pre:
8045 QdIdx = 1;
8046 QmIsPointer = true;
8047 break;
8048 }
8049
8050 const unsigned Qd = MRI->getEncodingValue(Inst.getOperand(QdIdx).getReg());
8051 const unsigned Qm = MRI->getEncodingValue(Inst.getOperand(QmIdx).getReg());
8052
8053 if (Qd == Qm) {
8054 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8055 Twine("destination vector register and vector ") +
8056 (QmIsPointer ? "pointer" : "offset") +
8057 " register can't be identical");
8058 }
8059 return false;
8060 }
8061
8062 case ARM::SBFX:
8063 case ARM::t2SBFX:
8064 case ARM::UBFX:
8065 case ARM::t2UBFX: {
8066 // Width must be in range [1, 32-lsb].
8067 unsigned LSB = Inst.getOperand(2).getImm();
8068 unsigned Widthm1 = Inst.getOperand(3).getImm();
8069 if (Widthm1 >= 32 - LSB)
8070 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8071 "bitfield width must be in range [1,32-lsb]");
8072 return false;
8073 }
8074 // Notionally handles ARM::tLDMIA_UPD too.
8075 case ARM::tLDMIA: {
8076 // If we're parsing Thumb2, the .w variant is available and handles
8077 // most cases that are normally illegal for a Thumb1 LDM instruction.
8078 // We'll make the transformation in processInstruction() if necessary.
8079 //
8080 // Thumb LDM instructions are writeback iff the base register is not
8081 // in the register list.
8082 MCRegister Rn = Inst.getOperand(0).getReg();
8083 bool HasWritebackToken =
8084 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8085 .isToken() &&
8086 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8087 .getToken() == "!");
8088
8089 bool ListContainsBase;
8090 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), ListContainsBase) &&
8091 !isThumbTwo())
8092 return Error(
8093 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8094 "registers must be in range r0-r7");
8095 // If we should have writeback, then there should be a '!' token.
8096 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8097 return Error(
8098 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8099 "writeback operator '!' expected");
8100 // If we should not have writeback, there must not be a '!'. This is
8101 // true even for the 32-bit wide encodings.
8102 if (ListContainsBase && HasWritebackToken)
8103 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8104 "writeback operator '!' not allowed when base register "
8105 "in register list");
8106
8107 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8108 return true;
8109 break;
8110 }
8111 case ARM::LDMIA_UPD:
8112 case ARM::LDMDB_UPD:
8113 case ARM::LDMIB_UPD:
8114 case ARM::LDMDA_UPD:
8115 // ARM variants loading and updating the same register are only officially
8116 // UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
8117 if (!hasV7Ops())
8118 break;
8119 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8120 return Error(Operands.back()->getStartLoc(),
8121 "writeback register not allowed in register list");
8122 break;
8123 case ARM::t2LDMIA:
8124 case ARM::t2LDMDB:
8125 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8126 return true;
8127 break;
8128 case ARM::t2STMIA:
8129 case ARM::t2STMDB:
8130 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8131 return true;
8132 break;
8133 case ARM::t2LDMIA_UPD:
8134 case ARM::t2LDMDB_UPD:
8135 case ARM::t2STMIA_UPD:
8136 case ARM::t2STMDB_UPD:
8137 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8138 return Error(Operands.back()->getStartLoc(),
8139 "writeback register not allowed in register list");
8140
8141 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8142 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8143 return true;
8144 } else {
8145 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8146 return true;
8147 }
8148 break;
8149
8150 case ARM::sysLDMIA_UPD:
8151 case ARM::sysLDMDA_UPD:
8152 case ARM::sysLDMDB_UPD:
8153 case ARM::sysLDMIB_UPD:
8154 if (!listContainsReg(Inst, 3, ARM::PC))
8155 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8156 "writeback register only allowed on system LDM "
8157 "if PC in register-list");
8158 break;
8159 case ARM::sysSTMIA_UPD:
8160 case ARM::sysSTMDA_UPD:
8161 case ARM::sysSTMDB_UPD:
8162 case ARM::sysSTMIB_UPD:
8163 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8164 "system STM cannot have writeback register");
8165 // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
8166 // so only issue a diagnostic for thumb1. The instructions will be
8167 // switched to the t2 encodings in processInstruction() if necessary.
8168 case ARM::tPOP: {
8169 bool ListContainsBase;
8170 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC,
8171 ListContainsBase) &&
8172 !isThumbTwo())
8173 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8174 "registers must be in range r0-r7 or pc");
8175 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 2, !isMClass()))
8176 return true;
8177 break;
8178 }
8179 case ARM::tPUSH: {
8180 bool ListContainsBase;
8181 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR,
8182 ListContainsBase) &&
8183 !isThumbTwo())
8184 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8185 "registers must be in range r0-r7 or lr");
8186 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 2))
8187 return true;
8188 break;
8189 }
8190 case ARM::tSTMIA_UPD: {
8191 bool ListContainsBase, InvalidLowList;
8192 InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(),
8193 0, ListContainsBase);
8194 if (InvalidLowList && !isThumbTwo())
8195 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8196 "registers must be in range r0-r7");
8197
8198 // This would be converted to a 32-bit stm, but that's not valid if the
8199 // writeback register is in the list.
8200 if (InvalidLowList && ListContainsBase)
8201 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8202 "writeback operator '!' not allowed when base register "
8203 "in register list");
8204
8205 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 4))
8206 return true;
8207 break;
8208 }
8209 case ARM::tADDrSP:
8210 // If the non-SP source operand and the destination operand are not the
8211 // same, we need thumb2 (for the wide encoding), or we have an error.
8212 if (!isThumbTwo() &&
8213 Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
8214 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8215 "source register must be the same as destination");
8216 }
8217 break;
8218
8219 case ARM::t2ADDrr:
8220 case ARM::t2ADDrs:
8221 case ARM::t2SUBrr:
8222 case ARM::t2SUBrs:
8223 if (Inst.getOperand(0).getReg() == ARM::SP &&
8224 Inst.getOperand(1).getReg() != ARM::SP)
8225 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8226 "source register must be sp if destination is sp");
8227 break;
8228
8229 // Final range checking for Thumb unconditional branch instructions.
8230 case ARM::tB:
8231 if (!(static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]))
8232 .isSignedOffset<11, 1>())
8233 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8234 "branch target out of range");
8235 break;
8236 case ARM::t2B: {
8237 int op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8238 : MnemonicOpsEndInd + 1;
8239 ARMOperand &Operand = static_cast<ARMOperand &>(*Operands[op]);
8240 // Delay the checks of symbolic expressions until they are resolved.
8241 if (!isa<MCBinaryExpr>(Operand.getImm()) &&
8242 !Operand.isSignedOffset<24, 1>())
8243 return Error(Operands[op]->getStartLoc(), "branch target out of range");
8244 break;
8245 }
8246 // Final range checking for Thumb conditional branch instructions.
8247 case ARM::tBcc:
8248 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8249 .isSignedOffset<8, 1>())
8250 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8251 "branch target out of range");
8252 break;
8253 case ARM::t2Bcc: {
8254 int Op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8255 : MnemonicOpsEndInd + 1;
8256 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
8257 return Error(Operands[Op]->getStartLoc(), "branch target out of range");
8258 break;
8259 }
8260 case ARM::tCBZ:
8261 case ARM::tCBNZ: {
8262 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8263 .isUnsignedOffset<6, 1>())
8264 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8265 "branch target out of range");
8266 break;
8267 }
8268 case ARM::MOVi16:
8269 case ARM::MOVTi16:
8270 case ARM::t2MOVi16:
8271 case ARM::t2MOVTi16:
8272 {
8273 // We want to avoid misleadingly allowing something like "mov r0, <symbol>"
8274 // especially when we turn it into a movw and the expression <symbol> does
8275 // not have a :lower16: or :upper16 as part of the expression. We don't
8276 // want the behavior of silently truncating, which can be unexpected and
8277 // lead to bugs that are difficult to find since this is an easy mistake
8278 // to make.
8279 int i = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8280 : MnemonicOpsEndInd + 1;
8281 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[i]);
8282 const MCExpr *E = Op.getImm();
8284 break;
8285 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(E);
8286 if (!ARM16Expr || (ARM16Expr->getSpecifier() != ARM::S_HI16 &&
8287 ARM16Expr->getSpecifier() != ARM::S_LO16))
8288 return Error(
8289 Op.getStartLoc(),
8290 "immediate expression for mov requires :lower16: or :upper16");
8291 break;
8292 }
8293 case ARM::tADDi8: {
8294 int i = (Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8295 : MnemonicOpsEndInd + 2;
8296 MCParsedAsmOperand &Op = *Operands[i];
8298 return Error(Op.getStartLoc(),
8299 "Immediate expression for Thumb adds requires :lower0_7:,"
8300 " :lower8_15:, :upper0_7: or :upper8_15:");
8301 break;
8302 }
8303 case ARM::tMOVi8: {
8304 MCParsedAsmOperand &Op = *Operands[MnemonicOpsEndInd + 1];
8306 return Error(Op.getStartLoc(),
8307 "Immediate expression for Thumb movs requires :lower0_7:,"
8308 " :lower8_15:, :upper0_7: or :upper8_15:");
8309 break;
8310 }
8311 case ARM::HINT:
8312 case ARM::t2HINT: {
8313 unsigned Imm8 = Inst.getOperand(0).getImm();
8314 unsigned Pred = Inst.getOperand(1).getImm();
8315 // ESB is not predicable (pred must be AL). Without the RAS extension, this
8316 // behaves as any other unallocated hint.
8317 if (Imm8 == 0x10 && Pred != ARMCC::AL && hasRAS())
8318 return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not "
8319 "predicable, but condition "
8320 "code specified");
8321 if (Imm8 == 0x14 && Pred != ARMCC::AL)
8322 return Error(Operands[1]->getStartLoc(), "instruction 'csdb' is not "
8323 "predicable, but condition "
8324 "code specified");
8325 break;
8326 }
8327 case ARM::t2BFi:
8328 case ARM::t2BFr:
8329 case ARM::t2BFLi:
8330 case ARM::t2BFLr: {
8331 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8332 .isUnsignedOffset<4, 1>() ||
8333 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0)) {
8334 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8335 "branch location out of range or not a multiple of 2");
8336 }
8337
8338 if (Opcode == ARM::t2BFi) {
8339 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8340 .isSignedOffset<16, 1>())
8341 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8342 "branch target out of range or not a multiple of 2");
8343 } else if (Opcode == ARM::t2BFLi) {
8344 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8345 .isSignedOffset<18, 1>())
8346 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8347 "branch target out of range or not a multiple of 2");
8348 }
8349 break;
8350 }
8351 case ARM::t2BFic: {
8352 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8353 .isUnsignedOffset<4, 1>() ||
8354 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0))
8355 return Error(Operands[1]->getStartLoc(),
8356 "branch location out of range or not a multiple of 2");
8357
8358 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8359 .isSignedOffset<16, 1>())
8360 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8361 "branch target out of range or not a multiple of 2");
8362
8363 assert(Inst.getOperand(0).isImm() == Inst.getOperand(2).isImm() &&
8364 "branch location and else branch target should either both be "
8365 "immediates or both labels");
8366
8367 if (Inst.getOperand(0).isImm() && Inst.getOperand(2).isImm()) {
8368 int Diff = Inst.getOperand(2).getImm() - Inst.getOperand(0).getImm();
8369 if (Diff != 4 && Diff != 2)
8370 return Error(
8371 Operands[3]->getStartLoc(),
8372 "else branch target must be 2 or 4 greater than the branch location");
8373 }
8374 break;
8375 }
8376 case ARM::t2CLRM: {
8377 for (unsigned i = 2; i < Inst.getNumOperands(); i++) {
8378 if (Inst.getOperand(i).isReg() &&
8379 !ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(
8380 Inst.getOperand(i).getReg())) {
8381 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8382 "invalid register in register list. Valid registers are "
8383 "r0-r12, lr/r14 and APSR.");
8384 }
8385 }
8386 break;
8387 }
8388 case ARM::DSB:
8389 case ARM::t2DSB: {
8390
8391 if (Inst.getNumOperands() < 2)
8392 break;
8393
8394 unsigned Option = Inst.getOperand(0).getImm();
8395 unsigned Pred = Inst.getOperand(1).getImm();
8396
8397 // SSBB and PSSBB (DSB #0|#4) are not predicable (pred must be AL).
8398 if (Option == 0 && Pred != ARMCC::AL)
8399 return Error(Operands[1]->getStartLoc(),
8400 "instruction 'ssbb' is not predicable, but condition code "
8401 "specified");
8402 if (Option == 4 && Pred != ARMCC::AL)
8403 return Error(Operands[1]->getStartLoc(),
8404 "instruction 'pssbb' is not predicable, but condition code "
8405 "specified");
8406 break;
8407 }
8408 case ARM::VMOVRRS: {
8409 // Source registers must be sequential.
8410 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8411 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(3).getReg());
8412 if (Sm1 != Sm + 1)
8413 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8414 "source operands must be sequential");
8415 break;
8416 }
8417 case ARM::VMOVSRR: {
8418 // Destination registers must be sequential.
8419 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8420 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
8421 if (Sm1 != Sm + 1)
8422 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8423 "destination operands must be sequential");
8424 break;
8425 }
8426 case ARM::VLDMDIA:
8427 case ARM::VSTMDIA: {
8428 ARMOperand &Op =
8429 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
8430 auto &RegList = Op.getRegList();
8431 if (RegList.size() < 1 || RegList.size() > 16)
8432 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8433 "list of registers must be at least 1 and at most 16");
8434 break;
8435 }
8436 case ARM::MVE_VQDMULLs32bh:
8437 case ARM::MVE_VQDMULLs32th:
8438 case ARM::MVE_VCMULf32:
8439 case ARM::MVE_VMULLBs32:
8440 case ARM::MVE_VMULLTs32:
8441 case ARM::MVE_VMULLBu32:
8442 case ARM::MVE_VMULLTu32: {
8443 if (Operands[MnemonicOpsEndInd]->getReg() ==
8444 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8445 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8446 "Qd register and Qn register can't be identical");
8447 }
8448 if (Operands[MnemonicOpsEndInd]->getReg() ==
8449 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8450 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8451 "Qd register and Qm register can't be identical");
8452 }
8453 break;
8454 }
8455 case ARM::MVE_VREV64_8:
8456 case ARM::MVE_VREV64_16:
8457 case ARM::MVE_VREV64_32:
8458 case ARM::MVE_VQDMULL_qr_s32bh:
8459 case ARM::MVE_VQDMULL_qr_s32th: {
8460 if (Operands[MnemonicOpsEndInd]->getReg() ==
8461 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8462 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8463 "Qd register and Qn register can't be identical");
8464 }
8465 break;
8466 }
8467 case ARM::MVE_VCADDi32:
8468 case ARM::MVE_VCADDf32:
8469 case ARM::MVE_VHCADDs32: {
8470 if (Operands[MnemonicOpsEndInd]->getReg() ==
8471 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8472 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8473 "Qd register and Qm register can't be identical");
8474 }
8475 break;
8476 }
8477 case ARM::MVE_VMOV_rr_q: {
8478 if (Operands[MnemonicOpsEndInd + 2]->getReg() !=
8479 Operands[MnemonicOpsEndInd + 4]->getReg())
8480 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8481 "Q-registers must be the same");
8482 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8483 .getVectorIndex() !=
8484 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 5])
8485 .getVectorIndex() +
8486 2)
8487 return Error(Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8488 "Q-register indexes must be 2 and 0 or 3 and 1");
8489 break;
8490 }
8491 case ARM::MVE_VMOV_q_rr: {
8492 if (Operands[MnemonicOpsEndInd]->getReg() !=
8493 Operands[MnemonicOpsEndInd + 2]->getReg())
8494 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8495 "Q-registers must be the same");
8496 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8497 .getVectorIndex() !=
8498 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8499 .getVectorIndex() +
8500 2)
8501 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8502 "Q-register indexes must be 2 and 0 or 3 and 1");
8503 break;
8504 }
8505 case ARM::MVE_SQRSHR:
8506 case ARM::MVE_UQRSHL: {
8507 if (Operands[MnemonicOpsEndInd]->getReg() ==
8508 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8509 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8510 "Rda register and Rm register can't be identical");
8511 }
8512 break;
8513 }
8514 case ARM::UMAAL:
8515 case ARM::UMLAL:
8516 case ARM::UMULL:
8517 case ARM::t2UMAAL:
8518 case ARM::t2UMLAL:
8519 case ARM::t2UMULL:
8520 case ARM::SMLAL:
8521 case ARM::SMLALBB:
8522 case ARM::SMLALBT:
8523 case ARM::SMLALD:
8524 case ARM::SMLALDX:
8525 case ARM::SMLALTB:
8526 case ARM::SMLALTT:
8527 case ARM::SMLSLD:
8528 case ARM::SMLSLDX:
8529 case ARM::SMULL:
8530 case ARM::t2SMLAL:
8531 case ARM::t2SMLALBB:
8532 case ARM::t2SMLALBT:
8533 case ARM::t2SMLALD:
8534 case ARM::t2SMLALDX:
8535 case ARM::t2SMLALTB:
8536 case ARM::t2SMLALTT:
8537 case ARM::t2SMLSLD:
8538 case ARM::t2SMLSLDX:
8539 case ARM::t2SMULL: {
8540 MCRegister RdHi = Inst.getOperand(0).getReg();
8541 MCRegister RdLo = Inst.getOperand(1).getReg();
8542 if(RdHi == RdLo) {
8543 return Error(Loc,
8544 "unpredictable instruction, RdHi and RdLo must be different");
8545 }
8546 break;
8547 }
8548
8549 case ARM::CDE_CX1:
8550 case ARM::CDE_CX1A:
8551 case ARM::CDE_CX1D:
8552 case ARM::CDE_CX1DA:
8553 case ARM::CDE_CX2:
8554 case ARM::CDE_CX2A:
8555 case ARM::CDE_CX2D:
8556 case ARM::CDE_CX2DA:
8557 case ARM::CDE_CX3:
8558 case ARM::CDE_CX3A:
8559 case ARM::CDE_CX3D:
8560 case ARM::CDE_CX3DA:
8561 case ARM::CDE_VCX1_vec:
8562 case ARM::CDE_VCX1_fpsp:
8563 case ARM::CDE_VCX1_fpdp:
8564 case ARM::CDE_VCX1A_vec:
8565 case ARM::CDE_VCX1A_fpsp:
8566 case ARM::CDE_VCX1A_fpdp:
8567 case ARM::CDE_VCX2_vec:
8568 case ARM::CDE_VCX2_fpsp:
8569 case ARM::CDE_VCX2_fpdp:
8570 case ARM::CDE_VCX2A_vec:
8571 case ARM::CDE_VCX2A_fpsp:
8572 case ARM::CDE_VCX2A_fpdp:
8573 case ARM::CDE_VCX3_vec:
8574 case ARM::CDE_VCX3_fpsp:
8575 case ARM::CDE_VCX3_fpdp:
8576 case ARM::CDE_VCX3A_vec:
8577 case ARM::CDE_VCX3A_fpsp:
8578 case ARM::CDE_VCX3A_fpdp: {
8579 assert(Inst.getOperand(1).isImm() &&
8580 "CDE operand 1 must be a coprocessor ID");
8581 int64_t Coproc = Inst.getOperand(1).getImm();
8582 if (Coproc < 8 && !ARM::isCDECoproc(Coproc, *STI))
8583 return Error(Operands[1]->getStartLoc(),
8584 "coprocessor must be configured as CDE");
8585 else if (Coproc >= 8)
8586 return Error(Operands[1]->getStartLoc(),
8587 "coprocessor must be in the range [p0, p7]");
8588 break;
8589 }
8590
8591 case ARM::t2CDP:
8592 case ARM::t2CDP2:
8593 case ARM::t2LDC2L_OFFSET:
8594 case ARM::t2LDC2L_OPTION:
8595 case ARM::t2LDC2L_POST:
8596 case ARM::t2LDC2L_PRE:
8597 case ARM::t2LDC2_OFFSET:
8598 case ARM::t2LDC2_OPTION:
8599 case ARM::t2LDC2_POST:
8600 case ARM::t2LDC2_PRE:
8601 case ARM::t2LDCL_OFFSET:
8602 case ARM::t2LDCL_OPTION:
8603 case ARM::t2LDCL_POST:
8604 case ARM::t2LDCL_PRE:
8605 case ARM::t2LDC_OFFSET:
8606 case ARM::t2LDC_OPTION:
8607 case ARM::t2LDC_POST:
8608 case ARM::t2LDC_PRE:
8609 case ARM::t2MCR:
8610 case ARM::t2MCR2:
8611 case ARM::t2MCRR:
8612 case ARM::t2MCRR2:
8613 case ARM::t2MRC:
8614 case ARM::t2MRC2:
8615 case ARM::t2MRRC:
8616 case ARM::t2MRRC2:
8617 case ARM::t2STC2L_OFFSET:
8618 case ARM::t2STC2L_OPTION:
8619 case ARM::t2STC2L_POST:
8620 case ARM::t2STC2L_PRE:
8621 case ARM::t2STC2_OFFSET:
8622 case ARM::t2STC2_OPTION:
8623 case ARM::t2STC2_POST:
8624 case ARM::t2STC2_PRE:
8625 case ARM::t2STCL_OFFSET:
8626 case ARM::t2STCL_OPTION:
8627 case ARM::t2STCL_POST:
8628 case ARM::t2STCL_PRE:
8629 case ARM::t2STC_OFFSET:
8630 case ARM::t2STC_OPTION:
8631 case ARM::t2STC_POST:
8632 case ARM::t2STC_PRE: {
8633 unsigned Opcode = Inst.getOpcode();
8634 // Inst.getOperand indexes operands in the (oops ...) and (iops ...) dags,
8635 // CopInd is the index of the coprocessor operand.
8636 size_t CopInd = 0;
8637 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8638 CopInd = 2;
8639 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8640 CopInd = 1;
8641 assert(Inst.getOperand(CopInd).isImm() &&
8642 "Operand must be a coprocessor ID");
8643 int64_t Coproc = Inst.getOperand(CopInd).getImm();
8644 // Operands[2] is the coprocessor operand at syntactic level
8645 if (ARM::isCDECoproc(Coproc, *STI))
8646 return Error(Operands[2]->getStartLoc(),
8647 "coprocessor must be configured as GCP");
8648 break;
8649 }
8650
8651 case ARM::VTOSHH:
8652 case ARM::VTOUHH:
8653 case ARM::VTOSLH:
8654 case ARM::VTOULH:
8655 case ARM::VTOSHS:
8656 case ARM::VTOUHS:
8657 case ARM::VTOSLS:
8658 case ARM::VTOULS:
8659 case ARM::VTOSHD:
8660 case ARM::VTOUHD:
8661 case ARM::VTOSLD:
8662 case ARM::VTOULD:
8663 case ARM::VSHTOH:
8664 case ARM::VUHTOH:
8665 case ARM::VSLTOH:
8666 case ARM::VULTOH:
8667 case ARM::VSHTOS:
8668 case ARM::VUHTOS:
8669 case ARM::VSLTOS:
8670 case ARM::VULTOS:
8671 case ARM::VSHTOD:
8672 case ARM::VUHTOD:
8673 case ARM::VSLTOD:
8674 case ARM::VULTOD: {
8675 if (Operands[MnemonicOpsEndInd]->getReg() !=
8676 Operands[MnemonicOpsEndInd + 1]->getReg())
8677 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8678 "source and destination registers must be the same");
8679 break;
8680 }
8681 }
8682
8683 return false;
8684}
8685
8686static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
8687 switch(Opc) {
8688 default: llvm_unreachable("unexpected opcode!");
8689 // VST1LN
8690 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8691 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8693 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8694 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8695 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8696 case ARM::VST1LNdAsm_8: Spacing = 1; return ARM::VST1LNd8;
8697 case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
8698 case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
8699
8700 // VST2LN
8701 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8702 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8704 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8706
8707 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8708 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8709 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8710 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8711 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8712
8713 case ARM::VST2LNdAsm_8: Spacing = 1; return ARM::VST2LNd8;
8714 case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
8715 case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
8716 case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
8717 case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
8718
8719 // VST3LN
8720 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8721 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8723 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8725 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8726 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8727 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8728 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
8729 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8730 case ARM::VST3LNdAsm_8: Spacing = 1; return ARM::VST3LNd8;
8731 case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
8732 case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
8733 case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
8734 case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
8735
8736 // VST3
8737 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8738 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8739 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8740 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8741 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8742 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8743 case ARM::VST3dWB_register_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8744 case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8745 case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8746 case ARM::VST3qWB_register_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8747 case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8748 case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8749 case ARM::VST3dAsm_8: Spacing = 1; return ARM::VST3d8;
8750 case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
8751 case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
8752 case ARM::VST3qAsm_8: Spacing = 2; return ARM::VST3q8;
8753 case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
8754 case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
8755
8756 // VST4LN
8757 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8758 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8760 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8762 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8763 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8764 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8765 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
8766 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8767 case ARM::VST4LNdAsm_8: Spacing = 1; return ARM::VST4LNd8;
8768 case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
8769 case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
8770 case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
8771 case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
8772
8773 // VST4
8774 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8775 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8776 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8777 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8778 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8779 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8780 case ARM::VST4dWB_register_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8781 case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8782 case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8783 case ARM::VST4qWB_register_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8784 case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8785 case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8786 case ARM::VST4dAsm_8: Spacing = 1; return ARM::VST4d8;
8787 case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
8788 case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
8789 case ARM::VST4qAsm_8: Spacing = 2; return ARM::VST4q8;
8790 case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
8791 case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
8792 }
8793}
8794
8795static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
8796 switch(Opc) {
8797 default: llvm_unreachable("unexpected opcode!");
8798 // VLD1LN
8799 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8800 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8802 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8805 case ARM::VLD1LNdAsm_8: Spacing = 1; return ARM::VLD1LNd8;
8806 case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
8807 case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
8808
8809 // VLD2LN
8810 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8811 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8813 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8815 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8818 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8820 case ARM::VLD2LNdAsm_8: Spacing = 1; return ARM::VLD2LNd8;
8821 case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
8822 case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
8823 case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
8824 case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
8825
8826 // VLD3DUP
8827 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8828 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8830 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8833 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8836 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8839 case ARM::VLD3DUPdAsm_8: Spacing = 1; return ARM::VLD3DUPd8;
8840 case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
8841 case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
8842 case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
8843 case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
8844 case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
8845
8846 // VLD3LN
8847 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8848 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8850 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8852 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8855 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8857 case ARM::VLD3LNdAsm_8: Spacing = 1; return ARM::VLD3LNd8;
8858 case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
8859 case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
8860 case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
8861 case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
8862
8863 // VLD3
8864 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8865 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8867 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8870 case ARM::VLD3dWB_register_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8871 case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8872 case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8873 case ARM::VLD3qWB_register_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8874 case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8875 case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8876 case ARM::VLD3dAsm_8: Spacing = 1; return ARM::VLD3d8;
8877 case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
8878 case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
8879 case ARM::VLD3qAsm_8: Spacing = 2; return ARM::VLD3q8;
8880 case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
8881 case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
8882
8883 // VLD4LN
8884 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8885 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8887 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8889 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8892 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8894 case ARM::VLD4LNdAsm_8: Spacing = 1; return ARM::VLD4LNd8;
8895 case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
8896 case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
8897 case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
8898 case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
8899
8900 // VLD4DUP
8901 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8902 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8904 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8907 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8910 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8913 case ARM::VLD4DUPdAsm_8: Spacing = 1; return ARM::VLD4DUPd8;
8914 case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
8915 case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
8916 case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
8917 case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
8918 case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
8919
8920 // VLD4
8921 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8922 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8924 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8927 case ARM::VLD4dWB_register_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8928 case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8929 case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8930 case ARM::VLD4qWB_register_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8931 case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8932 case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8933 case ARM::VLD4dAsm_8: Spacing = 1; return ARM::VLD4d8;
8934 case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
8935 case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
8936 case ARM::VLD4qAsm_8: Spacing = 2; return ARM::VLD4q8;
8937 case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
8938 case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
8939 }
8940}
8941
8942bool ARMAsmParser::processInstruction(MCInst &Inst,
8943 const OperandVector &Operands,
8944 unsigned MnemonicOpsEndInd,
8945 MCStreamer &Out) {
8946 // Check if we have the wide qualifier, because if it's present we
8947 // must avoid selecting a 16-bit thumb instruction.
8948 bool HasWideQualifier = false;
8949 for (auto &Op : Operands) {
8950 ARMOperand &ARMOp = static_cast<ARMOperand&>(*Op);
8951 if (ARMOp.isToken() && ARMOp.getToken() == ".w") {
8952 HasWideQualifier = true;
8953 break;
8954 }
8955 }
8956
8957 switch (Inst.getOpcode()) {
8958 case ARM::VLLDM:
8959 case ARM::VLSTM: {
8960 // In some cases both T1 and T2 are valid, causing tablegen pick T1 instead
8961 // of T2
8962 if (Operands.size() ==
8963 MnemonicOpsEndInd + 2) { // a register list has been provided
8964 ARMOperand &Op = static_cast<ARMOperand &>(
8965 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
8966 assert(Op.isDPRRegList());
8967 auto &RegList = Op.getRegList();
8968 // When the register list is {d0-d31} the instruction has to be the T2
8969 // variant
8970 if (RegList.size() == 32) {
8971 const unsigned Opcode =
8972 (Inst.getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8973 MCInst TmpInst;
8974 TmpInst.setOpcode(Opcode);
8975 TmpInst.addOperand(Inst.getOperand(0));
8976 TmpInst.addOperand(Inst.getOperand(1));
8977 TmpInst.addOperand(Inst.getOperand(2));
8978 TmpInst.addOperand(Inst.getOperand(3));
8979 Inst = TmpInst;
8980 return true;
8981 }
8982 }
8983 return false;
8984 }
8985 // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
8986 case ARM::LDRT_POST:
8987 case ARM::LDRBT_POST: {
8988 const unsigned Opcode =
8989 (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8990 : ARM::LDRBT_POST_IMM;
8991 MCInst TmpInst;
8992 TmpInst.setOpcode(Opcode);
8993 TmpInst.addOperand(Inst.getOperand(0));
8994 TmpInst.addOperand(Inst.getOperand(1));
8995 TmpInst.addOperand(Inst.getOperand(1));
8996 TmpInst.addOperand(MCOperand::createReg(0));
8997 TmpInst.addOperand(MCOperand::createImm(0));
8998 TmpInst.addOperand(Inst.getOperand(2));
8999 TmpInst.addOperand(Inst.getOperand(3));
9000 Inst = TmpInst;
9001 return true;
9002 }
9003 // Alias for 'ldr{sb,h,sh}t Rt, [Rn] {, #imm}' for omitted immediate.
9004 case ARM::LDRSBTii:
9005 case ARM::LDRHTii:
9006 case ARM::LDRSHTii: {
9007 MCInst TmpInst;
9008
9009 if (Inst.getOpcode() == ARM::LDRSBTii)
9010 TmpInst.setOpcode(ARM::LDRSBTi);
9011 else if (Inst.getOpcode() == ARM::LDRHTii)
9012 TmpInst.setOpcode(ARM::LDRHTi);
9013 else if (Inst.getOpcode() == ARM::LDRSHTii)
9014 TmpInst.setOpcode(ARM::LDRSHTi);
9015 TmpInst.addOperand(Inst.getOperand(0));
9016 TmpInst.addOperand(Inst.getOperand(1));
9017 TmpInst.addOperand(Inst.getOperand(1));
9018 TmpInst.addOperand(MCOperand::createImm(256));
9019 TmpInst.addOperand(Inst.getOperand(2));
9020 Inst = TmpInst;
9021 return true;
9022 }
9023 // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction.
9024 case ARM::STRT_POST:
9025 case ARM::STRBT_POST: {
9026 const unsigned Opcode =
9027 (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9028 : ARM::STRBT_POST_IMM;
9029 MCInst TmpInst;
9030 TmpInst.setOpcode(Opcode);
9031 TmpInst.addOperand(Inst.getOperand(1));
9032 TmpInst.addOperand(Inst.getOperand(0));
9033 TmpInst.addOperand(Inst.getOperand(1));
9034 TmpInst.addOperand(MCOperand::createReg(0));
9035 TmpInst.addOperand(MCOperand::createImm(0));
9036 TmpInst.addOperand(Inst.getOperand(2));
9037 TmpInst.addOperand(Inst.getOperand(3));
9038 Inst = TmpInst;
9039 return true;
9040 }
9041 // Alias for alternate form of 'ADR Rd, #imm' instruction.
9042 case ARM::ADDri: {
9043 if (Inst.getOperand(1).getReg() != ARM::PC || Inst.getOperand(5).getReg() ||
9044 !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
9045 return false;
9046 MCInst TmpInst;
9047 TmpInst.setOpcode(ARM::ADR);
9048 TmpInst.addOperand(Inst.getOperand(0));
9049 if (Inst.getOperand(2).isImm()) {
9050 // Immediate (mod_imm) will be in its encoded form, we must unencode it
9051 // before passing it to the ADR instruction.
9052 unsigned Enc = Inst.getOperand(2).getImm();
9054 llvm::rotr<uint32_t>(Enc & 0xFF, (Enc & 0xF00) >> 7)));
9055 } else {
9056 // Turn PC-relative expression into absolute expression.
9057 // Reading PC provides the start of the current instruction + 8 and
9058 // the transform to adr is biased by that.
9059 MCSymbol *Dot = getContext().createTempSymbol();
9060 Out.emitLabel(Dot);
9061 const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
9062 const MCExpr *InstPC = MCSymbolRefExpr::create(Dot,
9063 getContext());
9064 const MCExpr *Const8 = MCConstantExpr::create(8, getContext());
9065 const MCExpr *ReadPC = MCBinaryExpr::createAdd(InstPC, Const8,
9066 getContext());
9067 const MCExpr *FixupAddr = MCBinaryExpr::createAdd(ReadPC, OpExpr,
9068 getContext());
9069 TmpInst.addOperand(MCOperand::createExpr(FixupAddr));
9070 }
9071 TmpInst.addOperand(Inst.getOperand(3));
9072 TmpInst.addOperand(Inst.getOperand(4));
9073 Inst = TmpInst;
9074 return true;
9075 }
9076 // Aliases for imm syntax of LDR instructions.
9077 case ARM::t2LDR_PRE_imm:
9078 case ARM::t2LDR_POST_imm: {
9079 MCInst TmpInst;
9080 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDR_PRE_imm ? ARM::t2LDR_PRE
9081 : ARM::t2LDR_POST);
9082 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9083 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9084 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9085 TmpInst.addOperand(Inst.getOperand(2)); // imm
9086 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9087 TmpInst.addOperand(Inst.getOperand(4));
9088 Inst = TmpInst;
9089 return true;
9090 }
9091 // Aliases for imm syntax of STR instructions.
9092 case ARM::t2STR_PRE_imm:
9093 case ARM::t2STR_POST_imm: {
9094 MCInst TmpInst;
9095 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STR_PRE_imm ? ARM::t2STR_PRE
9096 : ARM::t2STR_POST);
9097 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9098 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9099 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9100 TmpInst.addOperand(Inst.getOperand(2)); // imm
9101 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9102 TmpInst.addOperand(Inst.getOperand(4));
9103 Inst = TmpInst;
9104 return true;
9105 }
9106 // Aliases for imm syntax of LDRB instructions.
9107 case ARM::t2LDRB_OFFSET_imm: {
9108 MCInst TmpInst;
9109 TmpInst.setOpcode(ARM::t2LDRBi8);
9110 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9111 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9112 TmpInst.addOperand(Inst.getOperand(2)); // imm
9113 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9114 Inst = TmpInst;
9115 return true;
9116 }
9117 case ARM::t2LDRB_PRE_imm:
9118 case ARM::t2LDRB_POST_imm: {
9119 MCInst TmpInst;
9120 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRB_PRE_imm
9121 ? ARM::t2LDRB_PRE
9122 : ARM::t2LDRB_POST);
9123 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9124 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9125 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9126 TmpInst.addOperand(Inst.getOperand(2)); // imm
9127 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9128 TmpInst.addOperand(Inst.getOperand(4));
9129 Inst = TmpInst;
9130 return true;
9131 }
9132 // Aliases for imm syntax of STRB instructions.
9133 case ARM::t2STRB_OFFSET_imm: {
9134 MCInst TmpInst;
9135 TmpInst.setOpcode(ARM::t2STRBi8);
9136 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9137 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9138 TmpInst.addOperand(Inst.getOperand(2)); // imm
9139 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9140 Inst = TmpInst;
9141 return true;
9142 }
9143 case ARM::t2STRB_PRE_imm:
9144 case ARM::t2STRB_POST_imm: {
9145 MCInst TmpInst;
9146 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRB_PRE_imm
9147 ? ARM::t2STRB_PRE
9148 : ARM::t2STRB_POST);
9149 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9150 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9151 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9152 TmpInst.addOperand(Inst.getOperand(2)); // imm
9153 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9154 TmpInst.addOperand(Inst.getOperand(4));
9155 Inst = TmpInst;
9156 return true;
9157 }
9158 // Aliases for imm syntax of LDRH instructions.
9159 case ARM::t2LDRH_OFFSET_imm: {
9160 MCInst TmpInst;
9161 TmpInst.setOpcode(ARM::t2LDRHi8);
9162 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9163 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9164 TmpInst.addOperand(Inst.getOperand(2)); // imm
9165 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9166 Inst = TmpInst;
9167 return true;
9168 }
9169 case ARM::t2LDRH_PRE_imm:
9170 case ARM::t2LDRH_POST_imm: {
9171 MCInst TmpInst;
9172 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRH_PRE_imm
9173 ? ARM::t2LDRH_PRE
9174 : ARM::t2LDRH_POST);
9175 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9176 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9177 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9178 TmpInst.addOperand(Inst.getOperand(2)); // imm
9179 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9180 TmpInst.addOperand(Inst.getOperand(4));
9181 Inst = TmpInst;
9182 return true;
9183 }
9184 // Aliases for imm syntax of STRH instructions.
9185 case ARM::t2STRH_OFFSET_imm: {
9186 MCInst TmpInst;
9187 TmpInst.setOpcode(ARM::t2STRHi8);
9188 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9189 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9190 TmpInst.addOperand(Inst.getOperand(2)); // imm
9191 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9192 Inst = TmpInst;
9193 return true;
9194 }
9195 case ARM::t2STRH_PRE_imm:
9196 case ARM::t2STRH_POST_imm: {
9197 MCInst TmpInst;
9198 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRH_PRE_imm
9199 ? ARM::t2STRH_PRE
9200 : ARM::t2STRH_POST);
9201 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9202 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9203 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9204 TmpInst.addOperand(Inst.getOperand(2)); // imm
9205 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9206 TmpInst.addOperand(Inst.getOperand(4));
9207 Inst = TmpInst;
9208 return true;
9209 }
9210 // Aliases for imm syntax of LDRSB instructions.
9211 case ARM::t2LDRSB_OFFSET_imm: {
9212 MCInst TmpInst;
9213 TmpInst.setOpcode(ARM::t2LDRSBi8);
9214 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9215 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9216 TmpInst.addOperand(Inst.getOperand(2)); // imm
9217 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9218 Inst = TmpInst;
9219 return true;
9220 }
9221 case ARM::t2LDRSB_PRE_imm:
9222 case ARM::t2LDRSB_POST_imm: {
9223 MCInst TmpInst;
9224 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSB_PRE_imm
9225 ? ARM::t2LDRSB_PRE
9226 : ARM::t2LDRSB_POST);
9227 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9228 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9229 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9230 TmpInst.addOperand(Inst.getOperand(2)); // imm
9231 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9232 TmpInst.addOperand(Inst.getOperand(4));
9233 Inst = TmpInst;
9234 return true;
9235 }
9236 // Aliases for imm syntax of LDRSH instructions.
9237 case ARM::t2LDRSH_OFFSET_imm: {
9238 MCInst TmpInst;
9239 TmpInst.setOpcode(ARM::t2LDRSHi8);
9240 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9241 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9242 TmpInst.addOperand(Inst.getOperand(2)); // imm
9243 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9244 Inst = TmpInst;
9245 return true;
9246 }
9247 case ARM::t2LDRSH_PRE_imm:
9248 case ARM::t2LDRSH_POST_imm: {
9249 MCInst TmpInst;
9250 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSH_PRE_imm
9251 ? ARM::t2LDRSH_PRE
9252 : ARM::t2LDRSH_POST);
9253 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9254 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9255 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9256 TmpInst.addOperand(Inst.getOperand(2)); // imm
9257 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9258 TmpInst.addOperand(Inst.getOperand(4));
9259 Inst = TmpInst;
9260 return true;
9261 }
9262 // Aliases for alternate PC+imm syntax of LDR instructions.
9263 case ARM::t2LDRpcrel:
9264 // Select the narrow version if the immediate will fit.
9265 if (Inst.getOperand(1).getImm() > 0 &&
9266 Inst.getOperand(1).getImm() <= 0xff &&
9267 !HasWideQualifier)
9268 Inst.setOpcode(ARM::tLDRpci);
9269 else
9270 Inst.setOpcode(ARM::t2LDRpci);
9271 return true;
9272 case ARM::t2LDRBpcrel:
9273 Inst.setOpcode(ARM::t2LDRBpci);
9274 return true;
9275 case ARM::t2LDRHpcrel:
9276 Inst.setOpcode(ARM::t2LDRHpci);
9277 return true;
9278 case ARM::t2LDRSBpcrel:
9279 Inst.setOpcode(ARM::t2LDRSBpci);
9280 return true;
9281 case ARM::t2LDRSHpcrel:
9282 Inst.setOpcode(ARM::t2LDRSHpci);
9283 return true;
9284 case ARM::LDRConstPool:
9285 case ARM::tLDRConstPool:
9286 case ARM::t2LDRConstPool: {
9287 // Pseudo instruction ldr rt, =immediate is converted to a
9288 // MOV rt, immediate if immediate is known and representable
9289 // otherwise we create a constant pool entry that we load from.
9290 MCInst TmpInst;
9291 if (Inst.getOpcode() == ARM::LDRConstPool)
9292 TmpInst.setOpcode(ARM::LDRi12);
9293 else if (Inst.getOpcode() == ARM::tLDRConstPool)
9294 TmpInst.setOpcode(ARM::tLDRpci);
9295 else if (Inst.getOpcode() == ARM::t2LDRConstPool)
9296 TmpInst.setOpcode(ARM::t2LDRpci);
9297 const ARMOperand &PoolOperand =
9298 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
9299 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9300 // If SubExprVal is a constant we may be able to use a MOV
9301 if (isa<MCConstantExpr>(SubExprVal) &&
9302 Inst.getOperand(0).getReg() != ARM::PC &&
9303 Inst.getOperand(0).getReg() != ARM::SP) {
9304 int64_t Value =
9305 (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue();
9306 bool UseMov = true;
9307 bool MovHasS = true;
9308 if (Inst.getOpcode() == ARM::LDRConstPool) {
9309 // ARM Constant
9310 if (ARM_AM::getSOImmVal(Value) != -1) {
9312 TmpInst.setOpcode(ARM::MOVi);
9313 }
9314 else if (ARM_AM::getSOImmVal(~Value) != -1) {
9316 TmpInst.setOpcode(ARM::MVNi);
9317 }
9318 else if (hasV6T2Ops() &&
9319 Value >=0 && Value < 65536) {
9320 TmpInst.setOpcode(ARM::MOVi16);
9321 MovHasS = false;
9322 }
9323 else
9324 UseMov = false;
9325 }
9326 else {
9327 // Thumb/Thumb2 Constant
9328 if (hasThumb2() &&
9330 TmpInst.setOpcode(ARM::t2MOVi);
9331 else if (hasThumb2() &&
9332 ARM_AM::getT2SOImmVal(~Value) != -1) {
9333 TmpInst.setOpcode(ARM::t2MVNi);
9334 Value = ~Value;
9335 }
9336 else if (hasV8MBaseline() &&
9337 Value >=0 && Value < 65536) {
9338 TmpInst.setOpcode(ARM::t2MOVi16);
9339 MovHasS = false;
9340 }
9341 else
9342 UseMov = false;
9343 }
9344 if (UseMov) {
9345 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9346 TmpInst.addOperand(MCOperand::createImm(Value)); // Immediate
9347 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9348 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9349 if (MovHasS)
9350 TmpInst.addOperand(MCOperand::createReg(0)); // S
9351 Inst = TmpInst;
9352 return true;
9353 }
9354 }
9355 // No opportunity to use MOV/MVN create constant pool
9356 const MCExpr *CPLoc =
9357 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9358 PoolOperand.getStartLoc());
9359 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9360 TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool
9361 if (TmpInst.getOpcode() == ARM::LDRi12)
9362 TmpInst.addOperand(MCOperand::createImm(0)); // unused offset
9363 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9364 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9365 Inst = TmpInst;
9366 return true;
9367 }
9368 // Handle NEON VST complex aliases.
9369 case ARM::VST1LNdWB_register_Asm_8:
9370 case ARM::VST1LNdWB_register_Asm_16:
9371 case ARM::VST1LNdWB_register_Asm_32: {
9372 MCInst TmpInst;
9373 // Shuffle the operands around so the lane index operand is in the
9374 // right place.
9375 unsigned Spacing;
9376 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9377 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9378 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9379 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9380 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9381 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9382 TmpInst.addOperand(Inst.getOperand(1)); // lane
9383 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9384 TmpInst.addOperand(Inst.getOperand(6));
9385 Inst = TmpInst;
9386 return true;
9387 }
9388
9389 case ARM::VST2LNdWB_register_Asm_8:
9390 case ARM::VST2LNdWB_register_Asm_16:
9391 case ARM::VST2LNdWB_register_Asm_32:
9392 case ARM::VST2LNqWB_register_Asm_16:
9393 case ARM::VST2LNqWB_register_Asm_32: {
9394 MCInst TmpInst;
9395 // Shuffle the operands around so the lane index operand is in the
9396 // right place.
9397 unsigned Spacing;
9398 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9399 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9400 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9401 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9402 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9403 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9405 Spacing));
9406 TmpInst.addOperand(Inst.getOperand(1)); // lane
9407 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9408 TmpInst.addOperand(Inst.getOperand(6));
9409 Inst = TmpInst;
9410 return true;
9411 }
9412
9413 case ARM::VST3LNdWB_register_Asm_8:
9414 case ARM::VST3LNdWB_register_Asm_16:
9415 case ARM::VST3LNdWB_register_Asm_32:
9416 case ARM::VST3LNqWB_register_Asm_16:
9417 case ARM::VST3LNqWB_register_Asm_32: {
9418 MCInst TmpInst;
9419 // Shuffle the operands around so the lane index operand is in the
9420 // right place.
9421 unsigned Spacing;
9422 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9423 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9424 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9425 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9426 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9427 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9429 Spacing));
9431 Spacing * 2));
9432 TmpInst.addOperand(Inst.getOperand(1)); // lane
9433 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9434 TmpInst.addOperand(Inst.getOperand(6));
9435 Inst = TmpInst;
9436 return true;
9437 }
9438
9439 case ARM::VST4LNdWB_register_Asm_8:
9440 case ARM::VST4LNdWB_register_Asm_16:
9441 case ARM::VST4LNdWB_register_Asm_32:
9442 case ARM::VST4LNqWB_register_Asm_16:
9443 case ARM::VST4LNqWB_register_Asm_32: {
9444 MCInst TmpInst;
9445 // Shuffle the operands around so the lane index operand is in the
9446 // right place.
9447 unsigned Spacing;
9448 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9449 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9450 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9451 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9452 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9453 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9455 Spacing));
9457 Spacing * 2));
9459 Spacing * 3));
9460 TmpInst.addOperand(Inst.getOperand(1)); // lane
9461 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9462 TmpInst.addOperand(Inst.getOperand(6));
9463 Inst = TmpInst;
9464 return true;
9465 }
9466
9467 case ARM::VST1LNdWB_fixed_Asm_8:
9468 case ARM::VST1LNdWB_fixed_Asm_16:
9469 case ARM::VST1LNdWB_fixed_Asm_32: {
9470 MCInst TmpInst;
9471 // Shuffle the operands around so the lane index operand is in the
9472 // right place.
9473 unsigned Spacing;
9474 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9475 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9476 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9477 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9478 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9479 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9480 TmpInst.addOperand(Inst.getOperand(1)); // lane
9481 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9482 TmpInst.addOperand(Inst.getOperand(5));
9483 Inst = TmpInst;
9484 return true;
9485 }
9486
9487 case ARM::VST2LNdWB_fixed_Asm_8:
9488 case ARM::VST2LNdWB_fixed_Asm_16:
9489 case ARM::VST2LNdWB_fixed_Asm_32:
9490 case ARM::VST2LNqWB_fixed_Asm_16:
9491 case ARM::VST2LNqWB_fixed_Asm_32: {
9492 MCInst TmpInst;
9493 // Shuffle the operands around so the lane index operand is in the
9494 // right place.
9495 unsigned Spacing;
9496 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9497 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9498 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9499 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9500 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9501 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9503 Spacing));
9504 TmpInst.addOperand(Inst.getOperand(1)); // lane
9505 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9506 TmpInst.addOperand(Inst.getOperand(5));
9507 Inst = TmpInst;
9508 return true;
9509 }
9510
9511 case ARM::VST3LNdWB_fixed_Asm_8:
9512 case ARM::VST3LNdWB_fixed_Asm_16:
9513 case ARM::VST3LNdWB_fixed_Asm_32:
9514 case ARM::VST3LNqWB_fixed_Asm_16:
9515 case ARM::VST3LNqWB_fixed_Asm_32: {
9516 MCInst TmpInst;
9517 // Shuffle the operands around so the lane index operand is in the
9518 // right place.
9519 unsigned Spacing;
9520 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9521 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9522 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9523 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9524 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9525 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9527 Spacing));
9529 Spacing * 2));
9530 TmpInst.addOperand(Inst.getOperand(1)); // lane
9531 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9532 TmpInst.addOperand(Inst.getOperand(5));
9533 Inst = TmpInst;
9534 return true;
9535 }
9536
9537 case ARM::VST4LNdWB_fixed_Asm_8:
9538 case ARM::VST4LNdWB_fixed_Asm_16:
9539 case ARM::VST4LNdWB_fixed_Asm_32:
9540 case ARM::VST4LNqWB_fixed_Asm_16:
9541 case ARM::VST4LNqWB_fixed_Asm_32: {
9542 MCInst TmpInst;
9543 // Shuffle the operands around so the lane index operand is in the
9544 // right place.
9545 unsigned Spacing;
9546 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9547 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9548 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9549 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9550 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9551 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9553 Spacing));
9555 Spacing * 2));
9557 Spacing * 3));
9558 TmpInst.addOperand(Inst.getOperand(1)); // lane
9559 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9560 TmpInst.addOperand(Inst.getOperand(5));
9561 Inst = TmpInst;
9562 return true;
9563 }
9564
9565 case ARM::VST1LNdAsm_8:
9566 case ARM::VST1LNdAsm_16:
9567 case ARM::VST1LNdAsm_32: {
9568 MCInst TmpInst;
9569 // Shuffle the operands around so the lane index operand is in the
9570 // right place.
9571 unsigned Spacing;
9572 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9573 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9574 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9575 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9576 TmpInst.addOperand(Inst.getOperand(1)); // lane
9577 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9578 TmpInst.addOperand(Inst.getOperand(5));
9579 Inst = TmpInst;
9580 return true;
9581 }
9582
9583 case ARM::VST2LNdAsm_8:
9584 case ARM::VST2LNdAsm_16:
9585 case ARM::VST2LNdAsm_32:
9586 case ARM::VST2LNqAsm_16:
9587 case ARM::VST2LNqAsm_32: {
9588 MCInst TmpInst;
9589 // Shuffle the operands around so the lane index operand is in the
9590 // right place.
9591 unsigned Spacing;
9592 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9593 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9594 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9595 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9597 Spacing));
9598 TmpInst.addOperand(Inst.getOperand(1)); // lane
9599 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9600 TmpInst.addOperand(Inst.getOperand(5));
9601 Inst = TmpInst;
9602 return true;
9603 }
9604
9605 case ARM::VST3LNdAsm_8:
9606 case ARM::VST3LNdAsm_16:
9607 case ARM::VST3LNdAsm_32:
9608 case ARM::VST3LNqAsm_16:
9609 case ARM::VST3LNqAsm_32: {
9610 MCInst TmpInst;
9611 // Shuffle the operands around so the lane index operand is in the
9612 // right place.
9613 unsigned Spacing;
9614 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9615 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9616 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9617 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9619 Spacing));
9621 Spacing * 2));
9622 TmpInst.addOperand(Inst.getOperand(1)); // lane
9623 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9624 TmpInst.addOperand(Inst.getOperand(5));
9625 Inst = TmpInst;
9626 return true;
9627 }
9628
9629 case ARM::VST4LNdAsm_8:
9630 case ARM::VST4LNdAsm_16:
9631 case ARM::VST4LNdAsm_32:
9632 case ARM::VST4LNqAsm_16:
9633 case ARM::VST4LNqAsm_32: {
9634 MCInst TmpInst;
9635 // Shuffle the operands around so the lane index operand is in the
9636 // right place.
9637 unsigned Spacing;
9638 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9639 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9640 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9641 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9643 Spacing));
9645 Spacing * 2));
9647 Spacing * 3));
9648 TmpInst.addOperand(Inst.getOperand(1)); // lane
9649 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9650 TmpInst.addOperand(Inst.getOperand(5));
9651 Inst = TmpInst;
9652 return true;
9653 }
9654
9655 // Handle NEON VLD complex aliases.
9656 case ARM::VLD1LNdWB_register_Asm_8:
9657 case ARM::VLD1LNdWB_register_Asm_16:
9658 case ARM::VLD1LNdWB_register_Asm_32: {
9659 MCInst TmpInst;
9660 // Shuffle the operands around so the lane index operand is in the
9661 // right place.
9662 unsigned Spacing;
9663 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9664 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9665 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9666 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9667 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9668 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9669 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9670 TmpInst.addOperand(Inst.getOperand(1)); // lane
9671 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9672 TmpInst.addOperand(Inst.getOperand(6));
9673 Inst = TmpInst;
9674 return true;
9675 }
9676
9677 case ARM::VLD2LNdWB_register_Asm_8:
9678 case ARM::VLD2LNdWB_register_Asm_16:
9679 case ARM::VLD2LNdWB_register_Asm_32:
9680 case ARM::VLD2LNqWB_register_Asm_16:
9681 case ARM::VLD2LNqWB_register_Asm_32: {
9682 MCInst TmpInst;
9683 // Shuffle the operands around so the lane index operand is in the
9684 // right place.
9685 unsigned Spacing;
9686 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9687 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9689 Spacing));
9690 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9691 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9692 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9693 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9694 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9696 Spacing));
9697 TmpInst.addOperand(Inst.getOperand(1)); // lane
9698 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9699 TmpInst.addOperand(Inst.getOperand(6));
9700 Inst = TmpInst;
9701 return true;
9702 }
9703
9704 case ARM::VLD3LNdWB_register_Asm_8:
9705 case ARM::VLD3LNdWB_register_Asm_16:
9706 case ARM::VLD3LNdWB_register_Asm_32:
9707 case ARM::VLD3LNqWB_register_Asm_16:
9708 case ARM::VLD3LNqWB_register_Asm_32: {
9709 MCInst TmpInst;
9710 // Shuffle the operands around so the lane index operand is in the
9711 // right place.
9712 unsigned Spacing;
9713 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9714 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9716 Spacing));
9718 Spacing * 2));
9719 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9720 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9721 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9722 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9723 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9725 Spacing));
9727 Spacing * 2));
9728 TmpInst.addOperand(Inst.getOperand(1)); // lane
9729 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9730 TmpInst.addOperand(Inst.getOperand(6));
9731 Inst = TmpInst;
9732 return true;
9733 }
9734
9735 case ARM::VLD4LNdWB_register_Asm_8:
9736 case ARM::VLD4LNdWB_register_Asm_16:
9737 case ARM::VLD4LNdWB_register_Asm_32:
9738 case ARM::VLD4LNqWB_register_Asm_16:
9739 case ARM::VLD4LNqWB_register_Asm_32: {
9740 MCInst TmpInst;
9741 // Shuffle the operands around so the lane index operand is in the
9742 // right place.
9743 unsigned Spacing;
9744 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9745 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9747 Spacing));
9749 Spacing * 2));
9751 Spacing * 3));
9752 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9753 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9754 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9755 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9756 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9758 Spacing));
9760 Spacing * 2));
9762 Spacing * 3));
9763 TmpInst.addOperand(Inst.getOperand(1)); // lane
9764 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9765 TmpInst.addOperand(Inst.getOperand(6));
9766 Inst = TmpInst;
9767 return true;
9768 }
9769
9770 case ARM::VLD1LNdWB_fixed_Asm_8:
9771 case ARM::VLD1LNdWB_fixed_Asm_16:
9772 case ARM::VLD1LNdWB_fixed_Asm_32: {
9773 MCInst TmpInst;
9774 // Shuffle the operands around so the lane index operand is in the
9775 // right place.
9776 unsigned Spacing;
9777 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9778 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9779 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9780 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9781 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9782 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9783 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9784 TmpInst.addOperand(Inst.getOperand(1)); // lane
9785 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9786 TmpInst.addOperand(Inst.getOperand(5));
9787 Inst = TmpInst;
9788 return true;
9789 }
9790
9791 case ARM::VLD2LNdWB_fixed_Asm_8:
9792 case ARM::VLD2LNdWB_fixed_Asm_16:
9793 case ARM::VLD2LNdWB_fixed_Asm_32:
9794 case ARM::VLD2LNqWB_fixed_Asm_16:
9795 case ARM::VLD2LNqWB_fixed_Asm_32: {
9796 MCInst TmpInst;
9797 // Shuffle the operands around so the lane index operand is in the
9798 // right place.
9799 unsigned Spacing;
9800 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9801 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9803 Spacing));
9804 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9805 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9806 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9807 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9808 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9810 Spacing));
9811 TmpInst.addOperand(Inst.getOperand(1)); // lane
9812 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9813 TmpInst.addOperand(Inst.getOperand(5));
9814 Inst = TmpInst;
9815 return true;
9816 }
9817
9818 case ARM::VLD3LNdWB_fixed_Asm_8:
9819 case ARM::VLD3LNdWB_fixed_Asm_16:
9820 case ARM::VLD3LNdWB_fixed_Asm_32:
9821 case ARM::VLD3LNqWB_fixed_Asm_16:
9822 case ARM::VLD3LNqWB_fixed_Asm_32: {
9823 MCInst TmpInst;
9824 // Shuffle the operands around so the lane index operand is in the
9825 // right place.
9826 unsigned Spacing;
9827 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9828 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9830 Spacing));
9832 Spacing * 2));
9833 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9834 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9835 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9836 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9837 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9839 Spacing));
9841 Spacing * 2));
9842 TmpInst.addOperand(Inst.getOperand(1)); // lane
9843 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9844 TmpInst.addOperand(Inst.getOperand(5));
9845 Inst = TmpInst;
9846 return true;
9847 }
9848
9849 case ARM::VLD4LNdWB_fixed_Asm_8:
9850 case ARM::VLD4LNdWB_fixed_Asm_16:
9851 case ARM::VLD4LNdWB_fixed_Asm_32:
9852 case ARM::VLD4LNqWB_fixed_Asm_16:
9853 case ARM::VLD4LNqWB_fixed_Asm_32: {
9854 MCInst TmpInst;
9855 // Shuffle the operands around so the lane index operand is in the
9856 // right place.
9857 unsigned Spacing;
9858 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9859 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9861 Spacing));
9863 Spacing * 2));
9865 Spacing * 3));
9866 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9867 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9868 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9869 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9870 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9872 Spacing));
9874 Spacing * 2));
9876 Spacing * 3));
9877 TmpInst.addOperand(Inst.getOperand(1)); // lane
9878 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9879 TmpInst.addOperand(Inst.getOperand(5));
9880 Inst = TmpInst;
9881 return true;
9882 }
9883
9884 case ARM::VLD1LNdAsm_8:
9885 case ARM::VLD1LNdAsm_16:
9886 case ARM::VLD1LNdAsm_32: {
9887 MCInst TmpInst;
9888 // Shuffle the operands around so the lane index operand is in the
9889 // right place.
9890 unsigned Spacing;
9891 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9892 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9893 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9894 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9895 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9896 TmpInst.addOperand(Inst.getOperand(1)); // lane
9897 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9898 TmpInst.addOperand(Inst.getOperand(5));
9899 Inst = TmpInst;
9900 return true;
9901 }
9902
9903 case ARM::VLD2LNdAsm_8:
9904 case ARM::VLD2LNdAsm_16:
9905 case ARM::VLD2LNdAsm_32:
9906 case ARM::VLD2LNqAsm_16:
9907 case ARM::VLD2LNqAsm_32: {
9908 MCInst TmpInst;
9909 // Shuffle the operands around so the lane index operand is in the
9910 // right place.
9911 unsigned Spacing;
9912 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9913 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9915 Spacing));
9916 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9917 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9918 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9920 Spacing));
9921 TmpInst.addOperand(Inst.getOperand(1)); // lane
9922 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9923 TmpInst.addOperand(Inst.getOperand(5));
9924 Inst = TmpInst;
9925 return true;
9926 }
9927
9928 case ARM::VLD3LNdAsm_8:
9929 case ARM::VLD3LNdAsm_16:
9930 case ARM::VLD3LNdAsm_32:
9931 case ARM::VLD3LNqAsm_16:
9932 case ARM::VLD3LNqAsm_32: {
9933 MCInst TmpInst;
9934 // Shuffle the operands around so the lane index operand is in the
9935 // right place.
9936 unsigned Spacing;
9937 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9938 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9940 Spacing));
9942 Spacing * 2));
9943 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9944 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9945 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9947 Spacing));
9949 Spacing * 2));
9950 TmpInst.addOperand(Inst.getOperand(1)); // lane
9951 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9952 TmpInst.addOperand(Inst.getOperand(5));
9953 Inst = TmpInst;
9954 return true;
9955 }
9956
9957 case ARM::VLD4LNdAsm_8:
9958 case ARM::VLD4LNdAsm_16:
9959 case ARM::VLD4LNdAsm_32:
9960 case ARM::VLD4LNqAsm_16:
9961 case ARM::VLD4LNqAsm_32: {
9962 MCInst TmpInst;
9963 // Shuffle the operands around so the lane index operand is in the
9964 // right place.
9965 unsigned Spacing;
9966 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9967 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9969 Spacing));
9971 Spacing * 2));
9973 Spacing * 3));
9974 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9975 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9976 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9978 Spacing));
9980 Spacing * 2));
9982 Spacing * 3));
9983 TmpInst.addOperand(Inst.getOperand(1)); // lane
9984 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9985 TmpInst.addOperand(Inst.getOperand(5));
9986 Inst = TmpInst;
9987 return true;
9988 }
9989
9990 // VLD3DUP single 3-element structure to all lanes instructions.
9991 case ARM::VLD3DUPdAsm_8:
9992 case ARM::VLD3DUPdAsm_16:
9993 case ARM::VLD3DUPdAsm_32:
9994 case ARM::VLD3DUPqAsm_8:
9995 case ARM::VLD3DUPqAsm_16:
9996 case ARM::VLD3DUPqAsm_32: {
9997 MCInst TmpInst;
9998 unsigned Spacing;
9999 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10000 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10002 Spacing));
10004 Spacing * 2));
10005 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10006 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10007 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10008 TmpInst.addOperand(Inst.getOperand(4));
10009 Inst = TmpInst;
10010 return true;
10011 }
10012
10013 case ARM::VLD3DUPdWB_fixed_Asm_8:
10014 case ARM::VLD3DUPdWB_fixed_Asm_16:
10015 case ARM::VLD3DUPdWB_fixed_Asm_32:
10016 case ARM::VLD3DUPqWB_fixed_Asm_8:
10017 case ARM::VLD3DUPqWB_fixed_Asm_16:
10018 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10019 MCInst TmpInst;
10020 unsigned Spacing;
10021 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10022 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10024 Spacing));
10026 Spacing * 2));
10027 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10028 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10029 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10030 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10031 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10032 TmpInst.addOperand(Inst.getOperand(4));
10033 Inst = TmpInst;
10034 return true;
10035 }
10036
10037 case ARM::VLD3DUPdWB_register_Asm_8:
10038 case ARM::VLD3DUPdWB_register_Asm_16:
10039 case ARM::VLD3DUPdWB_register_Asm_32:
10040 case ARM::VLD3DUPqWB_register_Asm_8:
10041 case ARM::VLD3DUPqWB_register_Asm_16:
10042 case ARM::VLD3DUPqWB_register_Asm_32: {
10043 MCInst TmpInst;
10044 unsigned Spacing;
10045 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10046 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10048 Spacing));
10050 Spacing * 2));
10051 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10052 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10053 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10054 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10055 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10056 TmpInst.addOperand(Inst.getOperand(5));
10057 Inst = TmpInst;
10058 return true;
10059 }
10060
10061 // VLD3 multiple 3-element structure instructions.
10062 case ARM::VLD3dAsm_8:
10063 case ARM::VLD3dAsm_16:
10064 case ARM::VLD3dAsm_32:
10065 case ARM::VLD3qAsm_8:
10066 case ARM::VLD3qAsm_16:
10067 case ARM::VLD3qAsm_32: {
10068 MCInst TmpInst;
10069 unsigned Spacing;
10070 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10071 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10073 Spacing));
10075 Spacing * 2));
10076 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10077 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10078 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10079 TmpInst.addOperand(Inst.getOperand(4));
10080 Inst = TmpInst;
10081 return true;
10082 }
10083
10084 case ARM::VLD3dWB_fixed_Asm_8:
10085 case ARM::VLD3dWB_fixed_Asm_16:
10086 case ARM::VLD3dWB_fixed_Asm_32:
10087 case ARM::VLD3qWB_fixed_Asm_8:
10088 case ARM::VLD3qWB_fixed_Asm_16:
10089 case ARM::VLD3qWB_fixed_Asm_32: {
10090 MCInst TmpInst;
10091 unsigned Spacing;
10092 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10093 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10095 Spacing));
10097 Spacing * 2));
10098 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10099 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10100 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10101 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10102 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10103 TmpInst.addOperand(Inst.getOperand(4));
10104 Inst = TmpInst;
10105 return true;
10106 }
10107
10108 case ARM::VLD3dWB_register_Asm_8:
10109 case ARM::VLD3dWB_register_Asm_16:
10110 case ARM::VLD3dWB_register_Asm_32:
10111 case ARM::VLD3qWB_register_Asm_8:
10112 case ARM::VLD3qWB_register_Asm_16:
10113 case ARM::VLD3qWB_register_Asm_32: {
10114 MCInst TmpInst;
10115 unsigned Spacing;
10116 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10117 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10119 Spacing));
10121 Spacing * 2));
10122 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10123 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10124 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10125 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10126 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10127 TmpInst.addOperand(Inst.getOperand(5));
10128 Inst = TmpInst;
10129 return true;
10130 }
10131
10132 // VLD4DUP single 3-element structure to all lanes instructions.
10133 case ARM::VLD4DUPdAsm_8:
10134 case ARM::VLD4DUPdAsm_16:
10135 case ARM::VLD4DUPdAsm_32:
10136 case ARM::VLD4DUPqAsm_8:
10137 case ARM::VLD4DUPqAsm_16:
10138 case ARM::VLD4DUPqAsm_32: {
10139 MCInst TmpInst;
10140 unsigned Spacing;
10141 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10142 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10144 Spacing));
10146 Spacing * 2));
10148 Spacing * 3));
10149 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10150 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10151 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10152 TmpInst.addOperand(Inst.getOperand(4));
10153 Inst = TmpInst;
10154 return true;
10155 }
10156
10157 case ARM::VLD4DUPdWB_fixed_Asm_8:
10158 case ARM::VLD4DUPdWB_fixed_Asm_16:
10159 case ARM::VLD4DUPdWB_fixed_Asm_32:
10160 case ARM::VLD4DUPqWB_fixed_Asm_8:
10161 case ARM::VLD4DUPqWB_fixed_Asm_16:
10162 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10163 MCInst TmpInst;
10164 unsigned Spacing;
10165 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10166 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10168 Spacing));
10170 Spacing * 2));
10172 Spacing * 3));
10173 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10174 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10175 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10176 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10177 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10178 TmpInst.addOperand(Inst.getOperand(4));
10179 Inst = TmpInst;
10180 return true;
10181 }
10182
10183 case ARM::VLD4DUPdWB_register_Asm_8:
10184 case ARM::VLD4DUPdWB_register_Asm_16:
10185 case ARM::VLD4DUPdWB_register_Asm_32:
10186 case ARM::VLD4DUPqWB_register_Asm_8:
10187 case ARM::VLD4DUPqWB_register_Asm_16:
10188 case ARM::VLD4DUPqWB_register_Asm_32: {
10189 MCInst TmpInst;
10190 unsigned Spacing;
10191 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10192 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10194 Spacing));
10196 Spacing * 2));
10198 Spacing * 3));
10199 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10200 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10201 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10202 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10203 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10204 TmpInst.addOperand(Inst.getOperand(5));
10205 Inst = TmpInst;
10206 return true;
10207 }
10208
10209 // VLD4 multiple 4-element structure instructions.
10210 case ARM::VLD4dAsm_8:
10211 case ARM::VLD4dAsm_16:
10212 case ARM::VLD4dAsm_32:
10213 case ARM::VLD4qAsm_8:
10214 case ARM::VLD4qAsm_16:
10215 case ARM::VLD4qAsm_32: {
10216 MCInst TmpInst;
10217 unsigned Spacing;
10218 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10219 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10221 Spacing));
10223 Spacing * 2));
10225 Spacing * 3));
10226 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10227 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10228 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10229 TmpInst.addOperand(Inst.getOperand(4));
10230 Inst = TmpInst;
10231 return true;
10232 }
10233
10234 case ARM::VLD4dWB_fixed_Asm_8:
10235 case ARM::VLD4dWB_fixed_Asm_16:
10236 case ARM::VLD4dWB_fixed_Asm_32:
10237 case ARM::VLD4qWB_fixed_Asm_8:
10238 case ARM::VLD4qWB_fixed_Asm_16:
10239 case ARM::VLD4qWB_fixed_Asm_32: {
10240 MCInst TmpInst;
10241 unsigned Spacing;
10242 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10243 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10245 Spacing));
10247 Spacing * 2));
10249 Spacing * 3));
10250 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10251 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10252 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10253 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10254 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10255 TmpInst.addOperand(Inst.getOperand(4));
10256 Inst = TmpInst;
10257 return true;
10258 }
10259
10260 case ARM::VLD4dWB_register_Asm_8:
10261 case ARM::VLD4dWB_register_Asm_16:
10262 case ARM::VLD4dWB_register_Asm_32:
10263 case ARM::VLD4qWB_register_Asm_8:
10264 case ARM::VLD4qWB_register_Asm_16:
10265 case ARM::VLD4qWB_register_Asm_32: {
10266 MCInst TmpInst;
10267 unsigned Spacing;
10268 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10269 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10271 Spacing));
10273 Spacing * 2));
10275 Spacing * 3));
10276 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10277 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10278 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10279 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10280 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10281 TmpInst.addOperand(Inst.getOperand(5));
10282 Inst = TmpInst;
10283 return true;
10284 }
10285
10286 // VST3 multiple 3-element structure instructions.
10287 case ARM::VST3dAsm_8:
10288 case ARM::VST3dAsm_16:
10289 case ARM::VST3dAsm_32:
10290 case ARM::VST3qAsm_8:
10291 case ARM::VST3qAsm_16:
10292 case ARM::VST3qAsm_32: {
10293 MCInst TmpInst;
10294 unsigned Spacing;
10295 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10296 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10297 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10298 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10300 Spacing));
10302 Spacing * 2));
10303 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10304 TmpInst.addOperand(Inst.getOperand(4));
10305 Inst = TmpInst;
10306 return true;
10307 }
10308
10309 case ARM::VST3dWB_fixed_Asm_8:
10310 case ARM::VST3dWB_fixed_Asm_16:
10311 case ARM::VST3dWB_fixed_Asm_32:
10312 case ARM::VST3qWB_fixed_Asm_8:
10313 case ARM::VST3qWB_fixed_Asm_16:
10314 case ARM::VST3qWB_fixed_Asm_32: {
10315 MCInst TmpInst;
10316 unsigned Spacing;
10317 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10318 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10319 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10320 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10321 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10322 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10324 Spacing));
10326 Spacing * 2));
10327 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10328 TmpInst.addOperand(Inst.getOperand(4));
10329 Inst = TmpInst;
10330 return true;
10331 }
10332
10333 case ARM::VST3dWB_register_Asm_8:
10334 case ARM::VST3dWB_register_Asm_16:
10335 case ARM::VST3dWB_register_Asm_32:
10336 case ARM::VST3qWB_register_Asm_8:
10337 case ARM::VST3qWB_register_Asm_16:
10338 case ARM::VST3qWB_register_Asm_32: {
10339 MCInst TmpInst;
10340 unsigned Spacing;
10341 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10342 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10343 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10344 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10345 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10346 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10348 Spacing));
10350 Spacing * 2));
10351 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10352 TmpInst.addOperand(Inst.getOperand(5));
10353 Inst = TmpInst;
10354 return true;
10355 }
10356
10357 // VST4 multiple 3-element structure instructions.
10358 case ARM::VST4dAsm_8:
10359 case ARM::VST4dAsm_16:
10360 case ARM::VST4dAsm_32:
10361 case ARM::VST4qAsm_8:
10362 case ARM::VST4qAsm_16:
10363 case ARM::VST4qAsm_32: {
10364 MCInst TmpInst;
10365 unsigned Spacing;
10366 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10367 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10368 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10369 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10371 Spacing));
10373 Spacing * 2));
10375 Spacing * 3));
10376 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10377 TmpInst.addOperand(Inst.getOperand(4));
10378 Inst = TmpInst;
10379 return true;
10380 }
10381
10382 case ARM::VST4dWB_fixed_Asm_8:
10383 case ARM::VST4dWB_fixed_Asm_16:
10384 case ARM::VST4dWB_fixed_Asm_32:
10385 case ARM::VST4qWB_fixed_Asm_8:
10386 case ARM::VST4qWB_fixed_Asm_16:
10387 case ARM::VST4qWB_fixed_Asm_32: {
10388 MCInst TmpInst;
10389 unsigned Spacing;
10390 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10391 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10392 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10393 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10394 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10395 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10397 Spacing));
10399 Spacing * 2));
10401 Spacing * 3));
10402 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10403 TmpInst.addOperand(Inst.getOperand(4));
10404 Inst = TmpInst;
10405 return true;
10406 }
10407
10408 case ARM::VST4dWB_register_Asm_8:
10409 case ARM::VST4dWB_register_Asm_16:
10410 case ARM::VST4dWB_register_Asm_32:
10411 case ARM::VST4qWB_register_Asm_8:
10412 case ARM::VST4qWB_register_Asm_16:
10413 case ARM::VST4qWB_register_Asm_32: {
10414 MCInst TmpInst;
10415 unsigned Spacing;
10416 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10417 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10418 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10419 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10420 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10421 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10423 Spacing));
10425 Spacing * 2));
10427 Spacing * 3));
10428 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10429 TmpInst.addOperand(Inst.getOperand(5));
10430 Inst = TmpInst;
10431 return true;
10432 }
10433
10434 // Handle encoding choice for the shift-immediate instructions.
10435 case ARM::t2LSLri:
10436 case ARM::t2LSRri:
10437 case ARM::t2ASRri:
10438 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10439 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10440 Inst.getOperand(5).getReg() ==
10441 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10442 !HasWideQualifier) {
10443 unsigned NewOpc;
10444 switch (Inst.getOpcode()) {
10445 default: llvm_unreachable("unexpected opcode");
10446 case ARM::t2LSLri: NewOpc = ARM::tLSLri; break;
10447 case ARM::t2LSRri: NewOpc = ARM::tLSRri; break;
10448 case ARM::t2ASRri: NewOpc = ARM::tASRri; break;
10449 }
10450 // The Thumb1 operands aren't in the same order. Awesome, eh?
10451 MCInst TmpInst;
10452 TmpInst.setOpcode(NewOpc);
10453 TmpInst.addOperand(Inst.getOperand(0));
10454 TmpInst.addOperand(Inst.getOperand(5));
10455 TmpInst.addOperand(Inst.getOperand(1));
10456 TmpInst.addOperand(Inst.getOperand(2));
10457 TmpInst.addOperand(Inst.getOperand(3));
10458 TmpInst.addOperand(Inst.getOperand(4));
10459 Inst = TmpInst;
10460 return true;
10461 }
10462 return false;
10463
10464 // Handle the Thumb2 mode MOV complex aliases.
10465 case ARM::t2MOVsr:
10466 case ARM::t2MOVSsr: {
10467 // Which instruction to expand to depends on the CCOut operand and
10468 // whether we're in an IT block if the register operands are low
10469 // registers.
10470 bool isNarrow = false;
10471 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10472 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10473 isARMLowRegister(Inst.getOperand(2).getReg()) &&
10474 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
10475 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr) &&
10476 !HasWideQualifier)
10477 isNarrow = true;
10478 MCInst TmpInst;
10479 unsigned newOpc;
10480 switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
10481 default: llvm_unreachable("unexpected opcode!");
10482 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
10483 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
10484 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
10485 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break;
10486 }
10487 TmpInst.setOpcode(newOpc);
10488 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10489 if (isNarrow)
10491 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10492 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10493 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10494 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10495 TmpInst.addOperand(Inst.getOperand(5));
10496 if (!isNarrow)
10498 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10499 Inst = TmpInst;
10500 return true;
10501 }
10502 case ARM::t2MOVsi:
10503 case ARM::t2MOVSsi: {
10504 // Which instruction to expand to depends on the CCOut operand and
10505 // whether we're in an IT block if the register operands are low
10506 // registers.
10507 bool isNarrow = false;
10508 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10509 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10510 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi) &&
10511 !HasWideQualifier)
10512 isNarrow = true;
10513 MCInst TmpInst;
10514 unsigned newOpc;
10515 unsigned Shift = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
10516 unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
10517 bool isMov = false;
10518 // MOV rd, rm, LSL #0 is actually a MOV instruction
10519 if (Shift == ARM_AM::lsl && Amount == 0) {
10520 isMov = true;
10521 // The 16-bit encoding of MOV rd, rm, LSL #N is explicitly encoding T2 of
10522 // MOV (register) in the ARMv8-A and ARMv8-M manuals, and immediate 0 is
10523 // unpredictable in an IT block so the 32-bit encoding T3 has to be used
10524 // instead.
10525 if (inITBlock()) {
10526 isNarrow = false;
10527 }
10528 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10529 } else {
10530 switch(Shift) {
10531 default: llvm_unreachable("unexpected opcode!");
10532 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
10533 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
10534 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
10535 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
10536 case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
10537 }
10538 }
10539 if (Amount == 32) Amount = 0;
10540 TmpInst.setOpcode(newOpc);
10541 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10542 if (isNarrow && !isMov)
10544 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10545 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10546 if (newOpc != ARM::t2RRX && !isMov)
10547 TmpInst.addOperand(MCOperand::createImm(Amount));
10548 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10549 TmpInst.addOperand(Inst.getOperand(4));
10550 if (!isNarrow)
10552 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10553 Inst = TmpInst;
10554 return true;
10555 }
10556 // Handle the ARM mode MOV complex aliases.
10557 case ARM::ASRr:
10558 case ARM::LSRr:
10559 case ARM::LSLr:
10560 case ARM::RORr: {
10561 ARM_AM::ShiftOpc ShiftTy;
10562 switch(Inst.getOpcode()) {
10563 default: llvm_unreachable("unexpected opcode!");
10564 case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
10565 case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
10566 case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
10567 case ARM::RORr: ShiftTy = ARM_AM::ror; break;
10568 }
10569 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
10570 MCInst TmpInst;
10571 TmpInst.setOpcode(ARM::MOVsr);
10572 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10573 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10574 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10575 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10576 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10577 TmpInst.addOperand(Inst.getOperand(4));
10578 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10579 Inst = TmpInst;
10580 return true;
10581 }
10582 case ARM::ASRi:
10583 case ARM::LSRi:
10584 case ARM::LSLi:
10585 case ARM::RORi: {
10586 ARM_AM::ShiftOpc ShiftTy;
10587 switch(Inst.getOpcode()) {
10588 default: llvm_unreachable("unexpected opcode!");
10589 case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
10590 case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
10591 case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
10592 case ARM::RORi: ShiftTy = ARM_AM::ror; break;
10593 }
10594 // A shift by zero is a plain MOVr, not a MOVsi.
10595 unsigned Amt = Inst.getOperand(2).getImm();
10596 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10597 // A shift by 32 should be encoded as 0 when permitted
10598 if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
10599 Amt = 0;
10600 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
10601 MCInst TmpInst;
10602 TmpInst.setOpcode(Opc);
10603 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10604 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10605 if (Opc == ARM::MOVsi)
10606 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10607 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10608 TmpInst.addOperand(Inst.getOperand(4));
10609 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10610 Inst = TmpInst;
10611 return true;
10612 }
10613 case ARM::RRXi: {
10614 unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
10615 MCInst TmpInst;
10616 TmpInst.setOpcode(ARM::MOVsi);
10617 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10618 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10619 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10620 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10621 TmpInst.addOperand(Inst.getOperand(3));
10622 TmpInst.addOperand(Inst.getOperand(4)); // cc_out
10623 Inst = TmpInst;
10624 return true;
10625 }
10626 case ARM::t2LDMIA_UPD: {
10627 // If this is a load of a single register, then we should use
10628 // a post-indexed LDR instruction instead, per the ARM ARM.
10629 if (Inst.getNumOperands() != 5)
10630 return false;
10631 MCInst TmpInst;
10632 TmpInst.setOpcode(ARM::t2LDR_POST);
10633 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10634 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10635 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10636 TmpInst.addOperand(MCOperand::createImm(4));
10637 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10638 TmpInst.addOperand(Inst.getOperand(3));
10639 Inst = TmpInst;
10640 return true;
10641 }
10642 case ARM::t2STMDB_UPD: {
10643 // If this is a store of a single register, then we should use
10644 // a pre-indexed STR instruction instead, per the ARM ARM.
10645 if (Inst.getNumOperands() != 5)
10646 return false;
10647 MCInst TmpInst;
10648 TmpInst.setOpcode(ARM::t2STR_PRE);
10649 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10650 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10651 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10652 TmpInst.addOperand(MCOperand::createImm(-4));
10653 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10654 TmpInst.addOperand(Inst.getOperand(3));
10655 Inst = TmpInst;
10656 return true;
10657 }
10658 case ARM::LDMIA_UPD:
10659 // If this is a load of a single register via a 'pop', then we should use
10660 // a post-indexed LDR instruction instead, per the ARM ARM.
10661 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "pop" &&
10662 Inst.getNumOperands() == 5) {
10663 MCInst TmpInst;
10664 TmpInst.setOpcode(ARM::LDR_POST_IMM);
10665 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10666 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10667 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10668 TmpInst.addOperand(MCOperand::createReg(0)); // am2offset
10669 TmpInst.addOperand(MCOperand::createImm(4));
10670 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10671 TmpInst.addOperand(Inst.getOperand(3));
10672 Inst = TmpInst;
10673 return true;
10674 }
10675 break;
10676 case ARM::STMDB_UPD:
10677 // If this is a store of a single register via a 'push', then we should use
10678 // a pre-indexed STR instruction instead, per the ARM ARM.
10679 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "push" &&
10680 Inst.getNumOperands() == 5) {
10681 MCInst TmpInst;
10682 TmpInst.setOpcode(ARM::STR_PRE_IMM);
10683 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10684 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10685 TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
10686 TmpInst.addOperand(MCOperand::createImm(-4));
10687 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10688 TmpInst.addOperand(Inst.getOperand(3));
10689 Inst = TmpInst;
10690 }
10691 break;
10692 case ARM::t2ADDri12:
10693 case ARM::t2SUBri12:
10694 case ARM::t2ADDspImm12:
10695 case ARM::t2SUBspImm12: {
10696 // If the immediate fits for encoding T3 and the generic
10697 // mnemonic was used, encoding T3 is preferred.
10698 const StringRef Token = static_cast<ARMOperand &>(*Operands[0]).getToken();
10699 if ((Token != "add" && Token != "sub") ||
10700 ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
10701 break;
10702 switch (Inst.getOpcode()) {
10703 case ARM::t2ADDri12:
10704 Inst.setOpcode(ARM::t2ADDri);
10705 break;
10706 case ARM::t2SUBri12:
10707 Inst.setOpcode(ARM::t2SUBri);
10708 break;
10709 case ARM::t2ADDspImm12:
10710 Inst.setOpcode(ARM::t2ADDspImm);
10711 break;
10712 case ARM::t2SUBspImm12:
10713 Inst.setOpcode(ARM::t2SUBspImm);
10714 break;
10715 }
10716
10717 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10718 return true;
10719 }
10720 case ARM::tADDi8:
10721 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10722 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10723 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10724 // to encoding T1 if <Rd> is omitted."
10725 if (Inst.getOperand(3).isImm() &&
10726 (unsigned)Inst.getOperand(3).getImm() < 8 &&
10727 Operands.size() == MnemonicOpsEndInd + 3) {
10728 Inst.setOpcode(ARM::tADDi3);
10729 return true;
10730 }
10731 break;
10732 case ARM::tSUBi8:
10733 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10734 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10735 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10736 // to encoding T1 if <Rd> is omitted."
10737 if ((unsigned)Inst.getOperand(3).getImm() < 8 &&
10738 Operands.size() == MnemonicOpsEndInd + 3) {
10739 Inst.setOpcode(ARM::tSUBi3);
10740 return true;
10741 }
10742 break;
10743 case ARM::t2ADDri:
10744 case ARM::t2SUBri: {
10745 // If the destination and first source operand are the same, and
10746 // the flags are compatible with the current IT status, use encoding T2
10747 // instead of T3. For compatibility with the system 'as'. Make sure the
10748 // wide encoding wasn't explicit.
10749 if (HasWideQualifier)
10750 break; // source code has asked for the 32-bit instruction
10751 if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg())
10752 break; // tADDi8 can't take different input and output registers
10753 if (!isARMLowRegister(Inst.getOperand(0).getReg()))
10754 break; // high register that tADDi8 can't access
10755 if (Inst.getOperand(5).getReg() !=
10756 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10757 break; // flag-modification would require overriding the IT state
10758 if (Inst.getOperand(2).isImm()) {
10759 if ((unsigned)Inst.getOperand(2).getImm() > 255)
10760 break; // large immediate that tADDi8 can't contain
10761 } else {
10762 int i = (Operands[MnemonicOpsEndInd + 1]->isImm())
10763 ? MnemonicOpsEndInd + 1
10764 : MnemonicOpsEndInd + 2;
10765 MCParsedAsmOperand &Op = *Operands[i];
10767 break; // a type of non-immediate that tADDi8 can't represent
10768 }
10769 MCInst TmpInst;
10770 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
10771 ARM::tADDi8 : ARM::tSUBi8);
10772 TmpInst.addOperand(Inst.getOperand(0));
10773 TmpInst.addOperand(Inst.getOperand(5));
10774 TmpInst.addOperand(Inst.getOperand(0));
10775 TmpInst.addOperand(Inst.getOperand(2));
10776 TmpInst.addOperand(Inst.getOperand(3));
10777 TmpInst.addOperand(Inst.getOperand(4));
10778 Inst = TmpInst;
10779 return true;
10780 }
10781 case ARM::t2ADDspImm:
10782 case ARM::t2SUBspImm: {
10783 // Prefer T1 encoding if possible
10784 if (Inst.getOperand(5).getReg() || HasWideQualifier)
10785 break;
10786 unsigned V = Inst.getOperand(2).getImm();
10787 if (V & 3 || V > ((1 << 7) - 1) << 2)
10788 break;
10789 MCInst TmpInst;
10790 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDspImm ? ARM::tADDspi
10791 : ARM::tSUBspi);
10792 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // destination reg
10793 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // source reg
10794 TmpInst.addOperand(MCOperand::createImm(V / 4)); // immediate
10795 TmpInst.addOperand(Inst.getOperand(3)); // pred
10796 TmpInst.addOperand(Inst.getOperand(4));
10797 Inst = TmpInst;
10798 return true;
10799 }
10800 case ARM::t2ADDrr: {
10801 // If the destination and first source operand are the same, and
10802 // there's no setting of the flags, use encoding T2 instead of T3.
10803 // Note that this is only for ADD, not SUB. This mirrors the system
10804 // 'as' behaviour. Also take advantage of ADD being commutative.
10805 // Make sure the wide encoding wasn't explicit.
10806 bool Swap = false;
10807 auto DestReg = Inst.getOperand(0).getReg();
10808 bool Transform = DestReg == Inst.getOperand(1).getReg();
10809 if (!Transform && DestReg == Inst.getOperand(2).getReg()) {
10810 Transform = true;
10811 Swap = true;
10812 }
10813 if (!Transform || Inst.getOperand(5).getReg() || HasWideQualifier)
10814 break;
10815 MCInst TmpInst;
10816 TmpInst.setOpcode(ARM::tADDhirr);
10817 TmpInst.addOperand(Inst.getOperand(0));
10818 TmpInst.addOperand(Inst.getOperand(0));
10819 TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2));
10820 TmpInst.addOperand(Inst.getOperand(3));
10821 TmpInst.addOperand(Inst.getOperand(4));
10822 Inst = TmpInst;
10823 return true;
10824 }
10825 case ARM::tADDrSP:
10826 // If the non-SP source operand and the destination operand are not the
10827 // same, we need to use the 32-bit encoding if it's available.
10828 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
10829 Inst.setOpcode(ARM::t2ADDrr);
10830 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10831 return true;
10832 }
10833 break;
10834 case ARM::tB:
10835 // A Thumb conditional branch outside of an IT block is a tBcc.
10836 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
10837 Inst.setOpcode(ARM::tBcc);
10838 return true;
10839 }
10840 break;
10841 case ARM::t2B:
10842 // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
10843 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
10844 Inst.setOpcode(ARM::t2Bcc);
10845 return true;
10846 }
10847 break;
10848 case ARM::t2Bcc:
10849 // If the conditional is AL or we're in an IT block, we really want t2B.
10850 if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
10851 Inst.setOpcode(ARM::t2B);
10852 return true;
10853 }
10854 break;
10855 case ARM::tBcc:
10856 // If the conditional is AL, we really want tB.
10857 if (Inst.getOperand(1).getImm() == ARMCC::AL) {
10858 Inst.setOpcode(ARM::tB);
10859 return true;
10860 }
10861 break;
10862 case ARM::tLDMIA: {
10863 // If the register list contains any high registers, or if the writeback
10864 // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
10865 // instead if we're in Thumb2. Otherwise, this should have generated
10866 // an error in validateInstruction().
10867 MCRegister Rn = Inst.getOperand(0).getReg();
10868 bool hasWritebackToken =
10869 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10870 .isToken() &&
10871 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10872 .getToken() == "!");
10873 bool listContainsBase;
10874 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), listContainsBase) ||
10875 (!listContainsBase && !hasWritebackToken) ||
10876 (listContainsBase && hasWritebackToken)) {
10877 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10878 assert(isThumbTwo());
10879 Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10880 // If we're switching to the updating version, we need to insert
10881 // the writeback tied operand.
10882 if (hasWritebackToken)
10883 Inst.insert(Inst.begin(),
10885 return true;
10886 }
10887 break;
10888 }
10889 case ARM::tSTMIA_UPD: {
10890 // If the register list contains any high registers, we need to use
10891 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10892 // should have generated an error in validateInstruction().
10893 MCRegister Rn = Inst.getOperand(0).getReg();
10894 bool listContainsBase;
10895 if (checkLowRegisterList(Inst, 4, Rn, MCRegister(), listContainsBase)) {
10896 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10897 assert(isThumbTwo());
10898 Inst.setOpcode(ARM::t2STMIA_UPD);
10899 return true;
10900 }
10901 break;
10902 }
10903 case ARM::tPOP: {
10904 bool listContainsBase;
10905 // If the register list contains any high registers, we need to use
10906 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10907 // should have generated an error in validateInstruction().
10908 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC, listContainsBase))
10909 return false;
10910 assert(isThumbTwo());
10911 Inst.setOpcode(ARM::t2LDMIA_UPD);
10912 // Add the base register and writeback operands.
10913 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10914 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10915 return true;
10916 }
10917 case ARM::tPUSH: {
10918 bool listContainsBase;
10919 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR, listContainsBase))
10920 return false;
10921 assert(isThumbTwo());
10922 Inst.setOpcode(ARM::t2STMDB_UPD);
10923 // Add the base register and writeback operands.
10924 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10925 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10926 return true;
10927 }
10928 case ARM::t2MOVi:
10929 // If we can use the 16-bit encoding and the user didn't explicitly
10930 // request the 32-bit variant, transform it here.
10931 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10932 (Inst.getOperand(1).isImm() &&
10933 (unsigned)Inst.getOperand(1).getImm() <= 255) &&
10934 Inst.getOperand(4).getReg() ==
10935 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10936 !HasWideQualifier) {
10937 // The operands aren't in the same order for tMOVi8...
10938 MCInst TmpInst;
10939 TmpInst.setOpcode(ARM::tMOVi8);
10940 TmpInst.addOperand(Inst.getOperand(0));
10941 TmpInst.addOperand(Inst.getOperand(4));
10942 TmpInst.addOperand(Inst.getOperand(1));
10943 TmpInst.addOperand(Inst.getOperand(2));
10944 TmpInst.addOperand(Inst.getOperand(3));
10945 Inst = TmpInst;
10946 return true;
10947 }
10948 break;
10949
10950 case ARM::t2MOVr:
10951 // If we can use the 16-bit encoding and the user didn't explicitly
10952 // request the 32-bit variant, transform it here.
10953 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10954 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10955 Inst.getOperand(2).getImm() == ARMCC::AL &&
10956 Inst.getOperand(4).getReg() == ARM::CPSR &&
10957 !HasWideQualifier) {
10958 // The operands aren't the same for tMOV[S]r... (no cc_out)
10959 MCInst TmpInst;
10960 unsigned Op = Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr;
10961 TmpInst.setOpcode(Op);
10962 TmpInst.addOperand(Inst.getOperand(0));
10963 TmpInst.addOperand(Inst.getOperand(1));
10964 if (Op == ARM::tMOVr) {
10965 TmpInst.addOperand(Inst.getOperand(2));
10966 TmpInst.addOperand(Inst.getOperand(3));
10967 }
10968 Inst = TmpInst;
10969 return true;
10970 }
10971 break;
10972
10973 case ARM::t2SXTH:
10974 case ARM::t2SXTB:
10975 case ARM::t2UXTH:
10976 case ARM::t2UXTB:
10977 // If we can use the 16-bit encoding and the user didn't explicitly
10978 // request the 32-bit variant, transform it here.
10979 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10980 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10981 Inst.getOperand(2).getImm() == 0 &&
10982 !HasWideQualifier) {
10983 unsigned NewOpc;
10984 switch (Inst.getOpcode()) {
10985 default: llvm_unreachable("Illegal opcode!");
10986 case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
10987 case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
10988 case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
10989 case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
10990 }
10991 // The operands aren't the same for thumb1 (no rotate operand).
10992 MCInst TmpInst;
10993 TmpInst.setOpcode(NewOpc);
10994 TmpInst.addOperand(Inst.getOperand(0));
10995 TmpInst.addOperand(Inst.getOperand(1));
10996 TmpInst.addOperand(Inst.getOperand(3));
10997 TmpInst.addOperand(Inst.getOperand(4));
10998 Inst = TmpInst;
10999 return true;
11000 }
11001 break;
11002
11003 case ARM::MOVsi: {
11005 // rrx shifts and asr/lsr of #32 is encoded as 0
11006 if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
11007 return false;
11008 if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
11009 // Shifting by zero is accepted as a vanilla 'MOVr'
11010 MCInst TmpInst;
11011 TmpInst.setOpcode(ARM::MOVr);
11012 TmpInst.addOperand(Inst.getOperand(0));
11013 TmpInst.addOperand(Inst.getOperand(1));
11014 TmpInst.addOperand(Inst.getOperand(3));
11015 TmpInst.addOperand(Inst.getOperand(4));
11016 TmpInst.addOperand(Inst.getOperand(5));
11017 Inst = TmpInst;
11018 return true;
11019 }
11020 return false;
11021 }
11022 case ARM::ANDrsi:
11023 case ARM::ORRrsi:
11024 case ARM::EORrsi:
11025 case ARM::BICrsi:
11026 case ARM::SUBrsi:
11027 case ARM::ADDrsi: {
11028 unsigned newOpc;
11030 if (SOpc == ARM_AM::rrx) return false;
11031 switch (Inst.getOpcode()) {
11032 default: llvm_unreachable("unexpected opcode!");
11033 case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
11034 case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
11035 case ARM::EORrsi: newOpc = ARM::EORrr; break;
11036 case ARM::BICrsi: newOpc = ARM::BICrr; break;
11037 case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
11038 case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
11039 }
11040 // If the shift is by zero, use the non-shifted instruction definition.
11041 // The exception is for right shifts, where 0 == 32
11042 if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 &&
11043 !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) {
11044 MCInst TmpInst;
11045 TmpInst.setOpcode(newOpc);
11046 TmpInst.addOperand(Inst.getOperand(0));
11047 TmpInst.addOperand(Inst.getOperand(1));
11048 TmpInst.addOperand(Inst.getOperand(2));
11049 TmpInst.addOperand(Inst.getOperand(4));
11050 TmpInst.addOperand(Inst.getOperand(5));
11051 TmpInst.addOperand(Inst.getOperand(6));
11052 Inst = TmpInst;
11053 return true;
11054 }
11055 return false;
11056 }
11057 case ARM::ITasm:
11058 case ARM::t2IT: {
11059 // Set up the IT block state according to the IT instruction we just
11060 // matched.
11061 assert(!inITBlock() && "nested IT blocks?!");
11062 startExplicitITBlock(ARMCC::CondCodes(Inst.getOperand(0).getImm()),
11063 Inst.getOperand(1).getImm());
11064 break;
11065 }
11066 case ARM::t2LSLrr:
11067 case ARM::t2LSRrr:
11068 case ARM::t2ASRrr:
11069 case ARM::t2SBCrr:
11070 case ARM::t2RORrr:
11071 case ARM::t2BICrr:
11072 // Assemblers should use the narrow encodings of these instructions when permissible.
11073 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11074 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11075 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
11076 Inst.getOperand(5).getReg() ==
11077 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11078 !HasWideQualifier) {
11079 unsigned NewOpc;
11080 switch (Inst.getOpcode()) {
11081 default: llvm_unreachable("unexpected opcode");
11082 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break;
11083 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break;
11084 case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break;
11085 case ARM::t2SBCrr: NewOpc = ARM::tSBC; break;
11086 case ARM::t2RORrr: NewOpc = ARM::tROR; break;
11087 case ARM::t2BICrr: NewOpc = ARM::tBIC; break;
11088 }
11089 MCInst TmpInst;
11090 TmpInst.setOpcode(NewOpc);
11091 TmpInst.addOperand(Inst.getOperand(0));
11092 TmpInst.addOperand(Inst.getOperand(5));
11093 TmpInst.addOperand(Inst.getOperand(1));
11094 TmpInst.addOperand(Inst.getOperand(2));
11095 TmpInst.addOperand(Inst.getOperand(3));
11096 TmpInst.addOperand(Inst.getOperand(4));
11097 Inst = TmpInst;
11098 return true;
11099 }
11100 return false;
11101
11102 case ARM::t2ANDrr:
11103 case ARM::t2EORrr:
11104 case ARM::t2ADCrr:
11105 case ARM::t2ORRrr:
11106 // Assemblers should use the narrow encodings of these instructions when permissible.
11107 // These instructions are special in that they are commutable, so shorter encodings
11108 // are available more often.
11109 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11110 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11111 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() ||
11112 Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) &&
11113 Inst.getOperand(5).getReg() ==
11114 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11115 !HasWideQualifier) {
11116 unsigned NewOpc;
11117 switch (Inst.getOpcode()) {
11118 default: llvm_unreachable("unexpected opcode");
11119 case ARM::t2ADCrr: NewOpc = ARM::tADC; break;
11120 case ARM::t2ANDrr: NewOpc = ARM::tAND; break;
11121 case ARM::t2EORrr: NewOpc = ARM::tEOR; break;
11122 case ARM::t2ORRrr: NewOpc = ARM::tORR; break;
11123 }
11124 MCInst TmpInst;
11125 TmpInst.setOpcode(NewOpc);
11126 TmpInst.addOperand(Inst.getOperand(0));
11127 TmpInst.addOperand(Inst.getOperand(5));
11128 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) {
11129 TmpInst.addOperand(Inst.getOperand(1));
11130 TmpInst.addOperand(Inst.getOperand(2));
11131 } else {
11132 TmpInst.addOperand(Inst.getOperand(2));
11133 TmpInst.addOperand(Inst.getOperand(1));
11134 }
11135 TmpInst.addOperand(Inst.getOperand(3));
11136 TmpInst.addOperand(Inst.getOperand(4));
11137 Inst = TmpInst;
11138 return true;
11139 }
11140 return false;
11141 case ARM::MVE_VPST:
11142 case ARM::MVE_VPTv16i8:
11143 case ARM::MVE_VPTv8i16:
11144 case ARM::MVE_VPTv4i32:
11145 case ARM::MVE_VPTv16u8:
11146 case ARM::MVE_VPTv8u16:
11147 case ARM::MVE_VPTv4u32:
11148 case ARM::MVE_VPTv16s8:
11149 case ARM::MVE_VPTv8s16:
11150 case ARM::MVE_VPTv4s32:
11151 case ARM::MVE_VPTv4f32:
11152 case ARM::MVE_VPTv8f16:
11153 case ARM::MVE_VPTv16i8r:
11154 case ARM::MVE_VPTv8i16r:
11155 case ARM::MVE_VPTv4i32r:
11156 case ARM::MVE_VPTv16u8r:
11157 case ARM::MVE_VPTv8u16r:
11158 case ARM::MVE_VPTv4u32r:
11159 case ARM::MVE_VPTv16s8r:
11160 case ARM::MVE_VPTv8s16r:
11161 case ARM::MVE_VPTv4s32r:
11162 case ARM::MVE_VPTv4f32r:
11163 case ARM::MVE_VPTv8f16r: {
11164 assert(!inVPTBlock() && "Nested VPT blocks are not allowed");
11165 MCOperand &MO = Inst.getOperand(0);
11166 VPTState.Mask = MO.getImm();
11167 VPTState.CurPosition = 0;
11168 break;
11169 }
11170 }
11171 return false;
11172}
11173
11174unsigned
11175ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11176 const OperandVector &Operands) {
11177 unsigned Opc = Inst.getOpcode();
11178 switch (Opc) {
11179 // Prevent the mov r8 r8 encoding for nop being selected when the v6/thumb 2
11180 // encoding is available.
11181 case ARM::tMOVr: {
11182 if (Operands[0]->isToken() &&
11183 static_cast<ARMOperand &>(*Operands[0]).getToken() == "nop" &&
11184 ((isThumb() && !isThumbOne()) || hasV6MOps())) {
11185 return Match_MnemonicFail;
11186 }
11187 }
11188 [[fallthrough]];
11189 default:
11190 return Match_Success;
11191 }
11192}
11193
11194unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11195 // 16-bit thumb arithmetic instructions either require or preclude the 'S'
11196 // suffix depending on whether they're in an IT block or not.
11197 unsigned Opc = Inst.getOpcode();
11198 const MCInstrDesc &MCID = MII.get(Opc);
11200 assert(MCID.hasOptionalDef() &&
11201 "optionally flag setting instruction missing optional def operand");
11202 assert(MCID.NumOperands == Inst.getNumOperands() &&
11203 "operand count mismatch!");
11204 bool IsCPSR = false;
11205 // Check if the instruction has CPSR set.
11206 for (unsigned OpNo = 0; OpNo < MCID.NumOperands; ++OpNo) {
11207 if (MCID.operands()[OpNo].isOptionalDef() &&
11208 Inst.getOperand(OpNo).isReg() &&
11209 Inst.getOperand(OpNo).getReg() == ARM::CPSR)
11210 IsCPSR = true;
11211 }
11212
11213 // If we're parsing Thumb1, reject it completely.
11214 if (isThumbOne() && !IsCPSR)
11215 return Match_RequiresFlagSetting;
11216 // If we're parsing Thumb2, which form is legal depends on whether we're
11217 // in an IT block.
11218 if (isThumbTwo() && !IsCPSR && !inITBlock())
11219 return Match_RequiresITBlock;
11220 if (isThumbTwo() && IsCPSR && inITBlock())
11221 return Match_RequiresNotITBlock;
11222 // LSL with zero immediate is not allowed in an IT block
11223 if (Opc == ARM::tLSLri && Inst.getOperand(3).getImm() == 0 && inITBlock())
11224 return Match_RequiresNotITBlock;
11225 } else if (isThumbOne()) {
11226 // Some high-register supporting Thumb1 encodings only allow both registers
11227 // to be from r0-r7 when in Thumb2.
11228 if (Opc == ARM::tADDhirr && !hasV6MOps() &&
11229 isARMLowRegister(Inst.getOperand(1).getReg()) &&
11231 return Match_RequiresThumb2;
11232 // Others only require ARMv6 or later.
11233 else if (Opc == ARM::tMOVr && !hasV6Ops() &&
11234 isARMLowRegister(Inst.getOperand(0).getReg()) &&
11236 return Match_RequiresV6;
11237 }
11238
11239 // Before ARMv8 the rules for when SP is allowed in t2MOVr are more complex
11240 // than the loop below can handle, so it uses the GPRnopc register class and
11241 // we do SP handling here.
11242 if (Opc == ARM::t2MOVr && !hasV8Ops())
11243 {
11244 // SP as both source and destination is not allowed
11245 if (Inst.getOperand(0).getReg() == ARM::SP &&
11246 Inst.getOperand(1).getReg() == ARM::SP)
11247 return Match_RequiresV8;
11248 // When flags-setting SP as either source or destination is not allowed
11249 if (Inst.getOperand(4).getReg() == ARM::CPSR &&
11250 (Inst.getOperand(0).getReg() == ARM::SP ||
11251 Inst.getOperand(1).getReg() == ARM::SP))
11252 return Match_RequiresV8;
11253 }
11254
11255 switch (Inst.getOpcode()) {
11256 case ARM::VMRS:
11257 case ARM::VMSR:
11258 case ARM::VMRS_FPCXTS:
11259 case ARM::VMRS_FPCXTNS:
11260 case ARM::VMSR_FPCXTS:
11261 case ARM::VMSR_FPCXTNS:
11262 case ARM::VMRS_FPSCR_NZCVQC:
11263 case ARM::VMSR_FPSCR_NZCVQC:
11264 case ARM::FMSTAT:
11265 case ARM::VMRS_VPR:
11266 case ARM::VMRS_P0:
11267 case ARM::VMSR_VPR:
11268 case ARM::VMSR_P0:
11269 // Use of SP for VMRS/VMSR is only allowed in ARM mode with the exception of
11270 // ARMv8-A.
11271 if (Inst.getOperand(0).isReg() && Inst.getOperand(0).getReg() == ARM::SP &&
11272 (isThumb() && !hasV8Ops()))
11273 return Match_InvalidOperand;
11274 break;
11275 case ARM::t2TBB:
11276 case ARM::t2TBH:
11277 // Rn = sp is only allowed with ARMv8-A
11278 if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP))
11279 return Match_RequiresV8;
11280 break;
11281 case ARM::tMUL:
11282 // The second source operand must be the same register as the destination
11283 // operand.
11284 // FIXME: Ideally this would be handled by ARMGenAsmMatcher and
11285 // emitAsmTiedOperandConstraints.
11286 if (Inst.getOperand(0).getReg() != Inst.getOperand(3).getReg())
11287 return Match_InvalidTiedOperand;
11288 break;
11289 default:
11290 break;
11291 }
11292
11293 for (unsigned I = 0; I < MCID.NumOperands; ++I)
11294 if (MCID.operands()[I].RegClass == ARM::rGPRRegClassID) {
11295 // rGPRRegClass excludes PC, and also excluded SP before ARMv8
11296 const auto &Op = Inst.getOperand(I);
11297 if (!Op.isReg()) {
11298 // This can happen in awkward cases with tied operands, e.g. a
11299 // writeback load/store with a complex addressing mode in
11300 // which there's an output operand corresponding to the
11301 // updated written-back base register: the Tablegen-generated
11302 // AsmMatcher will have written a placeholder operand to that
11303 // slot in the form of an immediate 0, because it can't
11304 // generate the register part of the complex addressing-mode
11305 // operand ahead of time.
11306 continue;
11307 }
11308
11309 MCRegister Reg = Op.getReg();
11310 if ((Reg == ARM::SP) && !hasV8Ops())
11311 return Match_RequiresV8;
11312 else if (Reg == ARM::PC)
11313 return Match_InvalidOperand;
11314 }
11315
11316 return Match_Success;
11317}
11318
11319namespace llvm {
11320
11321template <> inline bool IsCPSRDead<MCInst>(const MCInst *Instr) {
11322 return true; // In an assembly source, no need to second-guess
11323}
11324
11325} // end namespace llvm
11326
11327// Returns true if Inst is unpredictable if it is in and IT block, but is not
11328// the last instruction in the block.
11329bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const {
11330 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11331
11332 // All branch & call instructions terminate IT blocks with the exception of
11333 // SVC.
11334 if (MCID.isTerminator() || (MCID.isCall() && Inst.getOpcode() != ARM::tSVC) ||
11335 MCID.isReturn() || MCID.isBranch() || MCID.isIndirectBranch())
11336 return true;
11337
11338 // Any arithmetic instruction which writes to the PC also terminates the IT
11339 // block.
11340 if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI))
11341 return true;
11342
11343 return false;
11344}
11345
11346unsigned ARMAsmParser::MatchInstruction(OperandVector &Operands, MCInst &Inst,
11347 SmallVectorImpl<NearMissInfo> &NearMisses,
11348 bool MatchingInlineAsm,
11349 bool &EmitInITBlock,
11350 MCStreamer &Out) {
11351 // If we can't use an implicit IT block here, just match as normal.
11352 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11353 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11354
11355 // Try to match the instruction in an extension of the current IT block (if
11356 // there is one).
11357 if (inImplicitITBlock()) {
11358 extendImplicitITBlock(ITState.Cond);
11359 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11360 Match_Success) {
11361 // The match succeeded, but we still have to check that the instruction is
11362 // valid in this implicit IT block.
11363 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11364 if (MCID.isPredicable()) {
11365 ARMCC::CondCodes InstCond =
11367 .getImm();
11368 ARMCC::CondCodes ITCond = currentITCond();
11369 if (InstCond == ITCond) {
11370 EmitInITBlock = true;
11371 return Match_Success;
11372 } else if (InstCond == ARMCC::getOppositeCondition(ITCond)) {
11373 invertCurrentITCondition();
11374 EmitInITBlock = true;
11375 return Match_Success;
11376 }
11377 }
11378 }
11379 rewindImplicitITPosition();
11380 }
11381
11382 // Finish the current IT block, and try to match outside any IT block.
11383 flushPendingInstructions(Out);
11384 unsigned PlainMatchResult =
11385 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11386 if (PlainMatchResult == Match_Success) {
11387 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11388 if (MCID.isPredicable()) {
11389 ARMCC::CondCodes InstCond =
11391 .getImm();
11392 // Some forms of the branch instruction have their own condition code
11393 // fields, so can be conditionally executed without an IT block.
11394 if (Inst.getOpcode() == ARM::tBcc || Inst.getOpcode() == ARM::t2Bcc) {
11395 EmitInITBlock = false;
11396 return Match_Success;
11397 }
11398 if (InstCond == ARMCC::AL) {
11399 EmitInITBlock = false;
11400 return Match_Success;
11401 }
11402 } else {
11403 EmitInITBlock = false;
11404 return Match_Success;
11405 }
11406 }
11407
11408 // Try to match in a new IT block. The matcher doesn't check the actual
11409 // condition, so we create an IT block with a dummy condition, and fix it up
11410 // once we know the actual condition.
11411 startImplicitITBlock();
11412 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11413 Match_Success) {
11414 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11415 if (MCID.isPredicable()) {
11416 ITState.Cond =
11418 .getImm();
11419 EmitInITBlock = true;
11420 return Match_Success;
11421 }
11422 }
11423 discardImplicitITBlock();
11424
11425 // If none of these succeed, return the error we got when trying to match
11426 // outside any IT blocks.
11427 EmitInITBlock = false;
11428 return PlainMatchResult;
11429}
11430
11431static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
11432 unsigned VariantID = 0);
11433
11434static const char *getSubtargetFeatureName(uint64_t Val);
11435bool ARMAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
11436 OperandVector &Operands,
11438 bool MatchingInlineAsm) {
11439 MCInst Inst;
11440 unsigned MatchResult;
11441 bool PendConditionalInstruction = false;
11442
11444 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
11445 PendConditionalInstruction, Out);
11446
11447 // Find the number of operators that are part of the Mnumonic (LHS).
11448 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
11449
11450 switch (MatchResult) {
11451 case Match_Success:
11452 LLVM_DEBUG(dbgs() << "Parsed as: ";
11453 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11454 dbgs() << "\n");
11455
11456 // Context sensitive operand constraints aren't handled by the matcher,
11457 // so check them here.
11458 if (validateInstruction(Inst, Operands, MnemonicOpsEndInd)) {
11459 // Still progress the IT block, otherwise one wrong condition causes
11460 // nasty cascading errors.
11461 forwardITPosition();
11462 forwardVPTPosition();
11463 return true;
11464 }
11465
11466 {
11467 // Some instructions need post-processing to, for example, tweak which
11468 // encoding is selected. Loop on it while changes happen so the
11469 // individual transformations can chain off each other. E.g.,
11470 // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
11471 while (processInstruction(Inst, Operands, MnemonicOpsEndInd, Out))
11472 LLVM_DEBUG(dbgs() << "Changed to: ";
11473 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11474 dbgs() << "\n");
11475 }
11476
11477 // Only move forward at the very end so that everything in validate
11478 // and process gets a consistent answer about whether we're in an IT
11479 // block.
11480 forwardITPosition();
11481 forwardVPTPosition();
11482
11483 // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
11484 // doesn't actually encode.
11485 if (Inst.getOpcode() == ARM::ITasm)
11486 return false;
11487
11488 Inst.setLoc(IDLoc);
11489 if (PendConditionalInstruction) {
11490 PendingConditionalInsts.push_back(Inst);
11491 if (isITBlockFull() || isITBlockTerminator(Inst))
11492 flushPendingInstructions(Out);
11493 } else {
11494 Out.emitInstruction(Inst, getSTI());
11495 }
11496 return false;
11497 case Match_NearMisses:
11498 ReportNearMisses(NearMisses, IDLoc, Operands);
11499 return true;
11500 case Match_MnemonicFail: {
11501 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11502 std::string Suggestion = ARMMnemonicSpellCheck(
11503 ((ARMOperand &)*Operands[0]).getToken(), FBS);
11504 return Error(IDLoc, "invalid instruction" + Suggestion,
11505 ((ARMOperand &)*Operands[0]).getLocRange());
11506 }
11507 }
11508
11509 llvm_unreachable("Implement any new match types added!");
11510}
11511
11512/// ParseDirective parses the arm specific directives
11513bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11514 const MCContext::Environment Format = getContext().getObjectFileType();
11515 bool IsMachO = Format == MCContext::IsMachO;
11516 bool IsCOFF = Format == MCContext::IsCOFF;
11517
11518 std::string IDVal = DirectiveID.getIdentifier().lower();
11519 if (IDVal == ".word")
11520 parseLiteralValues(4, DirectiveID.getLoc());
11521 else if (IDVal == ".short" || IDVal == ".hword")
11522 parseLiteralValues(2, DirectiveID.getLoc());
11523 else if (IDVal == ".thumb")
11524 parseDirectiveThumb(DirectiveID.getLoc());
11525 else if (IDVal == ".arm")
11526 parseDirectiveARM(DirectiveID.getLoc());
11527 else if (IDVal == ".thumb_func")
11528 parseDirectiveThumbFunc(DirectiveID.getLoc());
11529 else if (IDVal == ".code")
11530 parseDirectiveCode(DirectiveID.getLoc());
11531 else if (IDVal == ".syntax")
11532 parseDirectiveSyntax(DirectiveID.getLoc());
11533 else if (IDVal == ".unreq")
11534 parseDirectiveUnreq(DirectiveID.getLoc());
11535 else if (IDVal == ".fnend")
11536 parseDirectiveFnEnd(DirectiveID.getLoc());
11537 else if (IDVal == ".cantunwind")
11538 parseDirectiveCantUnwind(DirectiveID.getLoc());
11539 else if (IDVal == ".personality")
11540 parseDirectivePersonality(DirectiveID.getLoc());
11541 else if (IDVal == ".handlerdata")
11542 parseDirectiveHandlerData(DirectiveID.getLoc());
11543 else if (IDVal == ".setfp")
11544 parseDirectiveSetFP(DirectiveID.getLoc());
11545 else if (IDVal == ".pad")
11546 parseDirectivePad(DirectiveID.getLoc());
11547 else if (IDVal == ".save")
11548 parseDirectiveRegSave(DirectiveID.getLoc(), false);
11549 else if (IDVal == ".vsave")
11550 parseDirectiveRegSave(DirectiveID.getLoc(), true);
11551 else if (IDVal == ".ltorg" || IDVal == ".pool")
11552 parseDirectiveLtorg(DirectiveID.getLoc());
11553 else if (IDVal == ".even")
11554 parseDirectiveEven(DirectiveID.getLoc());
11555 else if (IDVal == ".personalityindex")
11556 parseDirectivePersonalityIndex(DirectiveID.getLoc());
11557 else if (IDVal == ".unwind_raw")
11558 parseDirectiveUnwindRaw(DirectiveID.getLoc());
11559 else if (IDVal == ".movsp")
11560 parseDirectiveMovSP(DirectiveID.getLoc());
11561 else if (IDVal == ".arch_extension")
11562 parseDirectiveArchExtension(DirectiveID.getLoc());
11563 else if (IDVal == ".align")
11564 return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
11565 else if (IDVal == ".thumb_set")
11566 parseDirectiveThumbSet(DirectiveID.getLoc());
11567 else if (IDVal == ".inst")
11568 parseDirectiveInst(DirectiveID.getLoc());
11569 else if (IDVal == ".inst.n")
11570 parseDirectiveInst(DirectiveID.getLoc(), 'n');
11571 else if (IDVal == ".inst.w")
11572 parseDirectiveInst(DirectiveID.getLoc(), 'w');
11573 else if (!IsMachO && !IsCOFF) {
11574 if (IDVal == ".arch")
11575 parseDirectiveArch(DirectiveID.getLoc());
11576 else if (IDVal == ".cpu")
11577 parseDirectiveCPU(DirectiveID.getLoc());
11578 else if (IDVal == ".eabi_attribute")
11579 parseDirectiveEabiAttr(DirectiveID.getLoc());
11580 else if (IDVal == ".fpu")
11581 parseDirectiveFPU(DirectiveID.getLoc());
11582 else if (IDVal == ".fnstart")
11583 parseDirectiveFnStart(DirectiveID.getLoc());
11584 else if (IDVal == ".object_arch")
11585 parseDirectiveObjectArch(DirectiveID.getLoc());
11586 else if (IDVal == ".tlsdescseq")
11587 parseDirectiveTLSDescSeq(DirectiveID.getLoc());
11588 else
11589 return true;
11590 } else if (IsCOFF) {
11591 if (IDVal == ".seh_stackalloc")
11592 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/false);
11593 else if (IDVal == ".seh_stackalloc_w")
11594 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/true);
11595 else if (IDVal == ".seh_save_regs")
11596 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/false);
11597 else if (IDVal == ".seh_save_regs_w")
11598 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/true);
11599 else if (IDVal == ".seh_save_sp")
11600 parseDirectiveSEHSaveSP(DirectiveID.getLoc());
11601 else if (IDVal == ".seh_save_fregs")
11602 parseDirectiveSEHSaveFRegs(DirectiveID.getLoc());
11603 else if (IDVal == ".seh_save_lr")
11604 parseDirectiveSEHSaveLR(DirectiveID.getLoc());
11605 else if (IDVal == ".seh_endprologue")
11606 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/false);
11607 else if (IDVal == ".seh_endprologue_fragment")
11608 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/true);
11609 else if (IDVal == ".seh_nop")
11610 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/false);
11611 else if (IDVal == ".seh_nop_w")
11612 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/true);
11613 else if (IDVal == ".seh_startepilogue")
11614 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/false);
11615 else if (IDVal == ".seh_startepilogue_cond")
11616 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/true);
11617 else if (IDVal == ".seh_endepilogue")
11618 parseDirectiveSEHEpilogEnd(DirectiveID.getLoc());
11619 else if (IDVal == ".seh_custom")
11620 parseDirectiveSEHCustom(DirectiveID.getLoc());
11621 else
11622 return true;
11623 } else
11624 return true;
11625 return false;
11626}
11627
11628/// parseLiteralValues
11629/// ::= .hword expression [, expression]*
11630/// ::= .short expression [, expression]*
11631/// ::= .word expression [, expression]*
11632bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
11633 auto parseOne = [&]() -> bool {
11634 const MCExpr *Value;
11635 if (getParser().parseExpression(Value))
11636 return true;
11637 getParser().getStreamer().emitValue(Value, Size, L);
11638 return false;
11639 };
11640 return (parseMany(parseOne));
11641}
11642
11643/// parseDirectiveThumb
11644/// ::= .thumb
11645bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11646 if (parseEOL() || check(!hasThumb(), L, "target does not support Thumb mode"))
11647 return true;
11648
11649 if (!isThumb())
11650 SwitchMode();
11651
11652 getTargetStreamer().emitCode16();
11653 getParser().getStreamer().emitCodeAlignment(Align(2), &getSTI(), 0);
11654 return false;
11655}
11656
11657/// parseDirectiveARM
11658/// ::= .arm
11659bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11660 if (parseEOL() || check(!hasARM(), L, "target does not support ARM mode"))
11661 return true;
11662
11663 if (isThumb())
11664 SwitchMode();
11665 getTargetStreamer().emitCode32();
11666 getParser().getStreamer().emitCodeAlignment(Align(4), &getSTI(), 0);
11667 return false;
11668}
11669
11670void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11671 // We need to flush the current implicit IT block on a label, because it is
11672 // not legal to branch into an IT block.
11673 flushPendingInstructions(getStreamer());
11674}
11675
11676void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11677 if (NextSymbolIsThumb) {
11678 getTargetStreamer().emitThumbFunc(Symbol);
11679 NextSymbolIsThumb = false;
11680 }
11681}
11682
11683/// parseDirectiveThumbFunc
11684/// ::= .thumbfunc symbol_name
11685bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11686 MCAsmParser &Parser = getParser();
11687 const auto Format = getContext().getObjectFileType();
11688 bool IsMachO = Format == MCContext::IsMachO;
11689
11690 // Darwin asm has (optionally) function name after .thumb_func direction
11691 // ELF doesn't
11692
11693 if (IsMachO) {
11694 if (Parser.getTok().is(AsmToken::Identifier) ||
11695 Parser.getTok().is(AsmToken::String)) {
11696 MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
11697 Parser.getTok().getIdentifier());
11698 getTargetStreamer().emitThumbFunc(Func);
11699 Parser.Lex();
11700 if (parseEOL())
11701 return true;
11702 return false;
11703 }
11704 }
11705
11706 if (parseEOL())
11707 return true;
11708
11709 // .thumb_func implies .thumb
11710 if (!isThumb())
11711 SwitchMode();
11712
11713 getTargetStreamer().emitCode16();
11714
11715 NextSymbolIsThumb = true;
11716 return false;
11717}
11718
11719/// parseDirectiveSyntax
11720/// ::= .syntax unified | divided
11721bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11722 MCAsmParser &Parser = getParser();
11723 const AsmToken &Tok = Parser.getTok();
11724 if (Tok.isNot(AsmToken::Identifier)) {
11725 Error(L, "unexpected token in .syntax directive");
11726 return false;
11727 }
11728
11729 StringRef Mode = Tok.getString();
11730 Parser.Lex();
11731 if (check(Mode == "divided" || Mode == "DIVIDED", L,
11732 "'.syntax divided' arm assembly not supported") ||
11733 check(Mode != "unified" && Mode != "UNIFIED", L,
11734 "unrecognized syntax mode in .syntax directive") ||
11735 parseEOL())
11736 return true;
11737
11738 // TODO tell the MC streamer the mode
11739 // getParser().getStreamer().Emit???();
11740 return false;
11741}
11742
11743/// parseDirectiveCode
11744/// ::= .code 16 | 32
11745bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11746 MCAsmParser &Parser = getParser();
11747 const AsmToken &Tok = Parser.getTok();
11748 if (Tok.isNot(AsmToken::Integer))
11749 return Error(L, "unexpected token in .code directive");
11750 int64_t Val = Parser.getTok().getIntVal();
11751 if (Val != 16 && Val != 32) {
11752 Error(L, "invalid operand to .code directive");
11753 return false;
11754 }
11755 Parser.Lex();
11756
11757 if (parseEOL())
11758 return true;
11759
11760 if (Val == 16) {
11761 if (!hasThumb())
11762 return Error(L, "target does not support Thumb mode");
11763
11764 if (!isThumb())
11765 SwitchMode();
11766 getTargetStreamer().emitCode16();
11767 } else {
11768 if (!hasARM())
11769 return Error(L, "target does not support ARM mode");
11770
11771 if (isThumb())
11772 SwitchMode();
11773 getTargetStreamer().emitCode32();
11774 }
11775
11776 return false;
11777}
11778
11779/// parseDirectiveReq
11780/// ::= name .req registername
11781bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11782 MCAsmParser &Parser = getParser();
11783 Parser.Lex(); // Eat the '.req' token.
11784 MCRegister Reg;
11785 SMLoc SRegLoc, ERegLoc;
11786 const bool parseResult = parseRegister(Reg, SRegLoc, ERegLoc);
11787 if (check(parseResult, SRegLoc, "register name expected") || parseEOL())
11788 return true;
11789
11790 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg)
11791 return Error(SRegLoc,
11792 "redefinition of '" + Name + "' does not match original.");
11793
11794 return false;
11795}
11796
11797/// parseDirectiveUneq
11798/// ::= .unreq registername
11799bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11800 MCAsmParser &Parser = getParser();
11801 if (Parser.getTok().isNot(AsmToken::Identifier))
11802 return Error(L, "unexpected input in .unreq directive.");
11803 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
11804 Parser.Lex(); // Eat the identifier.
11805 return parseEOL();
11806}
11807
11808// After changing arch/CPU, try to put the ARM/Thumb mode back to what it was
11809// before, if supported by the new target, or emit mapping symbols for the mode
11810// switch.
11811void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) {
11812 if (WasThumb != isThumb()) {
11813 if (WasThumb && hasThumb()) {
11814 // Stay in Thumb mode
11815 SwitchMode();
11816 } else if (!WasThumb && hasARM()) {
11817 // Stay in ARM mode
11818 SwitchMode();
11819 } else {
11820 // Mode switch forced, because the new arch doesn't support the old mode.
11821 if (isThumb())
11822 getTargetStreamer().emitCode16();
11823 else
11824 getTargetStreamer().emitCode32();
11825 // Warn about the implicit mode switch. GAS does not switch modes here,
11826 // but instead stays in the old mode, reporting an error on any following
11827 // instructions as the mode does not exist on the target.
11828 Warning(Loc, Twine("new target does not support ") +
11829 (WasThumb ? "thumb" : "arm") + " mode, switching to " +
11830 (!WasThumb ? "thumb" : "arm") + " mode");
11831 }
11832 }
11833}
11834
11835/// parseDirectiveArch
11836/// ::= .arch token
11837bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11838 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11840
11841 if (ID == ARM::ArchKind::INVALID)
11842 return Error(L, "Unknown arch name");
11843
11844 bool WasThumb = isThumb();
11845 MCSubtargetInfo &STI = copySTI();
11846 STI.setDefaultFeatures("", /*TuneCPU*/ "",
11847 ("+" + ARM::getArchName(ID)).str());
11848 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11849 FixModeAfterArchChange(WasThumb, L);
11850
11851 getTargetStreamer().emitArch(ID);
11852 return false;
11853}
11854
11855/// parseDirectiveEabiAttr
11856/// ::= .eabi_attribute int, int [, "str"]
11857/// ::= .eabi_attribute Tag_name, int [, "str"]
11858bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11859 MCAsmParser &Parser = getParser();
11860 int64_t Tag;
11861 SMLoc TagLoc;
11862 TagLoc = Parser.getTok().getLoc();
11863 if (Parser.getTok().is(AsmToken::Identifier)) {
11864 StringRef Name = Parser.getTok().getIdentifier();
11865 std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString(
11867 if (!Ret) {
11868 Error(TagLoc, "attribute name not recognised: " + Name);
11869 return false;
11870 }
11871 Tag = *Ret;
11872 Parser.Lex();
11873 } else {
11874 const MCExpr *AttrExpr;
11875
11876 TagLoc = Parser.getTok().getLoc();
11877 if (Parser.parseExpression(AttrExpr))
11878 return true;
11879
11880 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
11881 if (check(!CE, TagLoc, "expected numeric constant"))
11882 return true;
11883
11884 Tag = CE->getValue();
11885 }
11886
11887 if (Parser.parseComma())
11888 return true;
11889
11890 StringRef StringValue = "";
11891 bool IsStringValue = false;
11892
11893 int64_t IntegerValue = 0;
11894 bool IsIntegerValue = false;
11895
11897 IsStringValue = true;
11898 else if (Tag == ARMBuildAttrs::compatibility) {
11899 IsStringValue = true;
11900 IsIntegerValue = true;
11901 } else if (Tag < 32 || Tag % 2 == 0)
11902 IsIntegerValue = true;
11903 else if (Tag % 2 == 1)
11904 IsStringValue = true;
11905 else
11906 llvm_unreachable("invalid tag type");
11907
11908 if (IsIntegerValue) {
11909 const MCExpr *ValueExpr;
11910 SMLoc ValueExprLoc = Parser.getTok().getLoc();
11911 if (Parser.parseExpression(ValueExpr))
11912 return true;
11913
11914 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
11915 if (!CE)
11916 return Error(ValueExprLoc, "expected numeric constant");
11917 IntegerValue = CE->getValue();
11918 }
11919
11921 if (Parser.parseComma())
11922 return true;
11923 }
11924
11925 std::string EscapedValue;
11926 if (IsStringValue) {
11927 if (Parser.getTok().isNot(AsmToken::String))
11928 return Error(Parser.getTok().getLoc(), "bad string constant");
11929
11931 if (Parser.parseEscapedString(EscapedValue))
11932 return Error(Parser.getTok().getLoc(), "bad escaped string constant");
11933
11934 StringValue = EscapedValue;
11935 } else {
11936 StringValue = Parser.getTok().getStringContents();
11937 Parser.Lex();
11938 }
11939 }
11940
11941 if (Parser.parseEOL())
11942 return true;
11943
11944 if (IsIntegerValue && IsStringValue) {
11946 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
11947 } else if (IsIntegerValue)
11948 getTargetStreamer().emitAttribute(Tag, IntegerValue);
11949 else if (IsStringValue)
11950 getTargetStreamer().emitTextAttribute(Tag, StringValue);
11951 return false;
11952}
11953
11954/// parseDirectiveCPU
11955/// ::= .cpu str
11956bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11957 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11958 getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
11959
11960 // FIXME: This is using table-gen data, but should be moved to
11961 // ARMTargetParser once that is table-gen'd.
11962 if (!getSTI().isCPUStringValid(CPU))
11963 return Error(L, "Unknown CPU name");
11964
11965 bool WasThumb = isThumb();
11966 MCSubtargetInfo &STI = copySTI();
11967 STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
11968 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11969 FixModeAfterArchChange(WasThumb, L);
11970
11971 return false;
11972}
11973
11974/// parseDirectiveFPU
11975/// ::= .fpu str
11976bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11977 SMLoc FPUNameLoc = getTok().getLoc();
11978 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11979
11981 std::vector<StringRef> Features;
11982 if (!ARM::getFPUFeatures(ID, Features))
11983 return Error(FPUNameLoc, "Unknown FPU name");
11984
11985 MCSubtargetInfo &STI = copySTI();
11986 for (auto Feature : Features)
11987 STI.ApplyFeatureFlag(Feature);
11988 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11989
11990 getTargetStreamer().emitFPU(ID);
11991 return false;
11992}
11993
11994/// parseDirectiveFnStart
11995/// ::= .fnstart
11996bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
11997 if (parseEOL())
11998 return true;
11999
12000 if (UC.hasFnStart()) {
12001 Error(L, ".fnstart starts before the end of previous one");
12002 UC.emitFnStartLocNotes();
12003 return true;
12004 }
12005
12006 // Reset the unwind directives parser state
12007 UC.reset();
12008
12009 getTargetStreamer().emitFnStart();
12010
12011 UC.recordFnStart(L);
12012 return false;
12013}
12014
12015/// parseDirectiveFnEnd
12016/// ::= .fnend
12017bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12018 if (parseEOL())
12019 return true;
12020 // Check the ordering of unwind directives
12021 if (!UC.hasFnStart())
12022 return Error(L, ".fnstart must precede .fnend directive");
12023
12024 // Reset the unwind directives parser state
12025 getTargetStreamer().emitFnEnd();
12026
12027 UC.reset();
12028 return false;
12029}
12030
12031/// parseDirectiveCantUnwind
12032/// ::= .cantunwind
12033bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12034 if (parseEOL())
12035 return true;
12036
12037 UC.recordCantUnwind(L);
12038 // Check the ordering of unwind directives
12039 if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive"))
12040 return true;
12041
12042 if (UC.hasHandlerData()) {
12043 Error(L, ".cantunwind can't be used with .handlerdata directive");
12044 UC.emitHandlerDataLocNotes();
12045 return true;
12046 }
12047 if (UC.hasPersonality()) {
12048 Error(L, ".cantunwind can't be used with .personality directive");
12049 UC.emitPersonalityLocNotes();
12050 return true;
12051 }
12052
12053 getTargetStreamer().emitCantUnwind();
12054 return false;
12055}
12056
12057/// parseDirectivePersonality
12058/// ::= .personality name
12059bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12060 MCAsmParser &Parser = getParser();
12061 bool HasExistingPersonality = UC.hasPersonality();
12062
12063 // Parse the name of the personality routine
12064 if (Parser.getTok().isNot(AsmToken::Identifier))
12065 return Error(L, "unexpected input in .personality directive.");
12066 StringRef Name(Parser.getTok().getIdentifier());
12067 Parser.Lex();
12068
12069 if (parseEOL())
12070 return true;
12071
12072 UC.recordPersonality(L);
12073
12074 // Check the ordering of unwind directives
12075 if (!UC.hasFnStart())
12076 return Error(L, ".fnstart must precede .personality directive");
12077 if (UC.cantUnwind()) {
12078 Error(L, ".personality can't be used with .cantunwind directive");
12079 UC.emitCantUnwindLocNotes();
12080 return true;
12081 }
12082 if (UC.hasHandlerData()) {
12083 Error(L, ".personality must precede .handlerdata directive");
12084 UC.emitHandlerDataLocNotes();
12085 return true;
12086 }
12087 if (HasExistingPersonality) {
12088 Error(L, "multiple personality directives");
12089 UC.emitPersonalityLocNotes();
12090 return true;
12091 }
12092
12093 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12094 getTargetStreamer().emitPersonality(PR);
12095 return false;
12096}
12097
12098/// parseDirectiveHandlerData
12099/// ::= .handlerdata
12100bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12101 if (parseEOL())
12102 return true;
12103
12104 UC.recordHandlerData(L);
12105 // Check the ordering of unwind directives
12106 if (!UC.hasFnStart())
12107 return Error(L, ".fnstart must precede .personality directive");
12108 if (UC.cantUnwind()) {
12109 Error(L, ".handlerdata can't be used with .cantunwind directive");
12110 UC.emitCantUnwindLocNotes();
12111 return true;
12112 }
12113
12114 getTargetStreamer().emitHandlerData();
12115 return false;
12116}
12117
12118/// parseDirectiveSetFP
12119/// ::= .setfp fpreg, spreg [, offset]
12120bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12121 MCAsmParser &Parser = getParser();
12122 // Check the ordering of unwind directives
12123 if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") ||
12124 check(UC.hasHandlerData(), L,
12125 ".setfp must precede .handlerdata directive"))
12126 return true;
12127
12128 // Parse fpreg
12129 SMLoc FPRegLoc = Parser.getTok().getLoc();
12130 MCRegister FPReg = tryParseRegister();
12131
12132 if (check(!FPReg, FPRegLoc, "frame pointer register expected") ||
12133 Parser.parseComma())
12134 return true;
12135
12136 // Parse spreg
12137 SMLoc SPRegLoc = Parser.getTok().getLoc();
12138 MCRegister SPReg = tryParseRegister();
12139 if (check(!SPReg, SPRegLoc, "stack pointer register expected") ||
12140 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
12141 "register should be either $sp or the latest fp register"))
12142 return true;
12143
12144 // Update the frame pointer register
12145 UC.saveFPReg(FPReg);
12146
12147 // Parse offset
12148 int64_t Offset = 0;
12149 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12150 if (Parser.getTok().isNot(AsmToken::Hash) &&
12151 Parser.getTok().isNot(AsmToken::Dollar))
12152 return Error(Parser.getTok().getLoc(), "'#' expected");
12153 Parser.Lex(); // skip hash token.
12154
12155 const MCExpr *OffsetExpr;
12156 SMLoc ExLoc = Parser.getTok().getLoc();
12157 SMLoc EndLoc;
12158 if (getParser().parseExpression(OffsetExpr, EndLoc))
12159 return Error(ExLoc, "malformed setfp offset");
12160 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12161 if (check(!CE, ExLoc, "setfp offset must be an immediate"))
12162 return true;
12163 Offset = CE->getValue();
12164 }
12165
12166 if (Parser.parseEOL())
12167 return true;
12168
12169 getTargetStreamer().emitSetFP(FPReg, SPReg, Offset);
12170 return false;
12171}
12172
12173/// parseDirectivePad
12174/// ::= .pad offset
12175bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12176 MCAsmParser &Parser = getParser();
12177 // Check the ordering of unwind directives
12178 if (!UC.hasFnStart())
12179 return Error(L, ".fnstart must precede .pad directive");
12180 if (UC.hasHandlerData())
12181 return Error(L, ".pad must precede .handlerdata directive");
12182
12183 // Parse the offset
12184 if (Parser.getTok().isNot(AsmToken::Hash) &&
12185 Parser.getTok().isNot(AsmToken::Dollar))
12186 return Error(Parser.getTok().getLoc(), "'#' expected");
12187 Parser.Lex(); // skip hash token.
12188
12189 const MCExpr *OffsetExpr;
12190 SMLoc ExLoc = Parser.getTok().getLoc();
12191 SMLoc EndLoc;
12192 if (getParser().parseExpression(OffsetExpr, EndLoc))
12193 return Error(ExLoc, "malformed pad offset");
12194 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12195 if (!CE)
12196 return Error(ExLoc, "pad offset must be an immediate");
12197
12198 if (parseEOL())
12199 return true;
12200
12201 getTargetStreamer().emitPad(CE->getValue());
12202 return false;
12203}
12204
12205/// parseDirectiveRegSave
12206/// ::= .save { registers }
12207/// ::= .vsave { registers }
12208bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
12209 // Check the ordering of unwind directives
12210 if (!UC.hasFnStart())
12211 return Error(L, ".fnstart must precede .save or .vsave directives");
12212 if (UC.hasHandlerData())
12213 return Error(L, ".save or .vsave must precede .handlerdata directive");
12214
12215 // RAII object to make sure parsed operands are deleted.
12217
12218 // Parse the register list
12219 if (parseRegisterList(Operands, true, true) || parseEOL())
12220 return true;
12221 ARMOperand &Op = (ARMOperand &)*Operands[0];
12222 if (!IsVector && !Op.isRegList())
12223 return Error(L, ".save expects GPR registers");
12224 if (IsVector && !Op.isDPRRegList())
12225 return Error(L, ".vsave expects DPR registers");
12226
12227 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
12228 return false;
12229}
12230
12231/// parseDirectiveInst
12232/// ::= .inst opcode [, ...]
12233/// ::= .inst.n opcode [, ...]
12234/// ::= .inst.w opcode [, ...]
12235bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
12236 int Width = 4;
12237
12238 if (isThumb()) {
12239 switch (Suffix) {
12240 case 'n':
12241 Width = 2;
12242 break;
12243 case 'w':
12244 break;
12245 default:
12246 Width = 0;
12247 break;
12248 }
12249 } else {
12250 if (Suffix)
12251 return Error(Loc, "width suffixes are invalid in ARM mode");
12252 }
12253
12254 auto parseOne = [&]() -> bool {
12255 const MCExpr *Expr;
12256 if (getParser().parseExpression(Expr))
12257 return true;
12258 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
12259 if (!Value) {
12260 return Error(Loc, "expected constant expression");
12261 }
12262
12263 char CurSuffix = Suffix;
12264 switch (Width) {
12265 case 2:
12266 if (Value->getValue() > 0xffff)
12267 return Error(Loc, "inst.n operand is too big, use inst.w instead");
12268 break;
12269 case 4:
12270 if (Value->getValue() > 0xffffffff)
12271 return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +
12272 " operand is too big");
12273 break;
12274 case 0:
12275 // Thumb mode, no width indicated. Guess from the opcode, if possible.
12276 if (Value->getValue() < 0xe800)
12277 CurSuffix = 'n';
12278 else if (Value->getValue() >= 0xe8000000)
12279 CurSuffix = 'w';
12280 else
12281 return Error(Loc, "cannot determine Thumb instruction size, "
12282 "use inst.n/inst.w instead");
12283 break;
12284 default:
12285 llvm_unreachable("only supported widths are 2 and 4");
12286 }
12287
12288 getTargetStreamer().emitInst(Value->getValue(), CurSuffix);
12289 forwardITPosition();
12290 forwardVPTPosition();
12291 return false;
12292 };
12293
12294 if (parseOptionalToken(AsmToken::EndOfStatement))
12295 return Error(Loc, "expected expression following directive");
12296 if (parseMany(parseOne))
12297 return true;
12298 return false;
12299}
12300
12301/// parseDirectiveLtorg
12302/// ::= .ltorg | .pool
12303bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12304 if (parseEOL())
12305 return true;
12306 getTargetStreamer().emitCurrentConstantPool();
12307 return false;
12308}
12309
12310bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12311 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12312
12313 if (parseEOL())
12314 return true;
12315
12316 if (!Section) {
12317 getStreamer().initSections(getSTI());
12318 Section = getStreamer().getCurrentSectionOnly();
12319 }
12320
12321 assert(Section && "must have section to emit alignment");
12322 if (getContext().getAsmInfo().useCodeAlign(*Section))
12323 getStreamer().emitCodeAlignment(Align(2), &getSTI());
12324 else
12325 getStreamer().emitValueToAlignment(Align(2));
12326
12327 return false;
12328}
12329
12330/// parseDirectivePersonalityIndex
12331/// ::= .personalityindex index
12332bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12333 MCAsmParser &Parser = getParser();
12334 bool HasExistingPersonality = UC.hasPersonality();
12335
12336 const MCExpr *IndexExpression;
12337 SMLoc IndexLoc = Parser.getTok().getLoc();
12338 if (Parser.parseExpression(IndexExpression) || parseEOL()) {
12339 return true;
12340 }
12341
12342 UC.recordPersonalityIndex(L);
12343
12344 if (!UC.hasFnStart()) {
12345 return Error(L, ".fnstart must precede .personalityindex directive");
12346 }
12347 if (UC.cantUnwind()) {
12348 Error(L, ".personalityindex cannot be used with .cantunwind");
12349 UC.emitCantUnwindLocNotes();
12350 return true;
12351 }
12352 if (UC.hasHandlerData()) {
12353 Error(L, ".personalityindex must precede .handlerdata directive");
12354 UC.emitHandlerDataLocNotes();
12355 return true;
12356 }
12357 if (HasExistingPersonality) {
12358 Error(L, "multiple personality directives");
12359 UC.emitPersonalityLocNotes();
12360 return true;
12361 }
12362
12363 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression);
12364 if (!CE)
12365 return Error(IndexLoc, "index must be a constant number");
12366 if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX)
12367 return Error(IndexLoc,
12368 "personality routine index should be in range [0-3]");
12369
12370 getTargetStreamer().emitPersonalityIndex(CE->getValue());
12371 return false;
12372}
12373
12374/// parseDirectiveUnwindRaw
12375/// ::= .unwind_raw offset, opcode [, opcode...]
12376bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12377 MCAsmParser &Parser = getParser();
12378 int64_t StackOffset;
12379 const MCExpr *OffsetExpr;
12380 SMLoc OffsetLoc = getLexer().getLoc();
12381
12382 if (!UC.hasFnStart())
12383 return Error(L, ".fnstart must precede .unwind_raw directives");
12384 if (getParser().parseExpression(OffsetExpr))
12385 return Error(OffsetLoc, "expected expression");
12386
12387 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12388 if (!CE)
12389 return Error(OffsetLoc, "offset must be a constant");
12390
12391 StackOffset = CE->getValue();
12392
12393 if (Parser.parseComma())
12394 return true;
12395
12397
12398 auto parseOne = [&]() -> bool {
12399 const MCExpr *OE = nullptr;
12400 SMLoc OpcodeLoc = getLexer().getLoc();
12401 if (check(getLexer().is(AsmToken::EndOfStatement) ||
12402 Parser.parseExpression(OE),
12403 OpcodeLoc, "expected opcode expression"))
12404 return true;
12405 const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE);
12406 if (!OC)
12407 return Error(OpcodeLoc, "opcode value must be a constant");
12408 const int64_t Opcode = OC->getValue();
12409 if (Opcode & ~0xff)
12410 return Error(OpcodeLoc, "invalid opcode");
12411 Opcodes.push_back(uint8_t(Opcode));
12412 return false;
12413 };
12414
12415 // Must have at least 1 element
12416 SMLoc OpcodeLoc = getLexer().getLoc();
12417 if (parseOptionalToken(AsmToken::EndOfStatement))
12418 return Error(OpcodeLoc, "expected opcode expression");
12419 if (parseMany(parseOne))
12420 return true;
12421
12422 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12423 return false;
12424}
12425
12426/// parseDirectiveTLSDescSeq
12427/// ::= .tlsdescseq tls-variable
12428bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12429 MCAsmParser &Parser = getParser();
12430
12431 if (getLexer().isNot(AsmToken::Identifier))
12432 return TokError("expected variable after '.tlsdescseq' directive");
12433
12434 auto *Sym = getContext().getOrCreateSymbol(Parser.getTok().getIdentifier());
12435 const auto *SRE =
12437 Lex();
12438
12439 if (parseEOL())
12440 return true;
12441
12442 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12443 return false;
12444}
12445
12446/// parseDirectiveMovSP
12447/// ::= .movsp reg [, #offset]
12448bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12449 MCAsmParser &Parser = getParser();
12450 if (!UC.hasFnStart())
12451 return Error(L, ".fnstart must precede .movsp directives");
12452 if (UC.getFPReg() != ARM::SP)
12453 return Error(L, "unexpected .movsp directive");
12454
12455 SMLoc SPRegLoc = Parser.getTok().getLoc();
12456 MCRegister SPReg = tryParseRegister();
12457 if (!SPReg)
12458 return Error(SPRegLoc, "register expected");
12459 if (SPReg == ARM::SP || SPReg == ARM::PC)
12460 return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
12461
12462 int64_t Offset = 0;
12463 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12464 if (Parser.parseToken(AsmToken::Hash, "expected #constant"))
12465 return true;
12466
12467 const MCExpr *OffsetExpr;
12468 SMLoc OffsetLoc = Parser.getTok().getLoc();
12469
12470 if (Parser.parseExpression(OffsetExpr))
12471 return Error(OffsetLoc, "malformed offset expression");
12472
12473 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12474 if (!CE)
12475 return Error(OffsetLoc, "offset must be an immediate constant");
12476
12477 Offset = CE->getValue();
12478 }
12479
12480 if (parseEOL())
12481 return true;
12482
12483 getTargetStreamer().emitMovSP(SPReg, Offset);
12484 UC.saveFPReg(SPReg);
12485
12486 return false;
12487}
12488
12489/// parseDirectiveObjectArch
12490/// ::= .object_arch name
12491bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12492 MCAsmParser &Parser = getParser();
12493 if (getLexer().isNot(AsmToken::Identifier))
12494 return Error(getLexer().getLoc(), "unexpected token");
12495
12496 StringRef Arch = Parser.getTok().getString();
12497 SMLoc ArchLoc = Parser.getTok().getLoc();
12498 Lex();
12499
12501
12502 if (ID == ARM::ArchKind::INVALID)
12503 return Error(ArchLoc, "unknown architecture '" + Arch + "'");
12504 if (parseToken(AsmToken::EndOfStatement))
12505 return true;
12506
12507 getTargetStreamer().emitObjectArch(ID);
12508 return false;
12509}
12510
12511/// parseDirectiveAlign
12512/// ::= .align
12513bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12514 // NOTE: if this is not the end of the statement, fall back to the target
12515 // agnostic handling for this directive which will correctly handle this.
12516 if (parseOptionalToken(AsmToken::EndOfStatement)) {
12517 // '.align' is target specifically handled to mean 2**2 byte alignment.
12518 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12519 assert(Section && "must have section to emit alignment");
12520 if (getContext().getAsmInfo().useCodeAlign(*Section))
12521 getStreamer().emitCodeAlignment(Align(4), &getSTI(), 0);
12522 else
12523 getStreamer().emitValueToAlignment(Align(4), 0, 1, 0);
12524 return false;
12525 }
12526 return true;
12527}
12528
12529/// parseDirectiveThumbSet
12530/// ::= .thumb_set name, value
12531bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12532 MCAsmParser &Parser = getParser();
12533
12534 StringRef Name;
12535 if (check(Parser.parseIdentifier(Name),
12536 "expected identifier after '.thumb_set'") ||
12537 Parser.parseComma())
12538 return true;
12539
12540 MCSymbol *Sym;
12541 const MCExpr *Value;
12542 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
12543 Parser, Sym, Value))
12544 return true;
12545
12546 getTargetStreamer().emitThumbSet(Sym, Value);
12547 return false;
12548}
12549
12550/// parseDirectiveSEHAllocStack
12551/// ::= .seh_stackalloc
12552/// ::= .seh_stackalloc_w
12553bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L, bool Wide) {
12554 int64_t Size;
12555 if (parseImmExpr(Size))
12556 return true;
12557 getTargetStreamer().emitARMWinCFIAllocStack(Size, Wide);
12558 return false;
12559}
12560
12561/// parseDirectiveSEHSaveRegs
12562/// ::= .seh_save_regs
12563/// ::= .seh_save_regs_w
12564bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L, bool Wide) {
12566
12567 if (parseRegisterList(Operands) || parseEOL())
12568 return true;
12569 ARMOperand &Op = (ARMOperand &)*Operands[0];
12570 if (!Op.isRegList())
12571 return Error(L, ".seh_save_regs{_w} expects GPR registers");
12572 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12573 uint32_t Mask = 0;
12574 for (size_t i = 0; i < RegList.size(); ++i) {
12575 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12576 if (Reg == 15) // pc -> lr
12577 Reg = 14;
12578 if (Reg == 13)
12579 return Error(L, ".seh_save_regs{_w} can't include SP");
12580 assert(Reg < 16U && "Register out of range");
12581 unsigned Bit = (1u << Reg);
12582 Mask |= Bit;
12583 }
12584 if (!Wide && (Mask & 0x1f00) != 0)
12585 return Error(L,
12586 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12587 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12588 return false;
12589}
12590
12591/// parseDirectiveSEHSaveSP
12592/// ::= .seh_save_sp
12593bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12594 MCRegister Reg = tryParseRegister();
12595 if (!Reg || !MRI->getRegClass(ARM::GPRRegClassID).contains(Reg))
12596 return Error(L, "expected GPR");
12597 unsigned Index = MRI->getEncodingValue(Reg);
12598 if (Index > 14 || Index == 13)
12599 return Error(L, "invalid register for .seh_save_sp");
12600 getTargetStreamer().emitARMWinCFISaveSP(Index);
12601 return false;
12602}
12603
12604/// parseDirectiveSEHSaveFRegs
12605/// ::= .seh_save_fregs
12606bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12608
12609 if (parseRegisterList(Operands) || parseEOL())
12610 return true;
12611 ARMOperand &Op = (ARMOperand &)*Operands[0];
12612 if (!Op.isDPRRegList())
12613 return Error(L, ".seh_save_fregs expects DPR registers");
12614 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12615 uint32_t Mask = 0;
12616 for (size_t i = 0; i < RegList.size(); ++i) {
12617 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12618 assert(Reg < 32U && "Register out of range");
12619 unsigned Bit = (1u << Reg);
12620 Mask |= Bit;
12621 }
12622
12623 if (Mask == 0)
12624 return Error(L, ".seh_save_fregs missing registers");
12625
12626 unsigned First = 0;
12627 while ((Mask & 1) == 0) {
12628 First++;
12629 Mask >>= 1;
12630 }
12631 if (((Mask + 1) & Mask) != 0)
12632 return Error(L,
12633 ".seh_save_fregs must take a contiguous range of registers");
12634 unsigned Last = First;
12635 while ((Mask & 2) != 0) {
12636 Last++;
12637 Mask >>= 1;
12638 }
12639 if (First < 16 && Last >= 16)
12640 return Error(L, ".seh_save_fregs must be all d0-d15 or d16-d31");
12641 getTargetStreamer().emitARMWinCFISaveFRegs(First, Last);
12642 return false;
12643}
12644
12645/// parseDirectiveSEHSaveLR
12646/// ::= .seh_save_lr
12647bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12648 int64_t Offset;
12649 if (parseImmExpr(Offset))
12650 return true;
12651 getTargetStreamer().emitARMWinCFISaveLR(Offset);
12652 return false;
12653}
12654
12655/// parseDirectiveSEHPrologEnd
12656/// ::= .seh_endprologue
12657/// ::= .seh_endprologue_fragment
12658bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L, bool Fragment) {
12659 getTargetStreamer().emitARMWinCFIPrologEnd(Fragment);
12660 return false;
12661}
12662
12663/// parseDirectiveSEHNop
12664/// ::= .seh_nop
12665/// ::= .seh_nop_w
12666bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L, bool Wide) {
12667 getTargetStreamer().emitARMWinCFINop(Wide);
12668 return false;
12669}
12670
12671/// parseDirectiveSEHEpilogStart
12672/// ::= .seh_startepilogue
12673/// ::= .seh_startepilogue_cond
12674bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L, bool Condition) {
12675 unsigned CC = ARMCC::AL;
12676 if (Condition) {
12677 MCAsmParser &Parser = getParser();
12678 SMLoc S = Parser.getTok().getLoc();
12679 const AsmToken &Tok = Parser.getTok();
12680 if (!Tok.is(AsmToken::Identifier))
12681 return Error(S, ".seh_startepilogue_cond missing condition");
12682 CC = ARMCondCodeFromString(Tok.getString());
12683 if (CC == ~0U)
12684 return Error(S, "invalid condition");
12685 Parser.Lex(); // Eat the token.
12686 }
12687
12688 getTargetStreamer().emitARMWinCFIEpilogStart(CC);
12689 return false;
12690}
12691
12692/// parseDirectiveSEHEpilogEnd
12693/// ::= .seh_endepilogue
12694bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12695 getTargetStreamer().emitARMWinCFIEpilogEnd();
12696 return false;
12697}
12698
12699/// parseDirectiveSEHCustom
12700/// ::= .seh_custom
12701bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12702 unsigned Opcode = 0;
12703 do {
12704 int64_t Byte;
12705 if (parseImmExpr(Byte))
12706 return true;
12707 if (Byte > 0xff || Byte < 0)
12708 return Error(L, "Invalid byte value in .seh_custom");
12709 if (Opcode > 0x00ffffff)
12710 return Error(L, "Too many bytes in .seh_custom");
12711 // Store the bytes as one big endian number in Opcode. In a multi byte
12712 // opcode sequence, the first byte can't be zero.
12713 Opcode = (Opcode << 8) | Byte;
12714 } while (parseOptionalToken(AsmToken::Comma));
12715 getTargetStreamer().emitARMWinCFICustom(Opcode);
12716 return false;
12717}
12718
12719/// Force static initialization.
12726
12727#define GET_REGISTER_MATCHER
12728#define GET_SUBTARGET_FEATURE_NAME
12729#define GET_MATCHER_IMPLEMENTATION
12730#define GET_MNEMONIC_SPELL_CHECKER
12731#include "ARMGenAsmMatcher.inc"
12732
12733// Some diagnostics need to vary with subtarget features, so they are handled
12734// here. For example, the DPR class has either 16 or 32 registers, depending
12735// on the FPU available.
12736const char *
12737ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12738 switch (MatchError) {
12739 // rGPR contains sp starting with ARMv8.
12740 case Match_rGPR:
12741 return hasV8Ops() ? "operand must be a register in range [r0, r14]"
12742 : "operand must be a register in range [r0, r12] or r14";
12743 // DPR contains 16 registers for some FPUs, and 32 for others.
12744 case Match_DPR:
12745 return hasD32() ? "operand must be a register in range [d0, d31]"
12746 : "operand must be a register in range [d0, d15]";
12747 case Match_DPR_RegList:
12748 return hasD32() ? "operand must be a list of registers in range [d0, d31]"
12749 : "operand must be a list of registers in range [d0, d15]";
12750
12751 // For all other diags, use the static string from tablegen.
12752 default:
12753 return getMatchKindDiag(MatchError);
12754 }
12755}
12756
12757// Process the list of near-misses, throwing away ones we don't want to report
12758// to the user, and converting the rest to a source location and string that
12759// should be reported.
12760void
12761ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12762 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12763 SMLoc IDLoc, OperandVector &Operands) {
12764 // TODO: If operand didn't match, sub in a dummy one and run target
12765 // predicate, so that we can avoid reporting near-misses that are invalid?
12766 // TODO: Many operand types dont have SuperClasses set, so we report
12767 // redundant ones.
12768 // TODO: Some operands are superclasses of registers (e.g.
12769 // MCK_RegShiftedImm), we don't have any way to represent that currently.
12770 // TODO: This is not all ARM-specific, can some of it be factored out?
12771
12772 // Record some information about near-misses that we have already seen, so
12773 // that we can avoid reporting redundant ones. For example, if there are
12774 // variants of an instruction that take 8- and 16-bit immediates, we want
12775 // to only report the widest one.
12776 std::multimap<unsigned, unsigned> OperandMissesSeen;
12777 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12778 bool ReportedTooFewOperands = false;
12779
12780 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
12781
12782 // Process the near-misses in reverse order, so that we see more general ones
12783 // first, and so can avoid emitting more specific ones.
12784 for (NearMissInfo &I : reverse(NearMissesIn)) {
12785 switch (I.getKind()) {
12787 SMLoc OperandLoc =
12788 ((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
12789 const char *OperandDiag =
12790 getCustomOperandDiag((ARMMatchResultTy)I.getOperandError());
12791
12792 // If we have already emitted a message for a superclass, don't also report
12793 // the sub-class. We consider all operand classes that we don't have a
12794 // specialised diagnostic for to be equal for the propose of this check,
12795 // so that we don't report the generic error multiple times on the same
12796 // operand.
12797 unsigned DupCheckMatchClass = OperandDiag ? I.getOperandClass() : ~0U;
12798 auto PrevReports = OperandMissesSeen.equal_range(I.getOperandIndex());
12799 if (std::any_of(PrevReports.first, PrevReports.second,
12800 [DupCheckMatchClass](
12801 const std::pair<unsigned, unsigned> Pair) {
12802 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12803 return Pair.second == DupCheckMatchClass;
12804 else
12805 return isSubclass((MatchClassKind)DupCheckMatchClass,
12806 (MatchClassKind)Pair.second);
12807 }))
12808 break;
12809 OperandMissesSeen.insert(
12810 std::make_pair(I.getOperandIndex(), DupCheckMatchClass));
12811
12812 NearMissMessage Message;
12813 Message.Loc = OperandLoc;
12814 if (OperandDiag) {
12815 Message.Message = OperandDiag;
12816 } else if (I.getOperandClass() == InvalidMatchClass) {
12817 Message.Message = "too many operands for instruction";
12818 } else {
12819 Message.Message = "invalid operand for instruction";
12820 LLVM_DEBUG(
12821 dbgs() << "Missing diagnostic string for operand class "
12822 << getMatchClassName((MatchClassKind)I.getOperandClass())
12823 << I.getOperandClass() << ", error " << I.getOperandError()
12824 << ", opcode " << MII.getName(I.getOpcode()) << "\n");
12825 }
12826 NearMissesOut.emplace_back(Message);
12827 break;
12828 }
12830 const FeatureBitset &MissingFeatures = I.getFeatures();
12831 // Don't report the same set of features twice.
12832 if (FeatureMissesSeen.count(MissingFeatures))
12833 break;
12834 FeatureMissesSeen.insert(MissingFeatures);
12835
12836 // Special case: don't report a feature set which includes arm-mode for
12837 // targets that don't have ARM mode.
12838 if (MissingFeatures.test(Feature_IsARMBit) && !hasARM())
12839 break;
12840 // Don't report any near-misses that both require switching instruction
12841 // set, and adding other subtarget features.
12842 if (isThumb() && MissingFeatures.test(Feature_IsARMBit) &&
12843 MissingFeatures.count() > 1)
12844 break;
12845 if (!isThumb() && MissingFeatures.test(Feature_IsThumbBit) &&
12846 MissingFeatures.count() > 1)
12847 break;
12848 if (!isThumb() && MissingFeatures.test(Feature_IsThumb2Bit) &&
12849 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12850 Feature_IsThumbBit})).any())
12851 break;
12852 if (isMClass() && MissingFeatures.test(Feature_HasNEONBit))
12853 break;
12854
12855 NearMissMessage Message;
12856 Message.Loc = IDLoc;
12857 raw_svector_ostream OS(Message.Message);
12858
12859 OS << "instruction requires:";
12860 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)
12861 if (MissingFeatures.test(i))
12862 OS << ' ' << getSubtargetFeatureName(i);
12863
12864 NearMissesOut.emplace_back(Message);
12865
12866 break;
12867 }
12869 NearMissMessage Message;
12870 Message.Loc = IDLoc;
12871 switch (I.getPredicateError()) {
12872 case Match_RequiresNotITBlock:
12873 Message.Message = "flag setting instruction only valid outside IT block";
12874 break;
12875 case Match_RequiresITBlock:
12876 Message.Message = "instruction only valid inside IT block";
12877 break;
12878 case Match_RequiresV6:
12879 Message.Message = "instruction variant requires ARMv6 or later";
12880 break;
12881 case Match_RequiresThumb2:
12882 Message.Message = "instruction variant requires Thumb2";
12883 break;
12884 case Match_RequiresV8:
12885 Message.Message = "instruction variant requires ARMv8 or later";
12886 break;
12887 case Match_RequiresFlagSetting:
12888 Message.Message = "no flag-preserving variant of this instruction available";
12889 break;
12890 case Match_InvalidTiedOperand: {
12891 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[0]);
12892 if (Op.isToken() && Op.getToken() == "mul") {
12893 Message.Message = "destination register must match a source register";
12894 Message.Loc = Operands[MnemonicOpsEndInd]->getStartLoc();
12895 } else {
12896 llvm_unreachable("Match_InvalidTiedOperand only used for tMUL.");
12897 }
12898 break;
12899 }
12900 case Match_InvalidOperand:
12901 Message.Message = "invalid operand for instruction";
12902 break;
12903 default:
12904 llvm_unreachable("Unhandled target predicate error");
12905 break;
12906 }
12907 NearMissesOut.emplace_back(Message);
12908 break;
12909 }
12911 if (!ReportedTooFewOperands) {
12912 SMLoc EndLoc = ((ARMOperand &)*Operands.back()).getEndLoc();
12913 NearMissesOut.emplace_back(NearMissMessage{
12914 EndLoc, StringRef("too few operands for instruction")});
12915 ReportedTooFewOperands = true;
12916 }
12917 break;
12918 }
12920 // This should never leave the matcher.
12921 llvm_unreachable("not a near-miss");
12922 break;
12923 }
12924 }
12925}
12926
12927void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
12928 SMLoc IDLoc, OperandVector &Operands) {
12930 FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
12931
12932 if (Messages.size() == 0) {
12933 // No near-misses were found, so the best we can do is "invalid
12934 // instruction".
12935 Error(IDLoc, "invalid instruction");
12936 } else if (Messages.size() == 1) {
12937 // One near miss was found, report it as the sole error.
12938 Error(Messages[0].Loc, Messages[0].Message);
12939 } else {
12940 // More than one near miss, so report a generic "invalid instruction"
12941 // error, followed by notes for each of the near-misses.
12942 Error(IDLoc, "invalid instruction, any one of the following would fix this:");
12943 for (auto &M : Messages) {
12944 Note(M.Loc, M.Message);
12945 }
12946 }
12947}
12948
12949bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
12950 // FIXME: This structure should be moved inside ARMTargetParser
12951 // when we start to table-generate them, and we can use the ARM
12952 // flags below, that were generated by table-gen.
12953 static const struct {
12954 const uint64_t Kind;
12955 const FeatureBitset ArchCheck;
12956 const FeatureBitset Features;
12957 } Extensions[] = {
12958 {ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}},
12959 {ARM::AEK_AES,
12960 {Feature_HasV8Bit},
12961 {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12963 {Feature_HasV8Bit},
12964 {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12966 {Feature_HasV8Bit},
12967 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12969 {Feature_HasV8_1MMainlineBit},
12970 {ARM::HasMVEFloatOps}},
12971 {ARM::AEK_FP,
12972 {Feature_HasV8Bit},
12973 {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12975 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12976 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}},
12977 {ARM::AEK_MP,
12978 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12979 {ARM::FeatureMP}},
12981 {Feature_HasV8Bit},
12982 {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12983 {ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}},
12984 // FIXME: Only available in A-class, isel not predicated
12985 {ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}},
12987 {Feature_HasV8_2aBit},
12988 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
12989 {ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
12990 {ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
12991 {ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI}},
12992 // FIXME: Unsupported extensions.
12993 {ARM::AEK_OS, {}, {}},
12994 {ARM::AEK_IWMMXT, {}, {}},
12995 {ARM::AEK_IWMMXT2, {}, {}},
12996 {ARM::AEK_MAVERICK, {}, {}},
12997 {ARM::AEK_XSCALE, {}, {}},
12998 };
12999 bool EnableFeature = !Name.consume_front_insensitive("no");
13000 uint64_t FeatureKind = ARM::parseArchExt(Name);
13001 if (FeatureKind == ARM::AEK_INVALID)
13002 return Error(ExtLoc, "unknown architectural extension: " + Name);
13003
13004 for (const auto &Extension : Extensions) {
13005 if (Extension.Kind != FeatureKind)
13006 continue;
13007
13008 if (Extension.Features.none())
13009 return Error(ExtLoc, "unsupported architectural extension: " + Name);
13010
13011 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck)
13012 return Error(ExtLoc, "architectural extension '" + Name +
13013 "' is not "
13014 "allowed for the current base architecture");
13015
13016 MCSubtargetInfo &STI = copySTI();
13017 if (EnableFeature) {
13019 } else {
13021 }
13022 FeatureBitset Features = ComputeAvailableFeatures(STI.getFeatureBits());
13023 setAvailableFeatures(Features);
13024 return true;
13025 }
13026 return false;
13027}
13028
13029/// parseDirectiveArchExtension
13030/// ::= .arch_extension [no]feature
13031bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
13032
13033 MCAsmParser &Parser = getParser();
13034
13035 if (getLexer().isNot(AsmToken::Identifier))
13036 return Error(getLexer().getLoc(), "expected architecture extension name");
13037
13038 StringRef Name = Parser.getTok().getString();
13039 SMLoc ExtLoc = Parser.getTok().getLoc();
13040 Lex();
13041
13042 if (parseEOL())
13043 return true;
13044
13045 if (Name == "nocrypto") {
13046 enableArchExtFeature("nosha2", ExtLoc);
13047 enableArchExtFeature("noaes", ExtLoc);
13048 }
13049
13050 if (enableArchExtFeature(Name, ExtLoc))
13051 return false;
13052
13053 return Error(ExtLoc, "unknown architectural extension: " + Name);
13054}
13055
13056// Define this matcher function after the auto-generated include so we
13057// have the match class enum definitions.
13058unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13059 unsigned Kind) {
13060 ARMOperand &Op = static_cast<ARMOperand &>(AsmOp);
13061 // If the kind is a token for a literal immediate, check if our asm
13062 // operand matches. This is for InstAliases which have a fixed-value
13063 // immediate in the syntax.
13064 switch (Kind) {
13065 default: break;
13066 case MCK__HASH_0:
13067 if (Op.isImm())
13068 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13069 if (CE->getValue() == 0)
13070 return Match_Success;
13071 break;
13072 case MCK__HASH_8:
13073 if (Op.isImm())
13074 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13075 if (CE->getValue() == 8)
13076 return Match_Success;
13077 break;
13078 case MCK__HASH_16:
13079 if (Op.isImm())
13080 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
13081 if (CE->getValue() == 16)
13082 return Match_Success;
13083 break;
13084 case MCK_ModImm:
13085 if (Op.isImm()) {
13086 const MCExpr *SOExpr = Op.getImm();
13087 int64_t Value;
13088 if (!SOExpr->evaluateAsAbsolute(Value))
13089 return Match_Success;
13090 assert((Value >= std::numeric_limits<int32_t>::min() &&
13091 Value <= std::numeric_limits<uint32_t>::max()) &&
13092 "expression value must be representable in 32 bits");
13093 }
13094 break;
13095 case MCK_rGPR:
13096 if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP)
13097 return Match_Success;
13098 return Match_rGPR;
13099 }
13100 return Match_InvalidOperand;
13101}
13102
13103bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic,
13104 StringRef ExtraToken) {
13105 if (!hasMVE())
13106 return false;
13107
13108 if (MS.isVPTPredicableCDEInstr(Mnemonic) ||
13109 (Mnemonic.starts_with("vldrh") && Mnemonic != "vldrhi") ||
13110 (Mnemonic.starts_with("vmov") &&
13111 !(ExtraToken == ".f16" || ExtraToken == ".32" || ExtraToken == ".16" ||
13112 ExtraToken == ".8")) ||
13113 (Mnemonic.starts_with("vrint") && Mnemonic != "vrintr") ||
13114 (Mnemonic.starts_with("vstrh") && Mnemonic != "vstrhi"))
13115 return true;
13116
13117 const char *predicable_prefixes[] = {
13118 "vabav", "vabd", "vabs", "vadc", "vadd",
13119 "vaddlv", "vaddv", "vand", "vbic", "vbrsr",
13120 "vcadd", "vcls", "vclz", "vcmla", "vcmp",
13121 "vcmul", "vctp", "vcvt", "vddup", "vdup",
13122 "vdwdup", "veor", "vfma", "vfmas", "vfms",
13123 "vhadd", "vhcadd", "vhsub", "vidup", "viwdup",
13124 "vldrb", "vldrd", "vldrw", "vmax", "vmaxa",
13125 "vmaxav", "vmaxnm", "vmaxnma", "vmaxnmav", "vmaxnmv",
13126 "vmaxv", "vmin", "vminav", "vminnm", "vminnmav",
13127 "vminnmv", "vminv", "vmla", "vmladav", "vmlaldav",
13128 "vmlalv", "vmlas", "vmlav", "vmlsdav", "vmlsldav",
13129 "vmovlb", "vmovlt", "vmovnb", "vmovnt", "vmul",
13130 "vmvn", "vneg", "vorn", "vorr", "vpnot",
13131 "vpsel", "vqabs", "vqadd", "vqdmladh", "vqdmlah",
13132 "vqdmlash", "vqdmlsdh", "vqdmulh", "vqdmull", "vqmovn",
13133 "vqmovun", "vqneg", "vqrdmladh", "vqrdmlah", "vqrdmlash",
13134 "vqrdmlsdh", "vqrdmulh", "vqrshl", "vqrshrn", "vqrshrun",
13135 "vqshl", "vqshrn", "vqshrun", "vqsub", "vrev16",
13136 "vrev32", "vrev64", "vrhadd", "vrmlaldavh", "vrmlalvh",
13137 "vrmlsldavh", "vrmulh", "vrshl", "vrshr", "vrshrn",
13138 "vsbc", "vshl", "vshlc", "vshll", "vshr",
13139 "vshrn", "vsli", "vsri", "vstrb", "vstrd",
13140 "vstrw", "vsub"};
13141
13142 return any_of(predicable_prefixes, [&Mnemonic](const char *prefix) {
13143 return Mnemonic.starts_with(prefix);
13144 });
13145}
13146
13147std::unique_ptr<ARMOperand> ARMAsmParser::defaultCondCodeOp() {
13148 return ARMOperand::CreateCondCode(ARMCC::AL, SMLoc(), *this);
13149}
13150
13151std::unique_ptr<ARMOperand> ARMAsmParser::defaultCCOutOp() {
13152 return ARMOperand::CreateCCOut(0, SMLoc(), *this);
13153}
13154
13155std::unique_ptr<ARMOperand> ARMAsmParser::defaultVPTPredOp() {
13156 return ARMOperand::CreateVPTPred(ARMVCC::None, SMLoc(), *this);
13157}
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing)
static bool instIsBreakpoint(const MCInst &Inst)
unsigned findCCOutInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
static bool isDataTypeToken(StringRef Tok)
}
static MCRegister getNextRegister(MCRegister Reg)
static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing)
unsigned getRegListInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
static bool isVectorPredicable(const MCInstrDesc &MCID)
static bool listContainsReg(const MCInst &Inst, unsigned OpNo, MCRegister Reg)
static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp)
MatchCoprocessorOperandName - Try to parse an coprocessor related instruction with a symbolic operand...
void removeCCOut(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo, MCRegister Reg, MCRegister HiReg, bool &containsReg)
static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMAsmParser()
Force static initialization.
static int findFirstVectorPredOperandIdx(const MCInstrDesc &MCID)
static bool isThumbI8Relocation(MCParsedAsmOperand &MCOp)
bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd)
void removeCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool insertNoDuplicates(SmallVectorImpl< std::pair< unsigned, MCRegister > > &Regs, unsigned Enc, MCRegister Reg)
static unsigned getMnemonicOpsEndInd(const OperandVector &Operands)
static bool isARMMCExpr(MCParsedAsmOperand &MCOp)
unsigned findCondCodeInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
void removeVPTCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool isThumb(const MCSubtargetInfo &STI)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define X(NUM, ENUM, NAME)
Definition ELF.h:853
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:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
static cl::opt< bool > AddBuildAttributes("hexagon-add-build-attributes")
#define op(i)
Value * getPointer(Value *Ptr)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
#define I(x, y, z)
Definition MD5.cpp:57
static bool containsReg(SmallSetVector< Register, 32 > LocalDefsV, const BitVector &LocalDefsP, Register Reg, const TargetRegisterInfo *TRI)
Check if target reg is contained in given lists, which are: LocalDefsV as given list for virtual regs...
Register Reg
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t High
#define P(N)
static constexpr MCPhysReg FPReg
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI Pre allocate WWM Registers
static cl::opt< ExtensionSet, false, SPIRVExtensionsParser > Extensions("spirv-ext", cl::desc("Specify list of enabled SPIR-V extensions"))
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:483
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:121
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:279
Base class for user error types.
Definition Error.h:354
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr size_t size() 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:343
int64_t getValue() const
Definition MCExpr.h:171
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
@ Constant
Constant expressions.
Definition MCExpr.h:42
SMLoc getLoc() const
Definition MCExpr.h:86
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getNumOperands() const
Definition MCInst.h:212
void setLoc(SMLoc loc)
Definition MCInst.h:207
unsigned getOpcode() const
Definition MCInst.h:202
LLVM_ABI void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCContext *Ctx=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Definition MCInst.cpp:90
iterator insert(iterator I, const MCOperand &Op)
Definition MCInst.h:232
void addOperand(const MCOperand Op)
Definition MCInst.h:215
iterator begin()
Definition MCInst.h:227
void setOpcode(unsigned Op)
Definition MCInst.h:201
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool isIndirectBranch() const
Return true if this is an indirect branch, such as a branch through a register.
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
LLVM_ABI bool hasDefOfPhysReg(const MCInst &MI, MCRegister Reg, const MCRegisterInfo &RI) const
Return true if this instruction defines the specified physical register, either explicitly or implici...
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
bool isReturn() const
Return true if the instruction is a return.
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getID() const
getID() - Return the register class ID number.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
constexpr unsigned id() const
Definition MCRegister.h:82
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Definition MCStreamer.h:333
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:214
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Target specific streamer interface.
Definition MCStreamer.h:95
MCStreamer & getStreamer()
Definition MCStreamer.h:103
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
Definition SMLoc.h:22
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:35
constexpr const char * getPointer() const
Definition SMLoc.h:33
Represents a range in source code.
Definition SMLoc.h:47
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
iterator insert(iterator I, T &&Elt)
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:133
iterator end()
Definition StringMap.h:224
iterator find(StringRef Key)
Definition StringMap.h:237
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition StringMap.h:285
void erase(iterator I)
Definition StringMap.h:427
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition StringMap.h:321
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:591
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:714
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:270
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Definition StringRef.h:170
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition StringSet.h:25
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition StringSet.h:39
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:175
#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:48
@ 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
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
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.
@ ARM
Windows AXP64.
Definition MCAsmInfo.h:49
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:50
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
Context & getContext() const
Definition BasicBlock.h:99
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:558
@ Length
Definition DWP.cpp:558
constexpr T rotr(T V, int R)
Definition bit.h:399
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
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).
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
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:1745
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
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:1969
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
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
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:221
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
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:1771
static unsigned ARMVectorCondCodeFromString(StringRef CC)
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
@ 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:876
#define N
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...