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 getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg.RegNum);
1380 }
1381 bool isQReg() const {
1382 return isReg() &&
1383 getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg.RegNum);
1384 }
1385 bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
1386 bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
1387 bool isFPSRegListWithVPR() const { return Kind == k_FPSRegisterListWithVPR; }
1388 bool isFPDRegListWithVPR() const { return Kind == k_FPDRegisterListWithVPR; }
1389 bool isToken() const override { return Kind == k_Token; }
1390 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
1391 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
1392 bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; }
1393 bool isMem() const override {
1394 return isGPRMem() || isMVEMem();
1395 }
1396 bool isMVEMem() const {
1397 if (Kind != k_Memory)
1398 return false;
1399 if (Memory.BaseRegNum &&
1400 !getARMMCRegisterClass(ARM::GPRRegClassID)
1401 .contains(Memory.BaseRegNum) &&
1402 !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Memory.BaseRegNum))
1403 return false;
1404 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::MQPRRegClassID)
1405 .contains(Memory.OffsetRegNum))
1406 return false;
1407 return true;
1408 }
1409 bool isGPRMem() const {
1410 if (Kind != k_Memory)
1411 return false;
1412 if (Memory.BaseRegNum &&
1413 !getARMMCRegisterClass(ARM::GPRRegClassID).contains(Memory.BaseRegNum))
1414 return false;
1415 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::GPRRegClassID)
1416 .contains(Memory.OffsetRegNum))
1417 return false;
1418 return true;
1419 }
1420 bool isShifterImm() const { return Kind == k_ShifterImmediate; }
1421 bool isRegShiftedReg() const {
1422 return Kind == k_ShiftedRegister &&
1423 getARMMCRegisterClass(ARM::GPRRegClassID)
1424 .contains(RegShiftedReg.SrcReg) &&
1425 getARMMCRegisterClass(ARM::GPRRegClassID)
1426 .contains(RegShiftedReg.ShiftReg);
1427 }
1428 bool isRegShiftedImm() const {
1429 return Kind == k_ShiftedImmediate &&
1430 getARMMCRegisterClass(ARM::GPRRegClassID)
1431 .contains(RegShiftedImm.SrcReg);
1432 }
1433 bool isRotImm() const { return Kind == k_RotateImmediate; }
1434
1435 template<unsigned Min, unsigned Max>
1436 bool isPowerTwoInRange() const {
1437 if (!isImm()) return false;
1438 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1439 if (!CE) return false;
1440 int64_t Value = CE->getValue();
1441 return Value > 0 && llvm::popcount((uint64_t)Value) == 1 && Value >= Min &&
1442 Value <= Max;
1443 }
1444 bool isModImm() const { return Kind == k_ModifiedImmediate; }
1445
1446 bool isModImmNot() const {
1447 if (!isImm()) return false;
1448 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1449 if (!CE) return false;
1450 int64_t Value = CE->getValue();
1451 return ARM_AM::getSOImmVal(~Value) != -1;
1452 }
1453
1454 bool isModImmNeg() const {
1455 if (!isImm()) return false;
1456 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1457 if (!CE) return false;
1458 int64_t Value = CE->getValue();
1459 return ARM_AM::getSOImmVal(Value) == -1 &&
1460 ARM_AM::getSOImmVal(-Value) != -1;
1461 }
1462
1463 bool isThumbModImmNeg1_7() const {
1464 if (!isImm()) return false;
1465 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1466 if (!CE) return false;
1467 int32_t Value = -(int32_t)CE->getValue();
1468 return 0 < Value && Value < 8;
1469 }
1470
1471 bool isThumbModImmNeg8_255() const {
1472 if (!isImm()) return false;
1473 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1474 if (!CE) return false;
1475 int32_t Value = -(int32_t)CE->getValue();
1476 return 7 < Value && Value < 256;
1477 }
1478
1479 bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
1480 bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
1481 bool isPostIdxRegShifted() const {
1482 return Kind == k_PostIndexRegister &&
1483 getARMMCRegisterClass(ARM::GPRRegClassID)
1484 .contains(PostIdxReg.RegNum);
1485 }
1486 bool isPostIdxReg() const {
1487 return isPostIdxRegShifted() && PostIdxReg.ShiftTy == ARM_AM::no_shift;
1488 }
1489 bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const {
1490 if (!isGPRMem())
1491 return false;
1492 // No offset of any kind.
1493 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1494 (alignOK || Memory.Alignment == Alignment);
1495 }
1496 bool isMemNoOffsetT2(bool alignOK = false, unsigned Alignment = 0) const {
1497 if (!isGPRMem())
1498 return false;
1499
1500 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1501 .contains(Memory.BaseRegNum))
1502 return false;
1503
1504 // No offset of any kind.
1505 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1506 (alignOK || Memory.Alignment == Alignment);
1507 }
1508 bool isMemNoOffsetT2NoSp(bool alignOK = false, unsigned Alignment = 0) const {
1509 if (!isGPRMem())
1510 return false;
1511
1512 if (!getARMMCRegisterClass(ARM::rGPRRegClassID).contains(Memory.BaseRegNum))
1513 return false;
1514
1515 // No offset of any kind.
1516 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1517 (alignOK || Memory.Alignment == Alignment);
1518 }
1519 bool isMemNoOffsetT(bool alignOK = false, unsigned Alignment = 0) const {
1520 if (!isGPRMem())
1521 return false;
1522
1523 if (!getARMMCRegisterClass(ARM::tGPRRegClassID).contains(Memory.BaseRegNum))
1524 return false;
1525
1526 // No offset of any kind.
1527 return !Memory.OffsetRegNum && Memory.OffsetImm == nullptr &&
1528 (alignOK || Memory.Alignment == Alignment);
1529 }
1530 bool isMemPCRelImm12() const {
1531 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1532 return false;
1533 // Base register must be PC.
1534 if (Memory.BaseRegNum != ARM::PC)
1535 return false;
1536 // Immediate offset in range [-4095, 4095].
1537 if (!Memory.OffsetImm) return true;
1538 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1539 int64_t Val = CE->getValue();
1540 return (Val > -4096 && Val < 4096) ||
1541 (Val == std::numeric_limits<int32_t>::min());
1542 }
1543 return false;
1544 }
1545
1546 bool isAlignedMemory() const {
1547 return isMemNoOffset(true);
1548 }
1549
1550 bool isAlignedMemoryNone() const {
1551 return isMemNoOffset(false, 0);
1552 }
1553
1554 bool isDupAlignedMemoryNone() const {
1555 return isMemNoOffset(false, 0);
1556 }
1557
1558 bool isAlignedMemory16() const {
1559 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1560 return true;
1561 return isMemNoOffset(false, 0);
1562 }
1563
1564 bool isDupAlignedMemory16() const {
1565 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
1566 return true;
1567 return isMemNoOffset(false, 0);
1568 }
1569
1570 bool isAlignedMemory32() const {
1571 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1572 return true;
1573 return isMemNoOffset(false, 0);
1574 }
1575
1576 bool isDupAlignedMemory32() const {
1577 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
1578 return true;
1579 return isMemNoOffset(false, 0);
1580 }
1581
1582 bool isAlignedMemory64() const {
1583 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1584 return true;
1585 return isMemNoOffset(false, 0);
1586 }
1587
1588 bool isDupAlignedMemory64() const {
1589 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1590 return true;
1591 return isMemNoOffset(false, 0);
1592 }
1593
1594 bool isAlignedMemory64or128() const {
1595 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1596 return true;
1597 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1598 return true;
1599 return isMemNoOffset(false, 0);
1600 }
1601
1602 bool isDupAlignedMemory64or128() const {
1603 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1604 return true;
1605 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1606 return true;
1607 return isMemNoOffset(false, 0);
1608 }
1609
1610 bool isAlignedMemory64or128or256() const {
1611 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
1612 return true;
1613 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
1614 return true;
1615 if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32.
1616 return true;
1617 return isMemNoOffset(false, 0);
1618 }
1619
1620 bool isAddrMode2() const {
1621 if (!isGPRMem() || Memory.Alignment != 0) return false;
1622 // Check for register offset.
1623 if (Memory.OffsetRegNum) return true;
1624 // Immediate offset in range [-4095, 4095].
1625 if (!Memory.OffsetImm) return true;
1626 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1627 int64_t Val = CE->getValue();
1628 return Val > -4096 && Val < 4096;
1629 }
1630 return false;
1631 }
1632
1633 bool isAM2OffsetImm() const {
1634 if (!isImm()) return false;
1635 // Immediate offset in range [-4095, 4095].
1636 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1637 if (!CE) return false;
1638 int64_t Val = CE->getValue();
1639 return (Val == std::numeric_limits<int32_t>::min()) ||
1640 (Val > -4096 && Val < 4096);
1641 }
1642
1643 bool isAddrMode3() const {
1644 // If we have an immediate that's not a constant, treat it as a label
1645 // reference needing a fixup. If it is a constant, it's something else
1646 // and we reject it.
1647 if (isImm() && !isa<MCConstantExpr>(getImm()))
1648 return true;
1649 if (!isGPRMem() || Memory.Alignment != 0) return false;
1650 // No shifts are legal for AM3.
1651 if (Memory.ShiftType != ARM_AM::no_shift) return false;
1652 // Check for register offset.
1653 if (Memory.OffsetRegNum) return true;
1654 // Immediate offset in range [-255, 255].
1655 if (!Memory.OffsetImm) return true;
1656 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1657 int64_t Val = CE->getValue();
1658 // The #-0 offset is encoded as std::numeric_limits<int32_t>::min(), and
1659 // we have to check for this too.
1660 return (Val > -256 && Val < 256) ||
1661 Val == std::numeric_limits<int32_t>::min();
1662 }
1663 return false;
1664 }
1665
1666 bool isAM3Offset() const {
1667 if (isPostIdxReg())
1668 return true;
1669 if (!isImm())
1670 return false;
1671 // Immediate offset in range [-255, 255].
1672 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1673 if (!CE) return false;
1674 int64_t Val = CE->getValue();
1675 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1676 return (Val > -256 && Val < 256) ||
1677 Val == std::numeric_limits<int32_t>::min();
1678 }
1679
1680 bool isAddrMode5() const {
1681 // If we have an immediate that's not a constant, treat it as a label
1682 // reference needing a fixup. If it is a constant, it's something else
1683 // and we reject it.
1684 if (isImm() && !isa<MCConstantExpr>(getImm()))
1685 return true;
1686 if (!isGPRMem() || Memory.Alignment != 0) return false;
1687 // Check for register offset.
1688 if (Memory.OffsetRegNum) return false;
1689 // Immediate offset in range [-1020, 1020] and a multiple of 4.
1690 if (!Memory.OffsetImm) return true;
1691 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1692 int64_t Val = CE->getValue();
1693 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1694 Val == std::numeric_limits<int32_t>::min();
1695 }
1696 return false;
1697 }
1698
1699 bool isAddrMode5FP16() const {
1700 // If we have an immediate that's not a constant, treat it as a label
1701 // reference needing a fixup. If it is a constant, it's something else
1702 // and we reject it.
1703 if (isImm() && !isa<MCConstantExpr>(getImm()))
1704 return true;
1705 if (!isGPRMem() || Memory.Alignment != 0) return false;
1706 // Check for register offset.
1707 if (Memory.OffsetRegNum) return false;
1708 // Immediate offset in range [-510, 510] and a multiple of 2.
1709 if (!Memory.OffsetImm) return true;
1710 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1711 int64_t Val = CE->getValue();
1712 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1713 Val == std::numeric_limits<int32_t>::min();
1714 }
1715 return false;
1716 }
1717
1718 bool isMemTBB() const {
1719 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1720 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1721 return false;
1722 return true;
1723 }
1724
1725 bool isMemTBH() const {
1726 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1727 Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
1728 Memory.Alignment != 0 )
1729 return false;
1730 return true;
1731 }
1732
1733 bool isMemRegOffset() const {
1734 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1735 return false;
1736 return true;
1737 }
1738
1739 bool isT2MemRegOffset() const {
1740 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1741 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1742 return false;
1743 // Only lsl #{0, 1, 2, 3} allowed.
1744 if (Memory.ShiftType == ARM_AM::no_shift)
1745 return true;
1746 if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
1747 return false;
1748 return true;
1749 }
1750
1751 bool isMemThumbRR() const {
1752 // Thumb reg+reg addressing is simple. Just two registers, a base and
1753 // an offset. No shifts, negations or any other complicating factors.
1754 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1755 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
1756 return false;
1757 return isARMLowRegister(Memory.BaseRegNum) &&
1758 (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
1759 }
1760
1761 bool isMemThumbRIs4() const {
1762 if (!isGPRMem() || Memory.OffsetRegNum ||
1763 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1764 return false;
1765 // Immediate offset, multiple of 4 in range [0, 124].
1766 if (!Memory.OffsetImm) return true;
1767 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1768 int64_t Val = CE->getValue();
1769 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1770 }
1771 return false;
1772 }
1773
1774 bool isMemThumbRIs2() const {
1775 if (!isGPRMem() || Memory.OffsetRegNum ||
1776 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1777 return false;
1778 // Immediate offset, multiple of 4 in range [0, 62].
1779 if (!Memory.OffsetImm) return true;
1780 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1781 int64_t Val = CE->getValue();
1782 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1783 }
1784 return false;
1785 }
1786
1787 bool isMemThumbRIs1() const {
1788 if (!isGPRMem() || Memory.OffsetRegNum ||
1789 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
1790 return false;
1791 // Immediate offset in range [0, 31].
1792 if (!Memory.OffsetImm) return true;
1793 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1794 int64_t Val = CE->getValue();
1795 return Val >= 0 && Val <= 31;
1796 }
1797 return false;
1798 }
1799
1800 bool isMemThumbSPI() const {
1801 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1802 Memory.Alignment != 0)
1803 return false;
1804 // Immediate offset, multiple of 4 in range [0, 1020].
1805 if (!Memory.OffsetImm) return true;
1806 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1807 int64_t Val = CE->getValue();
1808 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1809 }
1810 return false;
1811 }
1812
1813 bool isMemImm8s4Offset() const {
1814 // If we have an immediate that's not a constant, treat it as a label
1815 // reference needing a fixup. If it is a constant, it's something else
1816 // and we reject it.
1817 if (isImm() && !isa<MCConstantExpr>(getImm()))
1818 return true;
1819 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1820 return false;
1821 // Immediate offset a multiple of 4 in range [-1020, 1020].
1822 if (!Memory.OffsetImm) return true;
1823 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1824 int64_t Val = CE->getValue();
1825 // Special case, #-0 is std::numeric_limits<int32_t>::min().
1826 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1827 Val == std::numeric_limits<int32_t>::min();
1828 }
1829 return false;
1830 }
1831
1832 bool isMemImm7s4Offset() const {
1833 // If we have an immediate that's not a constant, treat it as a label
1834 // reference needing a fixup. If it is a constant, it's something else
1835 // and we reject it.
1836 if (isImm() && !isa<MCConstantExpr>(getImm()))
1837 return true;
1838 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1839 !getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1840 .contains(Memory.BaseRegNum))
1841 return false;
1842 // Immediate offset a multiple of 4 in range [-508, 508].
1843 if (!Memory.OffsetImm) return true;
1844 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1845 int64_t Val = CE->getValue();
1846 // Special case, #-0 is INT32_MIN.
1847 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1848 }
1849 return false;
1850 }
1851
1852 bool isMemImm0_1020s4Offset() const {
1853 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1854 return false;
1855 // Immediate offset a multiple of 4 in range [0, 1020].
1856 if (!Memory.OffsetImm) return true;
1857 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1858 int64_t Val = CE->getValue();
1859 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1860 }
1861 return false;
1862 }
1863
1864 bool isMemImm8Offset() const {
1865 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1866 return false;
1867 // Base reg of PC isn't allowed for these encodings.
1868 if (Memory.BaseRegNum == ARM::PC) return false;
1869 // Immediate offset in range [-255, 255].
1870 if (!Memory.OffsetImm) return true;
1871 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1872 int64_t Val = CE->getValue();
1873 return (Val == std::numeric_limits<int32_t>::min()) ||
1874 (Val > -256 && Val < 256);
1875 }
1876 return false;
1877 }
1878
1879 template<unsigned Bits, unsigned RegClassID>
1880 bool isMemImm7ShiftedOffset() const {
1881 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1882 !getARMMCRegisterClass(RegClassID).contains(Memory.BaseRegNum))
1883 return false;
1884
1885 // Expect an immediate offset equal to an element of the range
1886 // [-127, 127], shifted left by Bits.
1887
1888 if (!Memory.OffsetImm) return true;
1889 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1890 int64_t Val = CE->getValue();
1891
1892 // INT32_MIN is a special-case value (indicating the encoding with
1893 // zero offset and the subtract bit set)
1894 if (Val == INT32_MIN)
1895 return true;
1896
1897 unsigned Divisor = 1U << Bits;
1898
1899 // Check that the low bits are zero
1900 if (Val % Divisor != 0)
1901 return false;
1902
1903 // Check that the remaining offset is within range.
1904 Val /= Divisor;
1905 return (Val >= -127 && Val <= 127);
1906 }
1907 return false;
1908 }
1909
1910 template <int shift> bool isMemRegRQOffset() const {
1911 if (!isMVEMem() || Memory.OffsetImm != nullptr || Memory.Alignment != 0)
1912 return false;
1913
1914 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1915 .contains(Memory.BaseRegNum))
1916 return false;
1917 if (!getARMMCRegisterClass(ARM::MQPRRegClassID)
1918 .contains(Memory.OffsetRegNum))
1919 return false;
1920
1921 if (shift == 0 && Memory.ShiftType != ARM_AM::no_shift)
1922 return false;
1923
1924 if (shift > 0 &&
1925 (Memory.ShiftType != ARM_AM::uxtw || Memory.ShiftImm != shift))
1926 return false;
1927
1928 return true;
1929 }
1930
1931 template <int shift> bool isMemRegQOffset() const {
1932 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1933 return false;
1934
1935 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Memory.BaseRegNum))
1936 return false;
1937
1938 if (!Memory.OffsetImm)
1939 return true;
1940 static_assert(shift < 56,
1941 "Such that we dont shift by a value higher than 62");
1942 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1943 int64_t Val = CE->getValue();
1944
1945 // The value must be a multiple of (1 << shift)
1946 if ((Val & ((1U << shift) - 1)) != 0)
1947 return false;
1948
1949 // And be in the right range, depending on the amount that it is shifted
1950 // by. Shift 0, is equal to 7 unsigned bits, the sign bit is set
1951 // separately.
1952 int64_t Range = (1U << (7 + shift)) - 1;
1953 return (Val == INT32_MIN) || (Val > -Range && Val < Range);
1954 }
1955 return false;
1956 }
1957
1958 bool isMemPosImm8Offset() const {
1959 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1960 return false;
1961 // Immediate offset in range [0, 255].
1962 if (!Memory.OffsetImm) return true;
1963 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1964 int64_t Val = CE->getValue();
1965 return Val >= 0 && Val < 256;
1966 }
1967 return false;
1968 }
1969
1970 bool isMemNegImm8Offset() const {
1971 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1972 return false;
1973 // Base reg of PC isn't allowed for these encodings.
1974 if (Memory.BaseRegNum == ARM::PC) return false;
1975 // Immediate offset in range [-255, -1].
1976 if (!Memory.OffsetImm) return false;
1977 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1978 int64_t Val = CE->getValue();
1979 return (Val == std::numeric_limits<int32_t>::min()) ||
1980 (Val > -256 && Val < 0);
1981 }
1982 return false;
1983 }
1984
1985 bool isMemUImm12Offset() const {
1986 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1987 return false;
1988 // Immediate offset in range [0, 4095].
1989 if (!Memory.OffsetImm) return true;
1990 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
1991 int64_t Val = CE->getValue();
1992 return (Val >= 0 && Val < 4096);
1993 }
1994 return false;
1995 }
1996
1997 bool isMemImm12Offset() const {
1998 // If we have an immediate that's not a constant, treat it as a label
1999 // reference needing a fixup. If it is a constant, it's something else
2000 // and we reject it.
2001
2002 if (isImm() && !isa<MCConstantExpr>(getImm()))
2003 return true;
2004
2005 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2006 return false;
2007 // Immediate offset in range [-4095, 4095].
2008 if (!Memory.OffsetImm) return true;
2009 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
2010 int64_t Val = CE->getValue();
2011 return (Val > -4096 && Val < 4096) ||
2012 (Val == std::numeric_limits<int32_t>::min());
2013 }
2014 // If we have an immediate that's not a constant, treat it as a
2015 // symbolic expression needing a fixup.
2016 return true;
2017 }
2018
2019 bool isConstPoolAsmImm() const {
2020 // Delay processing of Constant Pool Immediate, this will turn into
2021 // a constant. Match no other operand
2022 return (isConstantPoolImm());
2023 }
2024
2025 bool isPostIdxImm8() const {
2026 if (!isImm()) return false;
2027 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2028 if (!CE) return false;
2029 int64_t Val = CE->getValue();
2030 return (Val > -256 && Val < 256) ||
2031 (Val == std::numeric_limits<int32_t>::min());
2032 }
2033
2034 bool isPostIdxImm8s4() const {
2035 if (!isImm()) return false;
2036 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2037 if (!CE) return false;
2038 int64_t Val = CE->getValue();
2039 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2040 (Val == std::numeric_limits<int32_t>::min());
2041 }
2042
2043 bool isMSRMask() const { return Kind == k_MSRMask; }
2044 bool isBankedReg() const { return Kind == k_BankedReg; }
2045 bool isProcIFlags() const { return Kind == k_ProcIFlags; }
2046
2047 // NEON operands.
2048 bool isAnyVectorList() const {
2049 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2050 Kind == k_VectorListIndexed;
2051 }
2052
2053 bool isVectorList() const { return Kind == k_VectorList; }
2054
2055 bool isSingleSpacedVectorList() const {
2056 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2057 }
2058
2059 bool isDoubleSpacedVectorList() const {
2060 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2061 }
2062
2063 bool isVecListOneD() const {
2064 // We convert a single D reg to a list containing a D reg
2065 if (isDReg() && !Parser->hasMVE())
2066 return true;
2067 if (!isSingleSpacedVectorList()) return false;
2068 return VectorList.Count == 1;
2069 }
2070
2071 bool isVecListTwoMQ() const {
2072 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2073 getARMMCRegisterClass(ARM::MQPRRegClassID)
2074 .contains(VectorList.RegNum);
2075 }
2076
2077 bool isVecListDPair() const {
2078 // We convert a single Q reg to a list with the two corresponding D
2079 // registers
2080 if (isQReg() && !Parser->hasMVE())
2081 return true;
2082 if (!isSingleSpacedVectorList()) return false;
2083 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2084 .contains(VectorList.RegNum));
2085 }
2086
2087 bool isVecListThreeD() const {
2088 if (!isSingleSpacedVectorList()) return false;
2089 return VectorList.Count == 3;
2090 }
2091
2092 bool isVecListFourD() const {
2093 if (!isSingleSpacedVectorList()) return false;
2094 return VectorList.Count == 4;
2095 }
2096
2097 bool isVecListDPairSpaced() const {
2098 if (Kind != k_VectorList) return false;
2099 if (isSingleSpacedVectorList()) return false;
2100 return (getARMMCRegisterClass(ARM::DPairSpcRegClassID)
2101 .contains(VectorList.RegNum));
2102 }
2103
2104 bool isVecListThreeQ() const {
2105 if (!isDoubleSpacedVectorList()) return false;
2106 return VectorList.Count == 3;
2107 }
2108
2109 bool isVecListFourQ() const {
2110 if (!isDoubleSpacedVectorList()) return false;
2111 return VectorList.Count == 4;
2112 }
2113
2114 bool isVecListFourMQ() const {
2115 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2116 getARMMCRegisterClass(ARM::MQPRRegClassID)
2117 .contains(VectorList.RegNum);
2118 }
2119
2120 bool isSingleSpacedVectorAllLanes() const {
2121 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2122 }
2123
2124 bool isDoubleSpacedVectorAllLanes() const {
2125 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2126 }
2127
2128 bool isVecListOneDAllLanes() const {
2129 if (!isSingleSpacedVectorAllLanes()) return false;
2130 return VectorList.Count == 1;
2131 }
2132
2133 bool isVecListDPairAllLanes() const {
2134 if (!isSingleSpacedVectorAllLanes()) return false;
2135 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2136 .contains(VectorList.RegNum));
2137 }
2138
2139 bool isVecListDPairSpacedAllLanes() const {
2140 if (!isDoubleSpacedVectorAllLanes()) return false;
2141 return VectorList.Count == 2;
2142 }
2143
2144 bool isVecListThreeDAllLanes() const {
2145 if (!isSingleSpacedVectorAllLanes()) return false;
2146 return VectorList.Count == 3;
2147 }
2148
2149 bool isVecListThreeQAllLanes() const {
2150 if (!isDoubleSpacedVectorAllLanes()) return false;
2151 return VectorList.Count == 3;
2152 }
2153
2154 bool isVecListFourDAllLanes() const {
2155 if (!isSingleSpacedVectorAllLanes()) return false;
2156 return VectorList.Count == 4;
2157 }
2158
2159 bool isVecListFourQAllLanes() const {
2160 if (!isDoubleSpacedVectorAllLanes()) return false;
2161 return VectorList.Count == 4;
2162 }
2163
2164 bool isSingleSpacedVectorIndexed() const {
2165 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2166 }
2167
2168 bool isDoubleSpacedVectorIndexed() const {
2169 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2170 }
2171
2172 bool isVecListOneDByteIndexed() const {
2173 if (!isSingleSpacedVectorIndexed()) return false;
2174 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2175 }
2176
2177 bool isVecListOneDHWordIndexed() const {
2178 if (!isSingleSpacedVectorIndexed()) return false;
2179 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2180 }
2181
2182 bool isVecListOneDWordIndexed() const {
2183 if (!isSingleSpacedVectorIndexed()) return false;
2184 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2185 }
2186
2187 bool isVecListTwoDByteIndexed() const {
2188 if (!isSingleSpacedVectorIndexed()) return false;
2189 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2190 }
2191
2192 bool isVecListTwoDHWordIndexed() const {
2193 if (!isSingleSpacedVectorIndexed()) return false;
2194 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2195 }
2196
2197 bool isVecListTwoQWordIndexed() const {
2198 if (!isDoubleSpacedVectorIndexed()) return false;
2199 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2200 }
2201
2202 bool isVecListTwoQHWordIndexed() const {
2203 if (!isDoubleSpacedVectorIndexed()) return false;
2204 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2205 }
2206
2207 bool isVecListTwoDWordIndexed() const {
2208 if (!isSingleSpacedVectorIndexed()) return false;
2209 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2210 }
2211
2212 bool isVecListThreeDByteIndexed() const {
2213 if (!isSingleSpacedVectorIndexed()) return false;
2214 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2215 }
2216
2217 bool isVecListThreeDHWordIndexed() const {
2218 if (!isSingleSpacedVectorIndexed()) return false;
2219 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2220 }
2221
2222 bool isVecListThreeQWordIndexed() const {
2223 if (!isDoubleSpacedVectorIndexed()) return false;
2224 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2225 }
2226
2227 bool isVecListThreeQHWordIndexed() const {
2228 if (!isDoubleSpacedVectorIndexed()) return false;
2229 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2230 }
2231
2232 bool isVecListThreeDWordIndexed() const {
2233 if (!isSingleSpacedVectorIndexed()) return false;
2234 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2235 }
2236
2237 bool isVecListFourDByteIndexed() const {
2238 if (!isSingleSpacedVectorIndexed()) return false;
2239 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2240 }
2241
2242 bool isVecListFourDHWordIndexed() const {
2243 if (!isSingleSpacedVectorIndexed()) return false;
2244 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2245 }
2246
2247 bool isVecListFourQWordIndexed() const {
2248 if (!isDoubleSpacedVectorIndexed()) return false;
2249 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2250 }
2251
2252 bool isVecListFourQHWordIndexed() const {
2253 if (!isDoubleSpacedVectorIndexed()) return false;
2254 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2255 }
2256
2257 bool isVecListFourDWordIndexed() const {
2258 if (!isSingleSpacedVectorIndexed()) return false;
2259 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2260 }
2261
2262 bool isVectorIndex() const { return Kind == k_VectorIndex; }
2263
2264 template <unsigned NumLanes>
2265 bool isVectorIndexInRange() const {
2266 if (Kind != k_VectorIndex) return false;
2267 return VectorIndex.Val < NumLanes;
2268 }
2269
2270 bool isVectorIndex8() const { return isVectorIndexInRange<8>(); }
2271 bool isVectorIndex16() const { return isVectorIndexInRange<4>(); }
2272 bool isVectorIndex32() const { return isVectorIndexInRange<2>(); }
2273 bool isVectorIndex64() const { return isVectorIndexInRange<1>(); }
2274
2275 template<int PermittedValue, int OtherPermittedValue>
2276 bool isMVEPairVectorIndex() const {
2277 if (Kind != k_VectorIndex) return false;
2278 return VectorIndex.Val == PermittedValue ||
2279 VectorIndex.Val == OtherPermittedValue;
2280 }
2281
2282 bool isNEONi8splat() const {
2283 if (!isImm()) return false;
2284 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2285 // Must be a constant.
2286 if (!CE) return false;
2287 int64_t Value = CE->getValue();
2288 // i8 value splatted across 8 bytes. The immediate is just the 8 byte
2289 // value.
2290 return Value >= 0 && Value < 256;
2291 }
2292
2293 bool isNEONi16splat() const {
2294 if (isNEONByteReplicate(2))
2295 return false; // Leave that for bytes replication and forbid by default.
2296 if (!isImm())
2297 return false;
2298 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2299 // Must be a constant.
2300 if (!CE) return false;
2301 unsigned Value = CE->getValue();
2303 }
2304
2305 bool isNEONi16splatNot() const {
2306 if (!isImm())
2307 return false;
2308 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2309 // Must be a constant.
2310 if (!CE) return false;
2311 unsigned Value = CE->getValue();
2312 return ARM_AM::isNEONi16splat(~Value & 0xffff);
2313 }
2314
2315 bool isNEONi32splat() const {
2316 if (isNEONByteReplicate(4))
2317 return false; // Leave that for bytes replication and forbid by default.
2318 if (!isImm())
2319 return false;
2320 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2321 // Must be a constant.
2322 if (!CE) return false;
2323 unsigned Value = CE->getValue();
2325 }
2326
2327 bool isNEONi32splatNot() const {
2328 if (!isImm())
2329 return false;
2330 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2331 // Must be a constant.
2332 if (!CE) return false;
2333 unsigned Value = CE->getValue();
2335 }
2336
2337 static bool isValidNEONi32vmovImm(int64_t Value) {
2338 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
2339 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
2340 return ((Value & 0xffffffffffffff00) == 0) ||
2341 ((Value & 0xffffffffffff00ff) == 0) ||
2342 ((Value & 0xffffffffff00ffff) == 0) ||
2343 ((Value & 0xffffffff00ffffff) == 0) ||
2344 ((Value & 0xffffffffffff00ff) == 0xff) ||
2345 ((Value & 0xffffffffff00ffff) == 0xffff);
2346 }
2347
2348 bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const {
2349 assert((Width == 8 || Width == 16 || Width == 32) &&
2350 "Invalid element width");
2351 assert(NumElems * Width <= 64 && "Invalid result width");
2352
2353 if (!isImm())
2354 return false;
2355 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2356 // Must be a constant.
2357 if (!CE)
2358 return false;
2359 int64_t Value = CE->getValue();
2360 if (!Value)
2361 return false; // Don't bother with zero.
2362 if (Inv)
2363 Value = ~Value;
2364
2365 uint64_t Mask = (1ull << Width) - 1;
2366 uint64_t Elem = Value & Mask;
2367 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2368 return false;
2369 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2370 return false;
2371
2372 for (unsigned i = 1; i < NumElems; ++i) {
2373 Value >>= Width;
2374 if ((Value & Mask) != Elem)
2375 return false;
2376 }
2377 return true;
2378 }
2379
2380 bool isNEONByteReplicate(unsigned NumBytes) const {
2381 return isNEONReplicate(8, NumBytes, false);
2382 }
2383
2384 static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
2385 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2386 "Invalid source width");
2387 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2388 "Invalid destination width");
2389 assert(FromW < ToW && "ToW is not less than FromW");
2390 }
2391
2392 template<unsigned FromW, unsigned ToW>
2393 bool isNEONmovReplicate() const {
2394 checkNeonReplicateArgs(FromW, ToW);
2395 if (ToW == 64 && isNEONi64splat())
2396 return false;
2397 return isNEONReplicate(FromW, ToW / FromW, false);
2398 }
2399
2400 template<unsigned FromW, unsigned ToW>
2401 bool isNEONinvReplicate() const {
2402 checkNeonReplicateArgs(FromW, ToW);
2403 return isNEONReplicate(FromW, ToW / FromW, true);
2404 }
2405
2406 bool isNEONi32vmov() const {
2407 if (isNEONByteReplicate(4))
2408 return false; // Let it to be classified as byte-replicate case.
2409 if (!isImm())
2410 return false;
2411 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2412 // Must be a constant.
2413 if (!CE)
2414 return false;
2415 return isValidNEONi32vmovImm(CE->getValue());
2416 }
2417
2418 bool isNEONi32vmovNeg() const {
2419 if (!isImm()) return false;
2420 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2421 // Must be a constant.
2422 if (!CE) return false;
2423 return isValidNEONi32vmovImm(~CE->getValue());
2424 }
2425
2426 bool isNEONi64splat() const {
2427 if (!isImm()) return false;
2428 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2429 // Must be a constant.
2430 if (!CE) return false;
2431 uint64_t Value = CE->getValue();
2432 // i64 value with each byte being either 0 or 0xff.
2433 for (unsigned i = 0; i < 8; ++i, Value >>= 8)
2434 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
2435 return true;
2436 }
2437
2438 template<int64_t Angle, int64_t Remainder>
2439 bool isComplexRotation() const {
2440 if (!isImm()) return false;
2441
2442 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2443 if (!CE) return false;
2444 uint64_t Value = CE->getValue();
2445
2446 return (Value % Angle == Remainder && Value <= 270);
2447 }
2448
2449 bool isMVELongShift() const {
2450 if (!isImm()) return false;
2451 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2452 // Must be a constant.
2453 if (!CE) return false;
2454 uint64_t Value = CE->getValue();
2455 return Value >= 1 && Value <= 32;
2456 }
2457
2458 bool isMveSaturateOp() const {
2459 if (!isImm()) return false;
2460 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2461 if (!CE) return false;
2462 uint64_t Value = CE->getValue();
2463 return Value == 48 || Value == 64;
2464 }
2465
2466 bool isITCondCodeNoAL() const {
2467 if (!isITCondCode()) return false;
2469 return CC != ARMCC::AL;
2470 }
2471
2472 bool isITCondCodeRestrictedI() const {
2473 if (!isITCondCode())
2474 return false;
2476 return CC == ARMCC::EQ || CC == ARMCC::NE;
2477 }
2478
2479 bool isITCondCodeRestrictedS() const {
2480 if (!isITCondCode())
2481 return false;
2483 return CC == ARMCC::LT || CC == ARMCC::GT || CC == ARMCC::LE ||
2484 CC == ARMCC::GE;
2485 }
2486
2487 bool isITCondCodeRestrictedU() const {
2488 if (!isITCondCode())
2489 return false;
2491 return CC == ARMCC::HS || CC == ARMCC::HI;
2492 }
2493
2494 bool isITCondCodeRestrictedFP() const {
2495 if (!isITCondCode())
2496 return false;
2498 return CC == ARMCC::EQ || CC == ARMCC::NE || CC == ARMCC::LT ||
2499 CC == ARMCC::GT || CC == ARMCC::LE || CC == ARMCC::GE;
2500 }
2501
2502 void setVecListDPair(unsigned int DPair) {
2503 Kind = k_VectorList;
2504 VectorList.RegNum = DPair;
2505 VectorList.Count = 2;
2506 VectorList.isDoubleSpaced = false;
2507 }
2508
2509 void setVecListOneD(unsigned int DReg) {
2510 Kind = k_VectorList;
2511 VectorList.RegNum = DReg;
2512 VectorList.Count = 1;
2513 VectorList.isDoubleSpaced = false;
2514 }
2515
2516 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2517 // Add as immediates when possible. Null MCExpr = 0.
2518 if (!Expr)
2520 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2521 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2522 else
2524 }
2525
2526 void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const {
2527 assert(N == 1 && "Invalid number of operands!");
2528 addExpr(Inst, getImm());
2529 }
2530
2531 void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const {
2532 assert(N == 1 && "Invalid number of operands!");
2533 addExpr(Inst, getImm());
2534 }
2535
2536 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
2537 assert(N == 2 && "Invalid number of operands!");
2538 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2539 unsigned RegNum = getCondCode() == ARMCC::AL ? ARM::NoRegister : ARM::CPSR;
2540 Inst.addOperand(MCOperand::createReg(RegNum));
2541 }
2542
2543 void addVPTPredNOperands(MCInst &Inst, unsigned N) const {
2544 assert(N == 3 && "Invalid number of operands!");
2545 Inst.addOperand(MCOperand::createImm(unsigned(getVPTPred())));
2546 unsigned RegNum = getVPTPred() == ARMVCC::None ? ARM::NoRegister : ARM::P0;
2547 Inst.addOperand(MCOperand::createReg(RegNum));
2549 }
2550
2551 void addVPTPredROperands(MCInst &Inst, unsigned N) const {
2552 assert(N == 4 && "Invalid number of operands!");
2553 addVPTPredNOperands(Inst, N-1);
2554 MCRegister RegNum;
2555 if (getVPTPred() == ARMVCC::None) {
2556 RegNum = ARM::NoRegister;
2557 } else {
2558 unsigned NextOpIndex = Inst.getNumOperands();
2559 auto &MCID = Parser->getInstrDesc(Inst.getOpcode());
2560 int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO);
2561 assert(TiedOp >= 0 &&
2562 "Inactive register in vpred_r is not tied to an output!");
2563 RegNum = Inst.getOperand(TiedOp).getReg();
2564 }
2565 Inst.addOperand(MCOperand::createReg(RegNum));
2566 }
2567
2568 void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
2569 assert(N == 1 && "Invalid number of operands!");
2570 Inst.addOperand(MCOperand::createImm(getCoproc()));
2571 }
2572
2573 void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
2574 assert(N == 1 && "Invalid number of operands!");
2575 Inst.addOperand(MCOperand::createImm(getCoproc()));
2576 }
2577
2578 void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
2579 assert(N == 1 && "Invalid number of operands!");
2580 Inst.addOperand(MCOperand::createImm(CoprocOption.Val));
2581 }
2582
2583 void addITMaskOperands(MCInst &Inst, unsigned N) const {
2584 assert(N == 1 && "Invalid number of operands!");
2585 Inst.addOperand(MCOperand::createImm(ITMask.Mask));
2586 }
2587
2588 void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
2589 assert(N == 1 && "Invalid number of operands!");
2590 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
2591 }
2592
2593 void addITCondCodeInvOperands(MCInst &Inst, unsigned N) const {
2594 assert(N == 1 && "Invalid number of operands!");
2596 }
2597
2598 void addCCOutOperands(MCInst &Inst, unsigned N) const {
2599 assert(N == 1 && "Invalid number of operands!");
2601 }
2602
2603 void addRegOperands(MCInst &Inst, unsigned N) const {
2604 assert(N == 1 && "Invalid number of operands!");
2606 }
2607
2608 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
2609 assert(N == 3 && "Invalid number of operands!");
2610 assert(isRegShiftedReg() &&
2611 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2612 Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg));
2613 Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg));
2615 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
2616 }
2617
2618 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
2619 assert(N == 2 && "Invalid number of operands!");
2620 assert(isRegShiftedImm() &&
2621 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2622 Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg));
2623 // Shift of #32 is encoded as 0 where permitted
2624 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2626 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
2627 }
2628
2629 void addShifterImmOperands(MCInst &Inst, unsigned N) const {
2630 assert(N == 1 && "Invalid number of operands!");
2631 Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) |
2632 ShifterImm.Imm));
2633 }
2634
2635 void addRegListOperands(MCInst &Inst, unsigned N) const {
2636 assert(N == 1 && "Invalid number of operands!");
2637 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2638 for (MCRegister Reg : RegList)
2640 }
2641
2642 void addRegListWithAPSROperands(MCInst &Inst, unsigned N) const {
2643 assert(N == 1 && "Invalid number of operands!");
2644 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2645 for (MCRegister Reg : RegList)
2647 }
2648
2649 void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
2650 addRegListOperands(Inst, N);
2651 }
2652
2653 void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
2654 addRegListOperands(Inst, N);
2655 }
2656
2657 void addFPSRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2658 addRegListOperands(Inst, N);
2659 }
2660
2661 void addFPDRegListWithVPROperands(MCInst &Inst, unsigned N) const {
2662 addRegListOperands(Inst, N);
2663 }
2664
2665 void addRotImmOperands(MCInst &Inst, unsigned N) const {
2666 assert(N == 1 && "Invalid number of operands!");
2667 // Encoded as val>>3. The printer handles display as 8, 16, 24.
2668 Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3));
2669 }
2670
2671 void addModImmOperands(MCInst &Inst, unsigned N) const {
2672 assert(N == 1 && "Invalid number of operands!");
2673
2674 // Support for fixups (MCFixup)
2675 if (isImm())
2676 return addImmOperands(Inst, N);
2677
2678 Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7)));
2679 }
2680
2681 void addModImmNotOperands(MCInst &Inst, unsigned N) const {
2682 assert(N == 1 && "Invalid number of operands!");
2683 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2684 uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue());
2686 }
2687
2688 void addModImmNegOperands(MCInst &Inst, unsigned N) const {
2689 assert(N == 1 && "Invalid number of operands!");
2690 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2691 uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue());
2693 }
2694
2695 void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const {
2696 assert(N == 1 && "Invalid number of operands!");
2697 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2698 uint32_t Val = -CE->getValue();
2700 }
2701
2702 void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const {
2703 assert(N == 1 && "Invalid number of operands!");
2704 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2705 uint32_t Val = -CE->getValue();
2707 }
2708
2709 void addBitfieldOperands(MCInst &Inst, unsigned N) const {
2710 assert(N == 1 && "Invalid number of operands!");
2711 // Munge the lsb/width into a bitfield mask.
2712 unsigned lsb = Bitfield.LSB;
2713 unsigned width = Bitfield.Width;
2714 // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
2715 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2716 (32 - (lsb + width)));
2717 Inst.addOperand(MCOperand::createImm(Mask));
2718 }
2719
2720 void addImmOperands(MCInst &Inst, unsigned N) const {
2721 assert(N == 1 && "Invalid number of operands!");
2722 addExpr(Inst, getImm());
2723 }
2724
2725 void addFBits16Operands(MCInst &Inst, unsigned N) const {
2726 assert(N == 1 && "Invalid number of operands!");
2727 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2728 Inst.addOperand(MCOperand::createImm(16 - CE->getValue()));
2729 }
2730
2731 void addFBits32Operands(MCInst &Inst, unsigned N) const {
2732 assert(N == 1 && "Invalid number of operands!");
2733 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2734 Inst.addOperand(MCOperand::createImm(32 - CE->getValue()));
2735 }
2736
2737 void addFPImmOperands(MCInst &Inst, unsigned N) const {
2738 assert(N == 1 && "Invalid number of operands!");
2739 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2740 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
2742 }
2743
2744 void addImm8s4Operands(MCInst &Inst, unsigned N) const {
2745 assert(N == 1 && "Invalid number of operands!");
2746 // FIXME: We really want to scale the value here, but the LDRD/STRD
2747 // instruction don't encode operands that way yet.
2748 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2749 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2750 }
2751
2752 void addImm7s4Operands(MCInst &Inst, unsigned N) const {
2753 assert(N == 1 && "Invalid number of operands!");
2754 // FIXME: We really want to scale the value here, but the VSTR/VLDR_VSYSR
2755 // instruction don't encode operands that way yet.
2756 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2757 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2758 }
2759
2760 void addImm7Shift0Operands(MCInst &Inst, unsigned N) const {
2761 assert(N == 1 && "Invalid number of operands!");
2762 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2763 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2764 }
2765
2766 void addImm7Shift1Operands(MCInst &Inst, unsigned N) const {
2767 assert(N == 1 && "Invalid number of operands!");
2768 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2769 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2770 }
2771
2772 void addImm7Shift2Operands(MCInst &Inst, unsigned N) const {
2773 assert(N == 1 && "Invalid number of operands!");
2774 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2775 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2776 }
2777
2778 void addImm7Operands(MCInst &Inst, unsigned N) const {
2779 assert(N == 1 && "Invalid number of operands!");
2780 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2781 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2782 }
2783
2784 void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
2785 assert(N == 1 && "Invalid number of operands!");
2786 // The immediate is scaled by four in the encoding and is stored
2787 // in the MCInst as such. Lop off the low two bits here.
2788 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2789 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2790 }
2791
2792 void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
2793 assert(N == 1 && "Invalid number of operands!");
2794 // The immediate is scaled by four in the encoding and is stored
2795 // in the MCInst as such. Lop off the low two bits here.
2796 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2797 Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4)));
2798 }
2799
2800 void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
2801 assert(N == 1 && "Invalid number of operands!");
2802 // The immediate is scaled by four in the encoding and is stored
2803 // in the MCInst as such. Lop off the low two bits here.
2804 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2805 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
2806 }
2807
2808 void addImm1_16Operands(MCInst &Inst, unsigned N) const {
2809 assert(N == 1 && "Invalid number of operands!");
2810 // The constant encodes as the immediate-1, and we store in the instruction
2811 // the bits as encoded, so subtract off one here.
2812 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2813 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2814 }
2815
2816 void addImm1_32Operands(MCInst &Inst, unsigned N) const {
2817 assert(N == 1 && "Invalid number of operands!");
2818 // The constant encodes as the immediate-1, and we store in the instruction
2819 // the bits as encoded, so subtract off one here.
2820 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2821 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
2822 }
2823
2824 void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
2825 assert(N == 1 && "Invalid number of operands!");
2826 // The constant encodes as the immediate, except for 32, which encodes as
2827 // zero.
2828 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2829 unsigned Imm = CE->getValue();
2830 Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm)));
2831 }
2832
2833 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
2834 assert(N == 1 && "Invalid number of operands!");
2835 // An ASR value of 32 encodes as 0, so that's how we want to add it to
2836 // the instruction as well.
2837 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2838 int Val = CE->getValue();
2839 Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val));
2840 }
2841
2842 void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
2843 assert(N == 1 && "Invalid number of operands!");
2844 // The operand is actually a t2_so_imm, but we have its bitwise
2845 // negation in the assembly source, so twiddle it here.
2846 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2847 Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue()));
2848 }
2849
2850 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
2851 assert(N == 1 && "Invalid number of operands!");
2852 // The operand is actually a t2_so_imm, but we have its
2853 // negation in the assembly source, so twiddle it here.
2854 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2855 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2856 }
2857
2858 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
2859 assert(N == 1 && "Invalid number of operands!");
2860 // The operand is actually an imm0_4095, but we have its
2861 // negation in the assembly source, so twiddle it here.
2862 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2863 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
2864 }
2865
2866 void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
2867 if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2868 Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2));
2869 return;
2870 }
2871 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2873 }
2874
2875 void addThumbMemPCOperands(MCInst &Inst, unsigned N) const {
2876 assert(N == 1 && "Invalid number of operands!");
2877 if (isImm()) {
2878 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2879 if (CE) {
2880 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2881 return;
2882 }
2883 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val);
2885 return;
2886 }
2887
2888 assert(isGPRMem() && "Unknown value type!");
2889 assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!");
2890 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
2891 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2892 else
2893 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
2894 }
2895
2896 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
2897 assert(N == 1 && "Invalid number of operands!");
2898 Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt())));
2899 }
2900
2901 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2902 assert(N == 1 && "Invalid number of operands!");
2903 Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
2904 }
2905
2906 void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
2907 assert(N == 1 && "Invalid number of operands!");
2908 Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt())));
2909 }
2910
2911 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
2912 assert(N == 1 && "Invalid number of operands!");
2913 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2914 }
2915
2916 void addMemNoOffsetT2Operands(MCInst &Inst, unsigned N) const {
2917 assert(N == 1 && "Invalid number of operands!");
2918 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2919 }
2920
2921 void addMemNoOffsetT2NoSpOperands(MCInst &Inst, unsigned N) const {
2922 assert(N == 1 && "Invalid number of operands!");
2923 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2924 }
2925
2926 void addMemNoOffsetTOperands(MCInst &Inst, unsigned N) const {
2927 assert(N == 1 && "Invalid number of operands!");
2928 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2929 }
2930
2931 void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
2932 assert(N == 1 && "Invalid number of operands!");
2933 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
2934 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2935 else
2936 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
2937 }
2938
2939 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
2940 assert(N == 1 && "Invalid number of operands!");
2941 assert(isImm() && "Not an immediate!");
2942
2943 // If we have an immediate that's not a constant, treat it as a label
2944 // reference needing a fixup.
2945 if (!isa<MCConstantExpr>(getImm())) {
2947 return;
2948 }
2949
2950 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
2951 int Val = CE->getValue();
2953 }
2954
2955 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
2956 assert(N == 2 && "Invalid number of operands!");
2957 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
2958 Inst.addOperand(MCOperand::createImm(Memory.Alignment));
2959 }
2960
2961 void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2962 addAlignedMemoryOperands(Inst, N);
2963 }
2964
2965 void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
2966 addAlignedMemoryOperands(Inst, N);
2967 }
2968
2969 void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2970 addAlignedMemoryOperands(Inst, N);
2971 }
2972
2973 void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
2974 addAlignedMemoryOperands(Inst, N);
2975 }
2976
2977 void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2978 addAlignedMemoryOperands(Inst, N);
2979 }
2980
2981 void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
2982 addAlignedMemoryOperands(Inst, N);
2983 }
2984
2985 void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2986 addAlignedMemoryOperands(Inst, N);
2987 }
2988
2989 void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
2990 addAlignedMemoryOperands(Inst, N);
2991 }
2992
2993 void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2994 addAlignedMemoryOperands(Inst, N);
2995 }
2996
2997 void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
2998 addAlignedMemoryOperands(Inst, N);
2999 }
3000
3001 void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const {
3002 addAlignedMemoryOperands(Inst, N);
3003 }
3004
3005 void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
3006 assert(N == 3 && "Invalid number of operands!");
3007 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3008 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3009 if (!Memory.OffsetRegNum) {
3010 if (!Memory.OffsetImm)
3012 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3013 int32_t Val = CE->getValue();
3015 // Special case for #-0
3016 if (Val == std::numeric_limits<int32_t>::min())
3017 Val = 0;
3018 if (Val < 0)
3019 Val = -Val;
3020 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
3022 } else
3023 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3024 } else {
3025 // For register offset, we encode the shift type and negation flag
3026 // here.
3027 int32_t Val =
3028 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3029 Memory.ShiftImm, Memory.ShiftType);
3031 }
3032 }
3033
3034 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
3035 assert(N == 2 && "Invalid number of operands!");
3036 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3037 assert(CE && "non-constant AM2OffsetImm operand!");
3038 int32_t Val = CE->getValue();
3040 // Special case for #-0
3041 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3042 if (Val < 0) Val = -Val;
3043 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
3046 }
3047
3048 void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
3049 assert(N == 3 && "Invalid number of operands!");
3050 // If we have an immediate that's not a constant, treat it as a label
3051 // reference needing a fixup. If it is a constant, it's something else
3052 // and we reject it.
3053 if (isImm()) {
3057 return;
3058 }
3059
3060 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3061 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3062 if (!Memory.OffsetRegNum) {
3063 if (!Memory.OffsetImm)
3065 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3066 int32_t Val = CE->getValue();
3068 // Special case for #-0
3069 if (Val == std::numeric_limits<int32_t>::min())
3070 Val = 0;
3071 if (Val < 0)
3072 Val = -Val;
3073 Val = ARM_AM::getAM3Opc(AddSub, Val);
3075 } else
3076 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3077 } else {
3078 // For register offset, we encode the shift type and negation flag
3079 // here.
3080 int32_t Val =
3081 ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
3083 }
3084 }
3085
3086 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
3087 assert(N == 2 && "Invalid number of operands!");
3088 if (Kind == k_PostIndexRegister) {
3089 int32_t Val =
3090 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
3091 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3093 return;
3094 }
3095
3096 // Constant offset.
3097 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
3098 int32_t Val = CE->getValue();
3100 // Special case for #-0
3101 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3102 if (Val < 0) Val = -Val;
3103 Val = ARM_AM::getAM3Opc(AddSub, Val);
3106 }
3107
3108 void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
3109 assert(N == 2 && "Invalid number of operands!");
3110 // If we have an immediate that's not a constant, treat it as a label
3111 // reference needing a fixup. If it is a constant, it's something else
3112 // and we reject it.
3113 if (isImm()) {
3116 return;
3117 }
3118
3119 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3120 if (!Memory.OffsetImm)
3122 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3123 // The lower two bits are always zero and as such are not encoded.
3124 int32_t Val = CE->getValue() / 4;
3126 // Special case for #-0
3127 if (Val == std::numeric_limits<int32_t>::min())
3128 Val = 0;
3129 if (Val < 0)
3130 Val = -Val;
3131 Val = ARM_AM::getAM5Opc(AddSub, Val);
3133 } else
3134 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3135 }
3136
3137 void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const {
3138 assert(N == 2 && "Invalid number of operands!");
3139 // If we have an immediate that's not a constant, treat it as a label
3140 // reference needing a fixup. If it is a constant, it's something else
3141 // and we reject it.
3142 if (isImm()) {
3145 return;
3146 }
3147
3148 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3149 // The lower bit is always zero and as such is not encoded.
3150 if (!Memory.OffsetImm)
3152 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) {
3153 int32_t Val = CE->getValue() / 2;
3155 // Special case for #-0
3156 if (Val == std::numeric_limits<int32_t>::min())
3157 Val = 0;
3158 if (Val < 0)
3159 Val = -Val;
3160 Val = ARM_AM::getAM5FP16Opc(AddSub, Val);
3162 } else
3163 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3164 }
3165
3166 void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
3167 assert(N == 2 && "Invalid number of operands!");
3168 // If we have an immediate that's not a constant, treat it as a label
3169 // reference needing a fixup. If it is a constant, it's something else
3170 // and we reject it.
3171 if (isImm()) {
3174 return;
3175 }
3176
3177 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3178 addExpr(Inst, Memory.OffsetImm);
3179 }
3180
3181 void addMemImm7s4OffsetOperands(MCInst &Inst, unsigned N) const {
3182 assert(N == 2 && "Invalid number of operands!");
3183 // If we have an immediate that's not a constant, treat it as a label
3184 // reference needing a fixup. If it is a constant, it's something else
3185 // and we reject it.
3186 if (isImm()) {
3189 return;
3190 }
3191
3192 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3193 addExpr(Inst, Memory.OffsetImm);
3194 }
3195
3196 void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
3197 assert(N == 2 && "Invalid number of operands!");
3198 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3199 if (!Memory.OffsetImm)
3201 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3202 // The lower two bits are always zero and as such are not encoded.
3203 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3204 else
3205 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3206 }
3207
3208 void addMemImmOffsetOperands(MCInst &Inst, unsigned N) const {
3209 assert(N == 2 && "Invalid number of operands!");
3210 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3211 addExpr(Inst, Memory.OffsetImm);
3212 }
3213
3214 void addMemRegRQOffsetOperands(MCInst &Inst, unsigned N) const {
3215 assert(N == 2 && "Invalid number of operands!");
3216 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3217 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3218 }
3219
3220 void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3221 assert(N == 2 && "Invalid number of operands!");
3222 // If this is an immediate, it's a label reference.
3223 if (isImm()) {
3224 addExpr(Inst, getImm());
3226 return;
3227 }
3228
3229 // Otherwise, it's a normal memory reg+offset.
3230 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3231 addExpr(Inst, Memory.OffsetImm);
3232 }
3233
3234 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
3235 assert(N == 2 && "Invalid number of operands!");
3236 // If this is an immediate, it's a label reference.
3237 if (isImm()) {
3238 addExpr(Inst, getImm());
3240 return;
3241 }
3242
3243 // Otherwise, it's a normal memory reg+offset.
3244 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3245 addExpr(Inst, Memory.OffsetImm);
3246 }
3247
3248 void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const {
3249 assert(N == 1 && "Invalid number of operands!");
3250 // This is container for the immediate that we will create the constant
3251 // pool from
3252 addExpr(Inst, getConstantPoolImm());
3253 }
3254
3255 void addMemTBBOperands(MCInst &Inst, unsigned N) const {
3256 assert(N == 2 && "Invalid number of operands!");
3257 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3258 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3259 }
3260
3261 void addMemTBHOperands(MCInst &Inst, unsigned N) const {
3262 assert(N == 2 && "Invalid number of operands!");
3263 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3264 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3265 }
3266
3267 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3268 assert(N == 3 && "Invalid number of operands!");
3269 unsigned Val =
3270 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
3271 Memory.ShiftImm, Memory.ShiftType);
3272 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3273 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3275 }
3276
3277 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
3278 assert(N == 3 && "Invalid number of operands!");
3279 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3280 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3281 Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
3282 }
3283
3284 void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
3285 assert(N == 2 && "Invalid number of operands!");
3286 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3287 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
3288 }
3289
3290 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
3291 assert(N == 2 && "Invalid number of operands!");
3292 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3293 if (!Memory.OffsetImm)
3295 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3296 // The lower two bits are always zero and as such are not encoded.
3297 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3298 else
3299 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3300 }
3301
3302 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
3303 assert(N == 2 && "Invalid number of operands!");
3304 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3305 if (!Memory.OffsetImm)
3307 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3308 Inst.addOperand(MCOperand::createImm(CE->getValue() / 2));
3309 else
3310 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3311 }
3312
3313 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
3314 assert(N == 2 && "Invalid number of operands!");
3315 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3316 addExpr(Inst, Memory.OffsetImm);
3317 }
3318
3319 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
3320 assert(N == 2 && "Invalid number of operands!");
3321 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
3322 if (!Memory.OffsetImm)
3324 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm))
3325 // The lower two bits are always zero and as such are not encoded.
3326 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
3327 else
3328 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm));
3329 }
3330
3331 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
3332 assert(N == 1 && "Invalid number of operands!");
3333 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3334 assert(CE && "non-constant post-idx-imm8 operand!");
3335 int Imm = CE->getValue();
3336 bool isAdd = Imm >= 0;
3337 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3338 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
3340 }
3341
3342 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
3343 assert(N == 1 && "Invalid number of operands!");
3344 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3345 assert(CE && "non-constant post-idx-imm8s4 operand!");
3346 int Imm = CE->getValue();
3347 bool isAdd = Imm >= 0;
3348 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
3349 // Immediate is scaled by 4.
3350 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
3352 }
3353
3354 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
3355 assert(N == 2 && "Invalid number of operands!");
3356 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3357 Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
3358 }
3359
3360 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
3361 assert(N == 2 && "Invalid number of operands!");
3362 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
3363 // The sign, shift type, and shift amount are encoded in a single operand
3364 // using the AM2 encoding helpers.
3365 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
3366 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
3367 PostIdxReg.ShiftTy);
3369 }
3370
3371 void addPowerTwoOperands(MCInst &Inst, unsigned N) const {
3372 assert(N == 1 && "Invalid number of operands!");
3373 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3374 Inst.addOperand(MCOperand::createImm(CE->getValue()));
3375 }
3376
3377 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
3378 assert(N == 1 && "Invalid number of operands!");
3379 Inst.addOperand(MCOperand::createImm(getMSRMask()));
3380 }
3381
3382 void addBankedRegOperands(MCInst &Inst, unsigned N) const {
3383 assert(N == 1 && "Invalid number of operands!");
3384 Inst.addOperand(MCOperand::createImm(getBankedReg()));
3385 }
3386
3387 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
3388 assert(N == 1 && "Invalid number of operands!");
3389 Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
3390 }
3391
3392 void addVecListOperands(MCInst &Inst, unsigned N) const {
3393 assert(N == 1 && "Invalid number of operands!");
3394
3395 if (isAnyVectorList())
3396 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3397 else if (isDReg() && !Parser->hasMVE()) {
3398 Inst.addOperand(MCOperand::createReg(Reg.RegNum));
3399 } else if (isQReg() && !Parser->hasMVE()) {
3400 MCRegister DPair = Parser->getDRegFromQReg(Reg.RegNum);
3401 DPair = Parser->getMRI()->getMatchingSuperReg(
3402 DPair, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
3403 Inst.addOperand(MCOperand::createReg(DPair));
3404 } else {
3405 LLVM_DEBUG(dbgs() << "TYPE: " << Kind << "\n");
3407 "attempted to add a vector list register with wrong type!");
3408 }
3409 }
3410
3411 void addMVEVecListOperands(MCInst &Inst, unsigned N) const {
3412 assert(N == 1 && "Invalid number of operands!");
3413
3414 // When we come here, the VectorList field will identify a range
3415 // of q-registers by its base register and length, and it will
3416 // have already been error-checked to be the expected length of
3417 // range and contain only q-regs in the range q0-q7. So we can
3418 // count on the base register being in the range q0-q6 (for 2
3419 // regs) or q0-q4 (for 4)
3420 //
3421 // The MVE instructions taking a register range of this kind will
3422 // need an operand in the MQQPR or MQQQQPR class, representing the
3423 // entire range as a unit. So we must translate into that class,
3424 // by finding the index of the base register in the MQPR reg
3425 // class, and returning the super-register at the corresponding
3426 // index in the target class.
3427
3428 const MCRegisterClass *RC_in = &getARMMCRegisterClass(ARM::MQPRRegClassID);
3429 const MCRegisterClass *RC_out =
3430 (VectorList.Count == 2)
3431 ? &getARMMCRegisterClass(ARM::MQQPRRegClassID)
3432 : &getARMMCRegisterClass(ARM::MQQQQPRRegClassID);
3433
3434 unsigned I, E = RC_out->getNumRegs();
3435 for (I = 0; I < E; I++)
3436 if (RC_in->getRegister(I) == VectorList.RegNum)
3437 break;
3438 assert(I < E && "Invalid vector list start register!");
3439
3441 }
3442
3443 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
3444 assert(N == 2 && "Invalid number of operands!");
3445 Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
3446 Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
3447 }
3448
3449 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
3450 assert(N == 1 && "Invalid number of operands!");
3451 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3452 }
3453
3454 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
3455 assert(N == 1 && "Invalid number of operands!");
3456 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3457 }
3458
3459 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
3460 assert(N == 1 && "Invalid number of operands!");
3461 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3462 }
3463
3464 void addVectorIndex64Operands(MCInst &Inst, unsigned N) const {
3465 assert(N == 1 && "Invalid number of operands!");
3466 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3467 }
3468
3469 void addMVEVectorIndexOperands(MCInst &Inst, unsigned N) const {
3470 assert(N == 1 && "Invalid number of operands!");
3471 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3472 }
3473
3474 void addMVEPairVectorIndexOperands(MCInst &Inst, unsigned N) const {
3475 assert(N == 1 && "Invalid number of operands!");
3476 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
3477 }
3478
3479 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
3480 assert(N == 1 && "Invalid number of operands!");
3481 // The immediate encodes the type of constant as well as the value.
3482 // Mask in that this is an i8 splat.
3483 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3484 Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
3485 }
3486
3487 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
3488 assert(N == 1 && "Invalid number of operands!");
3489 // The immediate encodes the type of constant as well as the value.
3490 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3491 unsigned Value = CE->getValue();
3494 }
3495
3496 void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
3497 assert(N == 1 && "Invalid number of operands!");
3498 // The immediate encodes the type of constant as well as the value.
3499 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3500 unsigned Value = CE->getValue();
3503 }
3504
3505 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
3506 assert(N == 1 && "Invalid number of operands!");
3507 // The immediate encodes the type of constant as well as the value.
3508 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3509 unsigned Value = CE->getValue();
3512 }
3513
3514 void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
3515 assert(N == 1 && "Invalid number of operands!");
3516 // The immediate encodes the type of constant as well as the value.
3517 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3518 unsigned Value = CE->getValue();
3521 }
3522
3523 void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
3524 // The immediate encodes the type of constant as well as the value.
3525 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3526 assert((Inst.getOpcode() == ARM::VMOVv8i8 ||
3527 Inst.getOpcode() == ARM::VMOVv16i8) &&
3528 "All instructions that wants to replicate non-zero byte "
3529 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3530 unsigned Value = CE->getValue();
3531 if (Inv)
3532 Value = ~Value;
3533 unsigned B = Value & 0xff;
3534 B |= 0xe00; // cmode = 0b1110
3536 }
3537
3538 void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3539 assert(N == 1 && "Invalid number of operands!");
3540 addNEONi8ReplicateOperands(Inst, true);
3541 }
3542
3543 static unsigned encodeNeonVMOVImmediate(unsigned Value) {
3544 if (Value >= 256 && Value <= 0xffff)
3545 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
3546 else if (Value > 0xffff && Value <= 0xffffff)
3547 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
3548 else if (Value > 0xffffff)
3549 Value = (Value >> 24) | 0x600;
3550 return Value;
3551 }
3552
3553 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
3554 assert(N == 1 && "Invalid number of operands!");
3555 // The immediate encodes the type of constant as well as the value.
3556 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3557 unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
3559 }
3560
3561 void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
3562 assert(N == 1 && "Invalid number of operands!");
3563 addNEONi8ReplicateOperands(Inst, false);
3564 }
3565
3566 void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
3567 assert(N == 1 && "Invalid number of operands!");
3568 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3569 assert((Inst.getOpcode() == ARM::VMOVv4i16 ||
3570 Inst.getOpcode() == ARM::VMOVv8i16 ||
3571 Inst.getOpcode() == ARM::VMVNv4i16 ||
3572 Inst.getOpcode() == ARM::VMVNv8i16) &&
3573 "All instructions that want to replicate non-zero half-word "
3574 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3575 uint64_t Value = CE->getValue();
3576 unsigned Elem = Value & 0xffff;
3577 if (Elem >= 256)
3578 Elem = (Elem >> 8) | 0x200;
3579 Inst.addOperand(MCOperand::createImm(Elem));
3580 }
3581
3582 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
3583 assert(N == 1 && "Invalid number of operands!");
3584 // The immediate encodes the type of constant as well as the value.
3585 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3586 unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
3588 }
3589
3590 void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
3591 assert(N == 1 && "Invalid number of operands!");
3592 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3593 assert((Inst.getOpcode() == ARM::VMOVv2i32 ||
3594 Inst.getOpcode() == ARM::VMOVv4i32 ||
3595 Inst.getOpcode() == ARM::VMVNv2i32 ||
3596 Inst.getOpcode() == ARM::VMVNv4i32) &&
3597 "All instructions that want to replicate non-zero word "
3598 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3599 uint64_t Value = CE->getValue();
3600 unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
3601 Inst.addOperand(MCOperand::createImm(Elem));
3602 }
3603
3604 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
3605 assert(N == 1 && "Invalid number of operands!");
3606 // The immediate encodes the type of constant as well as the value.
3607 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3608 uint64_t Value = CE->getValue();
3609 unsigned Imm = 0;
3610 for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
3611 Imm |= (Value & 1) << i;
3612 }
3613 Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
3614 }
3615
3616 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
3617 assert(N == 1 && "Invalid number of operands!");
3618 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3619 Inst.addOperand(MCOperand::createImm(CE->getValue() / 90));
3620 }
3621
3622 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
3623 assert(N == 1 && "Invalid number of operands!");
3624 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3625 Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
3626 }
3627
3628 void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
3629 assert(N == 1 && "Invalid number of operands!");
3630 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
3631 unsigned Imm = CE->getValue();
3632 assert((Imm == 48 || Imm == 64) && "Invalid saturate operand");
3633 Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0));
3634 }
3635
3636 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;
3637
3638 static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S,
3639 ARMAsmParser &Parser) {
3640 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3641 Op->ITMask.Mask = Mask;
3642 Op->StartLoc = S;
3643 Op->EndLoc = S;
3644 return Op;
3645 }
3646
3647 static std::unique_ptr<ARMOperand>
3648 CreateCondCode(ARMCC::CondCodes CC, SMLoc S, ARMAsmParser &Parser) {
3649 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3650 Op->CC.Val = CC;
3651 Op->StartLoc = S;
3652 Op->EndLoc = S;
3653 return Op;
3654 }
3655
3656 static std::unique_ptr<ARMOperand> CreateVPTPred(ARMVCC::VPTCodes CC, SMLoc S,
3657 ARMAsmParser &Parser) {
3658 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3659 Op->VCC.Val = CC;
3660 Op->StartLoc = S;
3661 Op->EndLoc = S;
3662 return Op;
3663 }
3664
3665 static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S,
3666 ARMAsmParser &Parser) {
3667 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3668 Op->Cop.Val = CopVal;
3669 Op->StartLoc = S;
3670 Op->EndLoc = S;
3671 return Op;
3672 }
3673
3674 static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S,
3675 ARMAsmParser &Parser) {
3676 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3677 Op->Cop.Val = CopVal;
3678 Op->StartLoc = S;
3679 Op->EndLoc = S;
3680 return Op;
3681 }
3682
3683 static std::unique_ptr<ARMOperand>
3684 CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3685 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3686 Op->Cop.Val = Val;
3687 Op->StartLoc = S;
3688 Op->EndLoc = E;
3689 return Op;
3690 }
3691
3692 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister Reg, SMLoc S,
3693 ARMAsmParser &Parser) {
3694 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3695 Op->Reg.RegNum = Reg;
3696 Op->StartLoc = S;
3697 Op->EndLoc = S;
3698 return Op;
3699 }
3700
3701 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3702 ARMAsmParser &Parser) {
3703 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3704 Op->Tok.Data = Str.data();
3705 Op->Tok.Length = Str.size();
3706 Op->StartLoc = S;
3707 Op->EndLoc = S;
3708 return Op;
3709 }
3710
3711 static std::unique_ptr<ARMOperand> CreateReg(MCRegister Reg, SMLoc S, SMLoc E,
3712 ARMAsmParser &Parser) {
3713 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3714 Op->Reg.RegNum = Reg;
3715 Op->StartLoc = S;
3716 Op->EndLoc = E;
3717 return Op;
3718 }
3719
3720 static std::unique_ptr<ARMOperand>
3721 CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, MCRegister SrcReg,
3722 MCRegister ShiftReg, unsigned ShiftImm, SMLoc S,
3723 SMLoc E, ARMAsmParser &Parser) {
3724 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3725 Op->RegShiftedReg.ShiftTy = ShTy;
3726 Op->RegShiftedReg.SrcReg = SrcReg;
3727 Op->RegShiftedReg.ShiftReg = ShiftReg;
3728 Op->RegShiftedReg.ShiftImm = ShiftImm;
3729 Op->StartLoc = S;
3730 Op->EndLoc = E;
3731 return Op;
3732 }
3733
3734 static std::unique_ptr<ARMOperand>
3735 CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, MCRegister SrcReg,
3736 unsigned ShiftImm, SMLoc S, SMLoc E,
3737 ARMAsmParser &Parser) {
3738 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3739 Op->RegShiftedImm.ShiftTy = ShTy;
3740 Op->RegShiftedImm.SrcReg = SrcReg;
3741 Op->RegShiftedImm.ShiftImm = ShiftImm;
3742 Op->StartLoc = S;
3743 Op->EndLoc = E;
3744 return Op;
3745 }
3746
3747 static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm,
3748 SMLoc S, SMLoc E,
3749 ARMAsmParser &Parser) {
3750 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3751 Op->ShifterImm.isASR = isASR;
3752 Op->ShifterImm.Imm = Imm;
3753 Op->StartLoc = S;
3754 Op->EndLoc = E;
3755 return Op;
3756 }
3757
3758 static std::unique_ptr<ARMOperand>
3759 CreateRotImm(unsigned Imm, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3760 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3761 Op->RotImm.Imm = Imm;
3762 Op->StartLoc = S;
3763 Op->EndLoc = E;
3764 return Op;
3765 }
3766
3767 static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
3768 SMLoc S, SMLoc E,
3769 ARMAsmParser &Parser) {
3770 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3771 Op->ModImm.Bits = Bits;
3772 Op->ModImm.Rot = Rot;
3773 Op->StartLoc = S;
3774 Op->EndLoc = E;
3775 return Op;
3776 }
3777
3778 static std::unique_ptr<ARMOperand>
3779 CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E,
3780 ARMAsmParser &Parser) {
3781 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3782 Op->Imm.Val = Val;
3783 Op->StartLoc = S;
3784 Op->EndLoc = E;
3785 return Op;
3786 }
3787
3788 static std::unique_ptr<ARMOperand> CreateBitfield(unsigned LSB,
3789 unsigned Width, SMLoc S,
3790 SMLoc E,
3791 ARMAsmParser &Parser) {
3792 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3793 Op->Bitfield.LSB = LSB;
3794 Op->Bitfield.Width = Width;
3795 Op->StartLoc = S;
3796 Op->EndLoc = E;
3797 return Op;
3798 }
3799
3800 static std::unique_ptr<ARMOperand>
3801 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3802 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3803 assert(Regs.size() > 0 && "RegList contains no registers?");
3804 KindTy Kind = k_RegisterList;
3805
3806 if (getARMMCRegisterClass(ARM::DPRRegClassID)
3807 .contains(Regs.front().second)) {
3808 if (Regs.back().second == ARM::VPR)
3809 Kind = k_FPDRegisterListWithVPR;
3810 else
3811 Kind = k_DPRRegisterList;
3812 } else if (getARMMCRegisterClass(ARM::SPRRegClassID)
3813 .contains(Regs.front().second)) {
3814 if (Regs.back().second == ARM::VPR)
3815 Kind = k_FPSRegisterListWithVPR;
3816 else
3817 Kind = k_SPRRegisterList;
3818 } else if (Regs.front().second == ARM::VPR) {
3819 assert(Regs.size() == 1 &&
3820 "Register list starting with VPR expected to only contain VPR");
3821 Kind = k_FPSRegisterListWithVPR;
3822 }
3823
3824 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3825 Kind = k_RegisterListWithAPSR;
3826
3827 assert(llvm::is_sorted(Regs) && "Register list must be sorted by encoding");
3828
3829 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3830 for (const auto &P : Regs)
3831 Op->Registers.push_back(P.second);
3832
3833 Op->StartLoc = StartLoc;
3834 Op->EndLoc = EndLoc;
3835 return Op;
3836 }
3837
3838 static std::unique_ptr<ARMOperand>
3839 CreateVectorList(MCRegister Reg, unsigned Count, bool isDoubleSpaced, SMLoc S,
3840 SMLoc E, ARMAsmParser &Parser) {
3841 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3842 Op->VectorList.RegNum = Reg;
3843 Op->VectorList.Count = Count;
3844 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3845 Op->StartLoc = S;
3846 Op->EndLoc = E;
3847 return Op;
3848 }
3849
3850 static std::unique_ptr<ARMOperand>
3851 CreateVectorListAllLanes(MCRegister Reg, unsigned Count, bool isDoubleSpaced,
3852 SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3853 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3854 Op->VectorList.RegNum = Reg;
3855 Op->VectorList.Count = Count;
3856 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3857 Op->StartLoc = S;
3858 Op->EndLoc = E;
3859 return Op;
3860 }
3861
3862 static std::unique_ptr<ARMOperand>
3863 CreateVectorListIndexed(MCRegister Reg, unsigned Count, unsigned Index,
3864 bool isDoubleSpaced, SMLoc S, SMLoc E,
3865 ARMAsmParser &Parser) {
3866 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3867 Op->VectorList.RegNum = Reg;
3868 Op->VectorList.Count = Count;
3869 Op->VectorList.LaneIndex = Index;
3870 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3871 Op->StartLoc = S;
3872 Op->EndLoc = E;
3873 return Op;
3874 }
3875
3876 static std::unique_ptr<ARMOperand> CreateVectorIndex(unsigned Idx, SMLoc S,
3877 SMLoc E, MCContext &Ctx,
3878 ARMAsmParser &Parser) {
3879 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3880 Op->VectorIndex.Val = Idx;
3881 Op->StartLoc = S;
3882 Op->EndLoc = E;
3883 return Op;
3884 }
3885
3886 static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S,
3887 SMLoc E, ARMAsmParser &Parser) {
3888 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3889 Op->Imm.Val = Val;
3890 Op->StartLoc = S;
3891 Op->EndLoc = E;
3892 return Op;
3893 }
3894
3895 static std::unique_ptr<ARMOperand>
3896 CreateMem(MCRegister BaseReg, const MCExpr *OffsetImm, MCRegister OffsetReg,
3897 ARM_AM::ShiftOpc ShiftType, unsigned ShiftImm, unsigned Alignment,
3898 bool isNegative, SMLoc S, SMLoc E, ARMAsmParser &Parser,
3899 SMLoc AlignmentLoc = SMLoc()) {
3900 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3901 Op->Memory.BaseRegNum = BaseReg;
3902 Op->Memory.OffsetImm = OffsetImm;
3903 Op->Memory.OffsetRegNum = OffsetReg;
3904 Op->Memory.ShiftType = ShiftType;
3905 Op->Memory.ShiftImm = ShiftImm;
3906 Op->Memory.Alignment = Alignment;
3907 Op->Memory.isNegative = isNegative;
3908 Op->StartLoc = S;
3909 Op->EndLoc = E;
3910 Op->AlignmentLoc = AlignmentLoc;
3911 return Op;
3912 }
3913
3914 static std::unique_ptr<ARMOperand>
3915 CreatePostIdxReg(MCRegister Reg, bool isAdd, ARM_AM::ShiftOpc ShiftTy,
3916 unsigned ShiftImm, SMLoc S, SMLoc E, ARMAsmParser &Parser) {
3917 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3918 Op->PostIdxReg.RegNum = Reg;
3919 Op->PostIdxReg.isAdd = isAdd;
3920 Op->PostIdxReg.ShiftTy = ShiftTy;
3921 Op->PostIdxReg.ShiftImm = ShiftImm;
3922 Op->StartLoc = S;
3923 Op->EndLoc = E;
3924 return Op;
3925 }
3926
3927 static std::unique_ptr<ARMOperand>
3928 CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3929 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3930 Op->MBOpt.Val = Opt;
3931 Op->StartLoc = S;
3932 Op->EndLoc = S;
3933 return Op;
3934 }
3935
3936 static std::unique_ptr<ARMOperand>
3937 CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S,
3938 ARMAsmParser &Parser) {
3939 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3940 Op->ISBOpt.Val = Opt;
3941 Op->StartLoc = S;
3942 Op->EndLoc = S;
3943 return Op;
3944 }
3945
3946 static std::unique_ptr<ARMOperand>
3947 CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S,
3948 ARMAsmParser &Parser) {
3949 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3950 Op->TSBOpt.Val = Opt;
3951 Op->StartLoc = S;
3952 Op->EndLoc = S;
3953 return Op;
3954 }
3955
3956 static std::unique_ptr<ARMOperand>
3957 CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S, ARMAsmParser &Parser) {
3958 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3959 Op->IFlags.Val = IFlags;
3960 Op->StartLoc = S;
3961 Op->EndLoc = S;
3962 return Op;
3963 }
3964
3965 static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S,
3966 ARMAsmParser &Parser) {
3967 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3968 Op->MMask.Val = MMask;
3969 Op->StartLoc = S;
3970 Op->EndLoc = S;
3971 return Op;
3972 }
3973
3974 static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S,
3975 ARMAsmParser &Parser) {
3976 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3977 Op->BankedReg.Val = Reg;
3978 Op->StartLoc = S;
3979 Op->EndLoc = S;
3980 return Op;
3981 }
3982};
3983
3984} // end anonymous namespace.
3985
3986void ARMOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
3987 auto RegName = [](MCRegister Reg) {
3988 if (Reg)
3990 else
3991 return "noreg";
3992 };
3993
3994 switch (Kind) {
3995 case k_CondCode:
3996 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
3997 break;
3998 case k_VPTPred:
3999 OS << "<ARMVCC::" << ARMVPTPredToString(getVPTPred()) << ">";
4000 break;
4001 case k_CCOut:
4002 OS << "<ccout " << RegName(getReg()) << ">";
4003 break;
4004 case k_ITCondMask: {
4005 static const char *const MaskStr[] = {
4006 "(invalid)", "(tttt)", "(ttt)", "(ttte)",
4007 "(tt)", "(ttet)", "(tte)", "(ttee)",
4008 "(t)", "(tett)", "(tet)", "(tete)",
4009 "(te)", "(teet)", "(tee)", "(teee)",
4010 };
4011 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4012 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
4013 break;
4014 }
4015 case k_CoprocNum:
4016 OS << "<coprocessor number: " << getCoproc() << ">";
4017 break;
4018 case k_CoprocReg:
4019 OS << "<coprocessor register: " << getCoproc() << ">";
4020 break;
4021 case k_CoprocOption:
4022 OS << "<coprocessor option: " << CoprocOption.Val << ">";
4023 break;
4024 case k_MSRMask:
4025 OS << "<mask: " << getMSRMask() << ">";
4026 break;
4027 case k_BankedReg:
4028 OS << "<banked reg: " << getBankedReg() << ">";
4029 break;
4030 case k_Immediate:
4031 MAI.printExpr(OS, *getImm());
4032 break;
4033 case k_MemBarrierOpt:
4034 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
4035 break;
4036 case k_InstSyncBarrierOpt:
4037 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
4038 break;
4039 case k_TraceSyncBarrierOpt:
4040 OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
4041 break;
4042 case k_Memory:
4043 OS << "<memory";
4044 if (Memory.BaseRegNum)
4045 OS << " base:" << RegName(Memory.BaseRegNum);
4046 if (Memory.OffsetImm) {
4047 OS << " offset-imm:";
4048 MAI.printExpr(OS, *Memory.OffsetImm);
4049 }
4050 if (Memory.OffsetRegNum)
4051 OS << " offset-reg:" << (Memory.isNegative ? "-" : "")
4052 << RegName(Memory.OffsetRegNum);
4053 if (Memory.ShiftType != ARM_AM::no_shift) {
4054 OS << " shift-type:" << ARM_AM::getShiftOpcStr(Memory.ShiftType);
4055 OS << " shift-imm:" << Memory.ShiftImm;
4056 }
4057 if (Memory.Alignment)
4058 OS << " alignment:" << Memory.Alignment;
4059 OS << ">";
4060 break;
4061 case k_PostIndexRegister:
4062 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
4063 << RegName(PostIdxReg.RegNum);
4064 if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
4065 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
4066 << PostIdxReg.ShiftImm;
4067 OS << ">";
4068 break;
4069 case k_ProcIFlags: {
4070 OS << "<ARM_PROC::";
4071 unsigned IFlags = getProcIFlags();
4072 for (int i=2; i >= 0; --i)
4073 if (IFlags & (1 << i))
4074 OS << ARM_PROC::IFlagsToString(1 << i);
4075 OS << ">";
4076 break;
4077 }
4078 case k_Register:
4079 OS << "<register " << RegName(getReg()) << ">";
4080 break;
4081 case k_ShifterImmediate:
4082 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
4083 << " #" << ShifterImm.Imm << ">";
4084 break;
4085 case k_ShiftedRegister:
4086 OS << "<so_reg_reg " << RegName(RegShiftedReg.SrcReg) << " "
4087 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) << " "
4088 << RegName(RegShiftedReg.ShiftReg) << ">";
4089 break;
4090 case k_ShiftedImmediate:
4091 OS << "<so_reg_imm " << RegName(RegShiftedImm.SrcReg) << " "
4092 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) << " #"
4093 << RegShiftedImm.ShiftImm << ">";
4094 break;
4095 case k_RotateImmediate:
4096 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
4097 break;
4098 case k_ModifiedImmediate:
4099 OS << "<mod_imm #" << ModImm.Bits << ", #"
4100 << ModImm.Rot << ")>";
4101 break;
4102 case k_ConstantPoolImmediate:
4103 OS << "<constant_pool_imm #";
4104 MAI.printExpr(OS, *getConstantPoolImm());
4105 break;
4106 case k_BitfieldDescriptor:
4107 OS << "<bitfield " << "lsb: " << Bitfield.LSB
4108 << ", width: " << Bitfield.Width << ">";
4109 break;
4110 case k_RegisterList:
4111 case k_RegisterListWithAPSR:
4112 case k_DPRRegisterList:
4113 case k_SPRRegisterList:
4114 case k_FPSRegisterListWithVPR:
4115 case k_FPDRegisterListWithVPR: {
4116 OS << "<register_list ";
4117
4118 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4119 for (auto I = RegList.begin(), E = RegList.end(); I != E;) {
4120 OS << RegName(*I);
4121 if (++I < E) OS << ", ";
4122 }
4123
4124 OS << ">";
4125 break;
4126 }
4127 case k_VectorList:
4128 OS << "<vector_list " << VectorList.Count << " * "
4129 << RegName(VectorList.RegNum) << ">";
4130 break;
4131 case k_VectorListAllLanes:
4132 OS << "<vector_list(all lanes) " << VectorList.Count << " * "
4133 << RegName(VectorList.RegNum) << ">";
4134 break;
4135 case k_VectorListIndexed:
4136 OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
4137 << VectorList.Count << " * " << RegName(VectorList.RegNum) << ">";
4138 break;
4139 case k_Token:
4140 OS << "'" << getToken() << "'";
4141 break;
4142 case k_VectorIndex:
4143 OS << "<vectorindex " << getVectorIndex() << ">";
4144 break;
4145 }
4146}
4147
4148/// @name Auto-generated Match Functions
4149/// {
4150
4152
4153/// }
4154
4155static bool isDataTypeToken(StringRef Tok) {
4156 static const DenseSet<StringRef> DataTypes{
4157 ".8", ".16", ".32", ".64", ".i8", ".i16", ".i32", ".i64",
4158 ".u8", ".u16", ".u32", ".u64", ".s8", ".s16", ".s32", ".s64",
4159 ".p8", ".p16", ".f32", ".f64", ".f", ".d"};
4160 return DataTypes.contains(Tok);
4161}
4162
4163static unsigned getMnemonicOpsEndInd(const OperandVector &Operands) {
4164 unsigned MnemonicOpsEndInd = 1;
4165 // Special case for CPS which has a Mnemonic side token for possibly storing
4166 // ie/id variant
4167 if (Operands[0]->isToken() &&
4168 static_cast<ARMOperand &>(*Operands[0]).getToken() == "cps") {
4169 if (Operands.size() > 1 && Operands[1]->isImm() &&
4170 static_cast<ARMOperand &>(*Operands[1]).getImm()->getKind() ==
4173 static_cast<ARMOperand &>(*Operands[1]).getImm())
4174 ->getValue() == ARM_PROC::IE ||
4176 static_cast<ARMOperand &>(*Operands[1]).getImm())
4177 ->getValue() == ARM_PROC::ID))
4178 ++MnemonicOpsEndInd;
4179 }
4180
4181 // In some circumstances the condition code moves to the right
4182 bool RHSCondCode = false;
4183 while (MnemonicOpsEndInd < Operands.size()) {
4184 auto Op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
4185 // Special case for it instructions which have a condition code on the RHS
4186 if (Op.isITMask()) {
4187 RHSCondCode = true;
4188 MnemonicOpsEndInd++;
4189 } else if (Op.isToken() &&
4190 (
4191 // There are several special cases not covered by
4192 // isDataTypeToken
4193 Op.getToken() == ".w" || Op.getToken() == ".bf16" ||
4194 Op.getToken() == ".p64" || Op.getToken() == ".f16" ||
4195 isDataTypeToken(Op.getToken()))) {
4196 // In the mnemonic operators the cond code must always precede the data
4197 // type. So we can now safely assume any subsequent cond code is on the
4198 // RHS. As is the case for VCMP and VPT.
4199 RHSCondCode = true;
4200 MnemonicOpsEndInd++;
4201 }
4202 // Skip all mnemonic operator types
4203 else if (Op.isCCOut() || (Op.isCondCode() && !RHSCondCode) ||
4204 Op.isVPTPred() || (Op.isToken() && Op.getToken() == ".w"))
4205 MnemonicOpsEndInd++;
4206 else
4207 break;
4208 }
4209 return MnemonicOpsEndInd;
4210}
4211
4212bool ARMAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
4213 SMLoc &EndLoc) {
4214 const AsmToken &Tok = getParser().getTok();
4215 StartLoc = Tok.getLoc();
4216 EndLoc = Tok.getEndLoc();
4217 Reg = tryParseRegister();
4218
4219 return !Reg;
4220}
4221
4222ParseStatus ARMAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
4223 SMLoc &EndLoc) {
4224 if (parseRegister(Reg, StartLoc, EndLoc))
4225 return ParseStatus::NoMatch;
4226 return ParseStatus::Success;
4227}
4228
4229/// Try to parse a register name. The token must be an Identifier when called,
4230/// and if it is a register name the token is eaten and the register is
4231/// returned. Otherwise return an invalid MCRegister.
4232MCRegister ARMAsmParser::tryParseRegister(bool AllowOutOfBoundReg) {
4233 MCAsmParser &Parser = getParser();
4234 const AsmToken &Tok = Parser.getTok();
4235 if (Tok.isNot(AsmToken::Identifier))
4236 return MCRegister();
4237
4238 std::string lowerCase = Tok.getString().lower();
4239 MCRegister Reg = MatchRegisterName(lowerCase);
4240 if (!Reg) {
4241 Reg = StringSwitch<MCRegister>(lowerCase)
4242 .Case("r13", ARM::SP)
4243 .Case("r14", ARM::LR)
4244 .Case("r15", ARM::PC)
4245 .Case("ip", ARM::R12)
4246 // Additional register name aliases for 'gas' compatibility.
4247 .Case("a1", ARM::R0)
4248 .Case("a2", ARM::R1)
4249 .Case("a3", ARM::R2)
4250 .Case("a4", ARM::R3)
4251 .Case("v1", ARM::R4)
4252 .Case("v2", ARM::R5)
4253 .Case("v3", ARM::R6)
4254 .Case("v4", ARM::R7)
4255 .Case("v5", ARM::R8)
4256 .Case("v6", ARM::R9)
4257 .Case("v7", ARM::R10)
4258 .Case("v8", ARM::R11)
4259 .Case("sb", ARM::R9)
4260 .Case("sl", ARM::R10)
4261 .Case("fp", ARM::R11)
4262 .Default(MCRegister());
4263 }
4264 if (!Reg) {
4265 // Check for aliases registered via .req. Canonicalize to lower case.
4266 // That's more consistent since register names are case insensitive, and
4267 // it's how the original entry was passed in from MC/MCParser/AsmParser.
4268 auto Entry = RegisterReqs.find(lowerCase);
4269 // If no match, return failure.
4270 if (Entry == RegisterReqs.end())
4271 return MCRegister();
4272 Parser.Lex(); // Eat identifier token.
4273 return Entry->getValue();
4274 }
4275
4276 // Some FPUs only have 16 D registers, so D16-D31 are invalid
4277 if (!AllowOutOfBoundReg && !hasD32() && Reg >= ARM::D16 && Reg <= ARM::D31)
4278 return MCRegister();
4279
4280 Parser.Lex(); // Eat identifier token.
4281
4282 return Reg;
4283}
4284
4285std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4286 MCAsmParser &Parser = getParser();
4287 const AsmToken &Tok = Parser.getTok();
4288 if (Tok.isNot(AsmToken::Identifier))
4289 return std::nullopt;
4290
4291 std::string lowerCase = Tok.getString().lower();
4292 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4293 .Case("asl", ARM_AM::lsl)
4294 .Case("lsl", ARM_AM::lsl)
4295 .Case("lsr", ARM_AM::lsr)
4296 .Case("asr", ARM_AM::asr)
4297 .Case("ror", ARM_AM::ror)
4298 .Case("rrx", ARM_AM::rrx)
4299 .Default(std::nullopt);
4300}
4301
4302// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0.
4303// If a recoverable error occurs, return 1. If an irrecoverable error
4304// occurs, return -1. An irrecoverable error is one where tokens have been
4305// consumed in the process of trying to parse the shifter (i.e., when it is
4306// indeed a shifter operand, but malformed).
4307int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
4308 MCAsmParser &Parser = getParser();
4309 SMLoc S = Parser.getTok().getLoc();
4310
4311 auto ShiftTyOpt = tryParseShiftToken();
4312 if (ShiftTyOpt == std::nullopt)
4313 return 1;
4314 auto ShiftTy = ShiftTyOpt.value();
4315
4316 Parser.Lex(); // Eat the operator.
4317
4318 // The source register for the shift has already been added to the
4319 // operand list, so we need to pop it off and combine it into the shifted
4320 // register operand instead.
4321 std::unique_ptr<ARMOperand> PrevOp(
4322 (ARMOperand *)Operands.pop_back_val().release());
4323 if (!PrevOp->isReg())
4324 return Error(PrevOp->getStartLoc(), "shift must be of a register");
4325 MCRegister SrcReg = PrevOp->getReg();
4326
4327 SMLoc EndLoc;
4328 int64_t Imm = 0;
4329 MCRegister ShiftReg;
4330 if (ShiftTy == ARM_AM::rrx) {
4331 // RRX Doesn't have an explicit shift amount. The encoder expects
4332 // the shift register to be the same as the source register. Seems odd,
4333 // but OK.
4334 ShiftReg = SrcReg;
4335 } else {
4336 // Figure out if this is shifted by a constant or a register (for non-RRX).
4337 if (Parser.getTok().is(AsmToken::Hash) ||
4338 Parser.getTok().is(AsmToken::Dollar)) {
4339 Parser.Lex(); // Eat hash.
4340 SMLoc ImmLoc = Parser.getTok().getLoc();
4341 const MCExpr *ShiftExpr = nullptr;
4342 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4343 Error(ImmLoc, "invalid immediate shift value");
4344 return -1;
4345 }
4346 // The expression must be evaluatable as an immediate.
4347 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
4348 if (!CE) {
4349 Error(ImmLoc, "invalid immediate shift value");
4350 return -1;
4351 }
4352 // Range check the immediate.
4353 // lsl, ror: 0 <= imm <= 31
4354 // lsr, asr: 0 <= imm <= 32
4355 Imm = CE->getValue();
4356 if (Imm < 0 ||
4357 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
4358 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
4359 Error(ImmLoc, "immediate shift value out of range");
4360 return -1;
4361 }
4362 // shift by zero is a nop. Always send it through as lsl.
4363 // ('as' compatibility)
4364 if (Imm == 0)
4365 ShiftTy = ARM_AM::lsl;
4366 } else if (Parser.getTok().is(AsmToken::Identifier)) {
4367 SMLoc L = Parser.getTok().getLoc();
4368 EndLoc = Parser.getTok().getEndLoc();
4369 ShiftReg = tryParseRegister();
4370 if (!ShiftReg) {
4371 Error(L, "expected immediate or register in shift operand");
4372 return -1;
4373 }
4374 } else {
4375 Error(Parser.getTok().getLoc(),
4376 "expected immediate or register in shift operand");
4377 return -1;
4378 }
4379 }
4380
4381 if (ShiftReg && ShiftTy != ARM_AM::rrx)
4382 Operands.push_back(ARMOperand::CreateShiftedRegister(
4383 ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *this));
4384 else
4385 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4386 S, EndLoc, *this));
4387
4388 return 0;
4389}
4390
4391/// Try to parse a register name. The token must be an Identifier when called.
4392/// If it's a register, an AsmOperand is created. Another AsmOperand is created
4393/// if there is a "writeback". 'true' if it's not a register.
4394///
4395/// TODO this is likely to change to allow different register types and or to
4396/// parse for a specific register type.
4397bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) {
4398 MCAsmParser &Parser = getParser();
4399 SMLoc RegStartLoc = Parser.getTok().getLoc();
4400 SMLoc RegEndLoc = Parser.getTok().getEndLoc();
4401 MCRegister Reg = tryParseRegister();
4402 if (!Reg)
4403 return true;
4404
4405 Operands.push_back(ARMOperand::CreateReg(Reg, RegStartLoc, RegEndLoc, *this));
4406
4407 const AsmToken &ExclaimTok = Parser.getTok();
4408 if (ExclaimTok.is(AsmToken::Exclaim)) {
4409 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
4410 ExclaimTok.getLoc(), *this));
4411 Parser.Lex(); // Eat exclaim token
4412 return false;
4413 }
4414
4415 // Also check for an index operand. This is only legal for vector registers,
4416 // but that'll get caught OK in operand matching, so we don't need to
4417 // explicitly filter everything else out here.
4418 if (Parser.getTok().is(AsmToken::LBrac)) {
4419 SMLoc SIdx = Parser.getTok().getLoc();
4420 Parser.Lex(); // Eat left bracket token.
4421
4422 const MCExpr *ImmVal;
4423 if (getParser().parseExpression(ImmVal))
4424 return true;
4425 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
4426 if (!MCE)
4427 return TokError("immediate value expected for vector index");
4428
4429 if (Parser.getTok().isNot(AsmToken::RBrac))
4430 return Error(Parser.getTok().getLoc(), "']' expected");
4431
4432 SMLoc E = Parser.getTok().getEndLoc();
4433 Parser.Lex(); // Eat right bracket token.
4434
4435 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), SIdx, E,
4436 getContext(), *this));
4437 }
4438
4439 return false;
4440}
4441
4442/// MatchCoprocessorOperandName - Try to parse an coprocessor related
4443/// instruction with a symbolic operand name.
4444/// We accept "crN" syntax for GAS compatibility.
4445/// <operand-name> ::= <prefix><number>
4446/// If CoprocOp is 'c', then:
4447/// <prefix> ::= c | cr
4448/// If CoprocOp is 'p', then :
4449/// <prefix> ::= p
4450/// <number> ::= integer in range [0, 15]
4451static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
4452 // Use the same layout as the tablegen'erated register name matcher. Ugly,
4453 // but efficient.
4454 if (Name.size() < 2 || Name[0] != CoprocOp)
4455 return -1;
4456 Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front();
4457
4458 switch (Name.size()) {
4459 default: return -1;
4460 case 1:
4461 switch (Name[0]) {
4462 default: return -1;
4463 case '0': return 0;
4464 case '1': return 1;
4465 case '2': return 2;
4466 case '3': return 3;
4467 case '4': return 4;
4468 case '5': return 5;
4469 case '6': return 6;
4470 case '7': return 7;
4471 case '8': return 8;
4472 case '9': return 9;
4473 }
4474 case 2:
4475 if (Name[0] != '1')
4476 return -1;
4477 switch (Name[1]) {
4478 default: return -1;
4479 // CP10 and CP11 are VFP/NEON and so vector instructions should be used.
4480 // However, old cores (v5/v6) did use them in that way.
4481 case '0': return 10;
4482 case '1': return 11;
4483 case '2': return 12;
4484 case '3': return 13;
4485 case '4': return 14;
4486 case '5': return 15;
4487 }
4488 }
4489}
4490
4491/// parseITCondCode - Try to parse a condition code for an IT instruction.
4492ParseStatus ARMAsmParser::parseITCondCode(OperandVector &Operands) {
4493 MCAsmParser &Parser = getParser();
4494 SMLoc S = Parser.getTok().getLoc();
4495 const AsmToken &Tok = Parser.getTok();
4496 if (!Tok.is(AsmToken::Identifier))
4497 return ParseStatus::NoMatch;
4498 unsigned CC = ARMCondCodeFromString(Tok.getString());
4499 if (CC == ~0U)
4500 return ParseStatus::NoMatch;
4501 Parser.Lex(); // Eat the token.
4502
4503 Operands.push_back(
4504 ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S, *this));
4505
4506 return ParseStatus::Success;
4507}
4508
4509/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
4510/// token must be an Identifier when called, and if it is a coprocessor
4511/// number, the token is eaten and the operand is added to the operand list.
4512ParseStatus ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
4513 MCAsmParser &Parser = getParser();
4514 SMLoc S = Parser.getTok().getLoc();
4515 const AsmToken &Tok = Parser.getTok();
4516 if (Tok.isNot(AsmToken::Identifier))
4517 return ParseStatus::NoMatch;
4518
4519 int Num = MatchCoprocessorOperandName(Tok.getString().lower(), 'p');
4520 if (Num == -1)
4521 return ParseStatus::NoMatch;
4522 if (!isValidCoprocessorNumber(Num, getSTI().getFeatureBits()))
4523 return ParseStatus::NoMatch;
4524
4525 Parser.Lex(); // Eat identifier token.
4526 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *this));
4527 return ParseStatus::Success;
4528}
4529
4530/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
4531/// token must be an Identifier when called, and if it is a coprocessor
4532/// number, the token is eaten and the operand is added to the operand list.
4533ParseStatus ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) {
4534 MCAsmParser &Parser = getParser();
4535 SMLoc S = Parser.getTok().getLoc();
4536 const AsmToken &Tok = Parser.getTok();
4537 if (Tok.isNot(AsmToken::Identifier))
4538 return ParseStatus::NoMatch;
4539
4540 int Reg = MatchCoprocessorOperandName(Tok.getString().lower(), 'c');
4541 if (Reg == -1)
4542 return ParseStatus::NoMatch;
4543
4544 Parser.Lex(); // Eat identifier token.
4545 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S, *this));
4546 return ParseStatus::Success;
4547}
4548
4549/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
4550/// coproc_option : '{' imm0_255 '}'
4551ParseStatus ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) {
4552 MCAsmParser &Parser = getParser();
4553 SMLoc S = Parser.getTok().getLoc();
4554
4555 // If this isn't a '{', this isn't a coprocessor immediate operand.
4556 if (Parser.getTok().isNot(AsmToken::LCurly))
4557 return ParseStatus::NoMatch;
4558 Parser.Lex(); // Eat the '{'
4559
4560 const MCExpr *Expr;
4561 SMLoc Loc = Parser.getTok().getLoc();
4562 if (getParser().parseExpression(Expr))
4563 return Error(Loc, "illegal expression");
4564 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
4565 if (!CE || CE->getValue() < 0 || CE->getValue() > 255)
4566 return Error(Loc,
4567 "coprocessor option must be an immediate in range [0, 255]");
4568 int Val = CE->getValue();
4569
4570 // Check for and consume the closing '}'
4571 if (Parser.getTok().isNot(AsmToken::RCurly))
4572 return ParseStatus::Failure;
4573 SMLoc E = Parser.getTok().getEndLoc();
4574 Parser.Lex(); // Eat the '}'
4575
4576 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E, *this));
4577 return ParseStatus::Success;
4578}
4579
4580// For register list parsing, we need to map from raw GPR register numbering
4581// to the enumeration values. The enumeration values aren't sorted by
4582// register number due to our using "sp", "lr" and "pc" as canonical names.
4584 // If this is a GPR, we need to do it manually, otherwise we can rely
4585 // on the sort ordering of the enumeration since the other reg-classes
4586 // are sane.
4587 if (!getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4588 return Reg + 1;
4589 switch (Reg.id()) {
4590 default: llvm_unreachable("Invalid GPR number!");
4591 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2;
4592 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4;
4593 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6;
4594 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8;
4595 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10;
4596 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
4597 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR;
4598 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0;
4599 }
4600}
4601
4602// Insert an <Encoding, Register> pair in an ordered vector. Return true on
4603// success, or false, if duplicate encoding found.
4604static bool
4605insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
4606 unsigned Enc, MCRegister Reg) {
4607 Regs.emplace_back(Enc, Reg);
4608 for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
4609 if (J->first == Enc) {
4610 Regs.erase(J.base());
4611 return false;
4612 }
4613 if (J->first < Enc)
4614 break;
4615 std::swap(*I, *J);
4616 }
4617 return true;
4618}
4619
4620/// Parse a register list.
4621bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
4622 bool AllowRAAC, bool IsLazyLoadStore,
4623 bool IsVSCCLRM) {
4624 MCAsmParser &Parser = getParser();
4625 if (Parser.getTok().isNot(AsmToken::LCurly))
4626 return TokError("Token is not a Left Curly Brace");
4627 SMLoc S = Parser.getTok().getLoc();
4628 Parser.Lex(); // Eat '{' token.
4629 SMLoc RegLoc = Parser.getTok().getLoc();
4630
4631 // Check the first register in the list to see what register class
4632 // this is a list of.
4633 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4634 MCRegister Reg = tryParseRegister(AllowOutOfBoundReg);
4635 if (!Reg)
4636 return Error(RegLoc, "register expected");
4637 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
4638 return Error(RegLoc, "pseudo-register not allowed");
4639 // The reglist instructions have at most 32 registers, so reserve
4640 // space for that many.
4641 int EReg = 0;
4643
4644 // Single-precision VSCCLRM can have double-precision registers in the
4645 // register list. When VSCCLRMAdjustEncoding is true then we've switched from
4646 // single-precision to double-precision and we pretend that these registers
4647 // are encoded as S32 onwards, which we can do by adding 16 to the encoding
4648 // value.
4649 bool VSCCLRMAdjustEncoding = false;
4650
4651 // Allow Q regs and just interpret them as the two D sub-registers.
4652 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4653 Reg = getDRegFromQReg(Reg);
4654 EReg = MRI->getEncodingValue(Reg);
4655 Registers.emplace_back(EReg, Reg);
4656 Reg = Reg + 1;
4657 }
4658 const MCRegisterClass *RC;
4659 if (Reg == ARM::RA_AUTH_CODE ||
4660 getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4661 RC = &getARMMCRegisterClass(ARM::GPRRegClassID);
4662 else if (getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg))
4663 RC = &getARMMCRegisterClass(ARM::DPRRegClassID);
4664 else if (getARMMCRegisterClass(ARM::SPRRegClassID).contains(Reg))
4665 RC = &getARMMCRegisterClass(ARM::SPRRegClassID);
4666 else if (getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).contains(Reg))
4667 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4668 else if (Reg == ARM::VPR)
4669 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4670 else
4671 return Error(RegLoc, "invalid register in register list");
4672
4673 // Store the register.
4674 EReg = MRI->getEncodingValue(Reg);
4675 Registers.emplace_back(EReg, Reg);
4676
4677 // This starts immediately after the first register token in the list,
4678 // so we can see either a comma or a minus (range separator) as a legal
4679 // next token.
4680 while (Parser.getTok().is(AsmToken::Comma) ||
4681 Parser.getTok().is(AsmToken::Minus)) {
4682 if (Parser.getTok().is(AsmToken::Minus)) {
4683 if (Reg == ARM::RA_AUTH_CODE)
4684 return Error(RegLoc, "pseudo-register not allowed");
4685 Parser.Lex(); // Eat the minus.
4686 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4687 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4688 if (!EndReg)
4689 return Error(AfterMinusLoc, "register expected");
4690 if (EndReg == ARM::RA_AUTH_CODE)
4691 return Error(AfterMinusLoc, "pseudo-register not allowed");
4692 // Allow Q regs and just interpret them as the two D sub-registers.
4693 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(EndReg))
4694 EndReg = getDRegFromQReg(EndReg) + 1;
4695 // If the register is the same as the start reg, there's nothing
4696 // more to do.
4697 if (Reg == EndReg)
4698 continue;
4699 // The register must be in the same register class as the first.
4700 if (!RC->contains(Reg))
4701 return Error(AfterMinusLoc, "invalid register in register list");
4702 // Ranges must go from low to high.
4703 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
4704 return Error(AfterMinusLoc, "bad range in register list");
4705
4706 // Add all the registers in the range to the register list.
4707 while (Reg != EndReg) {
4709 EReg = MRI->getEncodingValue(Reg);
4710 if (VSCCLRMAdjustEncoding)
4711 EReg += 16;
4712 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4713 Warning(AfterMinusLoc, StringRef("duplicated register (") +
4715 ") in register list");
4716 }
4717 }
4718 continue;
4719 }
4720 Parser.Lex(); // Eat the comma.
4721 RegLoc = Parser.getTok().getLoc();
4722 MCRegister OldReg = Reg;
4723 int EOldReg = EReg;
4724 const AsmToken RegTok = Parser.getTok();
4725 Reg = tryParseRegister(AllowOutOfBoundReg);
4726 if (!Reg)
4727 return Error(RegLoc, "register expected");
4728 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
4729 return Error(RegLoc, "pseudo-register not allowed");
4730 // Allow Q regs and just interpret them as the two D sub-registers.
4731 bool isQReg = false;
4732 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4733 Reg = getDRegFromQReg(Reg);
4734 isQReg = true;
4735 }
4736 if (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg) &&
4737 RC->getID() == getARMMCRegisterClass(ARM::GPRRegClassID).getID() &&
4738 getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).contains(Reg)) {
4739 // switch the register classes, as GPRwithAPSRnospRegClassID is a partial
4740 // subset of GPRRegClassId except it contains APSR as well.
4741 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4742 }
4743 if (Reg == ARM::VPR &&
4744 (RC == &getARMMCRegisterClass(ARM::SPRRegClassID) ||
4745 RC == &getARMMCRegisterClass(ARM::DPRRegClassID) ||
4746 RC == &getARMMCRegisterClass(ARM::FPWithVPRRegClassID))) {
4747 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4748 EReg = MRI->getEncodingValue(Reg);
4749 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4750 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4751 ") in register list");
4752 }
4753 continue;
4754 }
4755 // VSCCLRM can switch from single-precision to double-precision only when
4756 // S31 is followed by D16.
4757 if (IsVSCCLRM && OldReg == ARM::S31 && Reg == ARM::D16) {
4758 VSCCLRMAdjustEncoding = true;
4759 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4760 }
4761 // The register must be in the same register class as the first.
4762 if ((Reg == ARM::RA_AUTH_CODE &&
4763 RC != &getARMMCRegisterClass(ARM::GPRRegClassID)) ||
4764 (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg)))
4765 return Error(RegLoc, "invalid register in register list");
4766 // In most cases, the list must be monotonically increasing. An
4767 // exception is CLRM, which is order-independent anyway, so
4768 // there's no potential for confusion if you write clrm {r2,r1}
4769 // instead of clrm {r1,r2}.
4770 EReg = MRI->getEncodingValue(Reg);
4771 if (VSCCLRMAdjustEncoding)
4772 EReg += 16;
4773 if (EnforceOrder && EReg < EOldReg) {
4774 if (getARMMCRegisterClass(ARM::GPRRegClassID).contains(Reg))
4775 Warning(RegLoc, "register list not in ascending order");
4776 else if (!getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
4777 .contains(Reg))
4778 return Error(RegLoc, "register list not in ascending order");
4779 }
4780 // VFP register lists must also be contiguous.
4781 if (RC != &getARMMCRegisterClass(ARM::GPRRegClassID) &&
4782 RC != &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID) &&
4783 EReg != EOldReg + 1)
4784 return Error(RegLoc, "non-contiguous register range");
4785
4786 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4787 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4788 ") in register list");
4789 }
4790 if (isQReg) {
4791 Reg = Reg + 1;
4792 EReg = MRI->getEncodingValue(Reg);
4793 Registers.emplace_back(EReg, Reg);
4794 }
4795 }
4796
4797 if (Parser.getTok().isNot(AsmToken::RCurly))
4798 return Error(Parser.getTok().getLoc(), "'}' expected");
4799 SMLoc E = Parser.getTok().getEndLoc();
4800 Parser.Lex(); // Eat '}' token.
4801
4802 // Push the register list operand.
4803 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E, *this));
4804
4805 // The ARM system instruction variants for LDM/STM have a '^' token here.
4806 if (Parser.getTok().is(AsmToken::Caret)) {
4807 Operands.push_back(
4808 ARMOperand::CreateToken("^", Parser.getTok().getLoc(), *this));
4809 Parser.Lex(); // Eat '^' token.
4810 }
4811
4812 return false;
4813}
4814
4815// Helper function to parse the lane index for vector lists.
4816ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4817 unsigned &Index, SMLoc &EndLoc) {
4818 MCAsmParser &Parser = getParser();
4819 Index = 0; // Always return a defined index value.
4820 if (Parser.getTok().is(AsmToken::LBrac)) {
4821 Parser.Lex(); // Eat the '['.
4822 if (Parser.getTok().is(AsmToken::RBrac)) {
4823 // "Dn[]" is the 'all lanes' syntax.
4824 LaneKind = AllLanes;
4825 EndLoc = Parser.getTok().getEndLoc();
4826 Parser.Lex(); // Eat the ']'.
4827 return ParseStatus::Success;
4828 }
4829
4830 // There's an optional '#' token here. Normally there wouldn't be, but
4831 // inline assemble puts one in, and it's friendly to accept that.
4832 if (Parser.getTok().is(AsmToken::Hash))
4833 Parser.Lex(); // Eat '#' or '$'.
4834
4835 const MCExpr *LaneIndex;
4836 SMLoc Loc = Parser.getTok().getLoc();
4837 if (getParser().parseExpression(LaneIndex))
4838 return Error(Loc, "illegal expression");
4839 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
4840 if (!CE)
4841 return Error(Loc, "lane index must be empty or an integer");
4842 if (Parser.getTok().isNot(AsmToken::RBrac))
4843 return Error(Parser.getTok().getLoc(), "']' expected");
4844 EndLoc = Parser.getTok().getEndLoc();
4845 Parser.Lex(); // Eat the ']'.
4846 int64_t Val = CE->getValue();
4847
4848 // FIXME: Make this range check context sensitive for .8, .16, .32.
4849 if (Val < 0 || Val > 7)
4850 return Error(Parser.getTok().getLoc(), "lane index out of range");
4851 Index = Val;
4852 LaneKind = IndexedLane;
4853 return ParseStatus::Success;
4854 }
4855 LaneKind = NoLanes;
4856 return ParseStatus::Success;
4857}
4858
4859// parse a vector register list
4860ParseStatus ARMAsmParser::parseVectorList(OperandVector &Operands) {
4861 MCAsmParser &Parser = getParser();
4862 VectorLaneTy LaneKind;
4863 unsigned LaneIndex;
4864 SMLoc S = Parser.getTok().getLoc();
4865 // As an extension (to match gas), support a plain D register or Q register
4866 // (without encosing curly braces) as a single or double entry list,
4867 // respectively.
4868 // If there is no lane supplied, just parse as a register and
4869 // use the custom matcher to convert to list if necessary
4870 if (!hasMVE() && Parser.getTok().is(AsmToken::Identifier)) {
4871 SMLoc E = Parser.getTok().getEndLoc();
4872 MCRegister Reg = tryParseRegister();
4873 if (!Reg)
4874 return ParseStatus::NoMatch;
4875 if (getARMMCRegisterClass(ARM::DPRRegClassID).contains(Reg)) {
4876 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex, E);
4877 if (!Res.isSuccess())
4878 return Res;
4879 switch (LaneKind) {
4880 case NoLanes:
4881 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4882 break;
4883 case AllLanes:
4884 Operands.push_back(
4885 ARMOperand::CreateVectorListAllLanes(Reg, 1, false, S, E, *this));
4886 break;
4887 case IndexedLane:
4888 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4889 Reg, 1, LaneIndex, false, S, E, *this));
4890 break;
4891 }
4892 return ParseStatus::Success;
4893 }
4894 if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4895 Reg = getDRegFromQReg(Reg);
4896 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex, E);
4897 if (!Res.isSuccess())
4898 return Res;
4899 switch (LaneKind) {
4900 case NoLanes:
4901 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4902 break;
4903 case AllLanes:
4904 Reg = MRI->getMatchingSuperReg(
4905 Reg, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
4906 Operands.push_back(
4907 ARMOperand::CreateVectorListAllLanes(Reg, 2, false, S, E, *this));
4908 break;
4909 case IndexedLane:
4910 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4911 Reg, 2, LaneIndex, false, S, E, *this));
4912 break;
4913 }
4914 return ParseStatus::Success;
4915 }
4916 Operands.push_back(ARMOperand::CreateReg(Reg, S, E, *this));
4917 return ParseStatus::Success;
4918 }
4919
4920 if (Parser.getTok().isNot(AsmToken::LCurly))
4921 return ParseStatus::NoMatch;
4922
4923 Parser.Lex(); // Eat '{' token.
4924 SMLoc RegLoc = Parser.getTok().getLoc();
4925
4926 MCRegister Reg = tryParseRegister();
4927 if (!Reg)
4928 return Error(RegLoc, "register expected");
4929 unsigned Count = 1;
4930 int Spacing = 0;
4931 MCRegister FirstReg = Reg;
4932
4933 if (hasMVE() && !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Reg))
4934 return Error(Parser.getTok().getLoc(),
4935 "vector register in range Q0-Q7 expected");
4936 // The list is of D registers, but we also allow Q regs and just interpret
4937 // them as the two D sub-registers.
4938 else if (!hasMVE() &&
4939 getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
4940 FirstReg = Reg = getDRegFromQReg(Reg);
4941 Spacing = 1; // double-spacing requires explicit D registers, otherwise
4942 // it's ambiguous with four-register single spaced.
4943 Reg = Reg + 1;
4944 ++Count;
4945 }
4946
4947 SMLoc E;
4948 if (!parseVectorLane(LaneKind, LaneIndex, E).isSuccess())
4949 return ParseStatus::Failure;
4950
4951 while (Parser.getTok().is(AsmToken::Comma) ||
4952 Parser.getTok().is(AsmToken::Minus)) {
4953 if (Parser.getTok().is(AsmToken::Minus)) {
4954 if (!Spacing)
4955 Spacing = 1; // Register range implies a single spaced list.
4956 else if (Spacing == 2)
4957 return Error(Parser.getTok().getLoc(),
4958 "sequential registers in double spaced list");
4959 Parser.Lex(); // Eat the minus.
4960 SMLoc AfterMinusLoc = Parser.getTok().getLoc();
4961 MCRegister EndReg = tryParseRegister();
4962 if (!EndReg)
4963 return Error(AfterMinusLoc, "register expected");
4964 // Allow Q regs and just interpret them as the two D sub-registers.
4965 if (!hasMVE() &&
4966 getARMMCRegisterClass(ARM::QPRRegClassID).contains(EndReg))
4967 EndReg = getDRegFromQReg(EndReg) + 1;
4968 // If the register is the same as the start reg, there's nothing
4969 // more to do.
4970 if (Reg == EndReg)
4971 continue;
4972 // The register must be in the same register class as the first.
4973 if ((hasMVE() &&
4974 !getARMMCRegisterClass(ARM::MQPRRegClassID).contains(EndReg)) ||
4975 (!hasMVE() &&
4976 !getARMMCRegisterClass(ARM::DPRRegClassID).contains(EndReg)))
4977 return Error(AfterMinusLoc, "invalid register in register list");
4978 // Ranges must go from low to high.
4979 if (Reg > EndReg)
4980 return Error(AfterMinusLoc, "bad range in register list");
4981 // Parse the lane specifier if present.
4982 VectorLaneTy NextLaneKind;
4983 unsigned NextLaneIndex;
4984 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
4985 return ParseStatus::Failure;
4986 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4987 return Error(AfterMinusLoc, "mismatched lane index in register list");
4988
4989 // Add all the registers in the range to the register list.
4990 Count += EndReg - Reg;
4991 Reg = EndReg;
4992 continue;
4993 }
4994 Parser.Lex(); // Eat the comma.
4995 RegLoc = Parser.getTok().getLoc();
4996 MCRegister OldReg = Reg;
4997 Reg = tryParseRegister();
4998 if (!Reg)
4999 return Error(RegLoc, "register expected");
5000
5001 if (hasMVE()) {
5002 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).contains(Reg))
5003 return Error(RegLoc, "vector register in range Q0-Q7 expected");
5004 Spacing = 1;
5005 }
5006 // vector register lists must be contiguous.
5007 // It's OK to use the enumeration values directly here rather, as the
5008 // VFP register classes have the enum sorted properly.
5009 //
5010 // The list is of D registers, but we also allow Q regs and just interpret
5011 // them as the two D sub-registers.
5012 else if (getARMMCRegisterClass(ARM::QPRRegClassID).contains(Reg)) {
5013 if (!Spacing)
5014 Spacing = 1; // Register range implies a single spaced list.
5015 else if (Spacing == 2)
5016 return Error(
5017 RegLoc,
5018 "invalid register in double-spaced list (must be 'D' register')");
5019 Reg = getDRegFromQReg(Reg);
5020 if (Reg != OldReg + 1)
5021 return Error(RegLoc, "non-contiguous register range");
5022 Reg = Reg + 1;
5023 Count += 2;
5024 // Parse the lane specifier if present.
5025 VectorLaneTy NextLaneKind;
5026 unsigned NextLaneIndex;
5027 SMLoc LaneLoc = Parser.getTok().getLoc();
5028 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
5029 return ParseStatus::Failure;
5030 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5031 return Error(LaneLoc, "mismatched lane index in register list");
5032 continue;
5033 }
5034 // Normal D register.
5035 // Figure out the register spacing (single or double) of the list if
5036 // we don't know it already.
5037 if (!Spacing)
5038 Spacing = 1 + (Reg == OldReg + 2);
5039
5040 // Just check that it's contiguous and keep going.
5041 if (Reg != OldReg + Spacing)
5042 return Error(RegLoc, "non-contiguous register range");
5043 ++Count;
5044 // Parse the lane specifier if present.
5045 VectorLaneTy NextLaneKind;
5046 unsigned NextLaneIndex;
5047 SMLoc EndLoc = Parser.getTok().getLoc();
5048 if (!parseVectorLane(NextLaneKind, NextLaneIndex, E).isSuccess())
5049 return ParseStatus::Failure;
5050 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5051 return Error(EndLoc, "mismatched lane index in register list");
5052 }
5053
5054 if (Parser.getTok().isNot(AsmToken::RCurly))
5055 return Error(Parser.getTok().getLoc(), "'}' expected");
5056 E = Parser.getTok().getEndLoc();
5057 Parser.Lex(); // Eat '}' token.
5058
5059 switch (LaneKind) {
5060 case NoLanes:
5061 case AllLanes: {
5062 // Two-register operands have been converted to the
5063 // composite register classes.
5064 if (Count == 2 && !hasMVE()) {
5065 const MCRegisterClass *RC =
5066 (Spacing == 1) ? &getARMMCRegisterClass(ARM::DPairRegClassID)
5067 : &getARMMCRegisterClass(ARM::DPairSpcRegClassID);
5068 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
5069 }
5070 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5071 ARMOperand::CreateVectorListAllLanes);
5072 Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E, *this));
5073 break;
5074 }
5075 case IndexedLane:
5076 Operands.push_back(ARMOperand::CreateVectorListIndexed(
5077 FirstReg, Count, LaneIndex, (Spacing == 2), S, E, *this));
5078 break;
5079 }
5080 return ParseStatus::Success;
5081}
5082
5083/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
5084ParseStatus ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
5085 MCAsmParser &Parser = getParser();
5086 SMLoc S = Parser.getTok().getLoc();
5087 const AsmToken &Tok = Parser.getTok();
5088 unsigned Opt;
5089
5090 if (Tok.is(AsmToken::Identifier)) {
5091 StringRef OptStr = Tok.getString();
5092
5093 Opt = StringSwitch<unsigned>(OptStr.lower())
5094 .Case("sy", ARM_MB::SY)
5095 .Case("st", ARM_MB::ST)
5096 .Case("ld", ARM_MB::LD)
5097 .Case("sh", ARM_MB::ISH)
5098 .Case("ish", ARM_MB::ISH)
5099 .Case("shst", ARM_MB::ISHST)
5100 .Case("ishst", ARM_MB::ISHST)
5101 .Case("ishld", ARM_MB::ISHLD)
5102 .Case("nsh", ARM_MB::NSH)
5103 .Case("un", ARM_MB::NSH)
5104 .Case("nshst", ARM_MB::NSHST)
5105 .Case("nshld", ARM_MB::NSHLD)
5106 .Case("unst", ARM_MB::NSHST)
5107 .Case("osh", ARM_MB::OSH)
5108 .Case("oshst", ARM_MB::OSHST)
5109 .Case("oshld", ARM_MB::OSHLD)
5110 .Default(~0U);
5111
5112 // ishld, oshld, nshld and ld are only available from ARMv8.
5113 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD ||
5114 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD))
5115 Opt = ~0U;
5116
5117 if (Opt == ~0U)
5118 return ParseStatus::NoMatch;
5119
5120 Parser.Lex(); // Eat identifier token.
5121 } else if (Tok.is(AsmToken::Hash) ||
5122 Tok.is(AsmToken::Dollar) ||
5123 Tok.is(AsmToken::Integer)) {
5124 if (Parser.getTok().isNot(AsmToken::Integer))
5125 Parser.Lex(); // Eat '#' or '$'.
5126 SMLoc Loc = Parser.getTok().getLoc();
5127
5128 const MCExpr *MemBarrierID;
5129 if (getParser().parseExpression(MemBarrierID))
5130 return Error(Loc, "illegal expression");
5131
5132 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
5133 if (!CE)
5134 return Error(Loc, "constant expression expected");
5135
5136 int Val = CE->getValue();
5137 if (Val & ~0xf)
5138 return Error(Loc, "immediate value out of range");
5139
5140 Opt = ARM_MB::RESERVED_0 + Val;
5141 } else
5142 return Error(Parser.getTok().getLoc(),
5143 "expected an immediate or barrier type");
5144
5145 Operands.push_back(
5146 ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S, *this));
5147 return ParseStatus::Success;
5148}
5149
5150ParseStatus
5151ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) {
5152 MCAsmParser &Parser = getParser();
5153 SMLoc S = Parser.getTok().getLoc();
5154 const AsmToken &Tok = Parser.getTok();
5155
5156 if (Tok.isNot(AsmToken::Identifier))
5157 return ParseStatus::NoMatch;
5158
5159 if (!Tok.getString().equals_insensitive("csync"))
5160 return ParseStatus::NoMatch;
5161
5162 Parser.Lex(); // Eat identifier token.
5163
5164 Operands.push_back(
5165 ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S, *this));
5166 return ParseStatus::Success;
5167}
5168
5169/// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
5170ParseStatus
5171ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
5172 MCAsmParser &Parser = getParser();
5173 SMLoc S = Parser.getTok().getLoc();
5174 const AsmToken &Tok = Parser.getTok();
5175 unsigned Opt;
5176
5177 if (Tok.is(AsmToken::Identifier)) {
5178 StringRef OptStr = Tok.getString();
5179
5180 if (OptStr.equals_insensitive("sy"))
5181 Opt = ARM_ISB::SY;
5182 else
5183 return ParseStatus::NoMatch;
5184
5185 Parser.Lex(); // Eat identifier token.
5186 } else if (Tok.is(AsmToken::Hash) ||
5187 Tok.is(AsmToken::Dollar) ||
5188 Tok.is(AsmToken::Integer)) {
5189 if (Parser.getTok().isNot(AsmToken::Integer))
5190 Parser.Lex(); // Eat '#' or '$'.
5191 SMLoc Loc = Parser.getTok().getLoc();
5192
5193 const MCExpr *ISBarrierID;
5194 if (getParser().parseExpression(ISBarrierID))
5195 return Error(Loc, "illegal expression");
5196
5197 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID);
5198 if (!CE)
5199 return Error(Loc, "constant expression expected");
5200
5201 int Val = CE->getValue();
5202 if (Val & ~0xf)
5203 return Error(Loc, "immediate value out of range");
5204
5205 Opt = ARM_ISB::RESERVED_0 + Val;
5206 } else
5207 return Error(Parser.getTok().getLoc(),
5208 "expected an immediate or barrier type");
5209
5210 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
5211 (ARM_ISB::InstSyncBOpt)Opt, S, *this));
5212 return ParseStatus::Success;
5213}
5214
5215/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
5216ParseStatus ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {
5217 MCAsmParser &Parser = getParser();
5218 SMLoc S = Parser.getTok().getLoc();
5219 const AsmToken &Tok = Parser.getTok();
5220 if (!Tok.is(AsmToken::Identifier))
5221 return ParseStatus::NoMatch;
5222 StringRef IFlagsStr = Tok.getString();
5223
5224 // An iflags string of "none" is interpreted to mean that none of the AIF
5225 // bits are set. Not a terribly useful instruction, but a valid encoding.
5226 unsigned IFlags = 0;
5227 if (IFlagsStr != "none") {
5228 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
5229 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1).lower())
5230 .Case("a", ARM_PROC::A)
5231 .Case("i", ARM_PROC::I)
5232 .Case("f", ARM_PROC::F)
5233 .Default(~0U);
5234
5235 // If some specific iflag is already set, it means that some letter is
5236 // present more than once, this is not acceptable.
5237 if (Flag == ~0U || (IFlags & Flag))
5238 return ParseStatus::NoMatch;
5239
5240 IFlags |= Flag;
5241 }
5242 }
5243
5244 Parser.Lex(); // Eat identifier token.
5245 Operands.push_back(
5246 ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S, *this));
5247 return ParseStatus::Success;
5248}
5249
5250/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
5251ParseStatus ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {
5252 // Don't parse two MSR registers in a row
5253 if (static_cast<ARMOperand &>(*Operands.back()).isMSRMask() ||
5254 static_cast<ARMOperand &>(*Operands.back()).isBankedReg())
5255 return ParseStatus::NoMatch;
5256 MCAsmParser &Parser = getParser();
5257 SMLoc S = Parser.getTok().getLoc();
5258 const AsmToken &Tok = Parser.getTok();
5259
5260 if (Tok.is(AsmToken::Integer)) {
5261 int64_t Val = Tok.getIntVal();
5262 if (Val > 255 || Val < 0) {
5263 return ParseStatus::NoMatch;
5264 }
5265 unsigned SYSmvalue = Val & 0xFF;
5266 Parser.Lex();
5267 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this));
5268 return ParseStatus::Success;
5269 }
5270
5271 if (!Tok.is(AsmToken::Identifier))
5272 return ParseStatus::NoMatch;
5273 StringRef Mask = Tok.getString();
5274
5275 if (isMClass()) {
5276 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower());
5277 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5278 return ParseStatus::NoMatch;
5279
5280 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5281
5282 Parser.Lex(); // Eat identifier token.
5283 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *this));
5284 return ParseStatus::Success;
5285 }
5286
5287 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
5288 size_t Start = 0, Next = Mask.find('_');
5289 StringRef Flags = "";
5290 std::string SpecReg = Mask.slice(Start, Next).lower();
5291 if (Next != StringRef::npos)
5292 Flags = Mask.substr(Next + 1);
5293
5294 // FlagsVal contains the complete mask:
5295 // 3-0: Mask
5296 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5297 unsigned FlagsVal = 0;
5298
5299 if (SpecReg == "apsr") {
5300 FlagsVal = StringSwitch<unsigned>(Flags)
5301 .Case("nzcvq", 0x8) // same as CPSR_f
5302 .Case("g", 0x4) // same as CPSR_s
5303 .Case("nzcvqg", 0xc) // same as CPSR_fs
5304 .Default(~0U);
5305
5306 if (FlagsVal == ~0U) {
5307 if (!Flags.empty())
5308 return ParseStatus::NoMatch;
5309 else
5310 FlagsVal = 8; // No flag
5311 }
5312 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
5313 // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
5314 if (Flags == "all" || Flags == "")
5315 Flags = "fc";
5316 for (int i = 0, e = Flags.size(); i != e; ++i) {
5317 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
5318 .Case("c", 1)
5319 .Case("x", 2)
5320 .Case("s", 4)
5321 .Case("f", 8)
5322 .Default(~0U);
5323
5324 // If some specific flag is already set, it means that some letter is
5325 // present more than once, this is not acceptable.
5326 if (Flag == ~0U || (FlagsVal & Flag))
5327 return ParseStatus::NoMatch;
5328 FlagsVal |= Flag;
5329 }
5330 } else // No match for special register.
5331 return ParseStatus::NoMatch;
5332
5333 // Special register without flags is NOT equivalent to "fc" flags.
5334 // NOTE: This is a divergence from gas' behavior. Uncommenting the following
5335 // two lines would enable gas compatibility at the expense of breaking
5336 // round-tripping.
5337 //
5338 // if (!FlagsVal)
5339 // FlagsVal = 0x9;
5340
5341 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
5342 if (SpecReg == "spsr")
5343 FlagsVal |= 16;
5344
5345 Parser.Lex(); // Eat identifier token.
5346 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *this));
5347 return ParseStatus::Success;
5348}
5349
5350/// parseBankedRegOperand - Try to parse a banked register (e.g. "lr_irq") for
5351/// use in the MRS/MSR instructions added to support virtualization.
5352ParseStatus ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
5353 // Don't parse two Banked registers in a row
5354 if (static_cast<ARMOperand &>(*Operands.back()).isBankedReg() ||
5355 static_cast<ARMOperand &>(*Operands.back()).isMSRMask())
5356 return ParseStatus::NoMatch;
5357 MCAsmParser &Parser = getParser();
5358 SMLoc S = Parser.getTok().getLoc();
5359 const AsmToken &Tok = Parser.getTok();
5360 if (!Tok.is(AsmToken::Identifier))
5361 return ParseStatus::NoMatch;
5362 StringRef RegName = Tok.getString();
5363
5364 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.lower());
5365 if (!TheReg)
5366 return ParseStatus::NoMatch;
5367 unsigned Encoding = TheReg->Encoding;
5368
5369 Parser.Lex(); // Eat identifier token.
5370 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S, *this));
5371 return ParseStatus::Success;
5372}
5373
5374// FIXME: Unify the different methods for handling shift operators
5375// and use TableGen matching mechanisms to do the validation rather than
5376// separate parsing paths.
5377ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands,
5378 ARM_AM::ShiftOpc Op, int Low, int High) {
5379 MCAsmParser &Parser = getParser();
5380 auto ShiftCodeOpt = tryParseShiftToken();
5381
5382 if (!ShiftCodeOpt.has_value())
5383 return ParseStatus::NoMatch;
5384 auto ShiftCode = ShiftCodeOpt.value();
5385
5386 // The wrong shift code has been provided. Can error here as has matched the
5387 // correct operand in this case.
5388 if (ShiftCode != Op)
5389 return Error(Parser.getTok().getLoc(),
5390 ARM_AM::getShiftOpcStr(Op) + " operand expected.");
5391
5392 Parser.Lex(); // Eat shift type token.
5393
5394 // There must be a '#' and a shift amount.
5395 if (Parser.getTok().isNot(AsmToken::Hash) &&
5396 Parser.getTok().isNot(AsmToken::Dollar))
5397 return ParseStatus::NoMatch;
5398 Parser.Lex(); // Eat hash token.
5399
5400 const MCExpr *ShiftAmount;
5401 SMLoc Loc = Parser.getTok().getLoc();
5402 SMLoc EndLoc;
5403 if (getParser().parseExpression(ShiftAmount, EndLoc))
5404 return Error(Loc, "illegal expression");
5405 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5406 if (!CE)
5407 return Error(Loc, "constant expression expected");
5408 int Val = CE->getValue();
5409 if (Val < Low || Val > High)
5410 return Error(Loc, "immediate value out of range");
5411
5412 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *this));
5413
5414 return ParseStatus::Success;
5415}
5416
5417ParseStatus ARMAsmParser::parseSetEndImm(OperandVector &Operands) {
5418 MCAsmParser &Parser = getParser();
5419 const AsmToken &Tok = Parser.getTok();
5420 SMLoc S = Tok.getLoc();
5421 if (Tok.isNot(AsmToken::Identifier))
5422 return Error(S, "'be' or 'le' operand expected");
5423 int Val = StringSwitch<int>(Tok.getString().lower())
5424 .Case("be", 1)
5425 .Case("le", 0)
5426 .Default(-1);
5427 Parser.Lex(); // Eat the token.
5428
5429 if (Val == -1)
5430 return Error(S, "'be' or 'le' operand expected");
5431 Operands.push_back(ARMOperand::CreateImm(
5432 MCConstantExpr::create(Val, getContext()), S, Tok.getEndLoc(), *this));
5433 return ParseStatus::Success;
5434}
5435
5436/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
5437/// instructions. Legal values are:
5438/// lsl #n 'n' in [0,31]
5439/// asr #n 'n' in [1,32]
5440/// n == 32 encoded as n == 0.
5441ParseStatus ARMAsmParser::parseShifterImm(OperandVector &Operands) {
5442 MCAsmParser &Parser = getParser();
5443 const AsmToken &Tok = Parser.getTok();
5444 SMLoc S = Tok.getLoc();
5445 if (Tok.isNot(AsmToken::Identifier))
5446 return ParseStatus::NoMatch;
5447 StringRef ShiftName = Tok.getString();
5448 bool isASR;
5449 if (ShiftName == "lsl" || ShiftName == "LSL")
5450 isASR = false;
5451 else if (ShiftName == "asr" || ShiftName == "ASR")
5452 isASR = true;
5453 else
5454 return ParseStatus::NoMatch;
5455 Parser.Lex(); // Eat the operator.
5456
5457 // A '#' and a shift amount.
5458 if (Parser.getTok().isNot(AsmToken::Hash) &&
5459 Parser.getTok().isNot(AsmToken::Dollar))
5460 return Error(Parser.getTok().getLoc(), "'#' expected");
5461 Parser.Lex(); // Eat hash token.
5462 SMLoc ExLoc = Parser.getTok().getLoc();
5463
5464 const MCExpr *ShiftAmount;
5465 SMLoc EndLoc;
5466 if (getParser().parseExpression(ShiftAmount, EndLoc))
5467 return Error(ExLoc, "malformed shift expression");
5468 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5469 if (!CE)
5470 return Error(ExLoc, "shift amount must be an immediate");
5471
5472 int64_t Val = CE->getValue();
5473 if (isASR) {
5474 // Shift amount must be in [1,32]
5475 if (Val < 1 || Val > 32)
5476 return Error(ExLoc, "'asr' shift amount must be in range [1,32]");
5477 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
5478 if (isThumb() && Val == 32)
5479 return Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode");
5480 if (Val == 32) Val = 0;
5481 } else {
5482 // Shift amount must be in [1,32]
5483 if (Val < 0 || Val > 31)
5484 return Error(ExLoc, "'lsr' shift amount must be in range [0,31]");
5485 }
5486
5487 Operands.push_back(
5488 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *this));
5489
5490 return ParseStatus::Success;
5491}
5492
5493/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
5494/// of instructions. Legal values are:
5495/// ror #n 'n' in {0, 8, 16, 24}
5496ParseStatus ARMAsmParser::parseRotImm(OperandVector &Operands) {
5497 MCAsmParser &Parser = getParser();
5498 const AsmToken &Tok = Parser.getTok();
5499 SMLoc S = Tok.getLoc();
5500 if (Tok.isNot(AsmToken::Identifier))
5501 return ParseStatus::NoMatch;
5502 StringRef ShiftName = Tok.getString();
5503 if (ShiftName != "ror" && ShiftName != "ROR")
5504 return ParseStatus::NoMatch;
5505 Parser.Lex(); // Eat the operator.
5506
5507 // A '#' and a rotate amount.
5508 if (Parser.getTok().isNot(AsmToken::Hash) &&
5509 Parser.getTok().isNot(AsmToken::Dollar))
5510 return Error(Parser.getTok().getLoc(), "'#' expected");
5511 Parser.Lex(); // Eat hash token.
5512 SMLoc ExLoc = Parser.getTok().getLoc();
5513
5514 const MCExpr *ShiftAmount;
5515 SMLoc EndLoc;
5516 if (getParser().parseExpression(ShiftAmount, EndLoc))
5517 return Error(ExLoc, "malformed rotate expression");
5518 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
5519 if (!CE)
5520 return Error(ExLoc, "rotate amount must be an immediate");
5521
5522 int64_t Val = CE->getValue();
5523 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
5524 // normally, zero is represented in asm by omitting the rotate operand
5525 // entirely.
5526 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5527 return Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24");
5528
5529 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *this));
5530
5531 return ParseStatus::Success;
5532}
5533
5534ParseStatus ARMAsmParser::parseModImm(OperandVector &Operands) {
5535 MCAsmParser &Parser = getParser();
5536 AsmLexer &Lexer = getLexer();
5537 int64_t Imm1, Imm2;
5538
5539 SMLoc S = Parser.getTok().getLoc();
5540
5541 // 1) A mod_imm operand can appear in the place of a register name:
5542 // add r0, #mod_imm
5543 // add r0, r0, #mod_imm
5544 // to correctly handle the latter, we bail out as soon as we see an
5545 // identifier.
5546 //
5547 // 2) Similarly, we do not want to parse into complex operands:
5548 // mov r0, #mod_imm
5549 // mov r0, :lower16:(_foo)
5550 if (Parser.getTok().is(AsmToken::Identifier) ||
5551 Parser.getTok().is(AsmToken::Colon))
5552 return ParseStatus::NoMatch;
5553
5554 // Hash (dollar) is optional as per the ARMARM
5555 if (Parser.getTok().is(AsmToken::Hash) ||
5556 Parser.getTok().is(AsmToken::Dollar)) {
5557 // Avoid parsing into complex operands (#:)
5558 if (Lexer.peekTok().is(AsmToken::Colon))
5559 return ParseStatus::NoMatch;
5560
5561 // Eat the hash (dollar)
5562 Parser.Lex();
5563 }
5564
5565 SMLoc Sx1, Ex1;
5566 Sx1 = Parser.getTok().getLoc();
5567 const MCExpr *Imm1Exp;
5568 if (getParser().parseExpression(Imm1Exp, Ex1))
5569 return Error(Sx1, "malformed expression");
5570
5571 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
5572
5573 if (CE) {
5574 // Immediate must fit within 32-bits
5575 Imm1 = CE->getValue();
5576 int Enc = ARM_AM::getSOImmVal(Imm1);
5577 if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) {
5578 // We have a match!
5579 Operands.push_back(ARMOperand::CreateModImm(
5580 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *this));
5581 return ParseStatus::Success;
5582 }
5583
5584 // We have parsed an immediate which is not for us, fallback to a plain
5585 // immediate. This can happen for instruction aliases. For an example,
5586 // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
5587 // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
5588 // instruction with a mod_imm operand. The alias is defined such that the
5589 // parser method is shared, that's why we have to do this here.
5590 if (Parser.getTok().is(AsmToken::EndOfStatement)) {
5591 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this));
5592 return ParseStatus::Success;
5593 }
5594 } else {
5595 // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
5596 // MCFixup). Fallback to a plain immediate.
5597 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *this));
5598 return ParseStatus::Success;
5599 }
5600
5601 // From this point onward, we expect the input to be a (#bits, #rot) pair
5602 if (Parser.getTok().isNot(AsmToken::Comma))
5603 return Error(Sx1,
5604 "expected modified immediate operand: #[0, 255], #even[0-30]");
5605
5606 if (Imm1 & ~0xFF)
5607 return Error(Sx1, "immediate operand must a number in the range [0, 255]");
5608
5609 // Eat the comma
5610 Parser.Lex();
5611
5612 // Repeat for #rot
5613 SMLoc Sx2, Ex2;
5614 Sx2 = Parser.getTok().getLoc();
5615
5616 // Eat the optional hash (dollar)
5617 if (Parser.getTok().is(AsmToken::Hash) ||
5618 Parser.getTok().is(AsmToken::Dollar))
5619 Parser.Lex();
5620
5621 const MCExpr *Imm2Exp;
5622 if (getParser().parseExpression(Imm2Exp, Ex2))
5623 return Error(Sx2, "malformed expression");
5624
5625 CE = dyn_cast<MCConstantExpr>(Imm2Exp);
5626
5627 if (CE) {
5628 Imm2 = CE->getValue();
5629 if (!(Imm2 & ~0x1E)) {
5630 // We have a match!
5631 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *this));
5632 return ParseStatus::Success;
5633 }
5634 return Error(Sx2,
5635 "immediate operand must an even number in the range [0, 30]");
5636 } else {
5637 return Error(Sx2, "constant expression expected");
5638 }
5639}
5640
5641ParseStatus ARMAsmParser::parseBitfield(OperandVector &Operands) {
5642 MCAsmParser &Parser = getParser();
5643 SMLoc S = Parser.getTok().getLoc();
5644 // The bitfield descriptor is really two operands, the LSB and the width.
5645 if (Parser.getTok().isNot(AsmToken::Hash) &&
5646 Parser.getTok().isNot(AsmToken::Dollar))
5647 return ParseStatus::NoMatch;
5648 Parser.Lex(); // Eat hash token.
5649
5650 const MCExpr *LSBExpr;
5651 SMLoc E = Parser.getTok().getLoc();
5652 if (getParser().parseExpression(LSBExpr))
5653 return Error(E, "malformed immediate expression");
5654 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
5655 if (!CE)
5656 return Error(E, "'lsb' operand must be an immediate");
5657
5658 int64_t LSB = CE->getValue();
5659 // The LSB must be in the range [0,31]
5660 if (LSB < 0 || LSB > 31)
5661 return Error(E, "'lsb' operand must be in the range [0,31]");
5662 E = Parser.getTok().getLoc();
5663
5664 // Expect another immediate operand.
5665 if (Parser.getTok().isNot(AsmToken::Comma))
5666 return Error(Parser.getTok().getLoc(), "too few operands");
5667 Parser.Lex(); // Eat hash token.
5668 if (Parser.getTok().isNot(AsmToken::Hash) &&
5669 Parser.getTok().isNot(AsmToken::Dollar))
5670 return Error(Parser.getTok().getLoc(), "'#' expected");
5671 Parser.Lex(); // Eat hash token.
5672
5673 const MCExpr *WidthExpr;
5674 SMLoc EndLoc;
5675 if (getParser().parseExpression(WidthExpr, EndLoc))
5676 return Error(E, "malformed immediate expression");
5677 CE = dyn_cast<MCConstantExpr>(WidthExpr);
5678 if (!CE)
5679 return Error(E, "'width' operand must be an immediate");
5680
5681 int64_t Width = CE->getValue();
5682 // The LSB must be in the range [1,32-lsb]
5683 if (Width < 1 || Width > 32 - LSB)
5684 return Error(E, "'width' operand must be in the range [1,32-lsb]");
5685
5686 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *this));
5687
5688 return ParseStatus::Success;
5689}
5690
5691ParseStatus ARMAsmParser::parsePostIdxReg(OperandVector &Operands) {
5692 // Check for a post-index addressing register operand. Specifically:
5693 // postidx_reg := '+' register {, shift}
5694 // | '-' register {, shift}
5695 // | register {, shift}
5696
5697 // This method must return ParseStatus::NoMatch without consuming any tokens
5698 // in the case where there is no match, as other alternatives take other
5699 // parse methods.
5700 MCAsmParser &Parser = getParser();
5701 AsmToken Tok = Parser.getTok();
5702 SMLoc S = Tok.getLoc();
5703 bool haveEaten = false;
5704 bool isAdd = true;
5705 if (Tok.is(AsmToken::Plus)) {
5706 Parser.Lex(); // Eat the '+' token.
5707 haveEaten = true;
5708 } else if (Tok.is(AsmToken::Minus)) {
5709 Parser.Lex(); // Eat the '-' token.
5710 isAdd = false;
5711 haveEaten = true;
5712 }
5713
5714 SMLoc E = Parser.getTok().getEndLoc();
5715 MCRegister Reg = tryParseRegister();
5716 if (!Reg) {
5717 if (!haveEaten)
5718 return ParseStatus::NoMatch;
5719 return Error(Parser.getTok().getLoc(), "register expected");
5720 }
5721
5723 unsigned ShiftImm = 0;
5724 if (Parser.getTok().is(AsmToken::Comma)) {
5725 Parser.Lex(); // Eat the ','.
5726 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5727 return ParseStatus::Failure;
5728
5729 // FIXME: Only approximates end...may include intervening whitespace.
5730 E = Parser.getTok().getLoc();
5731 }
5732
5733 Operands.push_back(
5734 ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, ShiftImm, S, E, *this));
5735
5736 return ParseStatus::Success;
5737}
5738
5739ParseStatus ARMAsmParser::parseAM3Offset(OperandVector &Operands) {
5740 // Check for a post-index addressing register operand. Specifically:
5741 // am3offset := '+' register
5742 // | '-' register
5743 // | register
5744 // | # imm
5745 // | # + imm
5746 // | # - imm
5747
5748 // This method must return ParseStatus::NoMatch without consuming any tokens
5749 // in the case where there is no match, as other alternatives take other
5750 // parse methods.
5751 MCAsmParser &Parser = getParser();
5752 AsmToken Tok = Parser.getTok();
5753 SMLoc S = Tok.getLoc();
5754
5755 // Do immediates first, as we always parse those if we have a '#'.
5756 if (Parser.getTok().is(AsmToken::Hash) ||
5757 Parser.getTok().is(AsmToken::Dollar)) {
5758 Parser.Lex(); // Eat '#' or '$'.
5759 // Explicitly look for a '-', as we need to encode negative zero
5760 // differently.
5761 bool isNegative = Parser.getTok().is(AsmToken::Minus);
5762 const MCExpr *Offset;
5763 SMLoc E;
5764 if (getParser().parseExpression(Offset, E))
5765 return ParseStatus::Failure;
5766 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
5767 if (!CE)
5768 return Error(S, "constant expression expected");
5769 // Negative zero is encoded as the flag value
5770 // std::numeric_limits<int32_t>::min().
5771 int32_t Val = CE->getValue();
5772 if (isNegative && Val == 0)
5773 Val = std::numeric_limits<int32_t>::min();
5774
5775 Operands.push_back(ARMOperand::CreateImm(
5776 MCConstantExpr::create(Val, getContext()), S, E, *this));
5777
5778 return ParseStatus::Success;
5779 }
5780
5781 bool haveEaten = false;
5782 bool isAdd = true;
5783 if (Tok.is(AsmToken::Plus)) {
5784 Parser.Lex(); // Eat the '+' token.
5785 haveEaten = true;
5786 } else if (Tok.is(AsmToken::Minus)) {
5787 Parser.Lex(); // Eat the '-' token.
5788 isAdd = false;
5789 haveEaten = true;
5790 }
5791
5792 Tok = Parser.getTok();
5793 MCRegister Reg = tryParseRegister();
5794 if (!Reg) {
5795 if (!haveEaten)
5796 return ParseStatus::NoMatch;
5797 return Error(Tok.getLoc(), "register expected");
5798 }
5799
5800 Operands.push_back(ARMOperand::CreatePostIdxReg(
5801 Reg, isAdd, ARM_AM::no_shift, 0, S, Tok.getEndLoc(), *this));
5802
5803 return ParseStatus::Success;
5804}
5805
5806// Finds the index of the first CondCode operator, if there is none returns 0
5807unsigned findCondCodeInd(const OperandVector &Operands,
5808 unsigned MnemonicOpsEndInd) {
5809 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
5810 auto Op = static_cast<ARMOperand &>(*Operands[I]);
5811 if (Op.isCondCode())
5812 return I;
5813 }
5814 return 0;
5815}
5816
5817unsigned findCCOutInd(const OperandVector &Operands,
5818 unsigned MnemonicOpsEndInd) {
5819 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
5820 auto Op = static_cast<ARMOperand &>(*Operands[I]);
5821 if (Op.isCCOut())
5822 return I;
5823 }
5824 return 0;
5825}
5826
5827/// Convert parsed operands to MCInst. Needed here because this instruction
5828/// only has two register operands, but multiplication is commutative so
5829/// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN".
5830void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5831 const OperandVector &Operands) {
5832 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5833 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5834 unsigned CondOutI = findCCOutInd(Operands, MnemonicOpsEndInd);
5835
5836 // 2 operand form
5837 unsigned RegRd = MnemonicOpsEndInd;
5838 unsigned RegRn = MnemonicOpsEndInd + 1;
5839 unsigned RegRm = MnemonicOpsEndInd;
5840
5841 if (Operands.size() == MnemonicOpsEndInd + 3) {
5842 // If we have a three-operand form, make sure to set Rn to be the operand
5843 // that isn't the same as Rd.
5844 if (((ARMOperand &)*Operands[RegRd]).getReg() ==
5845 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1]).getReg()) {
5846 RegRn = MnemonicOpsEndInd + 2;
5847 RegRm = MnemonicOpsEndInd + 1;
5848 } else {
5849 RegRn = MnemonicOpsEndInd + 1;
5850 RegRm = MnemonicOpsEndInd + 2;
5851 }
5852 }
5853
5854 // Rd
5855 ((ARMOperand &)*Operands[RegRd]).addRegOperands(Inst, 1);
5856 // CCOut
5857 if (CondOutI != 0) {
5858 ((ARMOperand &)*Operands[CondOutI]).addCCOutOperands(Inst, 1);
5859 } else {
5860 ARMOperand Op =
5861 *ARMOperand::CreateCCOut(0, Operands[0]->getEndLoc(), *this);
5862 Op.addCCOutOperands(Inst, 1);
5863 }
5864 // Rn
5865 ((ARMOperand &)*Operands[RegRn]).addRegOperands(Inst, 1);
5866 // Rm
5867 ((ARMOperand &)*Operands[RegRm]).addRegOperands(Inst, 1);
5868
5869 // Cond code
5870 if (CondI != 0) {
5871 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5872 } else {
5873 ARMOperand Op = *ARMOperand::CreateCondCode(
5874 llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this);
5875 Op.addCondCodeOperands(Inst, 2);
5876 }
5877}
5878
5879void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5880 const OperandVector &Operands) {
5881 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5882 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5883 unsigned Cond =
5884 (CondI == 0 ? ARMCC::AL
5885 : static_cast<ARMOperand &>(*Operands[CondI]).getCondCode());
5886
5887 // first decide whether or not the branch should be conditional
5888 // by looking at it's location relative to an IT block
5889 if(inITBlock()) {
5890 // inside an IT block we cannot have any conditional branches. any
5891 // such instructions needs to be converted to unconditional form
5892 switch(Inst.getOpcode()) {
5893 case ARM::tBcc: Inst.setOpcode(ARM::tB); break;
5894 case ARM::t2Bcc: Inst.setOpcode(ARM::t2B); break;
5895 }
5896 } else {
5897 switch(Inst.getOpcode()) {
5898 case ARM::tB:
5899 case ARM::tBcc:
5900 Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc);
5901 break;
5902 case ARM::t2B:
5903 case ARM::t2Bcc:
5904 Inst.setOpcode(Cond == ARMCC::AL ? ARM::t2B : ARM::t2Bcc);
5905 break;
5906 }
5907 }
5908
5909 // now decide on encoding size based on branch target range
5910 switch(Inst.getOpcode()) {
5911 // classify tB as either t2B or t1B based on range of immediate operand
5912 case ARM::tB: {
5913 ARMOperand &op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
5914 if (!op.isSignedOffset<11, 1>() && isThumb() && hasV8MBaseline())
5915 Inst.setOpcode(ARM::t2B);
5916 break;
5917 }
5918 // classify tBcc as either t2Bcc or t1Bcc based on range of immediate operand
5919 case ARM::tBcc: {
5920 ARMOperand &op = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
5921 if (!op.isSignedOffset<8, 1>() && isThumb() && hasV8MBaseline())
5922 Inst.setOpcode(ARM::t2Bcc);
5923 break;
5924 }
5925 }
5926 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5927 if (CondI != 0) {
5928 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5929 } else {
5930 ARMOperand Op = *ARMOperand::CreateCondCode(
5931 llvm::ARMCC::AL, Operands[0]->getEndLoc(), *this);
5932 Op.addCondCodeOperands(Inst, 2);
5933 }
5934}
5935
5936void ARMAsmParser::cvtMVEVMOVQtoDReg(
5937 MCInst &Inst, const OperandVector &Operands) {
5938
5939 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
5940 unsigned CondI = findCondCodeInd(Operands, MnemonicOpsEndInd);
5941
5942 // mnemonic, condition code, Rt, Rt2, Qd, idx, Qd again, idx2
5943 assert(Operands.size() == MnemonicOpsEndInd + 6);
5944
5945 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1); // Rt
5946 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1])
5947 .addRegOperands(Inst, 1); // Rt2
5948 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 2])
5949 .addRegOperands(Inst, 1); // Qd
5950 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 3])
5951 .addMVEPairVectorIndexOperands(Inst, 1); // idx
5952 // skip second copy of Qd in Operands[6]
5953 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 5])
5954 .addMVEPairVectorIndexOperands(Inst, 1); // idx2
5955 if (CondI != 0) {
5956 ((ARMOperand &)*Operands[CondI])
5957 .addCondCodeOperands(Inst, 2); // condition code
5958 } else {
5959 ARMOperand Op =
5960 *ARMOperand::CreateCondCode(ARMCC::AL, Operands[0]->getEndLoc(), *this);
5961 Op.addCondCodeOperands(Inst, 2);
5962 }
5963}
5964
5965/// Parse an ARM memory expression, return false if successful else return true
5966/// or an error. The first token must be a '[' when called.
5967bool ARMAsmParser::parseMemory(OperandVector &Operands) {
5968 MCAsmParser &Parser = getParser();
5969 SMLoc S, E;
5970 if (Parser.getTok().isNot(AsmToken::LBrac))
5971 return TokError("Token is not a Left Bracket");
5972 S = Parser.getTok().getLoc();
5973 Parser.Lex(); // Eat left bracket token.
5974
5975 const AsmToken &BaseRegTok = Parser.getTok();
5976 MCRegister BaseReg = tryParseRegister();
5977 if (!BaseReg)
5978 return Error(BaseRegTok.getLoc(), "register expected");
5979
5980 // The next token must either be a comma, a colon or a closing bracket.
5981 const AsmToken &Tok = Parser.getTok();
5982 if (!Tok.is(AsmToken::Colon) && !Tok.is(AsmToken::Comma) &&
5983 !Tok.is(AsmToken::RBrac))
5984 return Error(Tok.getLoc(), "malformed memory operand");
5985
5986 if (Tok.is(AsmToken::RBrac)) {
5987 E = Tok.getEndLoc();
5988 Parser.Lex(); // Eat right bracket token.
5989
5990 Operands.push_back(ARMOperand::CreateMem(
5991 BaseReg, nullptr, 0, ARM_AM::no_shift, 0, 0, false, S, E, *this));
5992
5993 // If there's a pre-indexing writeback marker, '!', just add it as a token
5994 // operand. It's rather odd, but syntactically valid.
5995 if (Parser.getTok().is(AsmToken::Exclaim)) {
5996 Operands.push_back(
5997 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
5998 Parser.Lex(); // Eat the '!'.
5999 }
6000
6001 return false;
6002 }
6003
6004 assert((Tok.is(AsmToken::Colon) || Tok.is(AsmToken::Comma)) &&
6005 "Lost colon or comma in memory operand?!");
6006 if (Tok.is(AsmToken::Comma)) {
6007 Parser.Lex(); // Eat the comma.
6008 }
6009
6010 // If we have a ':', it's an alignment specifier.
6011 if (Parser.getTok().is(AsmToken::Colon)) {
6012 Parser.Lex(); // Eat the ':'.
6013 E = Parser.getTok().getLoc();
6014 SMLoc AlignmentLoc = Tok.getLoc();
6015
6016 const MCExpr *Expr;
6017 if (getParser().parseExpression(Expr))
6018 return true;
6019
6020 // The expression has to be a constant. Memory references with relocations
6021 // don't come through here, as they use the <label> forms of the relevant
6022 // instructions.
6023 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
6024 if (!CE)
6025 return Error (E, "constant expression expected");
6026
6027 unsigned Align = 0;
6028 switch (CE->getValue()) {
6029 default:
6030 return Error(E,
6031 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6032 case 16: Align = 2; break;
6033 case 32: Align = 4; break;
6034 case 64: Align = 8; break;
6035 case 128: Align = 16; break;
6036 case 256: Align = 32; break;
6037 }
6038
6039 // Now we should have the closing ']'
6040 if (Parser.getTok().isNot(AsmToken::RBrac))
6041 return Error(Parser.getTok().getLoc(), "']' expected");
6042 E = Parser.getTok().getEndLoc();
6043 Parser.Lex(); // Eat right bracket token.
6044
6045 // Don't worry about range checking the value here. That's handled by
6046 // the is*() predicates.
6047 Operands.push_back(ARMOperand::CreateMem(BaseReg, nullptr, 0,
6048 ARM_AM::no_shift, 0, Align, false,
6049 S, E, *this, AlignmentLoc));
6050
6051 // If there's a pre-indexing writeback marker, '!', just add it as a token
6052 // operand.
6053 if (Parser.getTok().is(AsmToken::Exclaim)) {
6054 Operands.push_back(
6055 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6056 Parser.Lex(); // Eat the '!'.
6057 }
6058
6059 return false;
6060 }
6061
6062 // If we have a '#' or '$', it's an immediate offset, else assume it's a
6063 // register offset. Be friendly and also accept a plain integer or expression
6064 // (without a leading hash) for gas compatibility.
6065 if (Parser.getTok().is(AsmToken::Hash) ||
6066 Parser.getTok().is(AsmToken::Dollar) ||
6067 Parser.getTok().is(AsmToken::LParen) ||
6068 Parser.getTok().is(AsmToken::Integer)) {
6069 if (Parser.getTok().is(AsmToken::Hash) ||
6070 Parser.getTok().is(AsmToken::Dollar))
6071 Parser.Lex(); // Eat '#' or '$'
6072 E = Parser.getTok().getLoc();
6073
6074 bool isNegative = getParser().getTok().is(AsmToken::Minus);
6075 const MCExpr *Offset, *AdjustedOffset;
6076 if (getParser().parseExpression(Offset))
6077 return true;
6078
6079 if (const auto *CE = dyn_cast<MCConstantExpr>(Offset)) {
6080 // If the constant was #-0, represent it as
6081 // std::numeric_limits<int32_t>::min().
6082 int32_t Val = CE->getValue();
6083 if (isNegative && Val == 0)
6084 CE = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
6085 getContext());
6086 // Don't worry about range checking the value here. That's handled by
6087 // the is*() predicates.
6088 AdjustedOffset = CE;
6089 } else
6090 AdjustedOffset = Offset;
6091 Operands.push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6092 ARM_AM::no_shift, 0, 0, false, S,
6093 E, *this));
6094
6095 // Now we should have the closing ']'
6096 if (Parser.getTok().isNot(AsmToken::RBrac))
6097 return Error(Parser.getTok().getLoc(), "']' expected");
6098 E = Parser.getTok().getEndLoc();
6099 Parser.Lex(); // Eat right bracket token.
6100
6101 // If there's a pre-indexing writeback marker, '!', just add it as a token
6102 // operand.
6103 if (Parser.getTok().is(AsmToken::Exclaim)) {
6104 Operands.push_back(
6105 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6106 Parser.Lex(); // Eat the '!'.
6107 }
6108
6109 return false;
6110 }
6111
6112 // The register offset is optionally preceded by a '+' or '-'
6113 bool isNegative = false;
6114 if (Parser.getTok().is(AsmToken::Minus)) {
6115 isNegative = true;
6116 Parser.Lex(); // Eat the '-'.
6117 } else if (Parser.getTok().is(AsmToken::Plus)) {
6118 // Nothing to do.
6119 Parser.Lex(); // Eat the '+'.
6120 }
6121
6122 E = Parser.getTok().getLoc();
6123 MCRegister OffsetReg = tryParseRegister();
6124 if (!OffsetReg)
6125 return Error(E, "register expected");
6126
6127 // If there's a shift operator, handle it.
6129 unsigned ShiftImm = 0;
6130 if (Parser.getTok().is(AsmToken::Comma)) {
6131 Parser.Lex(); // Eat the ','.
6132 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6133 return true;
6134 }
6135
6136 // Now we should have the closing ']'
6137 if (Parser.getTok().isNot(AsmToken::RBrac))
6138 return Error(Parser.getTok().getLoc(), "']' expected");
6139 E = Parser.getTok().getEndLoc();
6140 Parser.Lex(); // Eat right bracket token.
6141
6142 Operands.push_back(ARMOperand::CreateMem(BaseReg, nullptr, OffsetReg,
6143 ShiftType, ShiftImm, 0, isNegative,
6144 S, E, *this));
6145
6146 // If there's a pre-indexing writeback marker, '!', just add it as a token
6147 // operand.
6148 if (Parser.getTok().is(AsmToken::Exclaim)) {
6149 Operands.push_back(
6150 ARMOperand::CreateToken("!", Parser.getTok().getLoc(), *this));
6151 Parser.Lex(); // Eat the '!'.
6152 }
6153
6154 return false;
6155}
6156
6157/// parseMemRegOffsetShift - one of these two:
6158/// ( lsl | lsr | asr | ror ) , # shift_amount
6159/// rrx
6160/// return true if it parses a shift otherwise it returns false.
6161bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
6162 unsigned &Amount) {
6163 MCAsmParser &Parser = getParser();
6164 SMLoc Loc = Parser.getTok().getLoc();
6165 const AsmToken &Tok = Parser.getTok();
6166 if (Tok.isNot(AsmToken::Identifier))
6167 return Error(Loc, "illegal shift operator");
6168 StringRef ShiftName = Tok.getString();
6169 if (ShiftName == "lsl" || ShiftName == "LSL" ||
6170 ShiftName == "asl" || ShiftName == "ASL")
6171 St = ARM_AM::lsl;
6172 else if (ShiftName == "lsr" || ShiftName == "LSR")
6173 St = ARM_AM::lsr;
6174 else if (ShiftName == "asr" || ShiftName == "ASR")
6175 St = ARM_AM::asr;
6176 else if (ShiftName == "ror" || ShiftName == "ROR")
6177 St = ARM_AM::ror;
6178 else if (ShiftName == "rrx" || ShiftName == "RRX")
6179 St = ARM_AM::rrx;
6180 else if (ShiftName == "uxtw" || ShiftName == "UXTW")
6181 St = ARM_AM::uxtw;
6182 else
6183 return Error(Loc, "illegal shift operator");
6184 Parser.Lex(); // Eat shift type token.
6185
6186 // rrx stands alone.
6187 Amount = 0;
6188 if (St != ARM_AM::rrx) {
6189 Loc = Parser.getTok().getLoc();
6190 // A '#' and a shift amount.
6191 const AsmToken &HashTok = Parser.getTok();
6192 if (HashTok.isNot(AsmToken::Hash) &&
6193 HashTok.isNot(AsmToken::Dollar))
6194 return Error(HashTok.getLoc(), "'#' expected");
6195 Parser.Lex(); // Eat hash token.
6196
6197 const MCExpr *Expr;
6198 if (getParser().parseExpression(Expr))
6199 return true;
6200 // Range check the immediate.
6201 // lsl, ror: 0 <= imm <= 31
6202 // lsr, asr: 0 <= imm <= 32
6203 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
6204 if (!CE)
6205 return Error(Loc, "shift amount must be an immediate");
6206 int64_t Imm = CE->getValue();
6207 if (Imm < 0 ||
6208 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
6209 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
6210 return Error(Loc, "immediate shift value out of range");
6211 // If <ShiftTy> #0, turn it into a no_shift.
6212 if (Imm == 0)
6213 St = ARM_AM::lsl;
6214 // For consistency, treat lsr #32 and asr #32 as having immediate value 0.
6215 if (Imm == 32)
6216 Imm = 0;
6217 Amount = Imm;
6218 }
6219
6220 return false;
6221}
6222
6223/// parseFPImm - A floating point immediate expression operand.
6224ParseStatus ARMAsmParser::parseFPImm(OperandVector &Operands) {
6225 LLVM_DEBUG(dbgs() << "PARSE FPImm, Ops: " << Operands.size());
6226
6227 MCAsmParser &Parser = getParser();
6228 // Anything that can accept a floating point constant as an operand
6229 // needs to go through here, as the regular parseExpression is
6230 // integer only.
6231 //
6232 // This routine still creates a generic Immediate operand, containing
6233 // a bitcast of the 64-bit floating point value. The various operands
6234 // that accept floats can check whether the value is valid for them
6235 // via the standard is*() predicates.
6236
6237 SMLoc S = Parser.getTok().getLoc();
6238
6239 if (Parser.getTok().isNot(AsmToken::Hash) &&
6240 Parser.getTok().isNot(AsmToken::Dollar))
6241 return ParseStatus::NoMatch;
6242
6243 // Disambiguate the VMOV forms that can accept an FP immediate.
6244 // vmov.f32 <sreg>, #imm
6245 // vmov.f64 <dreg>, #imm
6246 // vmov.f32 <dreg>, #imm @ vector f32x2
6247 // vmov.f32 <qreg>, #imm @ vector f32x4
6248 //
6249 // There are also the NEON VMOV instructions which expect an
6250 // integer constant. Make sure we don't try to parse an FPImm
6251 // for these:
6252 // vmov.i{8|16|32|64} <dreg|qreg>, #imm
6253
6254 bool isVmovf = false;
6255 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
6256 for (unsigned I = 1; I < MnemonicOpsEndInd; ++I) {
6257 ARMOperand &TyOp = static_cast<ARMOperand &>(*Operands[I]);
6258 if (TyOp.isToken() &&
6259 (TyOp.getToken() == ".f32" || TyOp.getToken() == ".f64" ||
6260 TyOp.getToken() == ".f16")) {
6261 isVmovf = true;
6262 break;
6263 }
6264 }
6265
6266 ARMOperand &Mnemonic = static_cast<ARMOperand &>(*Operands[0]);
6267 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() == "fconstd" ||
6268 Mnemonic.getToken() == "fconsts");
6269 if (!(isVmovf || isFconst))
6270 return ParseStatus::NoMatch;
6271
6272 Parser.Lex(); // Eat '#' or '$'.
6273
6274 // Handle negation, as that still comes through as a separate token.
6275 bool isNegative = false;
6276 if (Parser.getTok().is(AsmToken::Minus)) {
6277 isNegative = true;
6278 Parser.Lex();
6279 }
6280 const AsmToken &Tok = Parser.getTok();
6281 SMLoc Loc = Tok.getLoc();
6282 if (Tok.is(AsmToken::Real) && isVmovf) {
6283 APFloat RealVal(APFloat::IEEEsingle(), Tok.getString());
6284 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
6285 // If we had a '-' in front, toggle the sign bit.
6286 IntVal ^= (uint64_t)isNegative << 31;
6287 Parser.Lex(); // Eat the token.
6288 Operands.push_back(
6289 ARMOperand::CreateImm(MCConstantExpr::create(IntVal, getContext()), S,
6290 Parser.getTok().getLoc(), *this));
6291 return ParseStatus::Success;
6292 }
6293 // Also handle plain integers. Instructions which allow floating point
6294 // immediates also allow a raw encoded 8-bit value.
6295 if (Tok.is(AsmToken::Integer) && isFconst) {
6296 int64_t Val = Tok.getIntVal();
6297 Parser.Lex(); // Eat the token.
6298 if (Val > 255 || Val < 0)
6299 return Error(Loc, "encoded floating point value out of range");
6300 float RealVal = ARM_AM::getFPImmFloat(Val);
6301 Val = APFloat(RealVal).bitcastToAPInt().getZExtValue();
6302
6303 Operands.push_back(
6304 ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S,
6305 Parser.getTok().getLoc(), *this));
6306 return ParseStatus::Success;
6307 }
6308
6309 return Error(Loc, "invalid floating point immediate");
6310}
6311
6312/// Parse a arm instruction operand. For now this parses the operand regardless
6313/// of the mnemonic.
6314bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6315 MCAsmParser &Parser = getParser();
6316 SMLoc S, E;
6317
6318 // Check if the current operand has a custom associated parser, if so, try to
6319 // custom parse the operand, or fallback to the general approach.
6320 ParseStatus ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6321 if (ResTy.isSuccess())
6322 return false;
6323 // If there wasn't a custom match, try the generic matcher below. Otherwise,
6324 // there was a match, but an error occurred, in which case, just return that
6325 // the operand parsing failed.
6326 if (ResTy.isFailure())
6327 return true;
6328
6329 switch (getLexer().getKind()) {
6330 default:
6331 Error(Parser.getTok().getLoc(), "unexpected token in operand");
6332 return true;
6333 case AsmToken::Identifier: {
6334 // If we've seen a branch mnemonic, the next operand must be a label. This
6335 // is true even if the label is a register name. So "br r1" means branch to
6336 // label "r1".
6337 bool ExpectLabel = Mnemonic == "b" || Mnemonic == "bl";
6338 if (!ExpectLabel) {
6339 if (!tryParseRegisterWithWriteBack(Operands))
6340 return false;
6341 int Res = tryParseShiftRegister(Operands);
6342 if (Res == 0) // success
6343 return false;
6344 else if (Res == -1) // irrecoverable error
6345 return true;
6346 // If this is VMRS, check for the apsr_nzcv operand.
6347 if (Mnemonic == "vmrs" &&
6348 Parser.getTok().getString().equals_insensitive("apsr_nzcv")) {
6349 S = Parser.getTok().getLoc();
6350 Parser.Lex();
6351 Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S, *this));
6352 return false;
6353 }
6354 }
6355
6356 // Fall though for the Identifier case that is not a register or a
6357 // special name.
6358 [[fallthrough]];
6359 }
6360 case AsmToken::LParen: // parenthesized expressions like (_strcmp-4)
6361 case AsmToken::Integer: // things like 1f and 2b as a branch targets
6362 case AsmToken::String: // quoted label names.
6363 case AsmToken::Dot: { // . as a branch target
6364 // This was not a register so parse other operands that start with an
6365 // identifier (like labels) as expressions and create them as immediates.
6366 const MCExpr *IdVal;
6367 S = Parser.getTok().getLoc();
6368 if (getParser().parseExpression(IdVal))
6369 return true;
6370 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6371 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E, *this));
6372 return false;
6373 }
6374 case AsmToken::LBrac:
6375 return parseMemory(Operands);
6376 case AsmToken::LCurly: {
6377 bool IsLazyLoadStore = Mnemonic == "vlldm" || Mnemonic == "vlstm";
6378 bool IsVSCCLRM = Mnemonic == "vscclrm";
6379 return parseRegisterList(Operands, !Mnemonic.starts_with("clr"), false,
6380 IsLazyLoadStore, IsVSCCLRM);
6381 }
6382 case AsmToken::Dollar:
6383 case AsmToken::Hash: {
6384 // #42 -> immediate
6385 // $ 42 -> immediate
6386 // $foo -> symbol name
6387 // $42 -> symbol name
6388 S = Parser.getTok().getLoc();
6389
6390 // Favor the interpretation of $-prefixed operands as symbol names.
6391 // Cases where immediates are explicitly expected are handled by their
6392 // specific ParseMethod implementations.
6393 auto AdjacentToken = getLexer().peekTok(/*ShouldSkipSpace=*/false);
6394 bool ExpectIdentifier = Parser.getTok().is(AsmToken::Dollar) &&
6395 (AdjacentToken.is(AsmToken::Identifier) ||
6396 AdjacentToken.is(AsmToken::Integer));
6397 if (!ExpectIdentifier) {
6398 // Token is not part of identifier. Drop leading $ or # before parsing
6399 // expression.
6400 Parser.Lex();
6401 }
6402
6403 if (Parser.getTok().isNot(AsmToken::Colon)) {
6404 bool IsNegative = Parser.getTok().is(AsmToken::Minus);
6405 const MCExpr *ImmVal;
6406 if (getParser().parseExpression(ImmVal))
6407 return true;
6408 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
6409 if (CE) {
6410 int32_t Val = CE->getValue();
6411 if (IsNegative && Val == 0)
6412 ImmVal = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
6413 getContext());
6414 }
6415 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6416 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E, *this));
6417
6418 // There can be a trailing '!' on operands that we want as a separate
6419 // '!' Token operand. Handle that here. For example, the compatibility
6420 // alias for 'srsdb sp!, #imm' is 'srsdb #imm!'.
6421 if (Parser.getTok().is(AsmToken::Exclaim)) {
6422 Operands.push_back(ARMOperand::CreateToken(
6423 Parser.getTok().getString(), Parser.getTok().getLoc(), *this));
6424 Parser.Lex(); // Eat exclaim token
6425 }
6426 return false;
6427 }
6428 // w/ a ':' after the '#', it's just like a plain ':'.
6429 [[fallthrough]];
6430 }
6431 case AsmToken::Colon: {
6432 S = Parser.getTok().getLoc();
6433 // ":lower16:", ":upper16:", ":lower0_7:", ":lower8_15:", ":upper0_7:" and
6434 // ":upper8_15:", expression prefixes
6435 // FIXME: Check it's an expression prefix,
6436 // e.g. (FOO - :lower16:BAR) isn't legal.
6437 ARM::Specifier Spec;
6438 if (parsePrefix(Spec))
6439 return true;
6440
6441 const MCExpr *SubExprVal;
6442 if (getParser().parseExpression(SubExprVal))
6443 return true;
6444
6445 const auto *ExprVal =
6446 MCSpecifierExpr::create(SubExprVal, Spec, getContext(), S);
6447 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6448 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E, *this));
6449 return false;
6450 }
6451 case AsmToken::Equal: {
6452 S = Parser.getTok().getLoc();
6453 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
6454 return Error(S, "unexpected token in operand");
6455 Parser.Lex(); // Eat '='
6456 const MCExpr *SubExprVal;
6457 if (getParser().parseExpression(SubExprVal))
6458 return true;
6459 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6460
6461 // execute-only: we assume that assembly programmers know what they are
6462 // doing and allow literal pool creation here
6463 Operands.push_back(
6464 ARMOperand::CreateConstantPoolImm(SubExprVal, S, E, *this));
6465 return false;
6466 }
6467 }
6468}
6469
6470bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6471 const MCExpr *Expr = nullptr;
6472 SMLoc L = getParser().getTok().getLoc();
6473 if (check(getParser().parseExpression(Expr), L, "expected expression"))
6474 return true;
6475 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
6476 if (check(!Value, L, "expected constant expression"))
6477 return true;
6478 Out = Value->getValue();
6479 return false;
6480}
6481
6482// parsePrefix - Parse ARM 16-bit relocations expression prefixes, i.e.
6483// :lower16: and :upper16: and Thumb 8-bit relocation expression prefixes, i.e.
6484// :upper8_15:, :upper0_7:, :lower8_15: and :lower0_7:
6485bool ARMAsmParser::parsePrefix(ARM::Specifier &Spec) {
6486 MCAsmParser &Parser = getParser();
6487 Spec = ARM::S_None;
6488
6489 // consume an optional '#' (GNU compatibility)
6490 if (getLexer().is(AsmToken::Hash))
6491 Parser.Lex();
6492
6493 assert(getLexer().is(AsmToken::Colon) && "expected a :");
6494 Parser.Lex(); // Eat ':'
6495
6496 if (getLexer().isNot(AsmToken::Identifier)) {
6497 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
6498 return true;
6499 }
6500
6501 enum {
6502 COFF = (1 << MCContext::IsCOFF),
6503 ELF = (1 << MCContext::IsELF),
6504 MACHO = (1 << MCContext::IsMachO),
6505 WASM = (1 << MCContext::IsWasm),
6506 };
6507 static const struct PrefixEntry {
6508 const char *Spelling;
6509 ARM::Specifier Spec;
6510 uint8_t SupportedFormats;
6511 } PrefixEntries[] = {
6512 {"upper16", ARM::S_HI16, COFF | ELF | MACHO},
6513 {"lower16", ARM::S_LO16, COFF | ELF | MACHO},
6514 {"upper8_15", ARM::S_HI_8_15, ELF},
6515 {"upper0_7", ARM::S_HI_0_7, ELF},
6516 {"lower8_15", ARM::S_LO_8_15, ELF},
6517 {"lower0_7", ARM::S_LO_0_7, ELF},
6518 };
6519
6520 StringRef IDVal = Parser.getTok().getIdentifier();
6521
6522 const auto &Prefix =
6523 llvm::find_if(PrefixEntries, [&IDVal](const PrefixEntry &PE) {
6524 return PE.Spelling == IDVal;
6525 });
6526 if (Prefix == std::end(PrefixEntries)) {
6527 Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
6528 return true;
6529 }
6530
6531 uint8_t CurrentFormat;
6532 switch (getContext().getObjectFileType()) {
6533 case MCContext::IsMachO:
6534 CurrentFormat = MACHO;
6535 break;
6536 case MCContext::IsELF:
6537 CurrentFormat = ELF;
6538 break;
6539 case MCContext::IsCOFF:
6540 CurrentFormat = COFF;
6541 break;
6542 case MCContext::IsWasm:
6543 CurrentFormat = WASM;
6544 break;
6545 case MCContext::IsGOFF:
6546 case MCContext::IsSPIRV:
6547 case MCContext::IsXCOFF:
6549 llvm_unreachable("unexpected object format");
6550 break;
6551 }
6552
6553 if (~Prefix->SupportedFormats & CurrentFormat) {
6554 Error(Parser.getTok().getLoc(),
6555 "cannot represent relocation in the current file format");
6556 return true;
6557 }
6558
6559 Spec = Prefix->Spec;
6560 Parser.Lex();
6561
6562 if (getLexer().isNot(AsmToken::Colon)) {
6563 Error(Parser.getTok().getLoc(), "unexpected token after prefix");
6564 return true;
6565 }
6566 Parser.Lex(); // Eat the last ':'
6567
6568 // consume an optional trailing '#' (GNU compatibility) bla
6569 parseOptionalToken(AsmToken::Hash);
6570
6571 return false;
6572}
6573
6574/// Given a mnemonic, split out possible predication code and carry
6575/// setting letters to form a canonical mnemonic and flags.
6576//
6577// FIXME: Would be nice to autogen this.
6578// FIXME: This is a bit of a maze of special cases.
6579StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6580 ARMCC::CondCodes &PredicationCode,
6581 ARMVCC::VPTCodes &VPTPredicationCode,
6582 bool &CarrySetting,
6583 unsigned &ProcessorIMod,
6584 StringRef &ITMask) {
6585 PredicationCode = ARMCC::AL;
6586 VPTPredicationCode = ARMVCC::None;
6587 CarrySetting = false;
6588 ProcessorIMod = 0;
6589
6590 // Ignore some mnemonics we know aren't predicated forms.
6591 //
6592 // FIXME: Would be nice to autogen this.
6593 if ((Mnemonic == "movs" && isThumb()) || Mnemonic == "teq" ||
6594 Mnemonic == "vceq" || Mnemonic == "svc" || Mnemonic == "mls" ||
6595 Mnemonic == "smmls" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
6596 Mnemonic == "vnmls" || Mnemonic == "vacge" || Mnemonic == "vcge" ||
6597 Mnemonic == "vclt" || Mnemonic == "vacgt" || Mnemonic == "vaclt" ||
6598 Mnemonic == "vacle" || Mnemonic == "hlt" || Mnemonic == "vcgt" ||
6599 Mnemonic == "vcle" || Mnemonic == "smlal" || Mnemonic == "umaal" ||
6600 Mnemonic == "umlal" || Mnemonic == "vabal" || Mnemonic == "vmlal" ||
6601 Mnemonic == "vpadal" || Mnemonic == "vqdmlal" || Mnemonic == "fmuls" ||
6602 Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" ||
6603 Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" ||
6604 Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" ||
6605 Mnemonic == "vrintm" || Mnemonic == "hvc" ||
6606 Mnemonic.starts_with("vsel") || Mnemonic == "vins" ||
6607 Mnemonic == "vmovx" || Mnemonic == "bxns" || Mnemonic == "blxns" ||
6608 Mnemonic == "vdot" || Mnemonic == "vmmla" || Mnemonic == "vudot" ||
6609 Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
6610 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || Mnemonic == "wls" ||
6611 Mnemonic == "le" || Mnemonic == "dls" || Mnemonic == "csel" ||
6612 Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" ||
6613 Mnemonic == "cinc" || Mnemonic == "cinv" || Mnemonic == "cneg" ||
6614 Mnemonic == "cset" || Mnemonic == "csetm" || Mnemonic == "aut" ||
6615 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "bti")
6616 return Mnemonic;
6617
6618 // First, split out any predication code. Ignore mnemonics we know aren't
6619 // predicated but do have a carry-set and so weren't caught above.
6620 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
6621 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
6622 Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
6623 Mnemonic != "sbcs" && Mnemonic != "rscs" &&
6624 !(hasMVE() &&
6625 (Mnemonic == "vmine" || Mnemonic == "vshle" || Mnemonic == "vshlt" ||
6626 Mnemonic == "vshllt" || Mnemonic == "vrshle" || Mnemonic == "vrshlt" ||
6627 Mnemonic == "vmvne" || Mnemonic == "vorne" || Mnemonic == "vnege" ||
6628 Mnemonic == "vnegt" || Mnemonic == "vmule" || Mnemonic == "vmult" ||
6629 Mnemonic == "vrintne" || Mnemonic == "vcmult" ||
6630 Mnemonic == "vcmule" || Mnemonic == "vpsele" || Mnemonic == "vpselt" ||
6631 Mnemonic.starts_with("vq")))) {
6632 unsigned CC = ARMCondCodeFromString(Mnemonic.substr(Mnemonic.size()-2));
6633 if (CC != ~0U) {
6634 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
6635 PredicationCode = static_cast<ARMCC::CondCodes>(CC);
6636 }
6637 }
6638
6639 // Next, determine if we have a carry setting bit. We explicitly ignore all
6640 // the instructions we know end in 's'.
6641 if (Mnemonic.ends_with("s") &&
6642 !(Mnemonic == "cps" || Mnemonic == "mls" || Mnemonic == "mrs" ||
6643 Mnemonic == "smmls" || Mnemonic == "vabs" || Mnemonic == "vcls" ||
6644 Mnemonic == "vmls" || Mnemonic == "vmrs" || Mnemonic == "vnmls" ||
6645 Mnemonic == "vqabs" || Mnemonic == "vrecps" || Mnemonic == "vrsqrts" ||
6646 Mnemonic == "srs" || Mnemonic == "flds" || Mnemonic == "fmrs" ||
6647 Mnemonic == "fsqrts" || Mnemonic == "fsubs" || Mnemonic == "fsts" ||
6648 Mnemonic == "fcpys" || Mnemonic == "fdivs" || Mnemonic == "fmuls" ||
6649 Mnemonic == "fcmps" || Mnemonic == "fcmpzs" || Mnemonic == "vfms" ||
6650 Mnemonic == "vfnms" || Mnemonic == "fconsts" || Mnemonic == "bxns" ||
6651 Mnemonic == "blxns" || Mnemonic == "vfmas" || Mnemonic == "vmlas" ||
6652 (Mnemonic == "movs" && isThumb()))) {
6653 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
6654 CarrySetting = true;
6655 }
6656
6657 // The "cps" instruction can have a interrupt mode operand which is glued into
6658 // the mnemonic. Check if this is the case, split it and parse the imod op
6659 if (Mnemonic.starts_with("cps")) {
6660 // Split out any imod code.
6661 unsigned IMod =
6662 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
6663 .Case("ie", ARM_PROC::IE)
6664 .Case("id", ARM_PROC::ID)
6665 .Default(~0U);
6666 if (IMod != ~0U) {
6667 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
6668 ProcessorIMod = IMod;
6669 }
6670 }
6671
6672 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic != "vmovlt" &&
6673 Mnemonic != "vshllt" && Mnemonic != "vrshrnt" && Mnemonic != "vshrnt" &&
6674 Mnemonic != "vqrshrunt" && Mnemonic != "vqshrunt" &&
6675 Mnemonic != "vqrshrnt" && Mnemonic != "vqshrnt" && Mnemonic != "vmullt" &&
6676 Mnemonic != "vqmovnt" && Mnemonic != "vqmovunt" && Mnemonic != "vmovnt" &&
6677 Mnemonic != "vqdmullt" && Mnemonic != "vpnot" && Mnemonic != "vcvtt" &&
6678 Mnemonic != "vcvt") {
6679 unsigned VCC =
6680 ARMVectorCondCodeFromString(Mnemonic.substr(Mnemonic.size() - 1));
6681 if (VCC != ~0U) {
6682 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-1);
6683 VPTPredicationCode = static_cast<ARMVCC::VPTCodes>(VCC);
6684 }
6685 return Mnemonic;
6686 }
6687
6688 // The "it" instruction has the condition mask on the end of the mnemonic.
6689 if (Mnemonic.starts_with("it")) {
6690 ITMask = Mnemonic.substr(2);
6691 Mnemonic = Mnemonic.slice(0, 2);
6692 }
6693
6694 if (Mnemonic.starts_with("vpst")) {
6695 ITMask = Mnemonic.substr(4);
6696 Mnemonic = Mnemonic.slice(0, 4);
6697 } else if (Mnemonic.starts_with("vpt")) {
6698 ITMask = Mnemonic.substr(3);
6699 Mnemonic = Mnemonic.slice(0, 3);
6700 }
6701
6702 return Mnemonic;
6703}
6704
6705/// Given a canonical mnemonic, determine if the instruction ever allows
6706/// inclusion of carry set or predication code operands.
6707//
6708// FIXME: It would be nice to autogen this.
6709void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6710 StringRef ExtraToken,
6711 StringRef FullInst,
6712 bool &CanAcceptCarrySet,
6713 bool &CanAcceptPredicationCode,
6714 bool &CanAcceptVPTPredicationCode) {
6715 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6716
6717 CanAcceptCarrySet =
6718 Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
6719 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
6720 Mnemonic == "add" || Mnemonic == "adc" || Mnemonic == "mul" ||
6721 Mnemonic == "bic" || Mnemonic == "asr" || Mnemonic == "orr" ||
6722 Mnemonic == "mvn" || Mnemonic == "rsb" || Mnemonic == "rsc" ||
6723 Mnemonic == "orn" || Mnemonic == "sbc" || Mnemonic == "eor" ||
6724 Mnemonic == "neg" || Mnemonic == "vfm" || Mnemonic == "vfnm" ||
6725 (!isThumb() &&
6726 (Mnemonic == "smull" || Mnemonic == "mov" || Mnemonic == "mla" ||
6727 Mnemonic == "smlal" || Mnemonic == "umlal" || Mnemonic == "umull"));
6728
6729 if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
6730 Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
6731 Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic == "udf" ||
6732 Mnemonic.starts_with("crc32") || Mnemonic.starts_with("cps") ||
6733 Mnemonic.starts_with("vsel") || Mnemonic == "vmaxnm" ||
6734 Mnemonic == "vminnm" || Mnemonic == "vcvta" || Mnemonic == "vcvtn" ||
6735 Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || Mnemonic == "vrinta" ||
6736 Mnemonic == "vrintn" || Mnemonic == "vrintp" || Mnemonic == "vrintm" ||
6737 Mnemonic.starts_with("aes") || Mnemonic == "hvc" ||
6738 Mnemonic == "setpan" || Mnemonic.starts_with("sha1") ||
6739 Mnemonic.starts_with("sha256") ||
6740 (FullInst.starts_with("vmull") && FullInst.ends_with(".p64")) ||
6741 Mnemonic == "vmovx" || Mnemonic == "vins" || Mnemonic == "vudot" ||
6742 Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
6743 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || Mnemonic == "vfmat" ||
6744 Mnemonic == "vfmab" || Mnemonic == "vdot" || Mnemonic == "vmmla" ||
6745 Mnemonic == "sb" || Mnemonic == "ssbb" || Mnemonic == "pssbb" ||
6746 Mnemonic == "vsmmla" || Mnemonic == "vummla" || Mnemonic == "vusmmla" ||
6747 Mnemonic == "vusdot" || Mnemonic == "vsudot" || Mnemonic == "bfcsel" ||
6748 Mnemonic == "wls" || Mnemonic == "dls" || Mnemonic == "le" ||
6749 Mnemonic == "csel" || Mnemonic == "csinc" || Mnemonic == "csinv" ||
6750 Mnemonic == "csneg" || Mnemonic == "cinc" || Mnemonic == "cinv" ||
6751 Mnemonic == "cneg" || Mnemonic == "cset" || Mnemonic == "csetm" ||
6752 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6753 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6754 Mnemonic.starts_with("vpt") || Mnemonic.starts_with("vpst") ||
6755 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "aut" ||
6756 Mnemonic == "bti" ||
6757 (hasMVE() &&
6758 (Mnemonic.starts_with("vst2") || Mnemonic.starts_with("vld2") ||
6759 Mnemonic.starts_with("vst4") || Mnemonic.starts_with("vld4") ||
6760 Mnemonic.starts_with("wlstp") || Mnemonic.starts_with("dlstp") ||
6761 Mnemonic.starts_with("letp")))) {
6762 // These mnemonics are never predicable
6763 CanAcceptPredicationCode = false;
6764 } else if (!isThumb()) {
6765 // Some instructions are only predicable in Thumb mode
6766 CanAcceptPredicationCode =
6767 Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" &&
6768 Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" &&
6769 Mnemonic != "dmb" && Mnemonic != "dfb" && Mnemonic != "dsb" &&
6770 Mnemonic != "isb" && Mnemonic != "pld" && Mnemonic != "pli" &&
6771 Mnemonic != "pldw" && Mnemonic != "ldc2" && Mnemonic != "ldc2l" &&
6772 Mnemonic != "stc2" && Mnemonic != "stc2l" && Mnemonic != "tsb" &&
6773 !Mnemonic.starts_with("rfe") && !Mnemonic.starts_with("srs");
6774 } else if (isThumbOne()) {
6775 if (hasV6MOps())
6776 CanAcceptPredicationCode = Mnemonic != "movs";
6777 else
6778 CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs";
6779 } else
6780 CanAcceptPredicationCode = true;
6781}
6782
6783bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6784 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I) {
6785 auto &Op = static_cast<ARMOperand &>(*Operands[I]);
6786 if (Op.isToken() && Op.getToken() == ".w")
6787 return true;
6788 }
6789 return false;
6790}
6791
6792// Some Thumb instructions have two operand forms that are not
6793// available as three operand, convert to two operand form if possible.
6794//
6795// FIXME: We would really like to be able to tablegen'erate this.
6796void ARMAsmParser::tryConvertingToTwoOperandForm(
6797 StringRef Mnemonic, ARMCC::CondCodes PredicationCode, bool CarrySetting,
6798 OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6799
6800 if (operandsContainWide(Operands, MnemonicOpsEndInd))
6801 return;
6802 if (Operands.size() != MnemonicOpsEndInd + 3)
6803 return;
6804
6805 const auto &Op3 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]);
6806 auto &Op4 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
6807 if (!Op3.isReg() || !Op4.isReg())
6808 return;
6809
6810 auto Op3Reg = Op3.getReg();
6811 auto Op4Reg = Op4.getReg();
6812
6813 // For most Thumb2 cases we just generate the 3 operand form and reduce
6814 // it in processInstruction(), but the 3 operand form of ADD (t2ADDrr)
6815 // won't accept SP or PC so we do the transformation here taking care
6816 // with immediate range in the 'add sp, sp #imm' case.
6817 auto &Op5 = static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 2]);
6818 if (isThumbTwo()) {
6819 if (Mnemonic != "add")
6820 return;
6821 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6822 (Op5.isReg() && Op5.getReg() == ARM::PC);
6823 if (!TryTransform) {
6824 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6825 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6826 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6827 Op5.isImm() && !Op5.isImm0_508s4());
6828 }
6829 if (!TryTransform)
6830 return;
6831 } else if (!isThumbOne())
6832 return;
6833
6834 if (!(Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
6835 Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
6836 Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
6837 Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic"))
6838 return;
6839
6840 // If first 2 operands of a 3 operand instruction are the same
6841 // then transform to 2 operand version of the same instruction
6842 // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
6843 bool Transform = Op3Reg == Op4Reg;
6844
6845 // For communtative operations, we might be able to transform if we swap
6846 // Op4 and Op5. The 'ADD Rdm, SP, Rdm' form is already handled specially
6847 // as tADDrsp.
6848 const ARMOperand *LastOp = &Op5;
6849 bool Swap = false;
6850 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6851 ((Mnemonic == "add" && Op4Reg != ARM::SP) ||
6852 Mnemonic == "and" || Mnemonic == "eor" ||
6853 Mnemonic == "adc" || Mnemonic == "orr")) {
6854 Swap = true;
6855 LastOp = &Op4;
6856 Transform = true;
6857 }
6858
6859 // If both registers are the same then remove one of them from
6860 // the operand list, with certain exceptions.
6861 if (Transform) {
6862 // Don't transform 'adds Rd, Rd, Rm' or 'sub{s} Rd, Rd, Rm' because the
6863 // 2 operand forms don't exist.
6864 if (((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub") &&
6865 LastOp->isReg())
6866 Transform = false;
6867
6868 // Don't transform 'add/sub{s} Rd, Rd, #imm' if the immediate fits into
6869 // 3-bits because the ARMARM says not to.
6870 if ((Mnemonic == "add" || Mnemonic == "sub") && LastOp->isImm0_7())
6871 Transform = false;
6872 }
6873
6874 if (Transform) {
6875 if (Swap)
6876 std::swap(Op4, Op5);
6877 Operands.erase(Operands.begin() + MnemonicOpsEndInd);
6878 }
6879}
6880
6881static bool isARMMCExpr(MCParsedAsmOperand &MCOp);
6882// this function returns true if the operand is one of the following
6883// relocations: :upper8_15:, :upper0_7:, :lower8_15: or :lower0_7:
6885 assert(isARMMCExpr(MCOp));
6886 ARMOperand &Op = static_cast<ARMOperand &>(MCOp);
6887 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(Op.getImm());
6888 if (ARM16Expr && (ARM16Expr->getSpecifier() == ARM::S_HI_8_15 ||
6889 ARM16Expr->getSpecifier() == ARM::S_HI_0_7 ||
6890 ARM16Expr->getSpecifier() == ARM::S_LO_8_15 ||
6891 ARM16Expr->getSpecifier() == ARM::S_LO_0_7))
6892 return true;
6893 return false;
6894}
6895
6896bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6897 StringRef Mnemonic, OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6898 if (!hasMVE() || Operands.size() <= MnemonicOpsEndInd)
6899 return true;
6900
6901 if (Mnemonic.starts_with("vld2") || Mnemonic.starts_with("vld4") ||
6902 Mnemonic.starts_with("vst2") || Mnemonic.starts_with("vst4"))
6903 return true;
6904
6905 if (Mnemonic.starts_with("vctp") || Mnemonic.starts_with("vpnot"))
6906 return false;
6907
6908 if (Mnemonic.starts_with("vmov") &&
6909 !(Mnemonic.starts_with("vmovl") || Mnemonic.starts_with("vmovn") ||
6910 Mnemonic.starts_with("vmovx"))) {
6911 for (auto &Operand : Operands) {
6912 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() ||
6913 ((*Operand).isReg() && (getARMMCRegisterClass(ARM::SPRRegClassID)
6914 .contains((*Operand).getReg()) ||
6915 getARMMCRegisterClass(ARM::DPRRegClassID)
6916 .contains((*Operand).getReg())))) {
6917 return true;
6918 }
6919 }
6920 return false;
6921 } else {
6922 for (auto &Operand : Operands) {
6923 // We check the larger class QPR instead of just the legal class
6924 // MQPR, to more accurately report errors when using Q registers
6925 // outside of the allowed range.
6926 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() ||
6927 static_cast<ARMOperand &>(*Operand).isQReg())
6928 return false;
6929 }
6930 return true;
6931 }
6932}
6933
6934// FIXME: This bit should probably be handled via an explicit match class
6935// in the .td files that matches the suffix instead of having it be
6936// a literal string token the way it is now.
6938 return Mnemonic.starts_with("vldm") || Mnemonic.starts_with("vstm");
6939}
6940
6941static void applyMnemonicAliases(StringRef &Mnemonic,
6942 const FeatureBitset &Features,
6943 unsigned VariantID);
6944
6945// The GNU assembler has aliases of ldrd, strd, ldrexd, strexd, ldaexd, and
6946// stlexd with the second register omitted. We don't have a way to do that in
6947// tablegen, so fix it up here.
6948//
6949// We have to be careful to not emit an invalid Rt2 here, because the rest of
6950// the assembly parser could then generate confusing diagnostics referring to
6951// it. If we do find anything that prevents us from doing the transformation we
6952// bail out, and let the assembly parser report an error on the instruction as
6953// it is written.
6954void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic,
6955 OperandVector &Operands,
6956 unsigned MnemonicOpsEndInd) {
6957 if (Mnemonic != "ldrd" && Mnemonic != "strd" && Mnemonic != "ldrexd" &&
6958 Mnemonic != "strexd" && Mnemonic != "ldaexd" && Mnemonic != "stlexd")
6959 return;
6960
6961 unsigned IdX = Mnemonic == "strexd" || Mnemonic == "stlexd"
6962 ? MnemonicOpsEndInd + 1
6963 : MnemonicOpsEndInd;
6964
6965 if (Operands.size() < IdX + 2)
6966 return;
6967
6968 ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[IdX]);
6969 ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[IdX + 1]);
6970
6971 if (!Op2.isReg())
6972 return;
6973 if (!Op3.isGPRMem())
6974 return;
6975
6976 const MCRegisterClass &GPR = MRI->getRegClass(ARM::GPRRegClassID);
6977 if (!GPR.contains(Op2.getReg()))
6978 return;
6979
6980 unsigned RtEncoding = MRI->getEncodingValue(Op2.getReg());
6981 if (!isThumb() && (RtEncoding & 1)) {
6982 // In ARM mode, the registers must be from an aligned pair, this
6983 // restriction does not apply in Thumb mode.
6984 return;
6985 }
6986 if (Op2.getReg() == ARM::PC)
6987 return;
6988 MCRegister PairedReg = GPR.getRegister(RtEncoding + 1);
6989 if (!PairedReg || PairedReg == ARM::PC ||
6990 (PairedReg == ARM::SP && !hasV8Ops()))
6991 return;
6992
6993 Operands.insert(Operands.begin() + IdX + 1,
6994 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(),
6995 Op2.getEndLoc(), *this));
6996}
6997
6998// Dual-register instruction have the following syntax:
6999// <mnemonic> <predicate>? <coproc>, <Rdest>, <Rdest+1>, <Rsrc>, ..., #imm
7000// This function tries to remove <Rdest+1> and replace <Rdest> with a pair
7001// operand. If the conversion fails an error is diagnosed, and the function
7002// returns true.
7003bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic,
7004 OperandVector &Operands,
7005 unsigned MnemonicOpsEndInd) {
7006 assert(MS.isCDEDualRegInstr(Mnemonic));
7007
7008 if (Operands.size() < 3 + MnemonicOpsEndInd)
7009 return false;
7010
7011 StringRef Op2Diag(
7012 "operand must be an even-numbered register in the range [r0, r10]");
7013
7014 const MCParsedAsmOperand &Op2 = *Operands[MnemonicOpsEndInd + 1];
7015 if (!Op2.isReg())
7016 return Error(Op2.getStartLoc(), Op2Diag);
7017
7018 MCRegister RNext;
7019 MCRegister RPair;
7020 switch (Op2.getReg().id()) {
7021 default:
7022 return Error(Op2.getStartLoc(), Op2Diag);
7023 case ARM::R0:
7024 RNext = ARM::R1;
7025 RPair = ARM::R0_R1;
7026 break;
7027 case ARM::R2:
7028 RNext = ARM::R3;
7029 RPair = ARM::R2_R3;
7030 break;
7031 case ARM::R4:
7032 RNext = ARM::R5;
7033 RPair = ARM::R4_R5;
7034 break;
7035 case ARM::R6:
7036 RNext = ARM::R7;
7037 RPair = ARM::R6_R7;
7038 break;
7039 case ARM::R8:
7040 RNext = ARM::R9;
7041 RPair = ARM::R8_R9;
7042 break;
7043 case ARM::R10:
7044 RNext = ARM::R11;
7045 RPair = ARM::R10_R11;
7046 break;
7047 }
7048
7049 const MCParsedAsmOperand &Op3 = *Operands[MnemonicOpsEndInd + 2];
7050 if (!Op3.isReg() || Op3.getReg() != RNext)
7051 return Error(Op3.getStartLoc(), "operand must be a consecutive register");
7052
7053 Operands.erase(Operands.begin() + MnemonicOpsEndInd + 2);
7054 Operands[MnemonicOpsEndInd + 1] =
7055 ARMOperand::CreateReg(RPair, Op2.getStartLoc(), Op2.getEndLoc(), *this);
7056 return false;
7057}
7058
7059void removeCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7060 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7061 if (static_cast<ARMOperand &>(*Operands[I]).isCondCode()) {
7062 Operands.erase(Operands.begin() + I);
7063 --MnemonicOpsEndInd;
7064 break;
7065 }
7066}
7067
7068void removeCCOut(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7069 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7070 if (static_cast<ARMOperand &>(*Operands[I]).isCCOut()) {
7071 Operands.erase(Operands.begin() + I);
7072 --MnemonicOpsEndInd;
7073 break;
7074 }
7075}
7076
7077void removeVPTCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd) {
7078 for (unsigned I = 0; I < MnemonicOpsEndInd; ++I)
7079 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred()) {
7080 Operands.erase(Operands.begin() + I);
7081 --MnemonicOpsEndInd;
7082 break;
7083 }
7084}
7085
7086/// Parse an arm instruction mnemonic followed by its operands.
7087bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7088 SMLoc NameLoc, OperandVector &Operands) {
7089 MCAsmParser &Parser = getParser();
7090
7091 // Apply mnemonic aliases before doing anything else, as the destination
7092 // mnemonic may include suffices and we want to handle them normally.
7093 // The generic tblgen'erated code does this later, at the start of
7094 // MatchInstructionImpl(), but that's too late for aliases that include
7095 // any sort of suffix.
7096 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
7097 unsigned AssemblerDialect = getParser().getAssemblerDialect();
7098 applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect);
7099
7100 // First check for the ARM-specific .req directive.
7101 if (Parser.getTok().is(AsmToken::Identifier) &&
7102 Parser.getTok().getIdentifier().lower() == ".req") {
7103 parseDirectiveReq(Name, NameLoc);
7104 // We always return 'error' for this, as we're done with this
7105 // statement and don't need to match the 'instruction."
7106 return true;
7107 }
7108
7109 // Create the leading tokens for the mnemonic, split by '.' characters.
7110 size_t Start = 0, Next = Name.find('.');
7111 StringRef Mnemonic = Name.slice(Start, Next);
7112 StringRef ExtraToken = Name.slice(Next, Name.find(' ', Next + 1));
7113
7114 // Split out the predication code and carry setting flag from the mnemonic.
7115 ARMCC::CondCodes PredicationCode;
7116 ARMVCC::VPTCodes VPTPredicationCode;
7117 unsigned ProcessorIMod;
7118 bool CarrySetting;
7119 StringRef ITMask;
7120 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode,
7121 CarrySetting, ProcessorIMod, ITMask);
7122
7123 // In Thumb1, only the branch (B) instruction can be predicated.
7124 if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
7125 return Error(NameLoc, "conditional execution not supported in Thumb1");
7126 }
7127
7128 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc, *this));
7129
7130 // Handle the mask for IT and VPT instructions. In ARMOperand and
7131 // MCOperand, this is stored in a format independent of the
7132 // condition code: the lowest set bit indicates the end of the
7133 // encoding, and above that, a 1 bit indicates 'else', and an 0
7134 // indicates 'then'. E.g.
7135 // IT -> 1000
7136 // ITx -> x100 (ITT -> 0100, ITE -> 1100)
7137 // ITxy -> xy10 (e.g. ITET -> 1010)
7138 // ITxyz -> xyz1 (e.g. ITEET -> 1101)
7139 // Note: See the ARM::PredBlockMask enum in
7140 // /lib/Target/ARM/Utils/ARMBaseInfo.h
7141 if (Mnemonic == "it" || Mnemonic.starts_with("vpt") ||
7142 Mnemonic.starts_with("vpst")) {
7143 SMLoc Loc = Mnemonic == "it" ? SMLoc::getFromPointer(NameLoc.getPointer() + 2) :
7144 Mnemonic == "vpt" ? SMLoc::getFromPointer(NameLoc.getPointer() + 3) :
7145 SMLoc::getFromPointer(NameLoc.getPointer() + 4);
7146 if (ITMask.size() > 3) {
7147 if (Mnemonic == "it")
7148 return Error(Loc, "too many conditions on IT instruction");
7149 return Error(Loc, "too many conditions on VPT instruction");
7150 }
7151 unsigned Mask = 8;
7152 for (char Pos : llvm::reverse(ITMask)) {
7153 if (Pos != 't' && Pos != 'e') {
7154 return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
7155 }
7156 Mask >>= 1;
7157 if (Pos == 'e')
7158 Mask |= 8;
7159 }
7160 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc, *this));
7161 }
7162
7163 // FIXME: This is all a pretty gross hack. We should automatically handle
7164 // optional operands like this via tblgen.
7165
7166 // Next, add the CCOut and ConditionCode operands, if needed.
7167 //
7168 // For mnemonics which can ever incorporate a carry setting bit or predication
7169 // code, our matching model involves us always generating CCOut and
7170 // ConditionCode operands to match the mnemonic "as written" and then we let
7171 // the matcher deal with finding the right instruction or generating an
7172 // appropriate error.
7173 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode;
7174 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet,
7175 CanAcceptPredicationCode, CanAcceptVPTPredicationCode);
7176
7177 // If we had a carry-set on an instruction that can't do that, issue an
7178 // error.
7179 if (!CanAcceptCarrySet && CarrySetting) {
7180 return Error(NameLoc, "instruction '" + Mnemonic +
7181 "' can not set flags, but 's' suffix specified");
7182 }
7183 // If we had a predication code on an instruction that can't do that, issue an
7184 // error.
7185 if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
7186 return Error(NameLoc, "instruction '" + Mnemonic +
7187 "' is not predicable, but condition code specified");
7188 }
7189
7190 // If we had a VPT predication code on an instruction that can't do that, issue an
7191 // error.
7192 if (!CanAcceptVPTPredicationCode && VPTPredicationCode != ARMVCC::None) {
7193 return Error(NameLoc, "instruction '" + Mnemonic +
7194 "' is not VPT predicable, but VPT code T/E is specified");
7195 }
7196
7197 // Add the carry setting operand, if necessary.
7198 if (CanAcceptCarrySet && CarrySetting) {
7199 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
7200 Operands.push_back(ARMOperand::CreateCCOut(
7201 CarrySetting ? ARM::CPSR : ARM::NoRegister, Loc, *this));
7202 }
7203
7204 // Add the predication code operand, if necessary.
7205 if (CanAcceptPredicationCode && PredicationCode != llvm::ARMCC::AL) {
7206 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
7207 CarrySetting);
7208 Operands.push_back(ARMOperand::CreateCondCode(
7209 ARMCC::CondCodes(PredicationCode), Loc, *this));
7210 }
7211
7212 // Add the VPT predication code operand, if necessary.
7213 // Dont add in certain cases of VCVT as this needs to be disambiguated
7214 // after operand parsing.
7215 if (CanAcceptVPTPredicationCode && VPTPredicationCode != llvm::ARMVCC::None &&
7216 !(Mnemonic.starts_with("vcvt") && Mnemonic != "vcvta" &&
7217 Mnemonic != "vcvtn" && Mnemonic != "vcvtp" && Mnemonic != "vcvtm")) {
7218 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
7219 CarrySetting);
7220 Operands.push_back(ARMOperand::CreateVPTPred(
7221 ARMVCC::VPTCodes(VPTPredicationCode), Loc, *this));
7222 }
7223
7224 // Add the processor imod operand, if necessary.
7225 if (ProcessorIMod) {
7226 Operands.push_back(ARMOperand::CreateImm(
7227 MCConstantExpr::create(ProcessorIMod, getContext()), NameLoc, NameLoc,
7228 *this));
7229 } else if (Mnemonic == "cps" && isMClass()) {
7230 return Error(NameLoc, "instruction 'cps' requires effect for M-class");
7231 }
7232
7233 // Add the remaining tokens in the mnemonic.
7234 while (Next != StringRef::npos) {
7235 Start = Next;
7236 Next = Name.find('.', Start + 1);
7237 ExtraToken = Name.slice(Start, Next);
7238
7239 // Some NEON instructions have an optional datatype suffix that is
7240 // completely ignored. Check for that.
7241 if (isDataTypeToken(ExtraToken) &&
7242 doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
7243 continue;
7244
7245 // For for ARM mode generate an error if the .n qualifier is used.
7246 if (ExtraToken == ".n" && !isThumb()) {
7247 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
7248 return Error(Loc, "instruction with .n (narrow) qualifier not allowed in "
7249 "arm mode");
7250 }
7251
7252 // The .n qualifier is always discarded as that is what the tables
7253 // and matcher expect. In ARM mode the .w qualifier has no effect,
7254 // so discard it to avoid errors that can be caused by the matcher.
7255 if (ExtraToken != ".n" && (isThumb() || ExtraToken != ".w")) {
7256 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
7257 Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc, *this));
7258 }
7259 }
7260
7261 // This marks the end of the LHS Mnemonic operators.
7262 // This is used for indexing into the non-mnemonic operators as some of the
7263 // mnemonic operators are optional and therefore indexes can differ.
7264 unsigned MnemonicOpsEndInd = Operands.size();
7265
7266 // Read the remaining operands.
7267 if (getLexer().isNot(AsmToken::EndOfStatement)) {
7268 // Read the first operand.
7269 if (parseOperand(Operands, Mnemonic)) {
7270 return true;
7271 }
7272
7273 while (parseOptionalToken(AsmToken::Comma)) {
7274 // Parse and remember the operand.
7275 if (parseOperand(Operands, Mnemonic)) {
7276 return true;
7277 }
7278 }
7279 }
7280
7281 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
7282 return true;
7283
7284 tryConvertingToTwoOperandForm(Mnemonic, PredicationCode, CarrySetting,
7285 Operands, MnemonicOpsEndInd);
7286
7287 if (hasCDE() && MS.isCDEInstr(Mnemonic)) {
7288 // Dual-register instructions use even-odd register pairs as their
7289 // destination operand, in assembly such pair is spelled as two
7290 // consecutive registers, without any special syntax. ConvertDualRegOperand
7291 // tries to convert such operand into register pair, e.g. r2, r3 -> r2_r3.
7292 // It returns true, if an error message has been emitted. If the function
7293 // returns false, the function either succeeded or an error (e.g. missing
7294 // operand) will be diagnosed elsewhere.
7295 if (MS.isCDEDualRegInstr(Mnemonic)) {
7296 bool GotError =
7297 CDEConvertDualRegOperand(Mnemonic, Operands, MnemonicOpsEndInd);
7298 if (GotError)
7299 return GotError;
7300 }
7301 }
7302
7303 if (hasMVE()) {
7304 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7305 MnemonicOpsEndInd) &&
7306 Mnemonic == "vmov" && PredicationCode == ARMCC::LT) {
7307 // Very nasty hack to deal with the vector predicated variant of vmovlt
7308 // the scalar predicated vmov with condition 'lt'. We can not tell them
7309 // apart until we have parsed their operands.
7310 Operands.erase(Operands.begin() + 1);
7311 Operands.erase(Operands.begin());
7312 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7313 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7314 Mnemonic.size() - 1 + CarrySetting);
7315 Operands.insert(Operands.begin(),
7316 ARMOperand::CreateVPTPred(ARMVCC::None, PLoc, *this));
7317 Operands.insert(Operands.begin(), ARMOperand::CreateToken(
7318 StringRef("vmovlt"), MLoc, *this));
7319 } else if (Mnemonic == "vcvt" && PredicationCode == ARMCC::NE &&
7320 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7321 MnemonicOpsEndInd)) {
7322 // Another nasty hack to deal with the ambiguity between vcvt with scalar
7323 // predication 'ne' and vcvtn with vector predication 'e'. As above we
7324 // can only distinguish between the two after we have parsed their
7325 // operands.
7326 Operands.erase(Operands.begin() + 1);
7327 Operands.erase(Operands.begin());
7328 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7329 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7330 Mnemonic.size() - 1 + CarrySetting);
7331 Operands.insert(Operands.begin(),
7332 ARMOperand::CreateVPTPred(ARMVCC::Else, PLoc, *this));
7333 Operands.insert(Operands.begin(),
7334 ARMOperand::CreateToken(StringRef("vcvtn"), MLoc, *this));
7335 } else if (Mnemonic == "vmul" && PredicationCode == ARMCC::LT &&
7336 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7337 MnemonicOpsEndInd)) {
7338 // Another hack, this time to distinguish between scalar predicated vmul
7339 // with 'lt' predication code and the vector instruction vmullt with
7340 // vector predication code "none"
7341 removeCondCode(Operands, MnemonicOpsEndInd);
7342 Operands.erase(Operands.begin());
7343 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7344 Operands.insert(Operands.begin(), ARMOperand::CreateToken(
7345 StringRef("vmullt"), MLoc, *this));
7346 } else if (Mnemonic.starts_with("vcvt") && !Mnemonic.starts_with("vcvta") &&
7347 !Mnemonic.starts_with("vcvtn") &&
7348 !Mnemonic.starts_with("vcvtp") &&
7349 !Mnemonic.starts_with("vcvtm")) {
7350 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7351 MnemonicOpsEndInd)) {
7352 // We could not split the vector predicate off vcvt because it might
7353 // have been the scalar vcvtt instruction. Now we know its a vector
7354 // instruction, we still need to check whether its the vector
7355 // predicated vcvt with 'Then' predication or the vector vcvtt. We can
7356 // distinguish the two based on the suffixes, if it is any of
7357 // ".f16.f32", ".f32.f16", ".f16.f64" or ".f64.f16" then it is the vcvtt.
7358 if (Mnemonic.starts_with("vcvtt") && MnemonicOpsEndInd > 2) {
7359 auto Sz1 =
7360 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd - 2]);
7361 auto Sz2 =
7362 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd - 1]);
7363 if (!(Sz1.isToken() && Sz1.getToken().starts_with(".f") &&
7364 Sz2.isToken() && Sz2.getToken().starts_with(".f"))) {
7365 Operands.erase(Operands.begin());
7366 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer());
7367 VPTPredicationCode = ARMVCC::Then;
7368
7369 Mnemonic = Mnemonic.substr(0, 4);
7370 Operands.insert(Operands.begin(),
7371 ARMOperand::CreateToken(Mnemonic, MLoc, *this));
7372 }
7373 }
7374 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
7375 Mnemonic.size() + CarrySetting);
7376 // Add VPTPred
7377 Operands.insert(Operands.begin() + 1,
7378 ARMOperand::CreateVPTPred(
7379 ARMVCC::VPTCodes(VPTPredicationCode), PLoc, *this));
7380 ++MnemonicOpsEndInd;
7381 }
7382 } else if (CanAcceptVPTPredicationCode) {
7383 // For all other instructions, make sure only one of the two
7384 // predication operands is left behind, depending on whether we should
7385 // use the vector predication.
7386 if (shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7387 MnemonicOpsEndInd)) {
7388 removeVPTCondCode(Operands, MnemonicOpsEndInd);
7389 }
7390 }
7391 }
7392
7393 if (VPTPredicationCode != ARMVCC::None) {
7394 bool usedVPTPredicationCode = false;
7395 for (unsigned I = 1; I < Operands.size(); ++I)
7396 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred())
7397 usedVPTPredicationCode = true;
7398 if (!usedVPTPredicationCode) {
7399 // If we have a VPT predication code and we haven't just turned it
7400 // into an operand, then it was a mistake for splitMnemonic to
7401 // separate it from the rest of the mnemonic in the first place,
7402 // and this may lead to wrong disassembly (e.g. scalar floating
7403 // point VCMPE is actually a different instruction from VCMP, so
7404 // we mustn't treat them the same). In that situation, glue it
7405 // back on.
7406 Mnemonic = Name.slice(0, Mnemonic.size() + 1);
7407 Operands.erase(Operands.begin());
7408 Operands.insert(Operands.begin(),
7409 ARMOperand::CreateToken(Mnemonic, NameLoc, *this));
7410 }
7411 }
7412
7413 // ARM mode 'blx' need special handling, as the register operand version
7414 // is predicable, but the label operand version is not. So, we can't rely
7415 // on the Mnemonic based checking to correctly figure out when to put
7416 // a k_CondCode operand in the list. If we're trying to match the label
7417 // version, remove the k_CondCode operand here.
7418 if (!isThumb() && Mnemonic == "blx" &&
7419 Operands.size() == MnemonicOpsEndInd + 1 &&
7420 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).isImm())
7421 removeCondCode(Operands, MnemonicOpsEndInd);
7422
7423 // GNU Assembler extension (compatibility).
7424 fixupGNULDRDAlias(Mnemonic, Operands, MnemonicOpsEndInd);
7425
7426 // Adjust operands of ldrexd/strexd to MCK_GPRPair.
7427 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
7428 // a single GPRPair reg operand is used in the .td file to replace the two
7429 // GPRs. However, when parsing from asm, the two GRPs cannot be
7430 // automatically
7431 // expressed as a GPRPair, so we have to manually merge them.
7432 // FIXME: We would really like to be able to tablegen'erate this.
7433 bool IsLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd");
7434 if (!isThumb() && Operands.size() > MnemonicOpsEndInd + 1 + (!IsLoad) &&
7435 (Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" ||
7436 Mnemonic == "stlexd")) {
7437 unsigned Idx = IsLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
7438 ARMOperand &Op1 = static_cast<ARMOperand &>(*Operands[Idx]);
7439 ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[Idx + 1]);
7440
7441 const MCRegisterClass &MRC = MRI->getRegClass(ARM::GPRRegClassID);
7442 // Adjust only if Op1 is a GPR.
7443 if (Op1.isReg() && MRC.contains(Op1.getReg())) {
7444 MCRegister Reg1 = Op1.getReg();
7445 unsigned Rt = MRI->getEncodingValue(Reg1);
7446 MCRegister Reg2 = Op2.getReg();
7447 unsigned Rt2 = MRI->getEncodingValue(Reg2);
7448 // Rt2 must be Rt + 1.
7449 if (Rt + 1 != Rt2)
7450 return Error(Op2.getStartLoc(),
7451 IsLoad ? "destination operands must be sequential"
7452 : "source operands must be sequential");
7453
7454 // Rt must be even
7455 if (Rt & 1)
7456 return Error(
7457 Op1.getStartLoc(),
7458 IsLoad ? "destination operands must start start at an even register"
7459 : "source operands must start start at an even register");
7460
7461 MCRegister NewReg = MRI->getMatchingSuperReg(
7462 Reg1, ARM::gsub_0, &(MRI->getRegClass(ARM::GPRPairRegClassID)));
7463 Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7464 Op2.getEndLoc(), *this);
7465 Operands.erase(Operands.begin() + Idx + 1);
7466 }
7467 }
7468
7469 // FIXME: As said above, this is all a pretty gross hack. This instruction
7470 // does not fit with other "subs" and tblgen.
7471 // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
7472 // so the Mnemonic is "subs" and delete the CCOut operand so it will match
7473 // the table entry.
7474 if (isThumbTwo() && Mnemonic == "sub" && CarrySetting &&
7475 Operands.size() == MnemonicOpsEndInd + 3 &&
7476 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).isReg() &&
7477 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]).getReg() ==
7478 ARM::PC &&
7479 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]).isReg() &&
7480 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]).getReg() ==
7481 ARM::LR &&
7482 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 2]).isImm()) {
7483 Operands.front() = ARMOperand::CreateToken("subs", NameLoc, *this);
7484 removeCCOut(Operands, MnemonicOpsEndInd);
7485 }
7486 return false;
7487}
7488
7489// Validate context-sensitive operand constraints.
7490
7491// return 'true' if register list contains non-low GPR registers,
7492// 'false' otherwise. If Reg is in the register list or is HiReg, set
7493// 'containsReg' to true.
7494static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo,
7495 MCRegister Reg, MCRegister HiReg,
7496 bool &containsReg) {
7497 containsReg = false;
7498 for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
7499 MCRegister OpReg = Inst.getOperand(i).getReg();
7500 if (OpReg == Reg)
7501 containsReg = true;
7502 // Anything other than a low register isn't legal here.
7503 if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
7504 return true;
7505 }
7506 return false;
7507}
7508
7509// Check if the specified regisgter is in the register list of the inst,
7510// starting at the indicated operand number.
7511static bool listContainsReg(const MCInst &Inst, unsigned OpNo, MCRegister Reg) {
7512 for (unsigned i = OpNo, e = Inst.getNumOperands(); i < e; ++i) {
7513 MCRegister OpReg = Inst.getOperand(i).getReg();
7514 if (OpReg == Reg)
7515 return true;
7516 }
7517 return false;
7518}
7519
7520// Return true if instruction has the interesting property of being
7521// allowed in IT blocks, but not being predicable.
7522static bool instIsBreakpoint(const MCInst &Inst) {
7523 return Inst.getOpcode() == ARM::tBKPT ||
7524 Inst.getOpcode() == ARM::BKPT ||
7525 Inst.getOpcode() == ARM::tHLT ||
7526 Inst.getOpcode() == ARM::HLT;
7527}
7528
7529unsigned getRegListInd(const OperandVector &Operands,
7530 unsigned MnemonicOpsEndInd) {
7531 for (unsigned I = MnemonicOpsEndInd; I < Operands.size(); ++I) {
7532 const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[I]);
7533 if (Op.isRegList()) {
7534 return I;
7535 }
7536 }
7537 return 0;
7538}
7539
7540bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst,
7541 const OperandVector &Operands,
7542 unsigned MnemonicOpsEndInd,
7543 unsigned ListIndex, bool IsARPop) {
7544 bool ListContainsSP = listContainsReg(Inst, ListIndex, ARM::SP);
7545 bool ListContainsLR = listContainsReg(Inst, ListIndex, ARM::LR);
7546 bool ListContainsPC = listContainsReg(Inst, ListIndex, ARM::PC);
7547
7548 if (!IsARPop && ListContainsSP)
7549 return Error(
7550 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7551 "SP may not be in the register list");
7552 if (ListContainsPC && ListContainsLR)
7553 return Error(
7554 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7555 "PC and LR may not be in the register list simultaneously");
7556 return false;
7557}
7558
7559bool ARMAsmParser::validatetSTMRegList(const MCInst &Inst,
7560 const OperandVector &Operands,
7561 unsigned MnemonicOpsEndInd,
7562 unsigned ListIndex) {
7563 bool ListContainsSP = listContainsReg(Inst, ListIndex, ARM::SP);
7564 bool ListContainsPC = listContainsReg(Inst, ListIndex, ARM::PC);
7565
7566 if (ListContainsSP && ListContainsPC)
7567 return Error(
7568 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7569 "SP and PC may not be in the register list");
7570 if (ListContainsSP)
7571 return Error(
7572 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7573 "SP may not be in the register list");
7574 if (ListContainsPC)
7575 return Error(
7576 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7577 "PC may not be in the register list");
7578 return false;
7579}
7580
7581bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
7582 bool Load, bool ARMMode, bool Writeback,
7583 unsigned MnemonicOpsEndInd) {
7584 unsigned RtIndex = Load || !Writeback ? 0 : 1;
7585 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(RtIndex).getReg());
7586 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(RtIndex + 1).getReg());
7587
7588 if (ARMMode) {
7589 // Rt can't be R14.
7590 if (Rt == 14)
7591 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7592 "Rt can't be R14");
7593
7594 // Rt must be even-numbered.
7595 if ((Rt & 1) == 1)
7596 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7597 "Rt must be even-numbered");
7598
7599 // Rt2 must be Rt + 1.
7600 if (Rt2 != Rt + 1) {
7601 if (Load)
7602 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7603 "destination operands must be sequential");
7604 else
7605 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7606 "source operands must be sequential");
7607 }
7608
7609 // FIXME: Diagnose m == 15
7610 // FIXME: Diagnose ldrd with m == t || m == t2.
7611 }
7612
7613 if (!ARMMode && Load) {
7614 if (Rt2 == Rt)
7615 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7616 "destination operands can't be identical");
7617 }
7618
7619 if (Writeback) {
7620 unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg());
7621
7622 if (Rn == Rt || Rn == Rt2) {
7623 if (Load)
7624 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7625 "base register needs to be different from destination "
7626 "registers");
7627 else
7628 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7629 "source register and base register can't be identical");
7630 }
7631
7632 // FIXME: Diagnose ldrd/strd with writeback and n == 15.
7633 // (Except the immediate form of ldrd?)
7634 }
7635
7636 return false;
7637}
7638
7640 for (unsigned i = 0; i < MCID.NumOperands; ++i) {
7641 if (ARM::isVpred(MCID.operands()[i].OperandType))
7642 return i;
7643 }
7644 return -1;
7645}
7646
7648 return findFirstVectorPredOperandIdx(MCID) != -1;
7649}
7650
7652 ARMOperand &Op = static_cast<ARMOperand &>(MCOp);
7653 if (!Op.isImm())
7654 return false;
7655 return !isa<MCConstantExpr>(Op.getImm());
7656}
7657
7658// FIXME: We would really like to be able to tablegen'erate this.
7659bool ARMAsmParser::validateInstruction(MCInst &Inst,
7660 const OperandVector &Operands,
7661 unsigned MnemonicOpsEndInd) {
7662 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
7663 SMLoc Loc = Operands[0]->getStartLoc();
7664
7665 // Check the IT block state first.
7666 // NOTE: BKPT and HLT instructions have the interesting property of being
7667 // allowed in IT blocks, but not being predicable. They just always execute.
7668 if (inITBlock() && !instIsBreakpoint(Inst)) {
7669 // The instruction must be predicable.
7670 if (!MCID.isPredicable())
7671 return Error(Loc, "instructions in IT block must be predicable");
7674 if (Cond != currentITCond()) {
7675 // Find the condition code Operand to get its SMLoc information.
7676 SMLoc CondLoc = Operands[0]->getEndLoc();
7677 for (unsigned I = 1; I < Operands.size(); ++I)
7678 if (static_cast<ARMOperand &>(*Operands[I]).isCondCode())
7679 CondLoc = Operands[I]->getStartLoc();
7680 return Error(CondLoc, "incorrect condition in IT block; got '" +
7681 StringRef(ARMCondCodeToString(Cond)) +
7682 "', but expected '" +
7683 ARMCondCodeToString(currentITCond()) + "'");
7684 }
7685 // Check for non-'al' condition codes outside of the IT block.
7686 } else if (isThumbTwo() && MCID.isPredicable() &&
7687 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
7688 ARMCC::AL && Inst.getOpcode() != ARM::tBcc &&
7689 Inst.getOpcode() != ARM::t2Bcc &&
7690 Inst.getOpcode() != ARM::t2BFic) {
7691 return Error(Loc, "predicated instructions must be in IT block");
7692 } else if (!isThumb() && !useImplicitITARM() && MCID.isPredicable() &&
7693 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
7694 ARMCC::AL) {
7695 return Warning(Loc, "predicated instructions should be in IT block");
7696 } else if (!MCID.isPredicable()) {
7697 // Check the instruction doesn't have a predicate operand anyway
7698 // that it's not allowed to use. Sometimes this happens in order
7699 // to keep instructions the same shape even though one cannot
7700 // legally be predicated, e.g. vmul.f16 vs vmul.f32.
7701 for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i) {
7702 if (MCID.operands()[i].isPredicate()) {
7703 if (Inst.getOperand(i).getImm() != ARMCC::AL)
7704 return Error(Loc, "instruction is not predicable");
7705 break;
7706 }
7707 }
7708 }
7709
7710 // PC-setting instructions in an IT block, but not the last instruction of
7711 // the block, are UNPREDICTABLE.
7712 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
7713 return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block");
7714 }
7715
7716 if (inVPTBlock() && !instIsBreakpoint(Inst)) {
7717 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
7718 if (!isVectorPredicable(MCID))
7719 return Error(Loc, "instruction in VPT block must be predicable");
7720 unsigned Pred = Inst.getOperand(findFirstVectorPredOperandIdx(MCID)).getImm();
7721 unsigned VPTPred = Bit ? ARMVCC::Else : ARMVCC::Then;
7722 if (Pred != VPTPred) {
7723 SMLoc PredLoc;
7724 for (unsigned I = 1; I < Operands.size(); ++I)
7725 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred())
7726 PredLoc = Operands[I]->getStartLoc();
7727 return Error(PredLoc, "incorrect predication in VPT block; got '" +
7728 StringRef(ARMVPTPredToString(ARMVCC::VPTCodes(Pred))) +
7729 "', but expected '" +
7730 ARMVPTPredToString(ARMVCC::VPTCodes(VPTPred)) + "'");
7731 }
7732 }
7733 else if (isVectorPredicable(MCID) &&
7736 return Error(Loc, "VPT predicated instructions must be in VPT block");
7737
7738 const unsigned Opcode = Inst.getOpcode();
7739 switch (Opcode) {
7740 case ARM::VLLDM:
7741 case ARM::VLLDM_T2:
7742 case ARM::VLSTM:
7743 case ARM::VLSTM_T2: {
7744 // Since in some cases both T1 and T2 are valid, tablegen can not always
7745 // pick the correct instruction.
7746 if (Operands.size() ==
7747 MnemonicOpsEndInd + 2) { // a register list has been provided
7748 ARMOperand &Op = static_cast<ARMOperand &>(
7749 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
7750 assert(Op.isDPRRegList());
7751 auto &RegList = Op.getRegList();
7752 // T2 requires v8.1-M.Main (cannot be handled by tablegen)
7753 if (RegList.size() == 32 && !hasV8_1MMainline()) {
7754 return Error(Op.getEndLoc(), "T2 version requires v8.1-M.Main");
7755 }
7756 // When target has 32 D registers, T1 is undefined.
7757 if (hasD32() && RegList.size() != 32) {
7758 return Error(Op.getEndLoc(), "operand must be exactly {d0-d31}");
7759 }
7760 // When target has 16 D registers, both T1 and T2 are valid.
7761 if (!hasD32() && (RegList.size() != 16 && RegList.size() != 32)) {
7762 return Error(Op.getEndLoc(),
7763 "operand must be exactly {d0-d15} (T1) or {d0-d31} (T2)");
7764 }
7765 }
7766 return false;
7767 }
7768 case ARM::t2IT: {
7769 // Encoding is unpredictable if it ever results in a notional 'NV'
7770 // predicate. Since we don't parse 'NV' directly this means an 'AL'
7771 // predicate with an "else" mask bit.
7772 unsigned Cond = Inst.getOperand(0).getImm();
7773 unsigned Mask = Inst.getOperand(1).getImm();
7774
7775 // Conditions only allowing a 't' are those with no set bit except
7776 // the lowest-order one that indicates the end of the sequence. In
7777 // other words, powers of 2.
7778 if (Cond == ARMCC::AL && llvm::popcount(Mask) != 1)
7779 return Error(Loc, "unpredictable IT predicate sequence");
7780 break;
7781 }
7782 case ARM::LDRD:
7783 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ true,
7784 /*Writeback*/ false, MnemonicOpsEndInd))
7785 return true;
7786 break;
7787 case ARM::LDRD_PRE:
7788 case ARM::LDRD_POST:
7789 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ true,
7790 /*Writeback*/ true, MnemonicOpsEndInd))
7791 return true;
7792 break;
7793 case ARM::t2LDRDi8:
7794 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ false,
7795 /*Writeback*/ false, MnemonicOpsEndInd))
7796 return true;
7797 break;
7798 case ARM::t2LDRD_PRE:
7799 case ARM::t2LDRD_POST:
7800 if (validateLDRDSTRD(Inst, Operands, /*Load*/ true, /*ARMMode*/ false,
7801 /*Writeback*/ true, MnemonicOpsEndInd))
7802 return true;
7803 break;
7804 case ARM::t2BXJ: {
7805 const MCRegister RmReg = Inst.getOperand(0).getReg();
7806 // Rm = SP is no longer unpredictable in v8-A
7807 if (RmReg == ARM::SP && !hasV8Ops())
7808 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7809 "r13 (SP) is an unpredictable operand to BXJ");
7810 return false;
7811 }
7812 case ARM::STRD:
7813 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ true,
7814 /*Writeback*/ false, MnemonicOpsEndInd))
7815 return true;
7816 break;
7817 case ARM::STRD_PRE:
7818 case ARM::STRD_POST:
7819 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ true,
7820 /*Writeback*/ true, MnemonicOpsEndInd))
7821 return true;
7822 break;
7823 case ARM::t2STRD_PRE:
7824 case ARM::t2STRD_POST:
7825 if (validateLDRDSTRD(Inst, Operands, /*Load*/ false, /*ARMMode*/ false,
7826 /*Writeback*/ true, MnemonicOpsEndInd))
7827 return true;
7828 break;
7829 case ARM::STR_PRE_IMM:
7830 case ARM::STR_PRE_REG:
7831 case ARM::t2STR_PRE:
7832 case ARM::STR_POST_IMM:
7833 case ARM::STR_POST_REG:
7834 case ARM::t2STR_POST:
7835 case ARM::STRH_PRE:
7836 case ARM::t2STRH_PRE:
7837 case ARM::STRH_POST:
7838 case ARM::t2STRH_POST:
7839 case ARM::STRB_PRE_IMM:
7840 case ARM::STRB_PRE_REG:
7841 case ARM::t2STRB_PRE:
7842 case ARM::STRB_POST_IMM:
7843 case ARM::STRB_POST_REG:
7844 case ARM::t2STRB_POST: {
7845 // Rt must be different from Rn.
7846 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7847 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
7848
7849 if (Rt == Rn)
7850 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7851 "source register and base register can't be identical");
7852 return false;
7853 }
7854 case ARM::t2LDR_PRE_imm:
7855 case ARM::t2LDR_POST_imm:
7856 case ARM::t2STR_PRE_imm:
7857 case ARM::t2STR_POST_imm: {
7858 // Rt must be different from Rn.
7859 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
7860 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(1).getReg());
7861
7862 if (Rt == Rn)
7863 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7864 "destination register and base register can't be identical");
7865 if (Inst.getOpcode() == ARM::t2LDR_POST_imm ||
7866 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7867 int Imm = Inst.getOperand(2).getImm();
7868 if (Imm > 255 || Imm < -255)
7869 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7870 "operand must be in range [-255, 255]");
7871 }
7872 if (Inst.getOpcode() == ARM::t2STR_PRE_imm ||
7873 Inst.getOpcode() == ARM::t2STR_POST_imm) {
7874 if (Inst.getOperand(0).getReg() == ARM::PC) {
7875 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7876 "operand must be a register in range [r0, r14]");
7877 }
7878 }
7879 return false;
7880 }
7881
7882 case ARM::t2LDRB_OFFSET_imm:
7883 case ARM::t2LDRB_PRE_imm:
7884 case ARM::t2LDRB_POST_imm:
7885 case ARM::t2STRB_OFFSET_imm:
7886 case ARM::t2STRB_PRE_imm:
7887 case ARM::t2STRB_POST_imm: {
7888 if (Inst.getOpcode() == ARM::t2LDRB_POST_imm ||
7889 Inst.getOpcode() == ARM::t2STRB_POST_imm ||
7890 Inst.getOpcode() == ARM::t2LDRB_PRE_imm ||
7891 Inst.getOpcode() == ARM::t2STRB_PRE_imm) {
7892 int Imm = Inst.getOperand(2).getImm();
7893 if (Imm > 255 || Imm < -255)
7894 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7895 "operand must be in range [-255, 255]");
7896 } else if (Inst.getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7897 Inst.getOpcode() == ARM::t2STRB_OFFSET_imm) {
7898 int Imm = Inst.getOperand(2).getImm();
7899 if (Imm > 0 || Imm < -255)
7900 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7901 "operand must be in range [0, 255] with a negative sign");
7902 }
7903 if (Inst.getOperand(0).getReg() == ARM::PC) {
7904 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7905 "if operand is PC, should call the LDRB (literal)");
7906 }
7907 return false;
7908 }
7909
7910 case ARM::t2LDRH_OFFSET_imm:
7911 case ARM::t2LDRH_PRE_imm:
7912 case ARM::t2LDRH_POST_imm:
7913 case ARM::t2STRH_OFFSET_imm:
7914 case ARM::t2STRH_PRE_imm:
7915 case ARM::t2STRH_POST_imm: {
7916 if (Inst.getOpcode() == ARM::t2LDRH_POST_imm ||
7917 Inst.getOpcode() == ARM::t2STRH_POST_imm ||
7918 Inst.getOpcode() == ARM::t2LDRH_PRE_imm ||
7919 Inst.getOpcode() == ARM::t2STRH_PRE_imm) {
7920 int Imm = Inst.getOperand(2).getImm();
7921 if (Imm > 255 || Imm < -255)
7922 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7923 "operand must be in range [-255, 255]");
7924 } else if (Inst.getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7925 Inst.getOpcode() == ARM::t2STRH_OFFSET_imm) {
7926 int Imm = Inst.getOperand(2).getImm();
7927 if (Imm > 0 || Imm < -255)
7928 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7929 "operand must be in range [0, 255] with a negative sign");
7930 }
7931 if (Inst.getOperand(0).getReg() == ARM::PC) {
7932 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7933 "if operand is PC, should call the LDRH (literal)");
7934 }
7935 return false;
7936 }
7937
7938 case ARM::t2LDRSB_OFFSET_imm:
7939 case ARM::t2LDRSB_PRE_imm:
7940 case ARM::t2LDRSB_POST_imm: {
7941 if (Inst.getOpcode() == ARM::t2LDRSB_POST_imm ||
7942 Inst.getOpcode() == ARM::t2LDRSB_PRE_imm) {
7943 int Imm = Inst.getOperand(2).getImm();
7944 if (Imm > 255 || Imm < -255)
7945 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7946 "operand must be in range [-255, 255]");
7947 } else if (Inst.getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7948 int Imm = Inst.getOperand(2).getImm();
7949 if (Imm > 0 || Imm < -255)
7950 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7951 "operand must be in range [0, 255] with a negative sign");
7952 }
7953 if (Inst.getOperand(0).getReg() == ARM::PC) {
7954 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7955 "if operand is PC, should call the LDRH (literal)");
7956 }
7957 return false;
7958 }
7959
7960 case ARM::t2LDRSH_OFFSET_imm:
7961 case ARM::t2LDRSH_PRE_imm:
7962 case ARM::t2LDRSH_POST_imm: {
7963 if (Inst.getOpcode() == ARM::t2LDRSH_POST_imm ||
7964 Inst.getOpcode() == ARM::t2LDRSH_PRE_imm) {
7965 int Imm = Inst.getOperand(2).getImm();
7966 if (Imm > 255 || Imm < -255)
7967 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7968 "operand must be in range [-255, 255]");
7969 } else if (Inst.getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7970 int Imm = Inst.getOperand(2).getImm();
7971 if (Imm > 0 || Imm < -255)
7972 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7973 "operand must be in range [0, 255] with a negative sign");
7974 }
7975 if (Inst.getOperand(0).getReg() == ARM::PC) {
7976 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7977 "if operand is PC, should call the LDRH (literal)");
7978 }
7979 return false;
7980 }
7981
7982 case ARM::LDR_PRE_IMM:
7983 case ARM::LDR_PRE_REG:
7984 case ARM::t2LDR_PRE:
7985 case ARM::LDR_POST_IMM:
7986 case ARM::LDR_POST_REG:
7987 case ARM::t2LDR_POST:
7988 case ARM::LDRH_PRE:
7989 case ARM::t2LDRH_PRE:
7990 case ARM::LDRH_POST:
7991 case ARM::t2LDRH_POST:
7992 case ARM::LDRSH_PRE:
7993 case ARM::t2LDRSH_PRE:
7994 case ARM::LDRSH_POST:
7995 case ARM::t2LDRSH_POST:
7996 case ARM::LDRB_PRE_IMM:
7997 case ARM::LDRB_PRE_REG:
7998 case ARM::t2LDRB_PRE:
7999 case ARM::LDRB_POST_IMM:
8000 case ARM::LDRB_POST_REG:
8001 case ARM::t2LDRB_POST:
8002 case ARM::LDRSB_PRE:
8003 case ARM::t2LDRSB_PRE:
8004 case ARM::LDRSB_POST:
8005 case ARM::t2LDRSB_POST: {
8006 // Rt must be different from Rn.
8007 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8008 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8009
8010 if (Rt == Rn)
8011 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8012 "destination register and base register can't be identical");
8013 return false;
8014 }
8015
8016 case ARM::MVE_VLDRBU8_rq:
8017 case ARM::MVE_VLDRBU16_rq:
8018 case ARM::MVE_VLDRBS16_rq:
8019 case ARM::MVE_VLDRBU32_rq:
8020 case ARM::MVE_VLDRBS32_rq:
8021 case ARM::MVE_VLDRHU16_rq:
8022 case ARM::MVE_VLDRHU16_rq_u:
8023 case ARM::MVE_VLDRHU32_rq:
8024 case ARM::MVE_VLDRHU32_rq_u:
8025 case ARM::MVE_VLDRHS32_rq:
8026 case ARM::MVE_VLDRHS32_rq_u:
8027 case ARM::MVE_VLDRWU32_rq:
8028 case ARM::MVE_VLDRWU32_rq_u:
8029 case ARM::MVE_VLDRDU64_rq:
8030 case ARM::MVE_VLDRDU64_rq_u:
8031 case ARM::MVE_VLDRWU32_qi:
8032 case ARM::MVE_VLDRWU32_qi_pre:
8033 case ARM::MVE_VLDRDU64_qi:
8034 case ARM::MVE_VLDRDU64_qi_pre: {
8035 // Qd must be different from Qm.
8036 unsigned QdIdx = 0, QmIdx = 2;
8037 bool QmIsPointer = false;
8038 switch (Opcode) {
8039 case ARM::MVE_VLDRWU32_qi:
8040 case ARM::MVE_VLDRDU64_qi:
8041 QmIdx = 1;
8042 QmIsPointer = true;
8043 break;
8044 case ARM::MVE_VLDRWU32_qi_pre:
8045 case ARM::MVE_VLDRDU64_qi_pre:
8046 QdIdx = 1;
8047 QmIsPointer = true;
8048 break;
8049 }
8050
8051 const unsigned Qd = MRI->getEncodingValue(Inst.getOperand(QdIdx).getReg());
8052 const unsigned Qm = MRI->getEncodingValue(Inst.getOperand(QmIdx).getReg());
8053
8054 if (Qd == Qm) {
8055 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8056 Twine("destination vector register and vector ") +
8057 (QmIsPointer ? "pointer" : "offset") +
8058 " register can't be identical");
8059 }
8060 return false;
8061 }
8062
8063 case ARM::SBFX:
8064 case ARM::t2SBFX:
8065 case ARM::UBFX:
8066 case ARM::t2UBFX: {
8067 // Width must be in range [1, 32-lsb].
8068 unsigned LSB = Inst.getOperand(2).getImm();
8069 unsigned Widthm1 = Inst.getOperand(3).getImm();
8070 if (Widthm1 >= 32 - LSB)
8071 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8072 "bitfield width must be in range [1,32-lsb]");
8073 return false;
8074 }
8075 // Notionally handles ARM::tLDMIA_UPD too.
8076 case ARM::tLDMIA: {
8077 // If we're parsing Thumb2, the .w variant is available and handles
8078 // most cases that are normally illegal for a Thumb1 LDM instruction.
8079 // We'll make the transformation in processInstruction() if necessary.
8080 //
8081 // Thumb LDM instructions are writeback iff the base register is not
8082 // in the register list.
8083 MCRegister Rn = Inst.getOperand(0).getReg();
8084 bool HasWritebackToken =
8085 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8086 .isToken() &&
8087 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8088 .getToken() == "!");
8089
8090 bool ListContainsBase;
8091 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), ListContainsBase) &&
8092 !isThumbTwo())
8093 return Error(
8094 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8095 "registers must be in range r0-r7");
8096 // If we should have writeback, then there should be a '!' token.
8097 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8098 return Error(
8099 Operands[getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8100 "writeback operator '!' expected");
8101 // If we should not have writeback, there must not be a '!'. This is
8102 // true even for the 32-bit wide encodings.
8103 if (ListContainsBase && HasWritebackToken)
8104 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8105 "writeback operator '!' not allowed when base register "
8106 "in register list");
8107
8108 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8109 return true;
8110 break;
8111 }
8112 case ARM::LDMIA_UPD:
8113 case ARM::LDMDB_UPD:
8114 case ARM::LDMIB_UPD:
8115 case ARM::LDMDA_UPD:
8116 // ARM variants loading and updating the same register are only officially
8117 // UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
8118 if (!hasV7Ops())
8119 break;
8120 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8121 return Error(Operands.back()->getStartLoc(),
8122 "writeback register not allowed in register list");
8123 break;
8124 case ARM::t2LDMIA:
8125 case ARM::t2LDMDB:
8126 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8127 return true;
8128 break;
8129 case ARM::t2STMIA:
8130 case ARM::t2STMDB:
8131 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8132 return true;
8133 break;
8134 case ARM::t2LDMIA_UPD:
8135 case ARM::t2LDMDB_UPD:
8136 case ARM::t2STMIA_UPD:
8137 case ARM::t2STMDB_UPD:
8138 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
8139 return Error(Operands.back()->getStartLoc(),
8140 "writeback register not allowed in register list");
8141
8142 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8143 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8144 return true;
8145 } else {
8146 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8147 return true;
8148 }
8149 break;
8150
8151 case ARM::sysLDMIA_UPD:
8152 case ARM::sysLDMDA_UPD:
8153 case ARM::sysLDMDB_UPD:
8154 case ARM::sysLDMIB_UPD:
8155 if (!listContainsReg(Inst, 3, ARM::PC))
8156 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8157 "writeback register only allowed on system LDM "
8158 "if PC in register-list");
8159 break;
8160 case ARM::sysSTMIA_UPD:
8161 case ARM::sysSTMDA_UPD:
8162 case ARM::sysSTMDB_UPD:
8163 case ARM::sysSTMIB_UPD:
8164 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8165 "system STM cannot have writeback register");
8166 // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
8167 // so only issue a diagnostic for thumb1. The instructions will be
8168 // switched to the t2 encodings in processInstruction() if necessary.
8169 case ARM::tPOP: {
8170 bool ListContainsBase;
8171 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC,
8172 ListContainsBase) &&
8173 !isThumbTwo())
8174 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8175 "registers must be in range r0-r7 or pc");
8176 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 2, !isMClass()))
8177 return true;
8178 break;
8179 }
8180 case ARM::tPUSH: {
8181 bool ListContainsBase;
8182 if (checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR,
8183 ListContainsBase) &&
8184 !isThumbTwo())
8185 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8186 "registers must be in range r0-r7 or lr");
8187 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 2))
8188 return true;
8189 break;
8190 }
8191 case ARM::tSTMIA_UPD: {
8192 bool ListContainsBase, InvalidLowList;
8193 InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(),
8194 0, ListContainsBase);
8195 if (InvalidLowList && !isThumbTwo())
8196 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8197 "registers must be in range r0-r7");
8198
8199 // This would be converted to a 32-bit stm, but that's not valid if the
8200 // writeback register is in the list.
8201 if (InvalidLowList && ListContainsBase)
8202 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8203 "writeback operator '!' not allowed when base register "
8204 "in register list");
8205
8206 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 4))
8207 return true;
8208 break;
8209 }
8210 case ARM::tADDrSP:
8211 // If the non-SP source operand and the destination operand are not the
8212 // same, we need thumb2 (for the wide encoding), or we have an error.
8213 if (!isThumbTwo() &&
8214 Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
8215 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8216 "source register must be the same as destination");
8217 }
8218 break;
8219
8220 case ARM::t2ADDrr:
8221 case ARM::t2ADDrs:
8222 case ARM::t2SUBrr:
8223 case ARM::t2SUBrs:
8224 if (Inst.getOperand(0).getReg() == ARM::SP &&
8225 Inst.getOperand(1).getReg() != ARM::SP)
8226 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8227 "source register must be sp if destination is sp");
8228 break;
8229
8230 // Final range checking for Thumb unconditional branch instructions.
8231 case ARM::tB:
8232 if (!(static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd]))
8233 .isSignedOffset<11, 1>())
8234 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8235 "branch target out of range");
8236 break;
8237 case ARM::t2B: {
8238 int op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8239 : MnemonicOpsEndInd + 1;
8240 ARMOperand &Operand = static_cast<ARMOperand &>(*Operands[op]);
8241 // Delay the checks of symbolic expressions until they are resolved.
8242 if (!isa<MCBinaryExpr>(Operand.getImm()) &&
8243 !Operand.isSignedOffset<24, 1>())
8244 return Error(Operands[op]->getStartLoc(), "branch target out of range");
8245 break;
8246 }
8247 // Final range checking for Thumb conditional branch instructions.
8248 case ARM::tBcc:
8249 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8250 .isSignedOffset<8, 1>())
8251 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8252 "branch target out of range");
8253 break;
8254 case ARM::t2Bcc: {
8255 int Op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8256 : MnemonicOpsEndInd + 1;
8257 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
8258 return Error(Operands[Op]->getStartLoc(), "branch target out of range");
8259 break;
8260 }
8261 case ARM::tCBZ:
8262 case ARM::tCBNZ: {
8263 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8264 .isUnsignedOffset<6, 1>())
8265 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8266 "branch target out of range");
8267 break;
8268 }
8269 case ARM::MOVi16:
8270 case ARM::MOVTi16:
8271 case ARM::t2MOVi16:
8272 case ARM::t2MOVTi16:
8273 {
8274 // We want to avoid misleadingly allowing something like "mov r0, <symbol>"
8275 // especially when we turn it into a movw and the expression <symbol> does
8276 // not have a :lower16: or :upper16 as part of the expression. We don't
8277 // want the behavior of silently truncating, which can be unexpected and
8278 // lead to bugs that are difficult to find since this is an easy mistake
8279 // to make.
8280 int i = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8281 : MnemonicOpsEndInd + 1;
8282 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[i]);
8283 const MCExpr *E = Op.getImm();
8285 break;
8286 auto *ARM16Expr = dyn_cast<MCSpecifierExpr>(E);
8287 if (!ARM16Expr || (ARM16Expr->getSpecifier() != ARM::S_HI16 &&
8288 ARM16Expr->getSpecifier() != ARM::S_LO16))
8289 return Error(
8290 Op.getStartLoc(),
8291 "immediate expression for mov requires :lower16: or :upper16");
8292 break;
8293 }
8294 case ARM::tADDi8: {
8295 int i = (Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8296 : MnemonicOpsEndInd + 2;
8297 MCParsedAsmOperand &Op = *Operands[i];
8299 return Error(Op.getStartLoc(),
8300 "Immediate expression for Thumb adds requires :lower0_7:,"
8301 " :lower8_15:, :upper0_7: or :upper8_15:");
8302 break;
8303 }
8304 case ARM::tMOVi8: {
8305 MCParsedAsmOperand &Op = *Operands[MnemonicOpsEndInd + 1];
8307 return Error(Op.getStartLoc(),
8308 "Immediate expression for Thumb movs requires :lower0_7:,"
8309 " :lower8_15:, :upper0_7: or :upper8_15:");
8310 break;
8311 }
8312 case ARM::HINT:
8313 case ARM::t2HINT: {
8314 unsigned Imm8 = Inst.getOperand(0).getImm();
8315 unsigned Pred = Inst.getOperand(1).getImm();
8316 // ESB is not predicable (pred must be AL). Without the RAS extension, this
8317 // behaves as any other unallocated hint.
8318 if (Imm8 == 0x10 && Pred != ARMCC::AL && hasRAS())
8319 return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not "
8320 "predicable, but condition "
8321 "code specified");
8322 if (Imm8 == 0x14 && Pred != ARMCC::AL)
8323 return Error(Operands[1]->getStartLoc(), "instruction 'csdb' is not "
8324 "predicable, but condition "
8325 "code specified");
8326 break;
8327 }
8328 case ARM::t2BFi:
8329 case ARM::t2BFr:
8330 case ARM::t2BFLi:
8331 case ARM::t2BFLr: {
8332 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8333 .isUnsignedOffset<4, 1>() ||
8334 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0)) {
8335 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8336 "branch location out of range or not a multiple of 2");
8337 }
8338
8339 if (Opcode == ARM::t2BFi) {
8340 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8341 .isSignedOffset<16, 1>())
8342 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8343 "branch target out of range or not a multiple of 2");
8344 } else if (Opcode == ARM::t2BFLi) {
8345 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8346 .isSignedOffset<18, 1>())
8347 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8348 "branch target out of range or not a multiple of 2");
8349 }
8350 break;
8351 }
8352 case ARM::t2BFic: {
8353 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd])
8354 .isUnsignedOffset<4, 1>() ||
8355 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0))
8356 return Error(Operands[1]->getStartLoc(),
8357 "branch location out of range or not a multiple of 2");
8358
8359 if (!static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8360 .isSignedOffset<16, 1>())
8361 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8362 "branch target out of range or not a multiple of 2");
8363
8364 assert(Inst.getOperand(0).isImm() == Inst.getOperand(2).isImm() &&
8365 "branch location and else branch target should either both be "
8366 "immediates or both labels");
8367
8368 if (Inst.getOperand(0).isImm() && Inst.getOperand(2).isImm()) {
8369 int Diff = Inst.getOperand(2).getImm() - Inst.getOperand(0).getImm();
8370 if (Diff != 4 && Diff != 2)
8371 return Error(
8372 Operands[3]->getStartLoc(),
8373 "else branch target must be 2 or 4 greater than the branch location");
8374 }
8375 break;
8376 }
8377 case ARM::t2CLRM: {
8378 for (unsigned i = 2; i < Inst.getNumOperands(); i++) {
8379 if (Inst.getOperand(i).isReg() &&
8380 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8381 .contains(Inst.getOperand(i).getReg())) {
8382 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8383 "invalid register in register list. Valid registers are "
8384 "r0-r12, lr/r14 and APSR.");
8385 }
8386 }
8387 break;
8388 }
8389 case ARM::DSB:
8390 case ARM::t2DSB: {
8391
8392 if (Inst.getNumOperands() < 2)
8393 break;
8394
8395 unsigned Option = Inst.getOperand(0).getImm();
8396 unsigned Pred = Inst.getOperand(1).getImm();
8397
8398 // SSBB and PSSBB (DSB #0|#4) are not predicable (pred must be AL).
8399 if (Option == 0 && Pred != ARMCC::AL)
8400 return Error(Operands[1]->getStartLoc(),
8401 "instruction 'ssbb' is not predicable, but condition code "
8402 "specified");
8403 if (Option == 4 && Pred != ARMCC::AL)
8404 return Error(Operands[1]->getStartLoc(),
8405 "instruction 'pssbb' is not predicable, but condition code "
8406 "specified");
8407 break;
8408 }
8409 case ARM::VMOVRRS: {
8410 // Source registers must be sequential.
8411 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(2).getReg());
8412 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(3).getReg());
8413 if (Sm1 != Sm + 1)
8414 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8415 "source operands must be sequential");
8416 break;
8417 }
8418 case ARM::VMOVSRR: {
8419 // Destination registers must be sequential.
8420 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(0).getReg());
8421 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
8422 if (Sm1 != Sm + 1)
8423 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8424 "destination operands must be sequential");
8425 break;
8426 }
8427 case ARM::VLDMDIA:
8428 case ARM::VSTMDIA: {
8429 ARMOperand &Op =
8430 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
8431 auto &RegList = Op.getRegList();
8432 if (RegList.size() < 1 || RegList.size() > 16)
8433 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8434 "list of registers must be at least 1 and at most 16");
8435 break;
8436 }
8437 case ARM::MVE_VQDMULLs32bh:
8438 case ARM::MVE_VQDMULLs32th:
8439 case ARM::MVE_VCMULf32:
8440 case ARM::MVE_VMULLBs32:
8441 case ARM::MVE_VMULLTs32:
8442 case ARM::MVE_VMULLBu32:
8443 case ARM::MVE_VMULLTu32: {
8444 if (Operands[MnemonicOpsEndInd]->getReg() ==
8445 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8446 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8447 "Qd register and Qn register can't be identical");
8448 }
8449 if (Operands[MnemonicOpsEndInd]->getReg() ==
8450 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8451 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8452 "Qd register and Qm register can't be identical");
8453 }
8454 break;
8455 }
8456 case ARM::MVE_VREV64_8:
8457 case ARM::MVE_VREV64_16:
8458 case ARM::MVE_VREV64_32:
8459 case ARM::MVE_VQDMULL_qr_s32bh:
8460 case ARM::MVE_VQDMULL_qr_s32th: {
8461 if (Operands[MnemonicOpsEndInd]->getReg() ==
8462 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8463 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8464 "Qd register and Qn register can't be identical");
8465 }
8466 break;
8467 }
8468 case ARM::MVE_VCADDi32:
8469 case ARM::MVE_VCADDf32:
8470 case ARM::MVE_VHCADDs32: {
8471 if (Operands[MnemonicOpsEndInd]->getReg() ==
8472 Operands[MnemonicOpsEndInd + 2]->getReg()) {
8473 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8474 "Qd register and Qm register can't be identical");
8475 }
8476 break;
8477 }
8478 case ARM::MVE_VMOV_rr_q: {
8479 if (Operands[MnemonicOpsEndInd + 2]->getReg() !=
8480 Operands[MnemonicOpsEndInd + 4]->getReg())
8481 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8482 "Q-registers must be the same");
8483 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8484 .getVectorIndex() !=
8485 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 5])
8486 .getVectorIndex() +
8487 2)
8488 return Error(Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8489 "Q-register indexes must be 2 and 0 or 3 and 1");
8490 break;
8491 }
8492 case ARM::MVE_VMOV_q_rr: {
8493 if (Operands[MnemonicOpsEndInd]->getReg() !=
8494 Operands[MnemonicOpsEndInd + 2]->getReg())
8495 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8496 "Q-registers must be the same");
8497 if (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
8498 .getVectorIndex() !=
8499 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 3])
8500 .getVectorIndex() +
8501 2)
8502 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8503 "Q-register indexes must be 2 and 0 or 3 and 1");
8504 break;
8505 }
8506 case ARM::MVE_SQRSHR:
8507 case ARM::MVE_UQRSHL: {
8508 if (Operands[MnemonicOpsEndInd]->getReg() ==
8509 Operands[MnemonicOpsEndInd + 1]->getReg()) {
8510 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8511 "Rda register and Rm register can't be identical");
8512 }
8513 break;
8514 }
8515 case ARM::UMAAL:
8516 case ARM::UMLAL:
8517 case ARM::UMULL:
8518 case ARM::t2UMAAL:
8519 case ARM::t2UMLAL:
8520 case ARM::t2UMULL:
8521 case ARM::SMLAL:
8522 case ARM::SMLALBB:
8523 case ARM::SMLALBT:
8524 case ARM::SMLALD:
8525 case ARM::SMLALDX:
8526 case ARM::SMLALTB:
8527 case ARM::SMLALTT:
8528 case ARM::SMLSLD:
8529 case ARM::SMLSLDX:
8530 case ARM::SMULL:
8531 case ARM::t2SMLAL:
8532 case ARM::t2SMLALBB:
8533 case ARM::t2SMLALBT:
8534 case ARM::t2SMLALD:
8535 case ARM::t2SMLALDX:
8536 case ARM::t2SMLALTB:
8537 case ARM::t2SMLALTT:
8538 case ARM::t2SMLSLD:
8539 case ARM::t2SMLSLDX:
8540 case ARM::t2SMULL: {
8541 MCRegister RdHi = Inst.getOperand(0).getReg();
8542 MCRegister RdLo = Inst.getOperand(1).getReg();
8543 if(RdHi == RdLo) {
8544 return Error(Loc,
8545 "unpredictable instruction, RdHi and RdLo must be different");
8546 }
8547 break;
8548 }
8549
8550 case ARM::CDE_CX1:
8551 case ARM::CDE_CX1A:
8552 case ARM::CDE_CX1D:
8553 case ARM::CDE_CX1DA:
8554 case ARM::CDE_CX2:
8555 case ARM::CDE_CX2A:
8556 case ARM::CDE_CX2D:
8557 case ARM::CDE_CX2DA:
8558 case ARM::CDE_CX3:
8559 case ARM::CDE_CX3A:
8560 case ARM::CDE_CX3D:
8561 case ARM::CDE_CX3DA:
8562 case ARM::CDE_VCX1_vec:
8563 case ARM::CDE_VCX1_fpsp:
8564 case ARM::CDE_VCX1_fpdp:
8565 case ARM::CDE_VCX1A_vec:
8566 case ARM::CDE_VCX1A_fpsp:
8567 case ARM::CDE_VCX1A_fpdp:
8568 case ARM::CDE_VCX2_vec:
8569 case ARM::CDE_VCX2_fpsp:
8570 case ARM::CDE_VCX2_fpdp:
8571 case ARM::CDE_VCX2A_vec:
8572 case ARM::CDE_VCX2A_fpsp:
8573 case ARM::CDE_VCX2A_fpdp:
8574 case ARM::CDE_VCX3_vec:
8575 case ARM::CDE_VCX3_fpsp:
8576 case ARM::CDE_VCX3_fpdp:
8577 case ARM::CDE_VCX3A_vec:
8578 case ARM::CDE_VCX3A_fpsp:
8579 case ARM::CDE_VCX3A_fpdp: {
8580 assert(Inst.getOperand(1).isImm() &&
8581 "CDE operand 1 must be a coprocessor ID");
8582 int64_t Coproc = Inst.getOperand(1).getImm();
8583 if (Coproc < 8 && !ARM::isCDECoproc(Coproc, *STI))
8584 return Error(Operands[1]->getStartLoc(),
8585 "coprocessor must be configured as CDE");
8586 else if (Coproc >= 8)
8587 return Error(Operands[1]->getStartLoc(),
8588 "coprocessor must be in the range [p0, p7]");
8589 break;
8590 }
8591
8592 case ARM::t2CDP:
8593 case ARM::t2CDP2:
8594 case ARM::t2LDC2L_OFFSET:
8595 case ARM::t2LDC2L_OPTION:
8596 case ARM::t2LDC2L_POST:
8597 case ARM::t2LDC2L_PRE:
8598 case ARM::t2LDC2_OFFSET:
8599 case ARM::t2LDC2_OPTION:
8600 case ARM::t2LDC2_POST:
8601 case ARM::t2LDC2_PRE:
8602 case ARM::t2LDCL_OFFSET:
8603 case ARM::t2LDCL_OPTION:
8604 case ARM::t2LDCL_POST:
8605 case ARM::t2LDCL_PRE:
8606 case ARM::t2LDC_OFFSET:
8607 case ARM::t2LDC_OPTION:
8608 case ARM::t2LDC_POST:
8609 case ARM::t2LDC_PRE:
8610 case ARM::t2MCR:
8611 case ARM::t2MCR2:
8612 case ARM::t2MCRR:
8613 case ARM::t2MCRR2:
8614 case ARM::t2MRC:
8615 case ARM::t2MRC2:
8616 case ARM::t2MRRC:
8617 case ARM::t2MRRC2:
8618 case ARM::t2STC2L_OFFSET:
8619 case ARM::t2STC2L_OPTION:
8620 case ARM::t2STC2L_POST:
8621 case ARM::t2STC2L_PRE:
8622 case ARM::t2STC2_OFFSET:
8623 case ARM::t2STC2_OPTION:
8624 case ARM::t2STC2_POST:
8625 case ARM::t2STC2_PRE:
8626 case ARM::t2STCL_OFFSET:
8627 case ARM::t2STCL_OPTION:
8628 case ARM::t2STCL_POST:
8629 case ARM::t2STCL_PRE:
8630 case ARM::t2STC_OFFSET:
8631 case ARM::t2STC_OPTION:
8632 case ARM::t2STC_POST:
8633 case ARM::t2STC_PRE: {
8634 unsigned Opcode = Inst.getOpcode();
8635 // Inst.getOperand indexes operands in the (oops ...) and (iops ...) dags,
8636 // CopInd is the index of the coprocessor operand.
8637 size_t CopInd = 0;
8638 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8639 CopInd = 2;
8640 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8641 CopInd = 1;
8642 assert(Inst.getOperand(CopInd).isImm() &&
8643 "Operand must be a coprocessor ID");
8644 int64_t Coproc = Inst.getOperand(CopInd).getImm();
8645 // Operands[2] is the coprocessor operand at syntactic level
8646 if (ARM::isCDECoproc(Coproc, *STI))
8647 return Error(Operands[2]->getStartLoc(),
8648 "coprocessor must be configured as GCP");
8649 break;
8650 }
8651
8652 case ARM::VTOSHH:
8653 case ARM::VTOUHH:
8654 case ARM::VTOSLH:
8655 case ARM::VTOULH:
8656 case ARM::VTOSHS:
8657 case ARM::VTOUHS:
8658 case ARM::VTOSLS:
8659 case ARM::VTOULS:
8660 case ARM::VTOSHD:
8661 case ARM::VTOUHD:
8662 case ARM::VTOSLD:
8663 case ARM::VTOULD:
8664 case ARM::VSHTOH:
8665 case ARM::VUHTOH:
8666 case ARM::VSLTOH:
8667 case ARM::VULTOH:
8668 case ARM::VSHTOS:
8669 case ARM::VUHTOS:
8670 case ARM::VSLTOS:
8671 case ARM::VULTOS:
8672 case ARM::VSHTOD:
8673 case ARM::VUHTOD:
8674 case ARM::VSLTOD:
8675 case ARM::VULTOD: {
8676 if (Operands[MnemonicOpsEndInd]->getReg() !=
8677 Operands[MnemonicOpsEndInd + 1]->getReg())
8678 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8679 "source and destination registers must be the same");
8680 break;
8681 }
8682 }
8683
8684 return false;
8685}
8686
8687static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
8688 switch(Opc) {
8689 default: llvm_unreachable("unexpected opcode!");
8690 // VST1LN
8691 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8693 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8694 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD;
8695 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
8696 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
8697 case ARM::VST1LNdAsm_8: Spacing = 1; return ARM::VST1LNd8;
8698 case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
8699 case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
8700
8701 // VST2LN
8702 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8704 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8706 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8707
8708 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD;
8709 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
8710 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
8711 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
8712 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
8713
8714 case ARM::VST2LNdAsm_8: Spacing = 1; return ARM::VST2LNd8;
8715 case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
8716 case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
8717 case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
8718 case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
8719
8720 // VST3LN
8721 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8723 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
8725 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8726 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD;
8727 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
8728 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
8729 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
8730 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
8731 case ARM::VST3LNdAsm_8: Spacing = 1; return ARM::VST3LNd8;
8732 case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
8733 case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
8734 case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
8735 case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
8736
8737 // VST3
8738 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8739 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8740 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8741 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8742 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8743 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8744 case ARM::VST3dWB_register_Asm_8: Spacing = 1; return ARM::VST3d8_UPD;
8745 case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
8746 case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
8747 case ARM::VST3qWB_register_Asm_8: Spacing = 2; return ARM::VST3q8_UPD;
8748 case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
8749 case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
8750 case ARM::VST3dAsm_8: Spacing = 1; return ARM::VST3d8;
8751 case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
8752 case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
8753 case ARM::VST3qAsm_8: Spacing = 2; return ARM::VST3q8;
8754 case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
8755 case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
8756
8757 // VST4LN
8758 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8760 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
8762 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8763 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD;
8764 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
8765 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
8766 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
8767 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
8768 case ARM::VST4LNdAsm_8: Spacing = 1; return ARM::VST4LNd8;
8769 case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
8770 case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
8771 case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
8772 case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
8773
8774 // VST4
8775 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8776 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8777 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8778 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8779 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8780 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8781 case ARM::VST4dWB_register_Asm_8: Spacing = 1; return ARM::VST4d8_UPD;
8782 case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
8783 case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
8784 case ARM::VST4qWB_register_Asm_8: Spacing = 2; return ARM::VST4q8_UPD;
8785 case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
8786 case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
8787 case ARM::VST4dAsm_8: Spacing = 1; return ARM::VST4d8;
8788 case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
8789 case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
8790 case ARM::VST4qAsm_8: Spacing = 2; return ARM::VST4q8;
8791 case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
8792 case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
8793 }
8794}
8795
8796static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
8797 switch(Opc) {
8798 default: llvm_unreachable("unexpected opcode!");
8799 // VLD1LN
8800 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8802 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
8805 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
8806 case ARM::VLD1LNdAsm_8: Spacing = 1; return ARM::VLD1LNd8;
8807 case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
8808 case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
8809
8810 // VLD2LN
8811 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8813 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
8815 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
8818 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
8820 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
8821 case ARM::VLD2LNdAsm_8: Spacing = 1; return ARM::VLD2LNd8;
8822 case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
8823 case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
8824 case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
8825 case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
8826
8827 // VLD3DUP
8828 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8830 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8833 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
8836 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
8839 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
8840 case ARM::VLD3DUPdAsm_8: Spacing = 1; return ARM::VLD3DUPd8;
8841 case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
8842 case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
8843 case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
8844 case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
8845 case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
8846
8847 // VLD3LN
8848 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8850 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
8852 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
8855 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
8857 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
8858 case ARM::VLD3LNdAsm_8: Spacing = 1; return ARM::VLD3LNd8;
8859 case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
8860 case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
8861 case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
8862 case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
8863
8864 // VLD3
8865 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8867 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8870 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8871 case ARM::VLD3dWB_register_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD;
8872 case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
8873 case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
8874 case ARM::VLD3qWB_register_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD;
8875 case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
8876 case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
8877 case ARM::VLD3dAsm_8: Spacing = 1; return ARM::VLD3d8;
8878 case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
8879 case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
8880 case ARM::VLD3qAsm_8: Spacing = 2; return ARM::VLD3q8;
8881 case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
8882 case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
8883
8884 // VLD4LN
8885 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8887 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8889 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
8892 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
8894 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
8895 case ARM::VLD4LNdAsm_8: Spacing = 1; return ARM::VLD4LNd8;
8896 case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
8897 case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
8898 case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
8899 case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
8900
8901 // VLD4DUP
8902 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8904 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
8907 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
8910 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
8913 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
8914 case ARM::VLD4DUPdAsm_8: Spacing = 1; return ARM::VLD4DUPd8;
8915 case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
8916 case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
8917 case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
8918 case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
8919 case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
8920
8921 // VLD4
8922 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8924 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8927 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8928 case ARM::VLD4dWB_register_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD;
8929 case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
8930 case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
8931 case ARM::VLD4qWB_register_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD;
8932 case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
8933 case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
8934 case ARM::VLD4dAsm_8: Spacing = 1; return ARM::VLD4d8;
8935 case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
8936 case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
8937 case ARM::VLD4qAsm_8: Spacing = 2; return ARM::VLD4q8;
8938 case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
8939 case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
8940 }
8941}
8942
8943bool ARMAsmParser::processInstruction(MCInst &Inst,
8944 const OperandVector &Operands,
8945 unsigned MnemonicOpsEndInd,
8946 MCStreamer &Out) {
8947 // Check if we have the wide qualifier, because if it's present we
8948 // must avoid selecting a 16-bit thumb instruction.
8949 bool HasWideQualifier = false;
8950 for (auto &Op : Operands) {
8951 ARMOperand &ARMOp = static_cast<ARMOperand&>(*Op);
8952 if (ARMOp.isToken() && ARMOp.getToken() == ".w") {
8953 HasWideQualifier = true;
8954 break;
8955 }
8956 }
8957
8958 switch (Inst.getOpcode()) {
8959 case ARM::VLLDM:
8960 case ARM::VLSTM: {
8961 // In some cases both T1 and T2 are valid, causing tablegen pick T1 instead
8962 // of T2
8963 if (Operands.size() ==
8964 MnemonicOpsEndInd + 2) { // a register list has been provided
8965 ARMOperand &Op = static_cast<ARMOperand &>(
8966 *Operands[MnemonicOpsEndInd + 1]); // the register list, a dpr_reglist
8967 assert(Op.isDPRRegList());
8968 auto &RegList = Op.getRegList();
8969 // When the register list is {d0-d31} the instruction has to be the T2
8970 // variant
8971 if (RegList.size() == 32) {
8972 const unsigned Opcode =
8973 (Inst.getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8974 MCInst TmpInst;
8975 TmpInst.setOpcode(Opcode);
8976 TmpInst.addOperand(Inst.getOperand(0));
8977 TmpInst.addOperand(Inst.getOperand(1));
8978 TmpInst.addOperand(Inst.getOperand(2));
8979 TmpInst.addOperand(Inst.getOperand(3));
8980 Inst = TmpInst;
8981 return true;
8982 }
8983 }
8984 return false;
8985 }
8986 // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
8987 case ARM::LDRT_POST:
8988 case ARM::LDRBT_POST: {
8989 const unsigned Opcode =
8990 (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8991 : ARM::LDRBT_POST_IMM;
8992 MCInst TmpInst;
8993 TmpInst.setOpcode(Opcode);
8994 TmpInst.addOperand(Inst.getOperand(0));
8995 TmpInst.addOperand(Inst.getOperand(1));
8996 TmpInst.addOperand(Inst.getOperand(1));
8997 TmpInst.addOperand(MCOperand::createReg(0));
8998 TmpInst.addOperand(MCOperand::createImm(0));
8999 TmpInst.addOperand(Inst.getOperand(2));
9000 TmpInst.addOperand(Inst.getOperand(3));
9001 Inst = TmpInst;
9002 return true;
9003 }
9004 // Alias for 'ldr{sb,h,sh}t Rt, [Rn] {, #imm}' for omitted immediate.
9005 case ARM::LDRSBTii:
9006 case ARM::LDRHTii:
9007 case ARM::LDRSHTii: {
9008 MCInst TmpInst;
9009
9010 if (Inst.getOpcode() == ARM::LDRSBTii)
9011 TmpInst.setOpcode(ARM::LDRSBTi);
9012 else if (Inst.getOpcode() == ARM::LDRHTii)
9013 TmpInst.setOpcode(ARM::LDRHTi);
9014 else if (Inst.getOpcode() == ARM::LDRSHTii)
9015 TmpInst.setOpcode(ARM::LDRSHTi);
9016 TmpInst.addOperand(Inst.getOperand(0));
9017 TmpInst.addOperand(Inst.getOperand(1));
9018 TmpInst.addOperand(Inst.getOperand(1));
9019 TmpInst.addOperand(MCOperand::createImm(256));
9020 TmpInst.addOperand(Inst.getOperand(2));
9021 Inst = TmpInst;
9022 return true;
9023 }
9024 // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction.
9025 case ARM::STRT_POST:
9026 case ARM::STRBT_POST: {
9027 const unsigned Opcode =
9028 (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9029 : ARM::STRBT_POST_IMM;
9030 MCInst TmpInst;
9031 TmpInst.setOpcode(Opcode);
9032 TmpInst.addOperand(Inst.getOperand(1));
9033 TmpInst.addOperand(Inst.getOperand(0));
9034 TmpInst.addOperand(Inst.getOperand(1));
9035 TmpInst.addOperand(MCOperand::createReg(0));
9036 TmpInst.addOperand(MCOperand::createImm(0));
9037 TmpInst.addOperand(Inst.getOperand(2));
9038 TmpInst.addOperand(Inst.getOperand(3));
9039 Inst = TmpInst;
9040 return true;
9041 }
9042 // Alias for alternate form of 'ADR Rd, #imm' instruction.
9043 case ARM::ADDri: {
9044 if (Inst.getOperand(1).getReg() != ARM::PC || Inst.getOperand(5).getReg() ||
9045 !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
9046 return false;
9047 MCInst TmpInst;
9048 TmpInst.setOpcode(ARM::ADR);
9049 TmpInst.addOperand(Inst.getOperand(0));
9050 if (Inst.getOperand(2).isImm()) {
9051 // Immediate (mod_imm) will be in its encoded form, we must unencode it
9052 // before passing it to the ADR instruction.
9053 unsigned Enc = Inst.getOperand(2).getImm();
9055 llvm::rotr<uint32_t>(Enc & 0xFF, (Enc & 0xF00) >> 7)));
9056 } else {
9057 // Turn PC-relative expression into absolute expression.
9058 // Reading PC provides the start of the current instruction + 8 and
9059 // the transform to adr is biased by that.
9060 MCSymbol *Dot = getContext().createTempSymbol();
9061 Out.emitLabel(Dot);
9062 const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
9063 const MCExpr *InstPC = MCSymbolRefExpr::create(Dot,
9064 getContext());
9065 const MCExpr *Const8 = MCConstantExpr::create(8, getContext());
9066 const MCExpr *ReadPC = MCBinaryExpr::createAdd(InstPC, Const8,
9067 getContext());
9068 const MCExpr *FixupAddr = MCBinaryExpr::createAdd(ReadPC, OpExpr,
9069 getContext());
9070 TmpInst.addOperand(MCOperand::createExpr(FixupAddr));
9071 }
9072 TmpInst.addOperand(Inst.getOperand(3));
9073 TmpInst.addOperand(Inst.getOperand(4));
9074 Inst = TmpInst;
9075 return true;
9076 }
9077 // Aliases for imm syntax of LDR instructions.
9078 case ARM::t2LDR_PRE_imm:
9079 case ARM::t2LDR_POST_imm: {
9080 MCInst TmpInst;
9081 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDR_PRE_imm ? ARM::t2LDR_PRE
9082 : ARM::t2LDR_POST);
9083 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9084 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9085 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9086 TmpInst.addOperand(Inst.getOperand(2)); // imm
9087 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9088 TmpInst.addOperand(Inst.getOperand(4));
9089 Inst = TmpInst;
9090 return true;
9091 }
9092 // Aliases for imm syntax of STR instructions.
9093 case ARM::t2STR_PRE_imm:
9094 case ARM::t2STR_POST_imm: {
9095 MCInst TmpInst;
9096 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STR_PRE_imm ? ARM::t2STR_PRE
9097 : ARM::t2STR_POST);
9098 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9099 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9100 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9101 TmpInst.addOperand(Inst.getOperand(2)); // imm
9102 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9103 TmpInst.addOperand(Inst.getOperand(4));
9104 Inst = TmpInst;
9105 return true;
9106 }
9107 // Aliases for imm syntax of LDRB instructions.
9108 case ARM::t2LDRB_OFFSET_imm: {
9109 MCInst TmpInst;
9110 TmpInst.setOpcode(ARM::t2LDRBi8);
9111 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9112 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9113 TmpInst.addOperand(Inst.getOperand(2)); // imm
9114 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9115 Inst = TmpInst;
9116 return true;
9117 }
9118 case ARM::t2LDRB_PRE_imm:
9119 case ARM::t2LDRB_POST_imm: {
9120 MCInst TmpInst;
9121 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRB_PRE_imm
9122 ? ARM::t2LDRB_PRE
9123 : ARM::t2LDRB_POST);
9124 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9125 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9126 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9127 TmpInst.addOperand(Inst.getOperand(2)); // imm
9128 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9129 TmpInst.addOperand(Inst.getOperand(4));
9130 Inst = TmpInst;
9131 return true;
9132 }
9133 // Aliases for imm syntax of STRB instructions.
9134 case ARM::t2STRB_OFFSET_imm: {
9135 MCInst TmpInst;
9136 TmpInst.setOpcode(ARM::t2STRBi8);
9137 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9138 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9139 TmpInst.addOperand(Inst.getOperand(2)); // imm
9140 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9141 Inst = TmpInst;
9142 return true;
9143 }
9144 case ARM::t2STRB_PRE_imm:
9145 case ARM::t2STRB_POST_imm: {
9146 MCInst TmpInst;
9147 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRB_PRE_imm
9148 ? ARM::t2STRB_PRE
9149 : ARM::t2STRB_POST);
9150 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9151 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9152 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9153 TmpInst.addOperand(Inst.getOperand(2)); // imm
9154 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9155 TmpInst.addOperand(Inst.getOperand(4));
9156 Inst = TmpInst;
9157 return true;
9158 }
9159 // Aliases for imm syntax of LDRH instructions.
9160 case ARM::t2LDRH_OFFSET_imm: {
9161 MCInst TmpInst;
9162 TmpInst.setOpcode(ARM::t2LDRHi8);
9163 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9164 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9165 TmpInst.addOperand(Inst.getOperand(2)); // imm
9166 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9167 Inst = TmpInst;
9168 return true;
9169 }
9170 case ARM::t2LDRH_PRE_imm:
9171 case ARM::t2LDRH_POST_imm: {
9172 MCInst TmpInst;
9173 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRH_PRE_imm
9174 ? ARM::t2LDRH_PRE
9175 : ARM::t2LDRH_POST);
9176 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9177 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9178 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9179 TmpInst.addOperand(Inst.getOperand(2)); // imm
9180 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9181 TmpInst.addOperand(Inst.getOperand(4));
9182 Inst = TmpInst;
9183 return true;
9184 }
9185 // Aliases for imm syntax of STRH instructions.
9186 case ARM::t2STRH_OFFSET_imm: {
9187 MCInst TmpInst;
9188 TmpInst.setOpcode(ARM::t2STRHi8);
9189 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9190 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9191 TmpInst.addOperand(Inst.getOperand(2)); // imm
9192 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9193 Inst = TmpInst;
9194 return true;
9195 }
9196 case ARM::t2STRH_PRE_imm:
9197 case ARM::t2STRH_POST_imm: {
9198 MCInst TmpInst;
9199 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STRH_PRE_imm
9200 ? ARM::t2STRH_PRE
9201 : ARM::t2STRH_POST);
9202 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9203 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9204 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9205 TmpInst.addOperand(Inst.getOperand(2)); // imm
9206 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9207 TmpInst.addOperand(Inst.getOperand(4));
9208 Inst = TmpInst;
9209 return true;
9210 }
9211 // Aliases for imm syntax of LDRSB instructions.
9212 case ARM::t2LDRSB_OFFSET_imm: {
9213 MCInst TmpInst;
9214 TmpInst.setOpcode(ARM::t2LDRSBi8);
9215 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9216 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9217 TmpInst.addOperand(Inst.getOperand(2)); // imm
9218 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9219 Inst = TmpInst;
9220 return true;
9221 }
9222 case ARM::t2LDRSB_PRE_imm:
9223 case ARM::t2LDRSB_POST_imm: {
9224 MCInst TmpInst;
9225 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSB_PRE_imm
9226 ? ARM::t2LDRSB_PRE
9227 : ARM::t2LDRSB_POST);
9228 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9229 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9230 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9231 TmpInst.addOperand(Inst.getOperand(2)); // imm
9232 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9233 TmpInst.addOperand(Inst.getOperand(4));
9234 Inst = TmpInst;
9235 return true;
9236 }
9237 // Aliases for imm syntax of LDRSH instructions.
9238 case ARM::t2LDRSH_OFFSET_imm: {
9239 MCInst TmpInst;
9240 TmpInst.setOpcode(ARM::t2LDRSHi8);
9241 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9242 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9243 TmpInst.addOperand(Inst.getOperand(2)); // imm
9244 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9245 Inst = TmpInst;
9246 return true;
9247 }
9248 case ARM::t2LDRSH_PRE_imm:
9249 case ARM::t2LDRSH_POST_imm: {
9250 MCInst TmpInst;
9251 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDRSH_PRE_imm
9252 ? ARM::t2LDRSH_PRE
9253 : ARM::t2LDRSH_POST);
9254 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9255 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb
9256 TmpInst.addOperand(Inst.getOperand(1)); // Rn
9257 TmpInst.addOperand(Inst.getOperand(2)); // imm
9258 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9259 TmpInst.addOperand(Inst.getOperand(4));
9260 Inst = TmpInst;
9261 return true;
9262 }
9263 // Aliases for alternate PC+imm syntax of LDR instructions.
9264 case ARM::t2LDRpcrel:
9265 // Select the narrow version if the immediate will fit.
9266 if (Inst.getOperand(1).getImm() > 0 &&
9267 Inst.getOperand(1).getImm() <= 0xff &&
9268 !HasWideQualifier)
9269 Inst.setOpcode(ARM::tLDRpci);
9270 else
9271 Inst.setOpcode(ARM::t2LDRpci);
9272 return true;
9273 case ARM::t2LDRBpcrel:
9274 Inst.setOpcode(ARM::t2LDRBpci);
9275 return true;
9276 case ARM::t2LDRHpcrel:
9277 Inst.setOpcode(ARM::t2LDRHpci);
9278 return true;
9279 case ARM::t2LDRSBpcrel:
9280 Inst.setOpcode(ARM::t2LDRSBpci);
9281 return true;
9282 case ARM::t2LDRSHpcrel:
9283 Inst.setOpcode(ARM::t2LDRSHpci);
9284 return true;
9285 case ARM::LDRConstPool:
9286 case ARM::tLDRConstPool:
9287 case ARM::t2LDRConstPool: {
9288 // Pseudo instruction ldr rt, =immediate is converted to a
9289 // MOV rt, immediate if immediate is known and representable
9290 // otherwise we create a constant pool entry that we load from.
9291 MCInst TmpInst;
9292 if (Inst.getOpcode() == ARM::LDRConstPool)
9293 TmpInst.setOpcode(ARM::LDRi12);
9294 else if (Inst.getOpcode() == ARM::tLDRConstPool)
9295 TmpInst.setOpcode(ARM::tLDRpci);
9296 else if (Inst.getOpcode() == ARM::t2LDRConstPool)
9297 TmpInst.setOpcode(ARM::t2LDRpci);
9298 const ARMOperand &PoolOperand =
9299 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1]);
9300 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9301 // If SubExprVal is a constant we may be able to use a MOV
9302 if (isa<MCConstantExpr>(SubExprVal) &&
9303 Inst.getOperand(0).getReg() != ARM::PC &&
9304 Inst.getOperand(0).getReg() != ARM::SP) {
9305 int64_t Value =
9306 (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue();
9307 bool UseMov = true;
9308 bool MovHasS = true;
9309 if (Inst.getOpcode() == ARM::LDRConstPool) {
9310 // ARM Constant
9311 if (ARM_AM::getSOImmVal(Value) != -1) {
9313 TmpInst.setOpcode(ARM::MOVi);
9314 }
9315 else if (ARM_AM::getSOImmVal(~Value) != -1) {
9317 TmpInst.setOpcode(ARM::MVNi);
9318 }
9319 else if (hasV6T2Ops() &&
9320 Value >=0 && Value < 65536) {
9321 TmpInst.setOpcode(ARM::MOVi16);
9322 MovHasS = false;
9323 }
9324 else
9325 UseMov = false;
9326 }
9327 else {
9328 // Thumb/Thumb2 Constant
9329 if (hasThumb2() &&
9331 TmpInst.setOpcode(ARM::t2MOVi);
9332 else if (hasThumb2() &&
9333 ARM_AM::getT2SOImmVal(~Value) != -1) {
9334 TmpInst.setOpcode(ARM::t2MVNi);
9335 Value = ~Value;
9336 }
9337 else if (hasV8MBaseline() &&
9338 Value >=0 && Value < 65536) {
9339 TmpInst.setOpcode(ARM::t2MOVi16);
9340 MovHasS = false;
9341 }
9342 else
9343 UseMov = false;
9344 }
9345 if (UseMov) {
9346 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9347 TmpInst.addOperand(MCOperand::createImm(Value)); // Immediate
9348 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9349 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9350 if (MovHasS)
9351 TmpInst.addOperand(MCOperand::createReg(0)); // S
9352 Inst = TmpInst;
9353 return true;
9354 }
9355 }
9356 // No opportunity to use MOV/MVN create constant pool
9357 const MCExpr *CPLoc =
9358 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9359 PoolOperand.getStartLoc());
9360 TmpInst.addOperand(Inst.getOperand(0)); // Rt
9361 TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool
9362 if (TmpInst.getOpcode() == ARM::LDRi12)
9363 TmpInst.addOperand(MCOperand::createImm(0)); // unused offset
9364 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
9365 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
9366 Inst = TmpInst;
9367 return true;
9368 }
9369 // Handle NEON VST complex aliases.
9370 case ARM::VST1LNdWB_register_Asm_8:
9371 case ARM::VST1LNdWB_register_Asm_16:
9372 case ARM::VST1LNdWB_register_Asm_32: {
9373 MCInst TmpInst;
9374 // Shuffle the operands around so the lane index operand is in the
9375 // right place.
9376 unsigned Spacing;
9377 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9378 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9379 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9380 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9381 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9382 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9383 TmpInst.addOperand(Inst.getOperand(1)); // lane
9384 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9385 TmpInst.addOperand(Inst.getOperand(6));
9386 Inst = TmpInst;
9387 return true;
9388 }
9389
9390 case ARM::VST2LNdWB_register_Asm_8:
9391 case ARM::VST2LNdWB_register_Asm_16:
9392 case ARM::VST2LNdWB_register_Asm_32:
9393 case ARM::VST2LNqWB_register_Asm_16:
9394 case ARM::VST2LNqWB_register_Asm_32: {
9395 MCInst TmpInst;
9396 // Shuffle the operands around so the lane index operand is in the
9397 // right place.
9398 unsigned Spacing;
9399 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9400 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9401 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9402 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9403 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9404 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9406 Spacing));
9407 TmpInst.addOperand(Inst.getOperand(1)); // lane
9408 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9409 TmpInst.addOperand(Inst.getOperand(6));
9410 Inst = TmpInst;
9411 return true;
9412 }
9413
9414 case ARM::VST3LNdWB_register_Asm_8:
9415 case ARM::VST3LNdWB_register_Asm_16:
9416 case ARM::VST3LNdWB_register_Asm_32:
9417 case ARM::VST3LNqWB_register_Asm_16:
9418 case ARM::VST3LNqWB_register_Asm_32: {
9419 MCInst TmpInst;
9420 // Shuffle the operands around so the lane index operand is in the
9421 // right place.
9422 unsigned Spacing;
9423 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9424 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9425 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9426 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9427 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9428 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9430 Spacing));
9432 Spacing * 2));
9433 TmpInst.addOperand(Inst.getOperand(1)); // lane
9434 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9435 TmpInst.addOperand(Inst.getOperand(6));
9436 Inst = TmpInst;
9437 return true;
9438 }
9439
9440 case ARM::VST4LNdWB_register_Asm_8:
9441 case ARM::VST4LNdWB_register_Asm_16:
9442 case ARM::VST4LNdWB_register_Asm_32:
9443 case ARM::VST4LNqWB_register_Asm_16:
9444 case ARM::VST4LNqWB_register_Asm_32: {
9445 MCInst TmpInst;
9446 // Shuffle the operands around so the lane index operand is in the
9447 // right place.
9448 unsigned Spacing;
9449 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9450 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9451 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9452 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9453 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9454 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9456 Spacing));
9458 Spacing * 2));
9460 Spacing * 3));
9461 TmpInst.addOperand(Inst.getOperand(1)); // lane
9462 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9463 TmpInst.addOperand(Inst.getOperand(6));
9464 Inst = TmpInst;
9465 return true;
9466 }
9467
9468 case ARM::VST1LNdWB_fixed_Asm_8:
9469 case ARM::VST1LNdWB_fixed_Asm_16:
9470 case ARM::VST1LNdWB_fixed_Asm_32: {
9471 MCInst TmpInst;
9472 // Shuffle the operands around so the lane index operand is in the
9473 // right place.
9474 unsigned Spacing;
9475 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9476 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9477 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9478 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9479 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9480 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9481 TmpInst.addOperand(Inst.getOperand(1)); // lane
9482 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9483 TmpInst.addOperand(Inst.getOperand(5));
9484 Inst = TmpInst;
9485 return true;
9486 }
9487
9488 case ARM::VST2LNdWB_fixed_Asm_8:
9489 case ARM::VST2LNdWB_fixed_Asm_16:
9490 case ARM::VST2LNdWB_fixed_Asm_32:
9491 case ARM::VST2LNqWB_fixed_Asm_16:
9492 case ARM::VST2LNqWB_fixed_Asm_32: {
9493 MCInst TmpInst;
9494 // Shuffle the operands around so the lane index operand is in the
9495 // right place.
9496 unsigned Spacing;
9497 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9498 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9499 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9500 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9501 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9502 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9504 Spacing));
9505 TmpInst.addOperand(Inst.getOperand(1)); // lane
9506 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9507 TmpInst.addOperand(Inst.getOperand(5));
9508 Inst = TmpInst;
9509 return true;
9510 }
9511
9512 case ARM::VST3LNdWB_fixed_Asm_8:
9513 case ARM::VST3LNdWB_fixed_Asm_16:
9514 case ARM::VST3LNdWB_fixed_Asm_32:
9515 case ARM::VST3LNqWB_fixed_Asm_16:
9516 case ARM::VST3LNqWB_fixed_Asm_32: {
9517 MCInst TmpInst;
9518 // Shuffle the operands around so the lane index operand is in the
9519 // right place.
9520 unsigned Spacing;
9521 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9522 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9523 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9524 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9525 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9526 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9528 Spacing));
9530 Spacing * 2));
9531 TmpInst.addOperand(Inst.getOperand(1)); // lane
9532 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9533 TmpInst.addOperand(Inst.getOperand(5));
9534 Inst = TmpInst;
9535 return true;
9536 }
9537
9538 case ARM::VST4LNdWB_fixed_Asm_8:
9539 case ARM::VST4LNdWB_fixed_Asm_16:
9540 case ARM::VST4LNdWB_fixed_Asm_32:
9541 case ARM::VST4LNqWB_fixed_Asm_16:
9542 case ARM::VST4LNqWB_fixed_Asm_32: {
9543 MCInst TmpInst;
9544 // Shuffle the operands around so the lane index operand is in the
9545 // right place.
9546 unsigned Spacing;
9547 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9548 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9549 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9550 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9551 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9552 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9554 Spacing));
9556 Spacing * 2));
9558 Spacing * 3));
9559 TmpInst.addOperand(Inst.getOperand(1)); // lane
9560 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9561 TmpInst.addOperand(Inst.getOperand(5));
9562 Inst = TmpInst;
9563 return true;
9564 }
9565
9566 case ARM::VST1LNdAsm_8:
9567 case ARM::VST1LNdAsm_16:
9568 case ARM::VST1LNdAsm_32: {
9569 MCInst TmpInst;
9570 // Shuffle the operands around so the lane index operand is in the
9571 // right place.
9572 unsigned Spacing;
9573 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9574 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9575 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9576 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9577 TmpInst.addOperand(Inst.getOperand(1)); // lane
9578 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9579 TmpInst.addOperand(Inst.getOperand(5));
9580 Inst = TmpInst;
9581 return true;
9582 }
9583
9584 case ARM::VST2LNdAsm_8:
9585 case ARM::VST2LNdAsm_16:
9586 case ARM::VST2LNdAsm_32:
9587 case ARM::VST2LNqAsm_16:
9588 case ARM::VST2LNqAsm_32: {
9589 MCInst TmpInst;
9590 // Shuffle the operands around so the lane index operand is in the
9591 // right place.
9592 unsigned Spacing;
9593 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9594 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9595 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9596 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9598 Spacing));
9599 TmpInst.addOperand(Inst.getOperand(1)); // lane
9600 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9601 TmpInst.addOperand(Inst.getOperand(5));
9602 Inst = TmpInst;
9603 return true;
9604 }
9605
9606 case ARM::VST3LNdAsm_8:
9607 case ARM::VST3LNdAsm_16:
9608 case ARM::VST3LNdAsm_32:
9609 case ARM::VST3LNqAsm_16:
9610 case ARM::VST3LNqAsm_32: {
9611 MCInst TmpInst;
9612 // Shuffle the operands around so the lane index operand is in the
9613 // right place.
9614 unsigned Spacing;
9615 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9616 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9617 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9618 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9620 Spacing));
9622 Spacing * 2));
9623 TmpInst.addOperand(Inst.getOperand(1)); // lane
9624 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9625 TmpInst.addOperand(Inst.getOperand(5));
9626 Inst = TmpInst;
9627 return true;
9628 }
9629
9630 case ARM::VST4LNdAsm_8:
9631 case ARM::VST4LNdAsm_16:
9632 case ARM::VST4LNdAsm_32:
9633 case ARM::VST4LNqAsm_16:
9634 case ARM::VST4LNqAsm_32: {
9635 MCInst TmpInst;
9636 // Shuffle the operands around so the lane index operand is in the
9637 // right place.
9638 unsigned Spacing;
9639 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
9640 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9641 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9642 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9644 Spacing));
9646 Spacing * 2));
9648 Spacing * 3));
9649 TmpInst.addOperand(Inst.getOperand(1)); // lane
9650 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9651 TmpInst.addOperand(Inst.getOperand(5));
9652 Inst = TmpInst;
9653 return true;
9654 }
9655
9656 // Handle NEON VLD complex aliases.
9657 case ARM::VLD1LNdWB_register_Asm_8:
9658 case ARM::VLD1LNdWB_register_Asm_16:
9659 case ARM::VLD1LNdWB_register_Asm_32: {
9660 MCInst TmpInst;
9661 // Shuffle the operands around so the lane index operand is in the
9662 // right place.
9663 unsigned Spacing;
9664 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9665 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9666 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9667 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9668 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9669 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9670 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9671 TmpInst.addOperand(Inst.getOperand(1)); // lane
9672 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9673 TmpInst.addOperand(Inst.getOperand(6));
9674 Inst = TmpInst;
9675 return true;
9676 }
9677
9678 case ARM::VLD2LNdWB_register_Asm_8:
9679 case ARM::VLD2LNdWB_register_Asm_16:
9680 case ARM::VLD2LNdWB_register_Asm_32:
9681 case ARM::VLD2LNqWB_register_Asm_16:
9682 case ARM::VLD2LNqWB_register_Asm_32: {
9683 MCInst TmpInst;
9684 // Shuffle the operands around so the lane index operand is in the
9685 // right place.
9686 unsigned Spacing;
9687 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9688 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9690 Spacing));
9691 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9692 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9693 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9694 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9695 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9697 Spacing));
9698 TmpInst.addOperand(Inst.getOperand(1)); // lane
9699 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9700 TmpInst.addOperand(Inst.getOperand(6));
9701 Inst = TmpInst;
9702 return true;
9703 }
9704
9705 case ARM::VLD3LNdWB_register_Asm_8:
9706 case ARM::VLD3LNdWB_register_Asm_16:
9707 case ARM::VLD3LNdWB_register_Asm_32:
9708 case ARM::VLD3LNqWB_register_Asm_16:
9709 case ARM::VLD3LNqWB_register_Asm_32: {
9710 MCInst TmpInst;
9711 // Shuffle the operands around so the lane index operand is in the
9712 // right place.
9713 unsigned Spacing;
9714 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9715 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9717 Spacing));
9719 Spacing * 2));
9720 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9721 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9722 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9723 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9724 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9726 Spacing));
9728 Spacing * 2));
9729 TmpInst.addOperand(Inst.getOperand(1)); // lane
9730 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9731 TmpInst.addOperand(Inst.getOperand(6));
9732 Inst = TmpInst;
9733 return true;
9734 }
9735
9736 case ARM::VLD4LNdWB_register_Asm_8:
9737 case ARM::VLD4LNdWB_register_Asm_16:
9738 case ARM::VLD4LNdWB_register_Asm_32:
9739 case ARM::VLD4LNqWB_register_Asm_16:
9740 case ARM::VLD4LNqWB_register_Asm_32: {
9741 MCInst TmpInst;
9742 // Shuffle the operands around so the lane index operand is in the
9743 // right place.
9744 unsigned Spacing;
9745 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9746 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9748 Spacing));
9750 Spacing * 2));
9752 Spacing * 3));
9753 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9754 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9755 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9756 TmpInst.addOperand(Inst.getOperand(4)); // Rm
9757 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9759 Spacing));
9761 Spacing * 2));
9763 Spacing * 3));
9764 TmpInst.addOperand(Inst.getOperand(1)); // lane
9765 TmpInst.addOperand(Inst.getOperand(5)); // CondCode
9766 TmpInst.addOperand(Inst.getOperand(6));
9767 Inst = TmpInst;
9768 return true;
9769 }
9770
9771 case ARM::VLD1LNdWB_fixed_Asm_8:
9772 case ARM::VLD1LNdWB_fixed_Asm_16:
9773 case ARM::VLD1LNdWB_fixed_Asm_32: {
9774 MCInst TmpInst;
9775 // Shuffle the operands around so the lane index operand is in the
9776 // right place.
9777 unsigned Spacing;
9778 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9779 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9780 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9781 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9782 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9783 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9784 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9785 TmpInst.addOperand(Inst.getOperand(1)); // lane
9786 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9787 TmpInst.addOperand(Inst.getOperand(5));
9788 Inst = TmpInst;
9789 return true;
9790 }
9791
9792 case ARM::VLD2LNdWB_fixed_Asm_8:
9793 case ARM::VLD2LNdWB_fixed_Asm_16:
9794 case ARM::VLD2LNdWB_fixed_Asm_32:
9795 case ARM::VLD2LNqWB_fixed_Asm_16:
9796 case ARM::VLD2LNqWB_fixed_Asm_32: {
9797 MCInst TmpInst;
9798 // Shuffle the operands around so the lane index operand is in the
9799 // right place.
9800 unsigned Spacing;
9801 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9802 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9804 Spacing));
9805 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9806 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9807 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9808 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9809 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9811 Spacing));
9812 TmpInst.addOperand(Inst.getOperand(1)); // lane
9813 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9814 TmpInst.addOperand(Inst.getOperand(5));
9815 Inst = TmpInst;
9816 return true;
9817 }
9818
9819 case ARM::VLD3LNdWB_fixed_Asm_8:
9820 case ARM::VLD3LNdWB_fixed_Asm_16:
9821 case ARM::VLD3LNdWB_fixed_Asm_32:
9822 case ARM::VLD3LNqWB_fixed_Asm_16:
9823 case ARM::VLD3LNqWB_fixed_Asm_32: {
9824 MCInst TmpInst;
9825 // Shuffle the operands around so the lane index operand is in the
9826 // right place.
9827 unsigned Spacing;
9828 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9829 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9831 Spacing));
9833 Spacing * 2));
9834 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9835 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9836 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9837 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9838 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9840 Spacing));
9842 Spacing * 2));
9843 TmpInst.addOperand(Inst.getOperand(1)); // lane
9844 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9845 TmpInst.addOperand(Inst.getOperand(5));
9846 Inst = TmpInst;
9847 return true;
9848 }
9849
9850 case ARM::VLD4LNdWB_fixed_Asm_8:
9851 case ARM::VLD4LNdWB_fixed_Asm_16:
9852 case ARM::VLD4LNdWB_fixed_Asm_32:
9853 case ARM::VLD4LNqWB_fixed_Asm_16:
9854 case ARM::VLD4LNqWB_fixed_Asm_32: {
9855 MCInst TmpInst;
9856 // Shuffle the operands around so the lane index operand is in the
9857 // right place.
9858 unsigned Spacing;
9859 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9860 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9862 Spacing));
9864 Spacing * 2));
9866 Spacing * 3));
9867 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
9868 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9869 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9870 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
9871 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9873 Spacing));
9875 Spacing * 2));
9877 Spacing * 3));
9878 TmpInst.addOperand(Inst.getOperand(1)); // lane
9879 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9880 TmpInst.addOperand(Inst.getOperand(5));
9881 Inst = TmpInst;
9882 return true;
9883 }
9884
9885 case ARM::VLD1LNdAsm_8:
9886 case ARM::VLD1LNdAsm_16:
9887 case ARM::VLD1LNdAsm_32: {
9888 MCInst TmpInst;
9889 // Shuffle the operands around so the lane index operand is in the
9890 // right place.
9891 unsigned Spacing;
9892 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9893 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9894 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9895 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9896 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9897 TmpInst.addOperand(Inst.getOperand(1)); // lane
9898 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9899 TmpInst.addOperand(Inst.getOperand(5));
9900 Inst = TmpInst;
9901 return true;
9902 }
9903
9904 case ARM::VLD2LNdAsm_8:
9905 case ARM::VLD2LNdAsm_16:
9906 case ARM::VLD2LNdAsm_32:
9907 case ARM::VLD2LNqAsm_16:
9908 case ARM::VLD2LNqAsm_32: {
9909 MCInst TmpInst;
9910 // Shuffle the operands around so the lane index operand is in the
9911 // right place.
9912 unsigned Spacing;
9913 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9914 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9916 Spacing));
9917 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9918 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9919 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9921 Spacing));
9922 TmpInst.addOperand(Inst.getOperand(1)); // lane
9923 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9924 TmpInst.addOperand(Inst.getOperand(5));
9925 Inst = TmpInst;
9926 return true;
9927 }
9928
9929 case ARM::VLD3LNdAsm_8:
9930 case ARM::VLD3LNdAsm_16:
9931 case ARM::VLD3LNdAsm_32:
9932 case ARM::VLD3LNqAsm_16:
9933 case ARM::VLD3LNqAsm_32: {
9934 MCInst TmpInst;
9935 // Shuffle the operands around so the lane index operand is in the
9936 // right place.
9937 unsigned Spacing;
9938 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9939 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9941 Spacing));
9943 Spacing * 2));
9944 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9945 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9946 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9948 Spacing));
9950 Spacing * 2));
9951 TmpInst.addOperand(Inst.getOperand(1)); // lane
9952 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9953 TmpInst.addOperand(Inst.getOperand(5));
9954 Inst = TmpInst;
9955 return true;
9956 }
9957
9958 case ARM::VLD4LNdAsm_8:
9959 case ARM::VLD4LNdAsm_16:
9960 case ARM::VLD4LNdAsm_32:
9961 case ARM::VLD4LNqAsm_16:
9962 case ARM::VLD4LNqAsm_32: {
9963 MCInst TmpInst;
9964 // Shuffle the operands around so the lane index operand is in the
9965 // right place.
9966 unsigned Spacing;
9967 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
9968 TmpInst.addOperand(Inst.getOperand(0)); // Vd
9970 Spacing));
9972 Spacing * 2));
9974 Spacing * 3));
9975 TmpInst.addOperand(Inst.getOperand(2)); // Rn
9976 TmpInst.addOperand(Inst.getOperand(3)); // alignment
9977 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
9979 Spacing));
9981 Spacing * 2));
9983 Spacing * 3));
9984 TmpInst.addOperand(Inst.getOperand(1)); // lane
9985 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
9986 TmpInst.addOperand(Inst.getOperand(5));
9987 Inst = TmpInst;
9988 return true;
9989 }
9990
9991 // VLD3DUP single 3-element structure to all lanes instructions.
9992 case ARM::VLD3DUPdAsm_8:
9993 case ARM::VLD3DUPdAsm_16:
9994 case ARM::VLD3DUPdAsm_32:
9995 case ARM::VLD3DUPqAsm_8:
9996 case ARM::VLD3DUPqAsm_16:
9997 case ARM::VLD3DUPqAsm_32: {
9998 MCInst TmpInst;
9999 unsigned Spacing;
10000 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10001 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10003 Spacing));
10005 Spacing * 2));
10006 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10007 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10008 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10009 TmpInst.addOperand(Inst.getOperand(4));
10010 Inst = TmpInst;
10011 return true;
10012 }
10013
10014 case ARM::VLD3DUPdWB_fixed_Asm_8:
10015 case ARM::VLD3DUPdWB_fixed_Asm_16:
10016 case ARM::VLD3DUPdWB_fixed_Asm_32:
10017 case ARM::VLD3DUPqWB_fixed_Asm_8:
10018 case ARM::VLD3DUPqWB_fixed_Asm_16:
10019 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10020 MCInst TmpInst;
10021 unsigned Spacing;
10022 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10023 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10025 Spacing));
10027 Spacing * 2));
10028 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10029 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10030 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10031 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10032 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10033 TmpInst.addOperand(Inst.getOperand(4));
10034 Inst = TmpInst;
10035 return true;
10036 }
10037
10038 case ARM::VLD3DUPdWB_register_Asm_8:
10039 case ARM::VLD3DUPdWB_register_Asm_16:
10040 case ARM::VLD3DUPdWB_register_Asm_32:
10041 case ARM::VLD3DUPqWB_register_Asm_8:
10042 case ARM::VLD3DUPqWB_register_Asm_16:
10043 case ARM::VLD3DUPqWB_register_Asm_32: {
10044 MCInst TmpInst;
10045 unsigned Spacing;
10046 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10047 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10049 Spacing));
10051 Spacing * 2));
10052 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10053 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10054 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10055 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10056 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10057 TmpInst.addOperand(Inst.getOperand(5));
10058 Inst = TmpInst;
10059 return true;
10060 }
10061
10062 // VLD3 multiple 3-element structure instructions.
10063 case ARM::VLD3dAsm_8:
10064 case ARM::VLD3dAsm_16:
10065 case ARM::VLD3dAsm_32:
10066 case ARM::VLD3qAsm_8:
10067 case ARM::VLD3qAsm_16:
10068 case ARM::VLD3qAsm_32: {
10069 MCInst TmpInst;
10070 unsigned Spacing;
10071 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10072 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10074 Spacing));
10076 Spacing * 2));
10077 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10078 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10079 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10080 TmpInst.addOperand(Inst.getOperand(4));
10081 Inst = TmpInst;
10082 return true;
10083 }
10084
10085 case ARM::VLD3dWB_fixed_Asm_8:
10086 case ARM::VLD3dWB_fixed_Asm_16:
10087 case ARM::VLD3dWB_fixed_Asm_32:
10088 case ARM::VLD3qWB_fixed_Asm_8:
10089 case ARM::VLD3qWB_fixed_Asm_16:
10090 case ARM::VLD3qWB_fixed_Asm_32: {
10091 MCInst TmpInst;
10092 unsigned Spacing;
10093 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10094 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10096 Spacing));
10098 Spacing * 2));
10099 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10100 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10101 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10102 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10103 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10104 TmpInst.addOperand(Inst.getOperand(4));
10105 Inst = TmpInst;
10106 return true;
10107 }
10108
10109 case ARM::VLD3dWB_register_Asm_8:
10110 case ARM::VLD3dWB_register_Asm_16:
10111 case ARM::VLD3dWB_register_Asm_32:
10112 case ARM::VLD3qWB_register_Asm_8:
10113 case ARM::VLD3qWB_register_Asm_16:
10114 case ARM::VLD3qWB_register_Asm_32: {
10115 MCInst TmpInst;
10116 unsigned Spacing;
10117 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10118 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10120 Spacing));
10122 Spacing * 2));
10123 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10124 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10125 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10126 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10127 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10128 TmpInst.addOperand(Inst.getOperand(5));
10129 Inst = TmpInst;
10130 return true;
10131 }
10132
10133 // VLD4DUP single 3-element structure to all lanes instructions.
10134 case ARM::VLD4DUPdAsm_8:
10135 case ARM::VLD4DUPdAsm_16:
10136 case ARM::VLD4DUPdAsm_32:
10137 case ARM::VLD4DUPqAsm_8:
10138 case ARM::VLD4DUPqAsm_16:
10139 case ARM::VLD4DUPqAsm_32: {
10140 MCInst TmpInst;
10141 unsigned Spacing;
10142 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10143 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10145 Spacing));
10147 Spacing * 2));
10149 Spacing * 3));
10150 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10151 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10152 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10153 TmpInst.addOperand(Inst.getOperand(4));
10154 Inst = TmpInst;
10155 return true;
10156 }
10157
10158 case ARM::VLD4DUPdWB_fixed_Asm_8:
10159 case ARM::VLD4DUPdWB_fixed_Asm_16:
10160 case ARM::VLD4DUPdWB_fixed_Asm_32:
10161 case ARM::VLD4DUPqWB_fixed_Asm_8:
10162 case ARM::VLD4DUPqWB_fixed_Asm_16:
10163 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10164 MCInst TmpInst;
10165 unsigned Spacing;
10166 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10167 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10169 Spacing));
10171 Spacing * 2));
10173 Spacing * 3));
10174 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10175 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10176 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10177 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10178 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10179 TmpInst.addOperand(Inst.getOperand(4));
10180 Inst = TmpInst;
10181 return true;
10182 }
10183
10184 case ARM::VLD4DUPdWB_register_Asm_8:
10185 case ARM::VLD4DUPdWB_register_Asm_16:
10186 case ARM::VLD4DUPdWB_register_Asm_32:
10187 case ARM::VLD4DUPqWB_register_Asm_8:
10188 case ARM::VLD4DUPqWB_register_Asm_16:
10189 case ARM::VLD4DUPqWB_register_Asm_32: {
10190 MCInst TmpInst;
10191 unsigned Spacing;
10192 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10193 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10195 Spacing));
10197 Spacing * 2));
10199 Spacing * 3));
10200 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10201 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10202 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10203 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10204 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10205 TmpInst.addOperand(Inst.getOperand(5));
10206 Inst = TmpInst;
10207 return true;
10208 }
10209
10210 // VLD4 multiple 4-element structure instructions.
10211 case ARM::VLD4dAsm_8:
10212 case ARM::VLD4dAsm_16:
10213 case ARM::VLD4dAsm_32:
10214 case ARM::VLD4qAsm_8:
10215 case ARM::VLD4qAsm_16:
10216 case ARM::VLD4qAsm_32: {
10217 MCInst TmpInst;
10218 unsigned Spacing;
10219 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10220 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10222 Spacing));
10224 Spacing * 2));
10226 Spacing * 3));
10227 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10228 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10229 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10230 TmpInst.addOperand(Inst.getOperand(4));
10231 Inst = TmpInst;
10232 return true;
10233 }
10234
10235 case ARM::VLD4dWB_fixed_Asm_8:
10236 case ARM::VLD4dWB_fixed_Asm_16:
10237 case ARM::VLD4dWB_fixed_Asm_32:
10238 case ARM::VLD4qWB_fixed_Asm_8:
10239 case ARM::VLD4qWB_fixed_Asm_16:
10240 case ARM::VLD4qWB_fixed_Asm_32: {
10241 MCInst TmpInst;
10242 unsigned Spacing;
10243 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10244 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10246 Spacing));
10248 Spacing * 2));
10250 Spacing * 3));
10251 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10252 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10253 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10254 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10255 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10256 TmpInst.addOperand(Inst.getOperand(4));
10257 Inst = TmpInst;
10258 return true;
10259 }
10260
10261 case ARM::VLD4dWB_register_Asm_8:
10262 case ARM::VLD4dWB_register_Asm_16:
10263 case ARM::VLD4dWB_register_Asm_32:
10264 case ARM::VLD4qWB_register_Asm_8:
10265 case ARM::VLD4qWB_register_Asm_16:
10266 case ARM::VLD4qWB_register_Asm_32: {
10267 MCInst TmpInst;
10268 unsigned Spacing;
10269 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
10270 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10272 Spacing));
10274 Spacing * 2));
10276 Spacing * 3));
10277 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10278 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10279 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10280 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10281 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10282 TmpInst.addOperand(Inst.getOperand(5));
10283 Inst = TmpInst;
10284 return true;
10285 }
10286
10287 // VST3 multiple 3-element structure instructions.
10288 case ARM::VST3dAsm_8:
10289 case ARM::VST3dAsm_16:
10290 case ARM::VST3dAsm_32:
10291 case ARM::VST3qAsm_8:
10292 case ARM::VST3qAsm_16:
10293 case ARM::VST3qAsm_32: {
10294 MCInst TmpInst;
10295 unsigned Spacing;
10296 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10297 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10298 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10299 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10301 Spacing));
10303 Spacing * 2));
10304 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10305 TmpInst.addOperand(Inst.getOperand(4));
10306 Inst = TmpInst;
10307 return true;
10308 }
10309
10310 case ARM::VST3dWB_fixed_Asm_8:
10311 case ARM::VST3dWB_fixed_Asm_16:
10312 case ARM::VST3dWB_fixed_Asm_32:
10313 case ARM::VST3qWB_fixed_Asm_8:
10314 case ARM::VST3qWB_fixed_Asm_16:
10315 case ARM::VST3qWB_fixed_Asm_32: {
10316 MCInst TmpInst;
10317 unsigned Spacing;
10318 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10319 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10320 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10321 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10322 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10323 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10325 Spacing));
10327 Spacing * 2));
10328 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10329 TmpInst.addOperand(Inst.getOperand(4));
10330 Inst = TmpInst;
10331 return true;
10332 }
10333
10334 case ARM::VST3dWB_register_Asm_8:
10335 case ARM::VST3dWB_register_Asm_16:
10336 case ARM::VST3dWB_register_Asm_32:
10337 case ARM::VST3qWB_register_Asm_8:
10338 case ARM::VST3qWB_register_Asm_16:
10339 case ARM::VST3qWB_register_Asm_32: {
10340 MCInst TmpInst;
10341 unsigned Spacing;
10342 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10343 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10344 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10345 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10346 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10347 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10349 Spacing));
10351 Spacing * 2));
10352 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10353 TmpInst.addOperand(Inst.getOperand(5));
10354 Inst = TmpInst;
10355 return true;
10356 }
10357
10358 // VST4 multiple 3-element structure instructions.
10359 case ARM::VST4dAsm_8:
10360 case ARM::VST4dAsm_16:
10361 case ARM::VST4dAsm_32:
10362 case ARM::VST4qAsm_8:
10363 case ARM::VST4qAsm_16:
10364 case ARM::VST4qAsm_32: {
10365 MCInst TmpInst;
10366 unsigned Spacing;
10367 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10368 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10369 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10370 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10372 Spacing));
10374 Spacing * 2));
10376 Spacing * 3));
10377 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10378 TmpInst.addOperand(Inst.getOperand(4));
10379 Inst = TmpInst;
10380 return true;
10381 }
10382
10383 case ARM::VST4dWB_fixed_Asm_8:
10384 case ARM::VST4dWB_fixed_Asm_16:
10385 case ARM::VST4dWB_fixed_Asm_32:
10386 case ARM::VST4qWB_fixed_Asm_8:
10387 case ARM::VST4qWB_fixed_Asm_16:
10388 case ARM::VST4qWB_fixed_Asm_32: {
10389 MCInst TmpInst;
10390 unsigned Spacing;
10391 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10392 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10393 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10394 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10395 TmpInst.addOperand(MCOperand::createReg(0)); // Rm
10396 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10398 Spacing));
10400 Spacing * 2));
10402 Spacing * 3));
10403 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10404 TmpInst.addOperand(Inst.getOperand(4));
10405 Inst = TmpInst;
10406 return true;
10407 }
10408
10409 case ARM::VST4dWB_register_Asm_8:
10410 case ARM::VST4dWB_register_Asm_16:
10411 case ARM::VST4dWB_register_Asm_32:
10412 case ARM::VST4qWB_register_Asm_8:
10413 case ARM::VST4qWB_register_Asm_16:
10414 case ARM::VST4qWB_register_Asm_32: {
10415 MCInst TmpInst;
10416 unsigned Spacing;
10417 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
10418 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10419 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
10420 TmpInst.addOperand(Inst.getOperand(2)); // alignment
10421 TmpInst.addOperand(Inst.getOperand(3)); // Rm
10422 TmpInst.addOperand(Inst.getOperand(0)); // Vd
10424 Spacing));
10426 Spacing * 2));
10428 Spacing * 3));
10429 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10430 TmpInst.addOperand(Inst.getOperand(5));
10431 Inst = TmpInst;
10432 return true;
10433 }
10434
10435 // Handle encoding choice for the shift-immediate instructions.
10436 case ARM::t2LSLri:
10437 case ARM::t2LSRri:
10438 case ARM::t2ASRri:
10439 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10440 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10441 Inst.getOperand(5).getReg() ==
10442 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10443 !HasWideQualifier) {
10444 unsigned NewOpc;
10445 switch (Inst.getOpcode()) {
10446 default: llvm_unreachable("unexpected opcode");
10447 case ARM::t2LSLri: NewOpc = ARM::tLSLri; break;
10448 case ARM::t2LSRri: NewOpc = ARM::tLSRri; break;
10449 case ARM::t2ASRri: NewOpc = ARM::tASRri; break;
10450 }
10451 // The Thumb1 operands aren't in the same order. Awesome, eh?
10452 MCInst TmpInst;
10453 TmpInst.setOpcode(NewOpc);
10454 TmpInst.addOperand(Inst.getOperand(0));
10455 TmpInst.addOperand(Inst.getOperand(5));
10456 TmpInst.addOperand(Inst.getOperand(1));
10457 TmpInst.addOperand(Inst.getOperand(2));
10458 TmpInst.addOperand(Inst.getOperand(3));
10459 TmpInst.addOperand(Inst.getOperand(4));
10460 Inst = TmpInst;
10461 return true;
10462 }
10463 return false;
10464
10465 // Handle the Thumb2 mode MOV complex aliases.
10466 case ARM::t2MOVsr:
10467 case ARM::t2MOVSsr: {
10468 // Which instruction to expand to depends on the CCOut operand and
10469 // whether we're in an IT block if the register operands are low
10470 // registers.
10471 bool isNarrow = false;
10472 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10473 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10474 isARMLowRegister(Inst.getOperand(2).getReg()) &&
10475 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
10476 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr) &&
10477 !HasWideQualifier)
10478 isNarrow = true;
10479 MCInst TmpInst;
10480 unsigned newOpc;
10481 switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
10482 default: llvm_unreachable("unexpected opcode!");
10483 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
10484 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
10485 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
10486 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break;
10487 }
10488 TmpInst.setOpcode(newOpc);
10489 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10490 if (isNarrow)
10492 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10493 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10494 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10495 TmpInst.addOperand(Inst.getOperand(4)); // CondCode
10496 TmpInst.addOperand(Inst.getOperand(5));
10497 if (!isNarrow)
10499 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10500 Inst = TmpInst;
10501 return true;
10502 }
10503 case ARM::t2MOVsi:
10504 case ARM::t2MOVSsi: {
10505 // Which instruction to expand to depends on the CCOut operand and
10506 // whether we're in an IT block if the register operands are low
10507 // registers.
10508 bool isNarrow = false;
10509 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10510 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10511 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi) &&
10512 !HasWideQualifier)
10513 isNarrow = true;
10514 MCInst TmpInst;
10515 unsigned newOpc;
10516 unsigned Shift = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
10517 unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
10518 bool isMov = false;
10519 // MOV rd, rm, LSL #0 is actually a MOV instruction
10520 if (Shift == ARM_AM::lsl && Amount == 0) {
10521 isMov = true;
10522 // The 16-bit encoding of MOV rd, rm, LSL #N is explicitly encoding T2 of
10523 // MOV (register) in the ARMv8-A and ARMv8-M manuals, and immediate 0 is
10524 // unpredictable in an IT block so the 32-bit encoding T3 has to be used
10525 // instead.
10526 if (inITBlock()) {
10527 isNarrow = false;
10528 }
10529 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10530 } else {
10531 switch(Shift) {
10532 default: llvm_unreachable("unexpected opcode!");
10533 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
10534 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
10535 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
10536 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
10537 case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
10538 }
10539 }
10540 if (Amount == 32) Amount = 0;
10541 TmpInst.setOpcode(newOpc);
10542 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10543 if (isNarrow && !isMov)
10545 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10546 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10547 if (newOpc != ARM::t2RRX && !isMov)
10548 TmpInst.addOperand(MCOperand::createImm(Amount));
10549 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10550 TmpInst.addOperand(Inst.getOperand(4));
10551 if (!isNarrow)
10553 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10554 Inst = TmpInst;
10555 return true;
10556 }
10557 // Handle the ARM mode MOV complex aliases.
10558 case ARM::ASRr:
10559 case ARM::LSRr:
10560 case ARM::LSLr:
10561 case ARM::RORr: {
10562 ARM_AM::ShiftOpc ShiftTy;
10563 switch(Inst.getOpcode()) {
10564 default: llvm_unreachable("unexpected opcode!");
10565 case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
10566 case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
10567 case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
10568 case ARM::RORr: ShiftTy = ARM_AM::ror; break;
10569 }
10570 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
10571 MCInst TmpInst;
10572 TmpInst.setOpcode(ARM::MOVsr);
10573 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10574 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10575 TmpInst.addOperand(Inst.getOperand(2)); // Rm
10576 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10577 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10578 TmpInst.addOperand(Inst.getOperand(4));
10579 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10580 Inst = TmpInst;
10581 return true;
10582 }
10583 case ARM::ASRi:
10584 case ARM::LSRi:
10585 case ARM::LSLi:
10586 case ARM::RORi: {
10587 ARM_AM::ShiftOpc ShiftTy;
10588 switch(Inst.getOpcode()) {
10589 default: llvm_unreachable("unexpected opcode!");
10590 case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
10591 case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
10592 case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
10593 case ARM::RORi: ShiftTy = ARM_AM::ror; break;
10594 }
10595 // A shift by zero is a plain MOVr, not a MOVsi.
10596 unsigned Amt = Inst.getOperand(2).getImm();
10597 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10598 // A shift by 32 should be encoded as 0 when permitted
10599 if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
10600 Amt = 0;
10601 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
10602 MCInst TmpInst;
10603 TmpInst.setOpcode(Opc);
10604 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10605 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10606 if (Opc == ARM::MOVsi)
10607 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10608 TmpInst.addOperand(Inst.getOperand(3)); // CondCode
10609 TmpInst.addOperand(Inst.getOperand(4));
10610 TmpInst.addOperand(Inst.getOperand(5)); // cc_out
10611 Inst = TmpInst;
10612 return true;
10613 }
10614 case ARM::RRXi: {
10615 unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
10616 MCInst TmpInst;
10617 TmpInst.setOpcode(ARM::MOVsi);
10618 TmpInst.addOperand(Inst.getOperand(0)); // Rd
10619 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10620 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
10621 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10622 TmpInst.addOperand(Inst.getOperand(3));
10623 TmpInst.addOperand(Inst.getOperand(4)); // cc_out
10624 Inst = TmpInst;
10625 return true;
10626 }
10627 case ARM::t2LDMIA_UPD: {
10628 // If this is a load of a single register, then we should use
10629 // a post-indexed LDR instruction instead, per the ARM ARM.
10630 if (Inst.getNumOperands() != 5)
10631 return false;
10632 MCInst TmpInst;
10633 TmpInst.setOpcode(ARM::t2LDR_POST);
10634 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10635 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10636 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10637 TmpInst.addOperand(MCOperand::createImm(4));
10638 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10639 TmpInst.addOperand(Inst.getOperand(3));
10640 Inst = TmpInst;
10641 return true;
10642 }
10643 case ARM::t2STMDB_UPD: {
10644 // If this is a store of a single register, then we should use
10645 // a pre-indexed STR instruction instead, per the ARM ARM.
10646 if (Inst.getNumOperands() != 5)
10647 return false;
10648 MCInst TmpInst;
10649 TmpInst.setOpcode(ARM::t2STR_PRE);
10650 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10651 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10652 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10653 TmpInst.addOperand(MCOperand::createImm(-4));
10654 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10655 TmpInst.addOperand(Inst.getOperand(3));
10656 Inst = TmpInst;
10657 return true;
10658 }
10659 case ARM::LDMIA_UPD:
10660 // If this is a load of a single register via a 'pop', then we should use
10661 // a post-indexed LDR instruction instead, per the ARM ARM.
10662 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "pop" &&
10663 Inst.getNumOperands() == 5) {
10664 MCInst TmpInst;
10665 TmpInst.setOpcode(ARM::LDR_POST_IMM);
10666 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10667 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10668 TmpInst.addOperand(Inst.getOperand(1)); // Rn
10669 TmpInst.addOperand(MCOperand::createReg(0)); // am2offset
10670 TmpInst.addOperand(MCOperand::createImm(4));
10671 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10672 TmpInst.addOperand(Inst.getOperand(3));
10673 Inst = TmpInst;
10674 return true;
10675 }
10676 break;
10677 case ARM::STMDB_UPD:
10678 // If this is a store of a single register via a 'push', then we should use
10679 // a pre-indexed STR instruction instead, per the ARM ARM.
10680 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "push" &&
10681 Inst.getNumOperands() == 5) {
10682 MCInst TmpInst;
10683 TmpInst.setOpcode(ARM::STR_PRE_IMM);
10684 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
10685 TmpInst.addOperand(Inst.getOperand(4)); // Rt
10686 TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
10687 TmpInst.addOperand(MCOperand::createImm(-4));
10688 TmpInst.addOperand(Inst.getOperand(2)); // CondCode
10689 TmpInst.addOperand(Inst.getOperand(3));
10690 Inst = TmpInst;
10691 }
10692 break;
10693 case ARM::t2ADDri12:
10694 case ARM::t2SUBri12:
10695 case ARM::t2ADDspImm12:
10696 case ARM::t2SUBspImm12: {
10697 // If the immediate fits for encoding T3 and the generic
10698 // mnemonic was used, encoding T3 is preferred.
10699 const StringRef Token = static_cast<ARMOperand &>(*Operands[0]).getToken();
10700 if ((Token != "add" && Token != "sub") ||
10701 ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
10702 break;
10703 switch (Inst.getOpcode()) {
10704 case ARM::t2ADDri12:
10705 Inst.setOpcode(ARM::t2ADDri);
10706 break;
10707 case ARM::t2SUBri12:
10708 Inst.setOpcode(ARM::t2SUBri);
10709 break;
10710 case ARM::t2ADDspImm12:
10711 Inst.setOpcode(ARM::t2ADDspImm);
10712 break;
10713 case ARM::t2SUBspImm12:
10714 Inst.setOpcode(ARM::t2SUBspImm);
10715 break;
10716 }
10717
10718 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10719 return true;
10720 }
10721 case ARM::tADDi8:
10722 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10723 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10724 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10725 // to encoding T1 if <Rd> is omitted."
10726 if (Inst.getOperand(3).isImm() &&
10727 (unsigned)Inst.getOperand(3).getImm() < 8 &&
10728 Operands.size() == MnemonicOpsEndInd + 3) {
10729 Inst.setOpcode(ARM::tADDi3);
10730 return true;
10731 }
10732 break;
10733 case ARM::tSUBi8:
10734 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
10735 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
10736 // to encoding T2 if <Rd> is specified and encoding T2 is preferred
10737 // to encoding T1 if <Rd> is omitted."
10738 if ((unsigned)Inst.getOperand(3).getImm() < 8 &&
10739 Operands.size() == MnemonicOpsEndInd + 3) {
10740 Inst.setOpcode(ARM::tSUBi3);
10741 return true;
10742 }
10743 break;
10744 case ARM::t2ADDri:
10745 case ARM::t2SUBri: {
10746 // If the destination and first source operand are the same, and
10747 // the flags are compatible with the current IT status, use encoding T2
10748 // instead of T3. For compatibility with the system 'as'. Make sure the
10749 // wide encoding wasn't explicit.
10750 if (HasWideQualifier)
10751 break; // source code has asked for the 32-bit instruction
10752 if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg())
10753 break; // tADDi8 can't take different input and output registers
10754 if (!isARMLowRegister(Inst.getOperand(0).getReg()))
10755 break; // high register that tADDi8 can't access
10756 if (Inst.getOperand(5).getReg() !=
10757 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10758 break; // flag-modification would require overriding the IT state
10759 if (Inst.getOperand(2).isImm()) {
10760 if ((unsigned)Inst.getOperand(2).getImm() > 255)
10761 break; // large immediate that tADDi8 can't contain
10762 } else {
10763 int i = (Operands[MnemonicOpsEndInd + 1]->isImm())
10764 ? MnemonicOpsEndInd + 1
10765 : MnemonicOpsEndInd + 2;
10766 MCParsedAsmOperand &Op = *Operands[i];
10768 break; // a type of non-immediate that tADDi8 can't represent
10769 }
10770 MCInst TmpInst;
10771 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
10772 ARM::tADDi8 : ARM::tSUBi8);
10773 TmpInst.addOperand(Inst.getOperand(0));
10774 TmpInst.addOperand(Inst.getOperand(5));
10775 TmpInst.addOperand(Inst.getOperand(0));
10776 TmpInst.addOperand(Inst.getOperand(2));
10777 TmpInst.addOperand(Inst.getOperand(3));
10778 TmpInst.addOperand(Inst.getOperand(4));
10779 Inst = TmpInst;
10780 return true;
10781 }
10782 case ARM::t2ADDspImm:
10783 case ARM::t2SUBspImm: {
10784 // Prefer T1 encoding if possible
10785 if (Inst.getOperand(5).getReg() || HasWideQualifier)
10786 break;
10787 unsigned V = Inst.getOperand(2).getImm();
10788 if (V & 3 || V > ((1 << 7) - 1) << 2)
10789 break;
10790 MCInst TmpInst;
10791 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDspImm ? ARM::tADDspi
10792 : ARM::tSUBspi);
10793 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // destination reg
10794 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // source reg
10795 TmpInst.addOperand(MCOperand::createImm(V / 4)); // immediate
10796 TmpInst.addOperand(Inst.getOperand(3)); // pred
10797 TmpInst.addOperand(Inst.getOperand(4));
10798 Inst = TmpInst;
10799 return true;
10800 }
10801 case ARM::t2ADDrr: {
10802 // If the destination and first source operand are the same, and
10803 // there's no setting of the flags, use encoding T2 instead of T3.
10804 // Note that this is only for ADD, not SUB. This mirrors the system
10805 // 'as' behaviour. Also take advantage of ADD being commutative.
10806 // Make sure the wide encoding wasn't explicit.
10807 bool Swap = false;
10808 auto DestReg = Inst.getOperand(0).getReg();
10809 bool Transform = DestReg == Inst.getOperand(1).getReg();
10810 if (!Transform && DestReg == Inst.getOperand(2).getReg()) {
10811 Transform = true;
10812 Swap = true;
10813 }
10814 if (!Transform || Inst.getOperand(5).getReg() || HasWideQualifier)
10815 break;
10816 MCInst TmpInst;
10817 TmpInst.setOpcode(ARM::tADDhirr);
10818 TmpInst.addOperand(Inst.getOperand(0));
10819 TmpInst.addOperand(Inst.getOperand(0));
10820 TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2));
10821 TmpInst.addOperand(Inst.getOperand(3));
10822 TmpInst.addOperand(Inst.getOperand(4));
10823 Inst = TmpInst;
10824 return true;
10825 }
10826 case ARM::tADDrSP:
10827 // If the non-SP source operand and the destination operand are not the
10828 // same, we need to use the 32-bit encoding if it's available.
10829 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
10830 Inst.setOpcode(ARM::t2ADDrr);
10831 Inst.addOperand(MCOperand::createReg(0)); // cc_out
10832 return true;
10833 }
10834 break;
10835 case ARM::tB:
10836 // A Thumb conditional branch outside of an IT block is a tBcc.
10837 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
10838 Inst.setOpcode(ARM::tBcc);
10839 return true;
10840 }
10841 break;
10842 case ARM::t2B:
10843 // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
10844 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
10845 Inst.setOpcode(ARM::t2Bcc);
10846 return true;
10847 }
10848 break;
10849 case ARM::t2Bcc:
10850 // If the conditional is AL or we're in an IT block, we really want t2B.
10851 if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
10852 Inst.setOpcode(ARM::t2B);
10853 return true;
10854 }
10855 break;
10856 case ARM::tBcc:
10857 // If the conditional is AL, we really want tB.
10858 if (Inst.getOperand(1).getImm() == ARMCC::AL) {
10859 Inst.setOpcode(ARM::tB);
10860 return true;
10861 }
10862 break;
10863 case ARM::tLDMIA: {
10864 // If the register list contains any high registers, or if the writeback
10865 // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
10866 // instead if we're in Thumb2. Otherwise, this should have generated
10867 // an error in validateInstruction().
10868 MCRegister Rn = Inst.getOperand(0).getReg();
10869 bool hasWritebackToken =
10870 (static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10871 .isToken() &&
10872 static_cast<ARMOperand &>(*Operands[MnemonicOpsEndInd + 1])
10873 .getToken() == "!");
10874 bool listContainsBase;
10875 if (checkLowRegisterList(Inst, 3, Rn, MCRegister(), listContainsBase) ||
10876 (!listContainsBase && !hasWritebackToken) ||
10877 (listContainsBase && hasWritebackToken)) {
10878 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10879 assert(isThumbTwo());
10880 Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10881 // If we're switching to the updating version, we need to insert
10882 // the writeback tied operand.
10883 if (hasWritebackToken)
10884 Inst.insert(Inst.begin(),
10886 return true;
10887 }
10888 break;
10889 }
10890 case ARM::tSTMIA_UPD: {
10891 // If the register list contains any high registers, we need to use
10892 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10893 // should have generated an error in validateInstruction().
10894 MCRegister Rn = Inst.getOperand(0).getReg();
10895 bool listContainsBase;
10896 if (checkLowRegisterList(Inst, 4, Rn, MCRegister(), listContainsBase)) {
10897 // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
10898 assert(isThumbTwo());
10899 Inst.setOpcode(ARM::t2STMIA_UPD);
10900 return true;
10901 }
10902 break;
10903 }
10904 case ARM::tPOP: {
10905 bool listContainsBase;
10906 // If the register list contains any high registers, we need to use
10907 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
10908 // should have generated an error in validateInstruction().
10909 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::PC, listContainsBase))
10910 return false;
10911 assert(isThumbTwo());
10912 Inst.setOpcode(ARM::t2LDMIA_UPD);
10913 // Add the base register and writeback operands.
10914 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10915 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10916 return true;
10917 }
10918 case ARM::tPUSH: {
10919 bool listContainsBase;
10920 if (!checkLowRegisterList(Inst, 2, MCRegister(), ARM::LR, listContainsBase))
10921 return false;
10922 assert(isThumbTwo());
10923 Inst.setOpcode(ARM::t2STMDB_UPD);
10924 // Add the base register and writeback operands.
10925 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10926 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
10927 return true;
10928 }
10929 case ARM::t2MOVi:
10930 // If we can use the 16-bit encoding and the user didn't explicitly
10931 // request the 32-bit variant, transform it here.
10932 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10933 (Inst.getOperand(1).isImm() &&
10934 (unsigned)Inst.getOperand(1).getImm() <= 255) &&
10935 Inst.getOperand(4).getReg() ==
10936 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10937 !HasWideQualifier) {
10938 // The operands aren't in the same order for tMOVi8...
10939 MCInst TmpInst;
10940 TmpInst.setOpcode(ARM::tMOVi8);
10941 TmpInst.addOperand(Inst.getOperand(0));
10942 TmpInst.addOperand(Inst.getOperand(4));
10943 TmpInst.addOperand(Inst.getOperand(1));
10944 TmpInst.addOperand(Inst.getOperand(2));
10945 TmpInst.addOperand(Inst.getOperand(3));
10946 Inst = TmpInst;
10947 return true;
10948 }
10949 break;
10950
10951 case ARM::t2MOVr:
10952 // If we can use the 16-bit encoding and the user didn't explicitly
10953 // request the 32-bit variant, transform it here.
10954 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10955 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10956 Inst.getOperand(2).getImm() == ARMCC::AL &&
10957 Inst.getOperand(4).getReg() == ARM::CPSR &&
10958 !HasWideQualifier) {
10959 // The operands aren't the same for tMOV[S]r... (no cc_out)
10960 MCInst TmpInst;
10961 unsigned Op = Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr;
10962 TmpInst.setOpcode(Op);
10963 TmpInst.addOperand(Inst.getOperand(0));
10964 TmpInst.addOperand(Inst.getOperand(1));
10965 if (Op == ARM::tMOVr) {
10966 TmpInst.addOperand(Inst.getOperand(2));
10967 TmpInst.addOperand(Inst.getOperand(3));
10968 }
10969 Inst = TmpInst;
10970 return true;
10971 }
10972 break;
10973
10974 case ARM::t2SXTH:
10975 case ARM::t2SXTB:
10976 case ARM::t2UXTH:
10977 case ARM::t2UXTB:
10978 // If we can use the 16-bit encoding and the user didn't explicitly
10979 // request the 32-bit variant, transform it here.
10980 if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
10981 isARMLowRegister(Inst.getOperand(1).getReg()) &&
10982 Inst.getOperand(2).getImm() == 0 &&
10983 !HasWideQualifier) {
10984 unsigned NewOpc;
10985 switch (Inst.getOpcode()) {
10986 default: llvm_unreachable("Illegal opcode!");
10987 case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
10988 case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
10989 case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
10990 case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
10991 }
10992 // The operands aren't the same for thumb1 (no rotate operand).
10993 MCInst TmpInst;
10994 TmpInst.setOpcode(NewOpc);
10995 TmpInst.addOperand(Inst.getOperand(0));
10996 TmpInst.addOperand(Inst.getOperand(1));
10997 TmpInst.addOperand(Inst.getOperand(3));
10998 TmpInst.addOperand(Inst.getOperand(4));
10999 Inst = TmpInst;
11000 return true;
11001 }
11002 break;
11003
11004 case ARM::MOVsi: {
11006 // rrx shifts and asr/lsr of #32 is encoded as 0
11007 if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
11008 return false;
11009 if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
11010 // Shifting by zero is accepted as a vanilla 'MOVr'
11011 MCInst TmpInst;
11012 TmpInst.setOpcode(ARM::MOVr);
11013 TmpInst.addOperand(Inst.getOperand(0));
11014 TmpInst.addOperand(Inst.getOperand(1));
11015 TmpInst.addOperand(Inst.getOperand(3));
11016 TmpInst.addOperand(Inst.getOperand(4));
11017 TmpInst.addOperand(Inst.getOperand(5));
11018 Inst = TmpInst;
11019 return true;
11020 }
11021 return false;
11022 }
11023 case ARM::ANDrsi:
11024 case ARM::ORRrsi:
11025 case ARM::EORrsi:
11026 case ARM::BICrsi:
11027 case ARM::SUBrsi:
11028 case ARM::ADDrsi: {
11029 unsigned newOpc;
11031 if (SOpc == ARM_AM::rrx) return false;
11032 switch (Inst.getOpcode()) {
11033 default: llvm_unreachable("unexpected opcode!");
11034 case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
11035 case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
11036 case ARM::EORrsi: newOpc = ARM::EORrr; break;
11037 case ARM::BICrsi: newOpc = ARM::BICrr; break;
11038 case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
11039 case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
11040 }
11041 // If the shift is by zero, use the non-shifted instruction definition.
11042 // The exception is for right shifts, where 0 == 32
11043 if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 &&
11044 !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) {
11045 MCInst TmpInst;
11046 TmpInst.setOpcode(newOpc);
11047 TmpInst.addOperand(Inst.getOperand(0));
11048 TmpInst.addOperand(Inst.getOperand(1));
11049 TmpInst.addOperand(Inst.getOperand(2));
11050 TmpInst.addOperand(Inst.getOperand(4));
11051 TmpInst.addOperand(Inst.getOperand(5));
11052 TmpInst.addOperand(Inst.getOperand(6));
11053 Inst = TmpInst;
11054 return true;
11055 }
11056 return false;
11057 }
11058 case ARM::ITasm:
11059 case ARM::t2IT: {
11060 // Set up the IT block state according to the IT instruction we just
11061 // matched.
11062 assert(!inITBlock() && "nested IT blocks?!");
11063 startExplicitITBlock(ARMCC::CondCodes(Inst.getOperand(0).getImm()),
11064 Inst.getOperand(1).getImm());
11065 break;
11066 }
11067 case ARM::t2LSLrr:
11068 case ARM::t2LSRrr:
11069 case ARM::t2ASRrr:
11070 case ARM::t2SBCrr:
11071 case ARM::t2RORrr:
11072 case ARM::t2BICrr:
11073 // Assemblers should use the narrow encodings of these instructions when permissible.
11074 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11075 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11076 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
11077 Inst.getOperand(5).getReg() ==
11078 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11079 !HasWideQualifier) {
11080 unsigned NewOpc;
11081 switch (Inst.getOpcode()) {
11082 default: llvm_unreachable("unexpected opcode");
11083 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break;
11084 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break;
11085 case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break;
11086 case ARM::t2SBCrr: NewOpc = ARM::tSBC; break;
11087 case ARM::t2RORrr: NewOpc = ARM::tROR; break;
11088 case ARM::t2BICrr: NewOpc = ARM::tBIC; break;
11089 }
11090 MCInst TmpInst;
11091 TmpInst.setOpcode(NewOpc);
11092 TmpInst.addOperand(Inst.getOperand(0));
11093 TmpInst.addOperand(Inst.getOperand(5));
11094 TmpInst.addOperand(Inst.getOperand(1));
11095 TmpInst.addOperand(Inst.getOperand(2));
11096 TmpInst.addOperand(Inst.getOperand(3));
11097 TmpInst.addOperand(Inst.getOperand(4));
11098 Inst = TmpInst;
11099 return true;
11100 }
11101 return false;
11102
11103 case ARM::t2ANDrr:
11104 case ARM::t2EORrr:
11105 case ARM::t2ADCrr:
11106 case ARM::t2ORRrr:
11107 // Assemblers should use the narrow encodings of these instructions when permissible.
11108 // These instructions are special in that they are commutable, so shorter encodings
11109 // are available more often.
11110 if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
11111 isARMLowRegister(Inst.getOperand(2).getReg())) &&
11112 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() ||
11113 Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) &&
11114 Inst.getOperand(5).getReg() ==
11115 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11116 !HasWideQualifier) {
11117 unsigned NewOpc;
11118 switch (Inst.getOpcode()) {
11119 default: llvm_unreachable("unexpected opcode");
11120 case ARM::t2ADCrr: NewOpc = ARM::tADC; break;
11121 case ARM::t2ANDrr: NewOpc = ARM::tAND; break;
11122 case ARM::t2EORrr: NewOpc = ARM::tEOR; break;
11123 case ARM::t2ORRrr: NewOpc = ARM::tORR; break;
11124 }
11125 MCInst TmpInst;
11126 TmpInst.setOpcode(NewOpc);
11127 TmpInst.addOperand(Inst.getOperand(0));
11128 TmpInst.addOperand(Inst.getOperand(5));
11129 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) {
11130 TmpInst.addOperand(Inst.getOperand(1));
11131 TmpInst.addOperand(Inst.getOperand(2));
11132 } else {
11133 TmpInst.addOperand(Inst.getOperand(2));
11134 TmpInst.addOperand(Inst.getOperand(1));
11135 }
11136 TmpInst.addOperand(Inst.getOperand(3));
11137 TmpInst.addOperand(Inst.getOperand(4));
11138 Inst = TmpInst;
11139 return true;
11140 }
11141 return false;
11142 case ARM::MVE_VPST:
11143 case ARM::MVE_VPTv16i8:
11144 case ARM::MVE_VPTv8i16:
11145 case ARM::MVE_VPTv4i32:
11146 case ARM::MVE_VPTv16u8:
11147 case ARM::MVE_VPTv8u16:
11148 case ARM::MVE_VPTv4u32:
11149 case ARM::MVE_VPTv16s8:
11150 case ARM::MVE_VPTv8s16:
11151 case ARM::MVE_VPTv4s32:
11152 case ARM::MVE_VPTv4f32:
11153 case ARM::MVE_VPTv8f16:
11154 case ARM::MVE_VPTv16i8r:
11155 case ARM::MVE_VPTv8i16r:
11156 case ARM::MVE_VPTv4i32r:
11157 case ARM::MVE_VPTv16u8r:
11158 case ARM::MVE_VPTv8u16r:
11159 case ARM::MVE_VPTv4u32r:
11160 case ARM::MVE_VPTv16s8r:
11161 case ARM::MVE_VPTv8s16r:
11162 case ARM::MVE_VPTv4s32r:
11163 case ARM::MVE_VPTv4f32r:
11164 case ARM::MVE_VPTv8f16r: {
11165 assert(!inVPTBlock() && "Nested VPT blocks are not allowed");
11166 MCOperand &MO = Inst.getOperand(0);
11167 VPTState.Mask = MO.getImm();
11168 VPTState.CurPosition = 0;
11169 break;
11170 }
11171 }
11172 return false;
11173}
11174
11175unsigned
11176ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11177 const OperandVector &Operands) {
11178 unsigned Opc = Inst.getOpcode();
11179 switch (Opc) {
11180 // Prevent the mov r8 r8 encoding for nop being selected when the v6/thumb 2
11181 // encoding is available.
11182 case ARM::tMOVr: {
11183 if (Operands[0]->isToken() &&
11184 static_cast<ARMOperand &>(*Operands[0]).getToken() == "nop" &&
11185 ((isThumb() && !isThumbOne()) || hasV6MOps())) {
11186 return Match_MnemonicFail;
11187 }
11188 }
11189 [[fallthrough]];
11190 default:
11191 return Match_Success;
11192 }
11193}
11194
11195unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11196 // 16-bit thumb arithmetic instructions either require or preclude the 'S'
11197 // suffix depending on whether they're in an IT block or not.
11198 unsigned Opc = Inst.getOpcode();
11199 const MCInstrDesc &MCID = MII.get(Opc);
11201 assert(MCID.hasOptionalDef() &&
11202 "optionally flag setting instruction missing optional def operand");
11203 assert(MCID.NumOperands == Inst.getNumOperands() &&
11204 "operand count mismatch!");
11205 bool IsCPSR = false;
11206 // Check if the instruction has CPSR set.
11207 for (unsigned OpNo = 0; OpNo < MCID.NumOperands; ++OpNo) {
11208 if (MCID.operands()[OpNo].isOptionalDef() &&
11209 Inst.getOperand(OpNo).isReg() &&
11210 Inst.getOperand(OpNo).getReg() == ARM::CPSR)
11211 IsCPSR = true;
11212 }
11213
11214 // If we're parsing Thumb1, reject it completely.
11215 if (isThumbOne() && !IsCPSR)
11216 return Match_RequiresFlagSetting;
11217 // If we're parsing Thumb2, which form is legal depends on whether we're
11218 // in an IT block.
11219 if (isThumbTwo() && !IsCPSR && !inITBlock())
11220 return Match_RequiresITBlock;
11221 if (isThumbTwo() && IsCPSR && inITBlock())
11222 return Match_RequiresNotITBlock;
11223 // LSL with zero immediate is not allowed in an IT block
11224 if (Opc == ARM::tLSLri && Inst.getOperand(3).getImm() == 0 && inITBlock())
11225 return Match_RequiresNotITBlock;
11226 } else if (isThumbOne()) {
11227 // Some high-register supporting Thumb1 encodings only allow both registers
11228 // to be from r0-r7 when in Thumb2.
11229 if (Opc == ARM::tADDhirr && !hasV6MOps() &&
11230 isARMLowRegister(Inst.getOperand(1).getReg()) &&
11232 return Match_RequiresThumb2;
11233 // Others only require ARMv6 or later.
11234 else if (Opc == ARM::tMOVr && !hasV6Ops() &&
11235 isARMLowRegister(Inst.getOperand(0).getReg()) &&
11237 return Match_RequiresV6;
11238 }
11239
11240 // Before ARMv8 the rules for when SP is allowed in t2MOVr are more complex
11241 // than the loop below can handle, so it uses the GPRnopc register class and
11242 // we do SP handling here.
11243 if (Opc == ARM::t2MOVr && !hasV8Ops())
11244 {
11245 // SP as both source and destination is not allowed
11246 if (Inst.getOperand(0).getReg() == ARM::SP &&
11247 Inst.getOperand(1).getReg() == ARM::SP)
11248 return Match_RequiresV8;
11249 // When flags-setting SP as either source or destination is not allowed
11250 if (Inst.getOperand(4).getReg() == ARM::CPSR &&
11251 (Inst.getOperand(0).getReg() == ARM::SP ||
11252 Inst.getOperand(1).getReg() == ARM::SP))
11253 return Match_RequiresV8;
11254 }
11255
11256 switch (Inst.getOpcode()) {
11257 case ARM::VMRS:
11258 case ARM::VMSR:
11259 case ARM::VMRS_FPCXTS:
11260 case ARM::VMRS_FPCXTNS:
11261 case ARM::VMSR_FPCXTS:
11262 case ARM::VMSR_FPCXTNS:
11263 case ARM::VMRS_FPSCR_NZCVQC:
11264 case ARM::VMSR_FPSCR_NZCVQC:
11265 case ARM::FMSTAT:
11266 case ARM::VMRS_VPR:
11267 case ARM::VMRS_P0:
11268 case ARM::VMSR_VPR:
11269 case ARM::VMSR_P0:
11270 // Use of SP for VMRS/VMSR is only allowed in ARM mode with the exception of
11271 // ARMv8-A.
11272 if (Inst.getOperand(0).isReg() && Inst.getOperand(0).getReg() == ARM::SP &&
11273 (isThumb() && !hasV8Ops()))
11274 return Match_InvalidOperand;
11275 break;
11276 case ARM::t2TBB:
11277 case ARM::t2TBH:
11278 // Rn = sp is only allowed with ARMv8-A
11279 if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP))
11280 return Match_RequiresV8;
11281 break;
11282 case ARM::tMUL:
11283 // The second source operand must be the same register as the destination
11284 // operand.
11285 // FIXME: Ideally this would be handled by ARMGenAsmMatcher and
11286 // emitAsmTiedOperandConstraints.
11287 if (Inst.getOperand(0).getReg() != Inst.getOperand(3).getReg())
11288 return Match_InvalidTiedOperand;
11289 break;
11290 default:
11291 break;
11292 }
11293
11294 for (unsigned I = 0; I < MCID.NumOperands; ++I)
11295 if (MCID.operands()[I].RegClass == ARM::rGPRRegClassID) {
11296 // rGPRRegClass excludes PC, and also excluded SP before ARMv8
11297 const auto &Op = Inst.getOperand(I);
11298 if (!Op.isReg()) {
11299 // This can happen in awkward cases with tied operands, e.g. a
11300 // writeback load/store with a complex addressing mode in
11301 // which there's an output operand corresponding to the
11302 // updated written-back base register: the Tablegen-generated
11303 // AsmMatcher will have written a placeholder operand to that
11304 // slot in the form of an immediate 0, because it can't
11305 // generate the register part of the complex addressing-mode
11306 // operand ahead of time.
11307 continue;
11308 }
11309
11310 MCRegister Reg = Op.getReg();
11311 if ((Reg == ARM::SP) && !hasV8Ops())
11312 return Match_RequiresV8;
11313 else if (Reg == ARM::PC)
11314 return Match_InvalidOperand;
11315 }
11316
11317 return Match_Success;
11318}
11319
11320namespace llvm {
11321
11322template <> inline bool IsCPSRDead<MCInst>(const MCInst *Instr) {
11323 return true; // In an assembly source, no need to second-guess
11324}
11325
11326} // end namespace llvm
11327
11328// Returns true if Inst is unpredictable if it is in and IT block, but is not
11329// the last instruction in the block.
11330bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const {
11331 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11332
11333 // All branch & call instructions terminate IT blocks with the exception of
11334 // SVC.
11335 if (MCID.isTerminator() || (MCID.isCall() && Inst.getOpcode() != ARM::tSVC) ||
11336 MCID.isReturn() || MCID.isBranch() || MCID.isIndirectBranch())
11337 return true;
11338
11339 // Any arithmetic instruction which writes to the PC also terminates the IT
11340 // block.
11341 if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI))
11342 return true;
11343
11344 return false;
11345}
11346
11347unsigned ARMAsmParser::MatchInstruction(OperandVector &Operands, MCInst &Inst,
11348 SmallVectorImpl<NearMissInfo> &NearMisses,
11349 bool MatchingInlineAsm,
11350 bool &EmitInITBlock,
11351 MCStreamer &Out) {
11352 // If we can't use an implicit IT block here, just match as normal.
11353 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11354 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11355
11356 // Try to match the instruction in an extension of the current IT block (if
11357 // there is one).
11358 if (inImplicitITBlock()) {
11359 extendImplicitITBlock(ITState.Cond);
11360 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11361 Match_Success) {
11362 // The match succeeded, but we still have to check that the instruction is
11363 // valid in this implicit IT block.
11364 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11365 if (MCID.isPredicable()) {
11366 ARMCC::CondCodes InstCond =
11368 .getImm();
11369 ARMCC::CondCodes ITCond = currentITCond();
11370 if (InstCond == ITCond) {
11371 EmitInITBlock = true;
11372 return Match_Success;
11373 } else if (InstCond == ARMCC::getOppositeCondition(ITCond)) {
11374 invertCurrentITCondition();
11375 EmitInITBlock = true;
11376 return Match_Success;
11377 }
11378 }
11379 }
11380 rewindImplicitITPosition();
11381 }
11382
11383 // Finish the current IT block, and try to match outside any IT block.
11384 flushPendingInstructions(Out);
11385 unsigned PlainMatchResult =
11386 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11387 if (PlainMatchResult == Match_Success) {
11388 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11389 if (MCID.isPredicable()) {
11390 ARMCC::CondCodes InstCond =
11392 .getImm();
11393 // Some forms of the branch instruction have their own condition code
11394 // fields, so can be conditionally executed without an IT block.
11395 if (Inst.getOpcode() == ARM::tBcc || Inst.getOpcode() == ARM::t2Bcc) {
11396 EmitInITBlock = false;
11397 return Match_Success;
11398 }
11399 if (InstCond == ARMCC::AL) {
11400 EmitInITBlock = false;
11401 return Match_Success;
11402 }
11403 } else {
11404 EmitInITBlock = false;
11405 return Match_Success;
11406 }
11407 }
11408
11409 // Try to match in a new IT block. The matcher doesn't check the actual
11410 // condition, so we create an IT block with a dummy condition, and fix it up
11411 // once we know the actual condition.
11412 startImplicitITBlock();
11413 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
11414 Match_Success) {
11415 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
11416 if (MCID.isPredicable()) {
11417 ITState.Cond =
11419 .getImm();
11420 EmitInITBlock = true;
11421 return Match_Success;
11422 }
11423 }
11424 discardImplicitITBlock();
11425
11426 // If none of these succeed, return the error we got when trying to match
11427 // outside any IT blocks.
11428 EmitInITBlock = false;
11429 return PlainMatchResult;
11430}
11431
11432static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
11433 unsigned VariantID = 0);
11434
11435static const char *getSubtargetFeatureName(uint64_t Val);
11436bool ARMAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
11437 OperandVector &Operands,
11439 bool MatchingInlineAsm) {
11440 MCInst Inst;
11441 unsigned MatchResult;
11442 bool PendConditionalInstruction = false;
11443
11445 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
11446 PendConditionalInstruction, Out);
11447
11448 // Find the number of operators that are part of the Mnumonic (LHS).
11449 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
11450
11451 switch (MatchResult) {
11452 case Match_Success:
11453 LLVM_DEBUG(dbgs() << "Parsed as: ";
11454 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11455 dbgs() << "\n");
11456
11457 // Context sensitive operand constraints aren't handled by the matcher,
11458 // so check them here.
11459 if (validateInstruction(Inst, Operands, MnemonicOpsEndInd)) {
11460 // Still progress the IT block, otherwise one wrong condition causes
11461 // nasty cascading errors.
11462 forwardITPosition();
11463 forwardVPTPosition();
11464 return true;
11465 }
11466
11467 {
11468 // Some instructions need post-processing to, for example, tweak which
11469 // encoding is selected. Loop on it while changes happen so the
11470 // individual transformations can chain off each other. E.g.,
11471 // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
11472 while (processInstruction(Inst, Operands, MnemonicOpsEndInd, Out))
11473 LLVM_DEBUG(dbgs() << "Changed to: ";
11474 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode()));
11475 dbgs() << "\n");
11476 }
11477
11478 // Only move forward at the very end so that everything in validate
11479 // and process gets a consistent answer about whether we're in an IT
11480 // block.
11481 forwardITPosition();
11482 forwardVPTPosition();
11483
11484 // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
11485 // doesn't actually encode.
11486 if (Inst.getOpcode() == ARM::ITasm)
11487 return false;
11488
11489 Inst.setLoc(IDLoc);
11490 if (PendConditionalInstruction) {
11491 PendingConditionalInsts.push_back(Inst);
11492 if (isITBlockFull() || isITBlockTerminator(Inst))
11493 flushPendingInstructions(Out);
11494 } else {
11495 Out.emitInstruction(Inst, getSTI());
11496 }
11497 return false;
11498 case Match_NearMisses:
11499 ReportNearMisses(NearMisses, IDLoc, Operands);
11500 return true;
11501 case Match_MnemonicFail: {
11502 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11503 std::string Suggestion = ARMMnemonicSpellCheck(
11504 ((ARMOperand &)*Operands[0]).getToken(), FBS);
11505 return Error(IDLoc, "invalid instruction" + Suggestion,
11506 ((ARMOperand &)*Operands[0]).getLocRange());
11507 }
11508 }
11509
11510 llvm_unreachable("Implement any new match types added!");
11511}
11512
11513/// ParseDirective parses the arm specific directives
11514bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11515 const MCContext::Environment Format = getContext().getObjectFileType();
11516 bool IsMachO = Format == MCContext::IsMachO;
11517 bool IsCOFF = Format == MCContext::IsCOFF;
11518
11519 std::string IDVal = DirectiveID.getIdentifier().lower();
11520 if (IDVal == ".word")
11521 parseLiteralValues(4, DirectiveID.getLoc());
11522 else if (IDVal == ".short" || IDVal == ".hword")
11523 parseLiteralValues(2, DirectiveID.getLoc());
11524 else if (IDVal == ".thumb")
11525 parseDirectiveThumb(DirectiveID.getLoc());
11526 else if (IDVal == ".arm")
11527 parseDirectiveARM(DirectiveID.getLoc());
11528 else if (IDVal == ".thumb_func")
11529 parseDirectiveThumbFunc(DirectiveID.getLoc());
11530 else if (IDVal == ".code")
11531 parseDirectiveCode(DirectiveID.getLoc());
11532 else if (IDVal == ".syntax")
11533 parseDirectiveSyntax(DirectiveID.getLoc());
11534 else if (IDVal == ".unreq")
11535 parseDirectiveUnreq(DirectiveID.getLoc());
11536 else if (IDVal == ".fnend")
11537 parseDirectiveFnEnd(DirectiveID.getLoc());
11538 else if (IDVal == ".cantunwind")
11539 parseDirectiveCantUnwind(DirectiveID.getLoc());
11540 else if (IDVal == ".personality")
11541 parseDirectivePersonality(DirectiveID.getLoc());
11542 else if (IDVal == ".handlerdata")
11543 parseDirectiveHandlerData(DirectiveID.getLoc());
11544 else if (IDVal == ".setfp")
11545 parseDirectiveSetFP(DirectiveID.getLoc());
11546 else if (IDVal == ".pad")
11547 parseDirectivePad(DirectiveID.getLoc());
11548 else if (IDVal == ".save")
11549 parseDirectiveRegSave(DirectiveID.getLoc(), false);
11550 else if (IDVal == ".vsave")
11551 parseDirectiveRegSave(DirectiveID.getLoc(), true);
11552 else if (IDVal == ".ltorg" || IDVal == ".pool")
11553 parseDirectiveLtorg(DirectiveID.getLoc());
11554 else if (IDVal == ".even")
11555 parseDirectiveEven(DirectiveID.getLoc());
11556 else if (IDVal == ".personalityindex")
11557 parseDirectivePersonalityIndex(DirectiveID.getLoc());
11558 else if (IDVal == ".unwind_raw")
11559 parseDirectiveUnwindRaw(DirectiveID.getLoc());
11560 else if (IDVal == ".movsp")
11561 parseDirectiveMovSP(DirectiveID.getLoc());
11562 else if (IDVal == ".arch_extension")
11563 parseDirectiveArchExtension(DirectiveID.getLoc());
11564 else if (IDVal == ".align")
11565 return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
11566 else if (IDVal == ".thumb_set")
11567 parseDirectiveThumbSet(DirectiveID.getLoc());
11568 else if (IDVal == ".inst")
11569 parseDirectiveInst(DirectiveID.getLoc());
11570 else if (IDVal == ".inst.n")
11571 parseDirectiveInst(DirectiveID.getLoc(), 'n');
11572 else if (IDVal == ".inst.w")
11573 parseDirectiveInst(DirectiveID.getLoc(), 'w');
11574 else if (!IsMachO && !IsCOFF) {
11575 if (IDVal == ".arch")
11576 parseDirectiveArch(DirectiveID.getLoc());
11577 else if (IDVal == ".cpu")
11578 parseDirectiveCPU(DirectiveID.getLoc());
11579 else if (IDVal == ".eabi_attribute")
11580 parseDirectiveEabiAttr(DirectiveID.getLoc());
11581 else if (IDVal == ".fpu")
11582 parseDirectiveFPU(DirectiveID.getLoc());
11583 else if (IDVal == ".fnstart")
11584 parseDirectiveFnStart(DirectiveID.getLoc());
11585 else if (IDVal == ".object_arch")
11586 parseDirectiveObjectArch(DirectiveID.getLoc());
11587 else if (IDVal == ".tlsdescseq")
11588 parseDirectiveTLSDescSeq(DirectiveID.getLoc());
11589 else
11590 return true;
11591 } else if (IsCOFF) {
11592 if (IDVal == ".seh_stackalloc")
11593 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/false);
11594 else if (IDVal == ".seh_stackalloc_w")
11595 parseDirectiveSEHAllocStack(DirectiveID.getLoc(), /*Wide=*/true);
11596 else if (IDVal == ".seh_save_regs")
11597 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/false);
11598 else if (IDVal == ".seh_save_regs_w")
11599 parseDirectiveSEHSaveRegs(DirectiveID.getLoc(), /*Wide=*/true);
11600 else if (IDVal == ".seh_save_sp")
11601 parseDirectiveSEHSaveSP(DirectiveID.getLoc());
11602 else if (IDVal == ".seh_save_fregs")
11603 parseDirectiveSEHSaveFRegs(DirectiveID.getLoc());
11604 else if (IDVal == ".seh_save_lr")
11605 parseDirectiveSEHSaveLR(DirectiveID.getLoc());
11606 else if (IDVal == ".seh_endprologue")
11607 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/false);
11608 else if (IDVal == ".seh_endprologue_fragment")
11609 parseDirectiveSEHPrologEnd(DirectiveID.getLoc(), /*Fragment=*/true);
11610 else if (IDVal == ".seh_nop")
11611 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/false);
11612 else if (IDVal == ".seh_nop_w")
11613 parseDirectiveSEHNop(DirectiveID.getLoc(), /*Wide=*/true);
11614 else if (IDVal == ".seh_startepilogue")
11615 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/false);
11616 else if (IDVal == ".seh_startepilogue_cond")
11617 parseDirectiveSEHEpilogStart(DirectiveID.getLoc(), /*Condition=*/true);
11618 else if (IDVal == ".seh_endepilogue")
11619 parseDirectiveSEHEpilogEnd(DirectiveID.getLoc());
11620 else if (IDVal == ".seh_custom")
11621 parseDirectiveSEHCustom(DirectiveID.getLoc());
11622 else
11623 return true;
11624 } else
11625 return true;
11626 return false;
11627}
11628
11629/// parseLiteralValues
11630/// ::= .hword expression [, expression]*
11631/// ::= .short expression [, expression]*
11632/// ::= .word expression [, expression]*
11633bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
11634 auto parseOne = [&]() -> bool {
11635 const MCExpr *Value;
11636 if (getParser().parseExpression(Value))
11637 return true;
11638 getParser().getStreamer().emitValue(Value, Size, L);
11639 return false;
11640 };
11641 return (parseMany(parseOne));
11642}
11643
11644/// parseDirectiveThumb
11645/// ::= .thumb
11646bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11647 if (parseEOL() || check(!hasThumb(), L, "target does not support Thumb mode"))
11648 return true;
11649
11650 if (!isThumb())
11651 SwitchMode();
11652
11653 getTargetStreamer().emitCode16();
11654 getParser().getStreamer().emitCodeAlignment(Align(2), getSTI(), 0);
11655 return false;
11656}
11657
11658/// parseDirectiveARM
11659/// ::= .arm
11660bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11661 if (parseEOL() || check(!hasARM(), L, "target does not support ARM mode"))
11662 return true;
11663
11664 if (isThumb())
11665 SwitchMode();
11666 getTargetStreamer().emitCode32();
11667 getParser().getStreamer().emitCodeAlignment(Align(4), getSTI(), 0);
11668 return false;
11669}
11670
11671void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11672 // We need to flush the current implicit IT block on a label, because it is
11673 // not legal to branch into an IT block.
11674 flushPendingInstructions(getStreamer());
11675}
11676
11677void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11678 if (NextSymbolIsThumb) {
11679 getTargetStreamer().emitThumbFunc(Symbol);
11680 NextSymbolIsThumb = false;
11681 }
11682}
11683
11684/// parseDirectiveThumbFunc
11685/// ::= .thumbfunc symbol_name
11686bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11687 MCAsmParser &Parser = getParser();
11688 const auto Format = getContext().getObjectFileType();
11689 bool IsMachO = Format == MCContext::IsMachO;
11690
11691 // Darwin asm has (optionally) function name after .thumb_func direction
11692 // ELF doesn't
11693
11694 if (IsMachO) {
11695 if (Parser.getTok().is(AsmToken::Identifier) ||
11696 Parser.getTok().is(AsmToken::String)) {
11697 MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
11698 Parser.getTok().getIdentifier());
11699 getTargetStreamer().emitThumbFunc(Func);
11700 Parser.Lex();
11701 if (parseEOL())
11702 return true;
11703 return false;
11704 }
11705 }
11706
11707 if (parseEOL())
11708 return true;
11709
11710 // .thumb_func implies .thumb
11711 if (!isThumb())
11712 SwitchMode();
11713
11714 getTargetStreamer().emitCode16();
11715
11716 NextSymbolIsThumb = true;
11717 return false;
11718}
11719
11720/// parseDirectiveSyntax
11721/// ::= .syntax unified | divided
11722bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11723 MCAsmParser &Parser = getParser();
11724 const AsmToken &Tok = Parser.getTok();
11725 if (Tok.isNot(AsmToken::Identifier)) {
11726 Error(L, "unexpected token in .syntax directive");
11727 return false;
11728 }
11729
11730 StringRef Mode = Tok.getString();
11731 Parser.Lex();
11732 if (check(Mode == "divided" || Mode == "DIVIDED", L,
11733 "'.syntax divided' arm assembly not supported") ||
11734 check(Mode != "unified" && Mode != "UNIFIED", L,
11735 "unrecognized syntax mode in .syntax directive") ||
11736 parseEOL())
11737 return true;
11738
11739 // TODO tell the MC streamer the mode
11740 // getParser().getStreamer().Emit???();
11741 return false;
11742}
11743
11744/// parseDirectiveCode
11745/// ::= .code 16 | 32
11746bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11747 MCAsmParser &Parser = getParser();
11748 const AsmToken &Tok = Parser.getTok();
11749 if (Tok.isNot(AsmToken::Integer))
11750 return Error(L, "unexpected token in .code directive");
11751 int64_t Val = Parser.getTok().getIntVal();
11752 if (Val != 16 && Val != 32) {
11753 Error(L, "invalid operand to .code directive");
11754 return false;
11755 }
11756 Parser.Lex();
11757
11758 if (parseEOL())
11759 return true;
11760
11761 if (Val == 16) {
11762 if (!hasThumb())
11763 return Error(L, "target does not support Thumb mode");
11764
11765 if (!isThumb())
11766 SwitchMode();
11767 getTargetStreamer().emitCode16();
11768 } else {
11769 if (!hasARM())
11770 return Error(L, "target does not support ARM mode");
11771
11772 if (isThumb())
11773 SwitchMode();
11774 getTargetStreamer().emitCode32();
11775 }
11776
11777 return false;
11778}
11779
11780/// parseDirectiveReq
11781/// ::= name .req registername
11782bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11783 MCAsmParser &Parser = getParser();
11784 Parser.Lex(); // Eat the '.req' token.
11785 MCRegister Reg;
11786 SMLoc SRegLoc, ERegLoc;
11787 const bool parseResult = parseRegister(Reg, SRegLoc, ERegLoc);
11788 if (check(parseResult, SRegLoc, "register name expected") || parseEOL())
11789 return true;
11790
11791 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg)
11792 return Error(SRegLoc,
11793 "redefinition of '" + Name + "' does not match original.");
11794
11795 return false;
11796}
11797
11798/// parseDirectiveUneq
11799/// ::= .unreq registername
11800bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11801 MCAsmParser &Parser = getParser();
11802 if (Parser.getTok().isNot(AsmToken::Identifier))
11803 return Error(L, "unexpected input in .unreq directive.");
11804 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
11805 Parser.Lex(); // Eat the identifier.
11806 return parseEOL();
11807}
11808
11809// After changing arch/CPU, try to put the ARM/Thumb mode back to what it was
11810// before, if supported by the new target, or emit mapping symbols for the mode
11811// switch.
11812void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) {
11813 if (WasThumb != isThumb()) {
11814 if (WasThumb && hasThumb()) {
11815 // Stay in Thumb mode
11816 SwitchMode();
11817 } else if (!WasThumb && hasARM()) {
11818 // Stay in ARM mode
11819 SwitchMode();
11820 } else {
11821 // Mode switch forced, because the new arch doesn't support the old mode.
11822 if (isThumb())
11823 getTargetStreamer().emitCode16();
11824 else
11825 getTargetStreamer().emitCode32();
11826 // Warn about the implicit mode switch. GAS does not switch modes here,
11827 // but instead stays in the old mode, reporting an error on any following
11828 // instructions as the mode does not exist on the target.
11829 Warning(Loc, Twine("new target does not support ") +
11830 (WasThumb ? "thumb" : "arm") + " mode, switching to " +
11831 (!WasThumb ? "thumb" : "arm") + " mode");
11832 }
11833 }
11834}
11835
11836/// parseDirectiveArch
11837/// ::= .arch token
11838bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11839 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11841
11842 if (ID == ARM::ArchKind::INVALID)
11843 return Error(L, "Unknown arch name");
11844
11845 bool WasThumb = isThumb();
11846 MCSubtargetInfo &STI = copySTI();
11847 STI.setDefaultFeatures("", /*TuneCPU*/ "",
11848 ("+" + ARM::getArchName(ID)).str());
11849 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11850 FixModeAfterArchChange(WasThumb, L);
11851
11852 getTargetStreamer().emitArch(ID);
11853 return false;
11854}
11855
11856/// parseDirectiveEabiAttr
11857/// ::= .eabi_attribute int, int [, "str"]
11858/// ::= .eabi_attribute Tag_name, int [, "str"]
11859bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11860 MCAsmParser &Parser = getParser();
11861 int64_t Tag;
11862 SMLoc TagLoc;
11863 TagLoc = Parser.getTok().getLoc();
11864 if (Parser.getTok().is(AsmToken::Identifier)) {
11865 StringRef Name = Parser.getTok().getIdentifier();
11866 std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString(
11868 if (!Ret) {
11869 Error(TagLoc, "attribute name not recognised: " + Name);
11870 return false;
11871 }
11872 Tag = *Ret;
11873 Parser.Lex();
11874 } else {
11875 const MCExpr *AttrExpr;
11876
11877 TagLoc = Parser.getTok().getLoc();
11878 if (Parser.parseExpression(AttrExpr))
11879 return true;
11880
11881 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
11882 if (check(!CE, TagLoc, "expected numeric constant"))
11883 return true;
11884
11885 Tag = CE->getValue();
11886 }
11887
11888 if (Parser.parseComma())
11889 return true;
11890
11891 StringRef StringValue = "";
11892 bool IsStringValue = false;
11893
11894 int64_t IntegerValue = 0;
11895 bool IsIntegerValue = false;
11896
11898 IsStringValue = true;
11899 else if (Tag == ARMBuildAttrs::compatibility) {
11900 IsStringValue = true;
11901 IsIntegerValue = true;
11902 } else if (Tag < 32 || Tag % 2 == 0)
11903 IsIntegerValue = true;
11904 else if (Tag % 2 == 1)
11905 IsStringValue = true;
11906 else
11907 llvm_unreachable("invalid tag type");
11908
11909 if (IsIntegerValue) {
11910 const MCExpr *ValueExpr;
11911 SMLoc ValueExprLoc = Parser.getTok().getLoc();
11912 if (Parser.parseExpression(ValueExpr))
11913 return true;
11914
11915 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
11916 if (!CE)
11917 return Error(ValueExprLoc, "expected numeric constant");
11918 IntegerValue = CE->getValue();
11919 }
11920
11922 if (Parser.parseComma())
11923 return true;
11924 }
11925
11926 std::string EscapedValue;
11927 if (IsStringValue) {
11928 if (Parser.getTok().isNot(AsmToken::String))
11929 return Error(Parser.getTok().getLoc(), "bad string constant");
11930
11932 if (Parser.parseEscapedString(EscapedValue))
11933 return Error(Parser.getTok().getLoc(), "bad escaped string constant");
11934
11935 StringValue = EscapedValue;
11936 } else {
11937 StringValue = Parser.getTok().getStringContents();
11938 Parser.Lex();
11939 }
11940 }
11941
11942 if (Parser.parseEOL())
11943 return true;
11944
11945 if (IsIntegerValue && IsStringValue) {
11947 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
11948 } else if (IsIntegerValue)
11949 getTargetStreamer().emitAttribute(Tag, IntegerValue);
11950 else if (IsStringValue)
11951 getTargetStreamer().emitTextAttribute(Tag, StringValue);
11952 return false;
11953}
11954
11955/// parseDirectiveCPU
11956/// ::= .cpu str
11957bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11958 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11959 getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
11960
11961 // FIXME: This is using table-gen data, but should be moved to
11962 // ARMTargetParser once that is table-gen'd.
11963 if (!getSTI().isCPUStringValid(CPU))
11964 return Error(L, "Unknown CPU name");
11965
11966 bool WasThumb = isThumb();
11967 MCSubtargetInfo &STI = copySTI();
11968 STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
11969 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11970 FixModeAfterArchChange(WasThumb, L);
11971
11972 return false;
11973}
11974
11975/// parseDirectiveFPU
11976/// ::= .fpu str
11977bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11978 SMLoc FPUNameLoc = getTok().getLoc();
11979 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11980
11982 std::vector<StringRef> Features;
11983 if (!ARM::getFPUFeatures(ID, Features))
11984 return Error(FPUNameLoc, "Unknown FPU name");
11985
11986 MCSubtargetInfo &STI = copySTI();
11987 for (auto Feature : Features)
11988 STI.ApplyFeatureFlag(Feature);
11989 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11990
11991 getTargetStreamer().emitFPU(ID);
11992 return false;
11993}
11994
11995/// parseDirectiveFnStart
11996/// ::= .fnstart
11997bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
11998 if (parseEOL())
11999 return true;
12000
12001 if (UC.hasFnStart()) {
12002 Error(L, ".fnstart starts before the end of previous one");
12003 UC.emitFnStartLocNotes();
12004 return true;
12005 }
12006
12007 // Reset the unwind directives parser state
12008 UC.reset();
12009
12010 getTargetStreamer().emitFnStart();
12011
12012 UC.recordFnStart(L);
12013 return false;
12014}
12015
12016/// parseDirectiveFnEnd
12017/// ::= .fnend
12018bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12019 if (parseEOL())
12020 return true;
12021 // Check the ordering of unwind directives
12022 if (!UC.hasFnStart())
12023 return Error(L, ".fnstart must precede .fnend directive");
12024
12025 // Reset the unwind directives parser state
12026 getTargetStreamer().emitFnEnd();
12027
12028 UC.reset();
12029 return false;
12030}
12031
12032/// parseDirectiveCantUnwind
12033/// ::= .cantunwind
12034bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12035 if (parseEOL())
12036 return true;
12037
12038 UC.recordCantUnwind(L);
12039 // Check the ordering of unwind directives
12040 if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive"))
12041 return true;
12042
12043 if (UC.hasHandlerData()) {
12044 Error(L, ".cantunwind can't be used with .handlerdata directive");
12045 UC.emitHandlerDataLocNotes();
12046 return true;
12047 }
12048 if (UC.hasPersonality()) {
12049 Error(L, ".cantunwind can't be used with .personality directive");
12050 UC.emitPersonalityLocNotes();
12051 return true;
12052 }
12053
12054 getTargetStreamer().emitCantUnwind();
12055 return false;
12056}
12057
12058/// parseDirectivePersonality
12059/// ::= .personality name
12060bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12061 MCAsmParser &Parser = getParser();
12062 bool HasExistingPersonality = UC.hasPersonality();
12063
12064 // Parse the name of the personality routine
12065 if (Parser.getTok().isNot(AsmToken::Identifier))
12066 return Error(L, "unexpected input in .personality directive.");
12067 StringRef Name(Parser.getTok().getIdentifier());
12068 Parser.Lex();
12069
12070 if (parseEOL())
12071 return true;
12072
12073 UC.recordPersonality(L);
12074
12075 // Check the ordering of unwind directives
12076 if (!UC.hasFnStart())
12077 return Error(L, ".fnstart must precede .personality directive");
12078 if (UC.cantUnwind()) {
12079 Error(L, ".personality can't be used with .cantunwind directive");
12080 UC.emitCantUnwindLocNotes();
12081 return true;
12082 }
12083 if (UC.hasHandlerData()) {
12084 Error(L, ".personality must precede .handlerdata directive");
12085 UC.emitHandlerDataLocNotes();
12086 return true;
12087 }
12088 if (HasExistingPersonality) {
12089 Error(L, "multiple personality directives");
12090 UC.emitPersonalityLocNotes();
12091 return true;
12092 }
12093
12094 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12095 getTargetStreamer().emitPersonality(PR);
12096 return false;
12097}
12098
12099/// parseDirectiveHandlerData
12100/// ::= .handlerdata
12101bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12102 if (parseEOL())
12103 return true;
12104
12105 UC.recordHandlerData(L);
12106 // Check the ordering of unwind directives
12107 if (!UC.hasFnStart())
12108 return Error(L, ".fnstart must precede .personality directive");
12109 if (UC.cantUnwind()) {
12110 Error(L, ".handlerdata can't be used with .cantunwind directive");
12111 UC.emitCantUnwindLocNotes();
12112 return true;
12113 }
12114
12115 getTargetStreamer().emitHandlerData();
12116 return false;
12117}
12118
12119/// parseDirectiveSetFP
12120/// ::= .setfp fpreg, spreg [, offset]
12121bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12122 MCAsmParser &Parser = getParser();
12123 // Check the ordering of unwind directives
12124 if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") ||
12125 check(UC.hasHandlerData(), L,
12126 ".setfp must precede .handlerdata directive"))
12127 return true;
12128
12129 // Parse fpreg
12130 SMLoc FPRegLoc = Parser.getTok().getLoc();
12131 MCRegister FPReg = tryParseRegister();
12132
12133 if (check(!FPReg, FPRegLoc, "frame pointer register expected") ||
12134 Parser.parseComma())
12135 return true;
12136
12137 // Parse spreg
12138 SMLoc SPRegLoc = Parser.getTok().getLoc();
12139 MCRegister SPReg = tryParseRegister();
12140 if (check(!SPReg, SPRegLoc, "stack pointer register expected") ||
12141 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
12142 "register should be either $sp or the latest fp register"))
12143 return true;
12144
12145 // Update the frame pointer register
12146 UC.saveFPReg(FPReg);
12147
12148 // Parse offset
12149 int64_t Offset = 0;
12150 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12151 if (Parser.getTok().isNot(AsmToken::Hash) &&
12152 Parser.getTok().isNot(AsmToken::Dollar))
12153 return Error(Parser.getTok().getLoc(), "'#' expected");
12154 Parser.Lex(); // skip hash token.
12155
12156 const MCExpr *OffsetExpr;
12157 SMLoc ExLoc = Parser.getTok().getLoc();
12158 SMLoc EndLoc;
12159 if (getParser().parseExpression(OffsetExpr, EndLoc))
12160 return Error(ExLoc, "malformed setfp offset");
12161 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12162 if (check(!CE, ExLoc, "setfp offset must be an immediate"))
12163 return true;
12164 Offset = CE->getValue();
12165 }
12166
12167 if (Parser.parseEOL())
12168 return true;
12169
12170 getTargetStreamer().emitSetFP(FPReg, SPReg, Offset);
12171 return false;
12172}
12173
12174/// parseDirectivePad
12175/// ::= .pad offset
12176bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12177 MCAsmParser &Parser = getParser();
12178 // Check the ordering of unwind directives
12179 if (!UC.hasFnStart())
12180 return Error(L, ".fnstart must precede .pad directive");
12181 if (UC.hasHandlerData())
12182 return Error(L, ".pad must precede .handlerdata directive");
12183
12184 // Parse the offset
12185 if (Parser.getTok().isNot(AsmToken::Hash) &&
12186 Parser.getTok().isNot(AsmToken::Dollar))
12187 return Error(Parser.getTok().getLoc(), "'#' expected");
12188 Parser.Lex(); // skip hash token.
12189
12190 const MCExpr *OffsetExpr;
12191 SMLoc ExLoc = Parser.getTok().getLoc();
12192 SMLoc EndLoc;
12193 if (getParser().parseExpression(OffsetExpr, EndLoc))
12194 return Error(ExLoc, "malformed pad offset");
12195 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12196 if (!CE)
12197 return Error(ExLoc, "pad offset must be an immediate");
12198
12199 if (parseEOL())
12200 return true;
12201
12202 getTargetStreamer().emitPad(CE->getValue());
12203 return false;
12204}
12205
12206/// parseDirectiveRegSave
12207/// ::= .save { registers }
12208/// ::= .vsave { registers }
12209bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
12210 // Check the ordering of unwind directives
12211 if (!UC.hasFnStart())
12212 return Error(L, ".fnstart must precede .save or .vsave directives");
12213 if (UC.hasHandlerData())
12214 return Error(L, ".save or .vsave must precede .handlerdata directive");
12215
12216 // RAII object to make sure parsed operands are deleted.
12218
12219 // Parse the register list
12220 if (parseRegisterList(Operands, true, true) || parseEOL())
12221 return true;
12222 ARMOperand &Op = (ARMOperand &)*Operands[0];
12223 if (!IsVector && !Op.isRegList())
12224 return Error(L, ".save expects GPR registers");
12225 if (IsVector && !Op.isDPRRegList())
12226 return Error(L, ".vsave expects DPR registers");
12227
12228 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
12229 return false;
12230}
12231
12232/// parseDirectiveInst
12233/// ::= .inst opcode [, ...]
12234/// ::= .inst.n opcode [, ...]
12235/// ::= .inst.w opcode [, ...]
12236bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
12237 int Width = 4;
12238
12239 if (isThumb()) {
12240 switch (Suffix) {
12241 case 'n':
12242 Width = 2;
12243 break;
12244 case 'w':
12245 break;
12246 default:
12247 Width = 0;
12248 break;
12249 }
12250 } else {
12251 if (Suffix)
12252 return Error(Loc, "width suffixes are invalid in ARM mode");
12253 }
12254
12255 auto parseOne = [&]() -> bool {
12256 const MCExpr *Expr;
12257 if (getParser().parseExpression(Expr))
12258 return true;
12259 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
12260 if (!Value) {
12261 return Error(Loc, "expected constant expression");
12262 }
12263
12264 char CurSuffix = Suffix;
12265 switch (Width) {
12266 case 2:
12267 if (Value->getValue() > 0xffff)
12268 return Error(Loc, "inst.n operand is too big, use inst.w instead");
12269 break;
12270 case 4:
12271 if (Value->getValue() > 0xffffffff)
12272 return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +
12273 " operand is too big");
12274 break;
12275 case 0:
12276 // Thumb mode, no width indicated. Guess from the opcode, if possible.
12277 if (Value->getValue() < 0xe800)
12278 CurSuffix = 'n';
12279 else if (Value->getValue() >= 0xe8000000)
12280 CurSuffix = 'w';
12281 else
12282 return Error(Loc, "cannot determine Thumb instruction size, "
12283 "use inst.n/inst.w instead");
12284 break;
12285 default:
12286 llvm_unreachable("only supported widths are 2 and 4");
12287 }
12288
12289 getTargetStreamer().emitInst(Value->getValue(), CurSuffix);
12290 forwardITPosition();
12291 forwardVPTPosition();
12292 return false;
12293 };
12294
12295 if (parseOptionalToken(AsmToken::EndOfStatement))
12296 return Error(Loc, "expected expression following directive");
12297 if (parseMany(parseOne))
12298 return true;
12299 return false;
12300}
12301
12302/// parseDirectiveLtorg
12303/// ::= .ltorg | .pool
12304bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12305 if (parseEOL())
12306 return true;
12307 getTargetStreamer().emitCurrentConstantPool();
12308 return false;
12309}
12310
12311bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12312 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12313
12314 if (parseEOL())
12315 return true;
12316
12317 if (!Section) {
12318 getStreamer().initSections(getSTI());
12319 Section = getStreamer().getCurrentSectionOnly();
12320 }
12321
12322 assert(Section && "must have section to emit alignment");
12323 if (getContext().getAsmInfo().useCodeAlign(*Section))
12324 getStreamer().emitCodeAlignment(Align(2), getSTI());
12325 else
12326 getStreamer().emitValueToAlignment(Align(2));
12327
12328 return false;
12329}
12330
12331/// parseDirectivePersonalityIndex
12332/// ::= .personalityindex index
12333bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12334 MCAsmParser &Parser = getParser();
12335 bool HasExistingPersonality = UC.hasPersonality();
12336
12337 const MCExpr *IndexExpression;
12338 SMLoc IndexLoc = Parser.getTok().getLoc();
12339 if (Parser.parseExpression(IndexExpression) || parseEOL()) {
12340 return true;
12341 }
12342
12343 UC.recordPersonalityIndex(L);
12344
12345 if (!UC.hasFnStart()) {
12346 return Error(L, ".fnstart must precede .personalityindex directive");
12347 }
12348 if (UC.cantUnwind()) {
12349 Error(L, ".personalityindex cannot be used with .cantunwind");
12350 UC.emitCantUnwindLocNotes();
12351 return true;
12352 }
12353 if (UC.hasHandlerData()) {
12354 Error(L, ".personalityindex must precede .handlerdata directive");
12355 UC.emitHandlerDataLocNotes();
12356 return true;
12357 }
12358 if (HasExistingPersonality) {
12359 Error(L, "multiple personality directives");
12360 UC.emitPersonalityLocNotes();
12361 return true;
12362 }
12363
12364 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression);
12365 if (!CE)
12366 return Error(IndexLoc, "index must be a constant number");
12367 if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX)
12368 return Error(IndexLoc,
12369 "personality routine index should be in range [0-3]");
12370
12371 getTargetStreamer().emitPersonalityIndex(CE->getValue());
12372 return false;
12373}
12374
12375/// parseDirectiveUnwindRaw
12376/// ::= .unwind_raw offset, opcode [, opcode...]
12377bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12378 MCAsmParser &Parser = getParser();
12379 int64_t StackOffset;
12380 const MCExpr *OffsetExpr;
12381 SMLoc OffsetLoc = getLexer().getLoc();
12382
12383 if (!UC.hasFnStart())
12384 return Error(L, ".fnstart must precede .unwind_raw directives");
12385 if (getParser().parseExpression(OffsetExpr))
12386 return Error(OffsetLoc, "expected expression");
12387
12388 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12389 if (!CE)
12390 return Error(OffsetLoc, "offset must be a constant");
12391
12392 StackOffset = CE->getValue();
12393
12394 if (Parser.parseComma())
12395 return true;
12396
12398
12399 auto parseOne = [&]() -> bool {
12400 const MCExpr *OE = nullptr;
12401 SMLoc OpcodeLoc = getLexer().getLoc();
12402 if (check(getLexer().is(AsmToken::EndOfStatement) ||
12403 Parser.parseExpression(OE),
12404 OpcodeLoc, "expected opcode expression"))
12405 return true;
12406 const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE);
12407 if (!OC)
12408 return Error(OpcodeLoc, "opcode value must be a constant");
12409 const int64_t Opcode = OC->getValue();
12410 if (Opcode & ~0xff)
12411 return Error(OpcodeLoc, "invalid opcode");
12412 Opcodes.push_back(uint8_t(Opcode));
12413 return false;
12414 };
12415
12416 // Must have at least 1 element
12417 SMLoc OpcodeLoc = getLexer().getLoc();
12418 if (parseOptionalToken(AsmToken::EndOfStatement))
12419 return Error(OpcodeLoc, "expected opcode expression");
12420 if (parseMany(parseOne))
12421 return true;
12422
12423 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12424 return false;
12425}
12426
12427/// parseDirectiveTLSDescSeq
12428/// ::= .tlsdescseq tls-variable
12429bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12430 MCAsmParser &Parser = getParser();
12431
12432 if (getLexer().isNot(AsmToken::Identifier))
12433 return TokError("expected variable after '.tlsdescseq' directive");
12434
12435 auto *Sym = getContext().getOrCreateSymbol(Parser.getTok().getIdentifier());
12436 const auto *SRE =
12438 Lex();
12439
12440 if (parseEOL())
12441 return true;
12442
12443 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12444 return false;
12445}
12446
12447/// parseDirectiveMovSP
12448/// ::= .movsp reg [, #offset]
12449bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12450 MCAsmParser &Parser = getParser();
12451 if (!UC.hasFnStart())
12452 return Error(L, ".fnstart must precede .movsp directives");
12453 if (UC.getFPReg() != ARM::SP)
12454 return Error(L, "unexpected .movsp directive");
12455
12456 SMLoc SPRegLoc = Parser.getTok().getLoc();
12457 MCRegister SPReg = tryParseRegister();
12458 if (!SPReg)
12459 return Error(SPRegLoc, "register expected");
12460 if (SPReg == ARM::SP || SPReg == ARM::PC)
12461 return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
12462
12463 int64_t Offset = 0;
12464 if (Parser.parseOptionalToken(AsmToken::Comma)) {
12465 if (Parser.parseToken(AsmToken::Hash, "expected #constant"))
12466 return true;
12467
12468 const MCExpr *OffsetExpr;
12469 SMLoc OffsetLoc = Parser.getTok().getLoc();
12470
12471 if (Parser.parseExpression(OffsetExpr))
12472 return Error(OffsetLoc, "malformed offset expression");
12473
12474 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
12475 if (!CE)
12476 return Error(OffsetLoc, "offset must be an immediate constant");
12477
12478 Offset = CE->getValue();
12479 }
12480
12481 if (parseEOL())
12482 return true;
12483
12484 getTargetStreamer().emitMovSP(SPReg, Offset);
12485 UC.saveFPReg(SPReg);
12486
12487 return false;
12488}
12489
12490/// parseDirectiveObjectArch
12491/// ::= .object_arch name
12492bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12493 MCAsmParser &Parser = getParser();
12494 if (getLexer().isNot(AsmToken::Identifier))
12495 return Error(getLexer().getLoc(), "unexpected token");
12496
12497 StringRef Arch = Parser.getTok().getString();
12498 SMLoc ArchLoc = Parser.getTok().getLoc();
12499 Lex();
12500
12502
12503 if (ID == ARM::ArchKind::INVALID)
12504 return Error(ArchLoc, "unknown architecture '" + Arch + "'");
12505 if (parseToken(AsmToken::EndOfStatement))
12506 return true;
12507
12508 getTargetStreamer().emitObjectArch(ID);
12509 return false;
12510}
12511
12512/// parseDirectiveAlign
12513/// ::= .align
12514bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12515 // NOTE: if this is not the end of the statement, fall back to the target
12516 // agnostic handling for this directive which will correctly handle this.
12517 if (parseOptionalToken(AsmToken::EndOfStatement)) {
12518 // '.align' is target specifically handled to mean 2**2 byte alignment.
12519 const MCSection *Section = getStreamer().getCurrentSectionOnly();
12520 assert(Section && "must have section to emit alignment");
12521 if (getContext().getAsmInfo().useCodeAlign(*Section))
12522 getStreamer().emitCodeAlignment(Align(4), getSTI(), 0);
12523 else
12524 getStreamer().emitValueToAlignment(Align(4), 0, 1, 0);
12525 return false;
12526 }
12527 return true;
12528}
12529
12530/// parseDirectiveThumbSet
12531/// ::= .thumb_set name, value
12532bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12533 MCAsmParser &Parser = getParser();
12534
12535 StringRef Name;
12536 if (check(Parser.parseIdentifier(Name),
12537 "expected identifier after '.thumb_set'") ||
12538 Parser.parseComma())
12539 return true;
12540
12541 MCSymbol *Sym;
12542 const MCExpr *Value;
12543 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
12544 Parser, Sym, Value))
12545 return true;
12546
12547 getTargetStreamer().emitThumbSet(Sym, Value);
12548 return false;
12549}
12550
12551/// parseDirectiveSEHAllocStack
12552/// ::= .seh_stackalloc
12553/// ::= .seh_stackalloc_w
12554bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L, bool Wide) {
12555 int64_t Size;
12556 if (parseImmExpr(Size))
12557 return true;
12558 getTargetStreamer().emitARMWinCFIAllocStack(Size, Wide);
12559 return false;
12560}
12561
12562/// parseDirectiveSEHSaveRegs
12563/// ::= .seh_save_regs
12564/// ::= .seh_save_regs_w
12565bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L, bool Wide) {
12567
12568 if (parseRegisterList(Operands) || parseEOL())
12569 return true;
12570 ARMOperand &Op = (ARMOperand &)*Operands[0];
12571 if (!Op.isRegList())
12572 return Error(L, ".seh_save_regs{_w} expects GPR registers");
12573 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12574 uint32_t Mask = 0;
12575 for (size_t i = 0; i < RegList.size(); ++i) {
12576 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12577 if (Reg == 15) // pc -> lr
12578 Reg = 14;
12579 if (Reg == 13)
12580 return Error(L, ".seh_save_regs{_w} can't include SP");
12581 assert(Reg < 16U && "Register out of range");
12582 unsigned Bit = (1u << Reg);
12583 Mask |= Bit;
12584 }
12585 if (!Wide && (Mask & 0x1f00) != 0)
12586 return Error(L,
12587 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12588 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12589 return false;
12590}
12591
12592/// parseDirectiveSEHSaveSP
12593/// ::= .seh_save_sp
12594bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12595 MCRegister Reg = tryParseRegister();
12596 if (!Reg || !MRI->getRegClass(ARM::GPRRegClassID).contains(Reg))
12597 return Error(L, "expected GPR");
12598 unsigned Index = MRI->getEncodingValue(Reg);
12599 if (Index > 14 || Index == 13)
12600 return Error(L, "invalid register for .seh_save_sp");
12601 getTargetStreamer().emitARMWinCFISaveSP(Index);
12602 return false;
12603}
12604
12605/// parseDirectiveSEHSaveFRegs
12606/// ::= .seh_save_fregs
12607bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12609
12610 if (parseRegisterList(Operands) || parseEOL())
12611 return true;
12612 ARMOperand &Op = (ARMOperand &)*Operands[0];
12613 if (!Op.isDPRRegList())
12614 return Error(L, ".seh_save_fregs expects DPR registers");
12615 const SmallVectorImpl<MCRegister> &RegList = Op.getRegList();
12616 uint32_t Mask = 0;
12617 for (size_t i = 0; i < RegList.size(); ++i) {
12618 unsigned Reg = MRI->getEncodingValue(RegList[i]);
12619 assert(Reg < 32U && "Register out of range");
12620 unsigned Bit = (1u << Reg);
12621 Mask |= Bit;
12622 }
12623
12624 if (Mask == 0)
12625 return Error(L, ".seh_save_fregs missing registers");
12626
12627 unsigned First = 0;
12628 while ((Mask & 1) == 0) {
12629 First++;
12630 Mask >>= 1;
12631 }
12632 if (((Mask + 1) & Mask) != 0)
12633 return Error(L,
12634 ".seh_save_fregs must take a contiguous range of registers");
12635 unsigned Last = First;
12636 while ((Mask & 2) != 0) {
12637 Last++;
12638 Mask >>= 1;
12639 }
12640 if (First < 16 && Last >= 16)
12641 return Error(L, ".seh_save_fregs must be all d0-d15 or d16-d31");
12642 getTargetStreamer().emitARMWinCFISaveFRegs(First, Last);
12643 return false;
12644}
12645
12646/// parseDirectiveSEHSaveLR
12647/// ::= .seh_save_lr
12648bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12649 int64_t Offset;
12650 if (parseImmExpr(Offset))
12651 return true;
12652 getTargetStreamer().emitARMWinCFISaveLR(Offset);
12653 return false;
12654}
12655
12656/// parseDirectiveSEHPrologEnd
12657/// ::= .seh_endprologue
12658/// ::= .seh_endprologue_fragment
12659bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L, bool Fragment) {
12660 getTargetStreamer().emitARMWinCFIPrologEnd(Fragment);
12661 return false;
12662}
12663
12664/// parseDirectiveSEHNop
12665/// ::= .seh_nop
12666/// ::= .seh_nop_w
12667bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L, bool Wide) {
12668 getTargetStreamer().emitARMWinCFINop(Wide);
12669 return false;
12670}
12671
12672/// parseDirectiveSEHEpilogStart
12673/// ::= .seh_startepilogue
12674/// ::= .seh_startepilogue_cond
12675bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L, bool Condition) {
12676 unsigned CC = ARMCC::AL;
12677 if (Condition) {
12678 MCAsmParser &Parser = getParser();
12679 SMLoc S = Parser.getTok().getLoc();
12680 const AsmToken &Tok = Parser.getTok();
12681 if (!Tok.is(AsmToken::Identifier))
12682 return Error(S, ".seh_startepilogue_cond missing condition");
12683 CC = ARMCondCodeFromString(Tok.getString());
12684 if (CC == ~0U)
12685 return Error(S, "invalid condition");
12686 Parser.Lex(); // Eat the token.
12687 }
12688
12689 getTargetStreamer().emitARMWinCFIEpilogStart(CC);
12690 return false;
12691}
12692
12693/// parseDirectiveSEHEpilogEnd
12694/// ::= .seh_endepilogue
12695bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12696 getTargetStreamer().emitARMWinCFIEpilogEnd();
12697 return false;
12698}
12699
12700/// parseDirectiveSEHCustom
12701/// ::= .seh_custom
12702bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12703 unsigned Opcode = 0;
12704 do {
12705 int64_t Byte;
12706 if (parseImmExpr(Byte))
12707 return true;
12708 if (Byte > 0xff || Byte < 0)
12709 return Error(L, "Invalid byte value in .seh_custom");
12710 if (Opcode > 0x00ffffff)
12711 return Error(L, "Too many bytes in .seh_custom");
12712 // Store the bytes as one big endian number in Opcode. In a multi byte
12713 // opcode sequence, the first byte can't be zero.
12714 Opcode = (Opcode << 8) | Byte;
12715 } while (parseOptionalToken(AsmToken::Comma));
12716 getTargetStreamer().emitARMWinCFICustom(Opcode);
12717 return false;
12718}
12719
12720/// Force static initialization.
12727
12728#define GET_REGISTER_MATCHER
12729#define GET_SUBTARGET_FEATURE_NAME
12730#define GET_MATCHER_IMPLEMENTATION
12731#define GET_MNEMONIC_SPELL_CHECKER
12732#include "ARMGenAsmMatcher.inc"
12733
12734// Some diagnostics need to vary with subtarget features, so they are handled
12735// here. For example, the DPR class has either 16 or 32 registers, depending
12736// on the FPU available.
12737const char *
12738ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12739 switch (MatchError) {
12740 // rGPR contains sp starting with ARMv8.
12741 case Match_rGPR:
12742 return hasV8Ops() ? "operand must be a register in range [r0, r14]"
12743 : "operand must be a register in range [r0, r12] or r14";
12744 // DPR contains 16 registers for some FPUs, and 32 for others.
12745 case Match_DPR:
12746 return hasD32() ? "operand must be a register in range [d0, d31]"
12747 : "operand must be a register in range [d0, d15]";
12748 case Match_DPR_RegList:
12749 return hasD32() ? "operand must be a list of registers in range [d0, d31]"
12750 : "operand must be a list of registers in range [d0, d15]";
12751
12752 // For all other diags, use the static string from tablegen.
12753 default:
12754 return getMatchKindDiag(MatchError);
12755 }
12756}
12757
12758// Process the list of near-misses, throwing away ones we don't want to report
12759// to the user, and converting the rest to a source location and string that
12760// should be reported.
12761void
12762ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12763 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12764 SMLoc IDLoc, OperandVector &Operands) {
12765 // TODO: If operand didn't match, sub in a dummy one and run target
12766 // predicate, so that we can avoid reporting near-misses that are invalid?
12767 // TODO: Many operand types dont have SuperClasses set, so we report
12768 // redundant ones.
12769 // TODO: Some operands are superclasses of registers (e.g.
12770 // MCK_RegShiftedImm), we don't have any way to represent that currently.
12771 // TODO: This is not all ARM-specific, can some of it be factored out?
12772
12773 // Record some information about near-misses that we have already seen, so
12774 // that we can avoid reporting redundant ones. For example, if there are
12775 // variants of an instruction that take 8- and 16-bit immediates, we want
12776 // to only report the widest one.
12777 std::multimap<unsigned, unsigned> OperandMissesSeen;
12778 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12779 bool ReportedTooFewOperands = false;
12780
12781 unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd(Operands);
12782
12783 // Process the near-misses in reverse order, so that we see more general ones
12784 // first, and so can avoid emitting more specific ones.
12785 for (NearMissInfo &I : reverse(NearMissesIn)) {
12786 switch (I.getKind()) {
12788 SMLoc OperandLoc =
12789 ((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
12790 const char *OperandDiag =
12791 getCustomOperandDiag((ARMMatchResultTy)I.getOperandError());
12792
12793 // If we have already emitted a message for a superclass, don't also report
12794 // the sub-class. We consider all operand classes that we don't have a
12795 // specialised diagnostic for to be equal for the propose of this check,
12796 // so that we don't report the generic error multiple times on the same
12797 // operand.
12798 unsigned DupCheckMatchClass = OperandDiag ? I.getOperandClass() : ~0U;
12799 auto PrevReports = OperandMissesSeen.equal_range(I.getOperandIndex());
12800 if (std::any_of(PrevReports.first, PrevReports.second,
12801 [DupCheckMatchClass](
12802 const std::pair<unsigned, unsigned> Pair) {
12803 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12804 return Pair.second == DupCheckMatchClass;
12805 else
12806 return isSubclass((MatchClassKind)DupCheckMatchClass,
12807 (MatchClassKind)Pair.second);
12808 }))
12809 break;
12810 OperandMissesSeen.insert(
12811 std::make_pair(I.getOperandIndex(), DupCheckMatchClass));
12812
12813 NearMissMessage Message;
12814 Message.Loc = OperandLoc;
12815 if (OperandDiag) {
12816 Message.Message = OperandDiag;
12817 } else if (I.getOperandClass() == InvalidMatchClass) {
12818 Message.Message = "too many operands for instruction";
12819 } else {
12820 Message.Message = "invalid operand for instruction";
12821 LLVM_DEBUG(
12822 dbgs() << "Missing diagnostic string for operand class "
12823 << getMatchClassName((MatchClassKind)I.getOperandClass())
12824 << I.getOperandClass() << ", error " << I.getOperandError()
12825 << ", opcode " << MII.getName(I.getOpcode()) << "\n");
12826 }
12827 NearMissesOut.emplace_back(Message);
12828 break;
12829 }
12831 const FeatureBitset &MissingFeatures = I.getFeatures();
12832 // Don't report the same set of features twice.
12833 if (FeatureMissesSeen.count(MissingFeatures))
12834 break;
12835 FeatureMissesSeen.insert(MissingFeatures);
12836
12837 // Special case: don't report a feature set which includes arm-mode for
12838 // targets that don't have ARM mode.
12839 if (MissingFeatures.test(Feature_IsARMBit) && !hasARM())
12840 break;
12841 // Don't report any near-misses that both require switching instruction
12842 // set, and adding other subtarget features.
12843 if (isThumb() && MissingFeatures.test(Feature_IsARMBit) &&
12844 MissingFeatures.count() > 1)
12845 break;
12846 if (!isThumb() && MissingFeatures.test(Feature_IsThumbBit) &&
12847 MissingFeatures.count() > 1)
12848 break;
12849 if (!isThumb() && MissingFeatures.test(Feature_IsThumb2Bit) &&
12850 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12851 Feature_IsThumbBit})).any())
12852 break;
12853 if (isMClass() && MissingFeatures.test(Feature_HasNEONBit))
12854 break;
12855
12856 NearMissMessage Message;
12857 Message.Loc = IDLoc;
12858 raw_svector_ostream OS(Message.Message);
12859
12860 OS << "instruction requires:";
12861 for (unsigned Feature : MissingFeatures)
12862 OS << ' ' << getSubtargetFeatureName(Feature);
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:856
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:215
#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:484
This file implements the SmallBitVector class.
This file defines the SmallSet class.
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
Definition AsmLexer.h: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:289
Base class for user error types.
Definition Error.h:354
Container class for subtarget features.
constexpr bool test(unsigned I) const
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Generic assembler parser interface, for use by target specific assembly parsers.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual void Note(SMLoc L, const Twine &Msg, SMRange Range={})=0
Emit a note at the location L, with the message Msg.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:342
int64_t getValue() const
Definition MCExpr.h:171
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
@ Constant
Constant expressions.
Definition MCExpr.h:42
SMLoc getLoc() const
Definition MCExpr.h:86
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getNumOperands() const
Definition MCInst.h:212
void setLoc(SMLoc loc)
Definition MCInst.h:207
unsigned getOpcode() const
Definition MCInst.h:202
LLVM_ABI void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCContext *Ctx=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Definition MCInst.cpp:90
iterator insert(iterator I, const MCOperand &Op)
Definition MCInst.h:232
void addOperand(const MCOperand Op)
Definition MCInst.h:215
iterator begin()
Definition MCInst.h:227
void setOpcode(unsigned Op)
Definition MCInst.h:201
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool isIndirectBranch() const
Return true if this is an indirect branch, such as a branch through a register.
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
LLVM_ABI bool hasDefOfPhysReg(const MCInst &MI, MCRegister Reg, const MCRegisterInfo &RI) const
Return true if this instruction defines the specified physical register, either explicitly or implici...
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
bool isReturn() const
Return true if the instruction is a return.
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getID() const
getID() - Return the register class ID number.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
constexpr unsigned id() const
Definition MCRegister.h:82
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Definition MCStreamer.h:336
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
const FeatureBitset & ApplyFeatureFlag(StringRef FS)
Apply a feature flag and return the re-computed feature bits, including all feature bits implied by t...
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Target specific streamer interface.
Definition MCStreamer.h:95
MCStreamer & getStreamer()
Definition MCStreamer.h:103
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
Definition SMLoc.h:22
static SMLoc getFromPointer(const char *Ptr)
Definition SMLoc.h:35
constexpr const char * getPointer() const
Definition SMLoc.h:33
Represents a range in source code.
Definition SMLoc.h:47
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
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:128
iterator end()
Definition StringMap.h:213
iterator find(StringRef Key)
Definition StringMap.h:226
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition StringMap.h:274
void erase(iterator I)
Definition StringMap.h:417
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition StringMap.h:310
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static constexpr size_t npos
Definition StringRef.h:58
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:720
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:270
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Definition StringRef.h:170
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition StringSet.h:25
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition StringSet.h:39
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:185
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
LLVM_ABI const TagNameMap & getARMAttributeTags()
static CondCodes getOppositeCondition(CondCodes CC)
Definition ARMBaseInfo.h:49
@ ThumbArithFlagSetting
unsigned getSORegOffset(unsigned Op)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
unsigned encodeNEONi16splat(unsigned Value)
float getFPImmFloat(unsigned Imm)
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset)
getAM5Opc - This function encodes the addrmode5 opc field.
ShiftOpc getSORegShOp(unsigned Op)
bool isNEONi16splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
unsigned getAM5FP16Opc(AddrOpc Opc, unsigned char Offset)
getAM5FP16Opc - This function encodes the addrmode5fp16 opc field.
unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
bool isNEONi32splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
StringRef getShiftOpcStr(ShiftOpc Op)
unsigned encodeNEONi32splat(unsigned Value)
Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR.
static const char * IFlagsToString(unsigned val)
Definition ARMBaseInfo.h:37
LLVM_ABI bool getFPUFeatures(FPUKind FPUKind, std::vector< StringRef > &Features)
LLVM_ABI StringRef getArchName(ArchKind AK)
LLVM_ABI uint64_t parseArchExt(StringRef ArchExt)
LLVM_ABI ArchKind parseArch(StringRef Arch)
bool isVpred(OperandType op)
uint16_t Specifier
LLVM_ABI FPUKind parseFPU(StringRef FPU)
bool isCDECoproc(size_t Coproc, const MCSubtargetInfo &STI)
@ D16
Only 16 D registers.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Entry
Definition COFF.h:862
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.
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h: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:573
@ Length
Definition DWP.cpp:573
constexpr T rotr(T V, int R)
Definition bit.h:399
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
Target & getTheThumbBETarget()
static unsigned ARMCondCodeFromString(StringRef CC)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:156
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition STLExtras.h:1970
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h: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
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
static unsigned ARMVectorCondCodeFromString(StringRef CC)
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
@ Always
Always emit .debug_str_offsets talbes as DWARF64 for testing.
Definition DWP.h:32
Target & getTheARMLETarget()
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
#define N
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...