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" 11 #include "MCTargetDesc/ARMAddressingModes.h" 12 #include "MCTargetDesc/ARMBaseInfo.h" 13 #include "MCTargetDesc/ARMInstPrinter.h" 14 #include "MCTargetDesc/ARMMCExpr.h" 15 #include "MCTargetDesc/ARMMCTargetDesc.h" 16 #include "TargetInfo/ARMTargetInfo.h" 17 #include "Utils/ARMBaseInfo.h" 18 #include "llvm/ADT/APFloat.h" 19 #include "llvm/ADT/APInt.h" 20 #include "llvm/ADT/None.h" 21 #include "llvm/ADT/STLExtras.h" 22 #include "llvm/ADT/SmallSet.h" 23 #include "llvm/ADT/SmallVector.h" 24 #include "llvm/ADT/StringMap.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/ADT/StringSet.h" 27 #include "llvm/ADT/StringSwitch.h" 28 #include "llvm/ADT/Triple.h" 29 #include "llvm/ADT/Twine.h" 30 #include "llvm/MC/MCContext.h" 31 #include "llvm/MC/MCExpr.h" 32 #include "llvm/MC/MCInst.h" 33 #include "llvm/MC/MCInstrDesc.h" 34 #include "llvm/MC/MCInstrInfo.h" 35 #include "llvm/MC/MCParser/MCAsmLexer.h" 36 #include "llvm/MC/MCParser/MCAsmParser.h" 37 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 38 #include "llvm/MC/MCParser/MCAsmParserUtils.h" 39 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 40 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 41 #include "llvm/MC/MCRegisterInfo.h" 42 #include "llvm/MC/MCSection.h" 43 #include "llvm/MC/MCStreamer.h" 44 #include "llvm/MC/MCSubtargetInfo.h" 45 #include "llvm/MC/MCSymbol.h" 46 #include "llvm/MC/SubtargetFeature.h" 47 #include "llvm/MC/TargetRegistry.h" 48 #include "llvm/Support/ARMBuildAttributes.h" 49 #include "llvm/Support/ARMEHABI.h" 50 #include "llvm/Support/Casting.h" 51 #include "llvm/Support/CommandLine.h" 52 #include "llvm/Support/Compiler.h" 53 #include "llvm/Support/ErrorHandling.h" 54 #include "llvm/Support/MathExtras.h" 55 #include "llvm/Support/SMLoc.h" 56 #include "llvm/Support/TargetParser.h" 57 #include "llvm/Support/raw_ostream.h" 58 #include <algorithm> 59 #include <cassert> 60 #include <cstddef> 61 #include <cstdint> 62 #include <iterator> 63 #include <limits> 64 #include <memory> 65 #include <string> 66 #include <utility> 67 #include <vector> 68 69 #define DEBUG_TYPE "asm-parser" 70 71 using namespace llvm; 72 73 namespace llvm { 74 extern const MCInstrDesc ARMInsts[]; 75 } // end namespace llvm 76 77 namespace { 78 79 enum class ImplicitItModeTy { Always, Never, ARMOnly, ThumbOnly }; 80 81 static cl::opt<ImplicitItModeTy> ImplicitItMode( 82 "arm-implicit-it", cl::init(ImplicitItModeTy::ARMOnly), 83 cl::desc("Allow conditional instructions outdside of an IT block"), 84 cl::values(clEnumValN(ImplicitItModeTy::Always, "always", 85 "Accept in both ISAs, emit implicit ITs in Thumb"), 86 clEnumValN(ImplicitItModeTy::Never, "never", 87 "Warn in ARM, reject in Thumb"), 88 clEnumValN(ImplicitItModeTy::ARMOnly, "arm", 89 "Accept in ARM, reject in Thumb"), 90 clEnumValN(ImplicitItModeTy::ThumbOnly, "thumb", 91 "Warn in ARM, emit implicit ITs in Thumb"))); 92 93 static cl::opt<bool> AddBuildAttributes("arm-add-build-attributes", 94 cl::init(false)); 95 96 enum VectorLaneTy { NoLanes, AllLanes, IndexedLane }; 97 98 static inline unsigned extractITMaskBit(unsigned Mask, unsigned Position) { 99 // Position==0 means we're not in an IT block at all. Position==1 100 // means we want the first state bit, which is always 0 (Then). 101 // Position==2 means we want the second state bit, stored at bit 3 102 // of Mask, and so on downwards. So (5 - Position) will shift the 103 // right bit down to bit 0, including the always-0 bit at bit 4 for 104 // the mandatory initial Then. 105 return (Mask >> (5 - Position) & 1); 106 } 107 108 class UnwindContext { 109 using Locs = SmallVector<SMLoc, 4>; 110 111 MCAsmParser &Parser; 112 Locs FnStartLocs; 113 Locs CantUnwindLocs; 114 Locs PersonalityLocs; 115 Locs PersonalityIndexLocs; 116 Locs HandlerDataLocs; 117 int FPReg; 118 119 public: 120 UnwindContext(MCAsmParser &P) : Parser(P), FPReg(ARM::SP) {} 121 122 bool hasFnStart() const { return !FnStartLocs.empty(); } 123 bool cantUnwind() const { return !CantUnwindLocs.empty(); } 124 bool hasHandlerData() const { return !HandlerDataLocs.empty(); } 125 126 bool hasPersonality() const { 127 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty()); 128 } 129 130 void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); } 131 void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); } 132 void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); } 133 void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); } 134 void recordPersonalityIndex(SMLoc L) { PersonalityIndexLocs.push_back(L); } 135 136 void saveFPReg(int Reg) { FPReg = Reg; } 137 int getFPReg() const { return FPReg; } 138 139 void emitFnStartLocNotes() const { 140 for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end(); 141 FI != FE; ++FI) 142 Parser.Note(*FI, ".fnstart was specified here"); 143 } 144 145 void emitCantUnwindLocNotes() const { 146 for (Locs::const_iterator UI = CantUnwindLocs.begin(), 147 UE = CantUnwindLocs.end(); UI != UE; ++UI) 148 Parser.Note(*UI, ".cantunwind was specified here"); 149 } 150 151 void emitHandlerDataLocNotes() const { 152 for (Locs::const_iterator HI = HandlerDataLocs.begin(), 153 HE = HandlerDataLocs.end(); HI != HE; ++HI) 154 Parser.Note(*HI, ".handlerdata was specified here"); 155 } 156 157 void emitPersonalityLocNotes() const { 158 for (Locs::const_iterator PI = PersonalityLocs.begin(), 159 PE = PersonalityLocs.end(), 160 PII = PersonalityIndexLocs.begin(), 161 PIE = PersonalityIndexLocs.end(); 162 PI != PE || PII != PIE;) { 163 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer())) 164 Parser.Note(*PI++, ".personality was specified here"); 165 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer())) 166 Parser.Note(*PII++, ".personalityindex was specified here"); 167 else 168 llvm_unreachable(".personality and .personalityindex cannot be " 169 "at the same location"); 170 } 171 } 172 173 void reset() { 174 FnStartLocs = Locs(); 175 CantUnwindLocs = Locs(); 176 PersonalityLocs = Locs(); 177 HandlerDataLocs = Locs(); 178 PersonalityIndexLocs = Locs(); 179 FPReg = ARM::SP; 180 } 181 }; 182 183 // Various sets of ARM instruction mnemonics which are used by the asm parser 184 class ARMMnemonicSets { 185 StringSet<> CDE; 186 StringSet<> CDEWithVPTSuffix; 187 public: 188 ARMMnemonicSets(const MCSubtargetInfo &STI); 189 190 /// Returns true iff a given mnemonic is a CDE instruction 191 bool isCDEInstr(StringRef Mnemonic) { 192 // Quick check before searching the set 193 if (!Mnemonic.startswith("cx") && !Mnemonic.startswith("vcx")) 194 return false; 195 return CDE.count(Mnemonic); 196 } 197 198 /// Returns true iff a given mnemonic is a VPT-predicable CDE instruction 199 /// (possibly with a predication suffix "e" or "t") 200 bool isVPTPredicableCDEInstr(StringRef Mnemonic) { 201 if (!Mnemonic.startswith("vcx")) 202 return false; 203 return CDEWithVPTSuffix.count(Mnemonic); 204 } 205 206 /// Returns true iff a given mnemonic is an IT-predicable CDE instruction 207 /// (possibly with a condition suffix) 208 bool isITPredicableCDEInstr(StringRef Mnemonic) { 209 if (!Mnemonic.startswith("cx")) 210 return false; 211 return Mnemonic.startswith("cx1a") || Mnemonic.startswith("cx1da") || 212 Mnemonic.startswith("cx2a") || Mnemonic.startswith("cx2da") || 213 Mnemonic.startswith("cx3a") || Mnemonic.startswith("cx3da"); 214 } 215 216 /// Return true iff a given mnemonic is an integer CDE instruction with 217 /// dual-register destination 218 bool isCDEDualRegInstr(StringRef Mnemonic) { 219 if (!Mnemonic.startswith("cx")) 220 return false; 221 return Mnemonic == "cx1d" || Mnemonic == "cx1da" || 222 Mnemonic == "cx2d" || Mnemonic == "cx2da" || 223 Mnemonic == "cx3d" || Mnemonic == "cx3da"; 224 } 225 }; 226 227 ARMMnemonicSets::ARMMnemonicSets(const MCSubtargetInfo &STI) { 228 for (StringRef Mnemonic: { "cx1", "cx1a", "cx1d", "cx1da", 229 "cx2", "cx2a", "cx2d", "cx2da", 230 "cx3", "cx3a", "cx3d", "cx3da", }) 231 CDE.insert(Mnemonic); 232 for (StringRef Mnemonic : 233 {"vcx1", "vcx1a", "vcx2", "vcx2a", "vcx3", "vcx3a"}) { 234 CDE.insert(Mnemonic); 235 CDEWithVPTSuffix.insert(Mnemonic); 236 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "t"); 237 CDEWithVPTSuffix.insert(std::string(Mnemonic) + "e"); 238 } 239 } 240 241 class ARMAsmParser : public MCTargetAsmParser { 242 const MCRegisterInfo *MRI; 243 UnwindContext UC; 244 ARMMnemonicSets MS; 245 246 ARMTargetStreamer &getTargetStreamer() { 247 assert(getParser().getStreamer().getTargetStreamer() && 248 "do not have a target streamer"); 249 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 250 return static_cast<ARMTargetStreamer &>(TS); 251 } 252 253 // Map of register aliases registers via the .req directive. 254 StringMap<unsigned> RegisterReqs; 255 256 bool NextSymbolIsThumb; 257 258 bool useImplicitITThumb() const { 259 return ImplicitItMode == ImplicitItModeTy::Always || 260 ImplicitItMode == ImplicitItModeTy::ThumbOnly; 261 } 262 263 bool useImplicitITARM() const { 264 return ImplicitItMode == ImplicitItModeTy::Always || 265 ImplicitItMode == ImplicitItModeTy::ARMOnly; 266 } 267 268 struct { 269 ARMCC::CondCodes Cond; // Condition for IT block. 270 unsigned Mask:4; // Condition mask for instructions. 271 // Starting at first 1 (from lsb). 272 // '1' condition as indicated in IT. 273 // '0' inverse of condition (else). 274 // Count of instructions in IT block is 275 // 4 - trailingzeroes(mask) 276 // Note that this does not have the same encoding 277 // as in the IT instruction, which also depends 278 // on the low bit of the condition code. 279 280 unsigned CurPosition; // Current position in parsing of IT 281 // block. In range [0,4], with 0 being the IT 282 // instruction itself. Initialized according to 283 // count of instructions in block. ~0U if no 284 // active IT block. 285 286 bool IsExplicit; // true - The IT instruction was present in the 287 // input, we should not modify it. 288 // false - The IT instruction was added 289 // implicitly, we can extend it if that 290 // would be legal. 291 } ITState; 292 293 SmallVector<MCInst, 4> PendingConditionalInsts; 294 295 void flushPendingInstructions(MCStreamer &Out) override { 296 if (!inImplicitITBlock()) { 297 assert(PendingConditionalInsts.size() == 0); 298 return; 299 } 300 301 // Emit the IT instruction 302 MCInst ITInst; 303 ITInst.setOpcode(ARM::t2IT); 304 ITInst.addOperand(MCOperand::createImm(ITState.Cond)); 305 ITInst.addOperand(MCOperand::createImm(ITState.Mask)); 306 Out.emitInstruction(ITInst, getSTI()); 307 308 // Emit the conditonal instructions 309 assert(PendingConditionalInsts.size() <= 4); 310 for (const MCInst &Inst : PendingConditionalInsts) { 311 Out.emitInstruction(Inst, getSTI()); 312 } 313 PendingConditionalInsts.clear(); 314 315 // Clear the IT state 316 ITState.Mask = 0; 317 ITState.CurPosition = ~0U; 318 } 319 320 bool inITBlock() { return ITState.CurPosition != ~0U; } 321 bool inExplicitITBlock() { return inITBlock() && ITState.IsExplicit; } 322 bool inImplicitITBlock() { return inITBlock() && !ITState.IsExplicit; } 323 324 bool lastInITBlock() { 325 return ITState.CurPosition == 4 - countTrailingZeros(ITState.Mask); 326 } 327 328 void forwardITPosition() { 329 if (!inITBlock()) return; 330 // Move to the next instruction in the IT block, if there is one. If not, 331 // mark the block as done, except for implicit IT blocks, which we leave 332 // open until we find an instruction that can't be added to it. 333 unsigned TZ = countTrailingZeros(ITState.Mask); 334 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit) 335 ITState.CurPosition = ~0U; // Done with the IT block after this. 336 } 337 338 // Rewind the state of the current IT block, removing the last slot from it. 339 void rewindImplicitITPosition() { 340 assert(inImplicitITBlock()); 341 assert(ITState.CurPosition > 1); 342 ITState.CurPosition--; 343 unsigned TZ = countTrailingZeros(ITState.Mask); 344 unsigned NewMask = 0; 345 NewMask |= ITState.Mask & (0xC << TZ); 346 NewMask |= 0x2 << TZ; 347 ITState.Mask = NewMask; 348 } 349 350 // Rewind the state of the current IT block, removing the last slot from it. 351 // If we were at the first slot, this closes the IT block. 352 void discardImplicitITBlock() { 353 assert(inImplicitITBlock()); 354 assert(ITState.CurPosition == 1); 355 ITState.CurPosition = ~0U; 356 } 357 358 // Return the low-subreg of a given Q register. 359 unsigned getDRegFromQReg(unsigned QReg) const { 360 return MRI->getSubReg(QReg, ARM::dsub_0); 361 } 362 363 // Get the condition code corresponding to the current IT block slot. 364 ARMCC::CondCodes currentITCond() { 365 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition); 366 return MaskBit ? ARMCC::getOppositeCondition(ITState.Cond) : ITState.Cond; 367 } 368 369 // Invert the condition of the current IT block slot without changing any 370 // other slots in the same block. 371 void invertCurrentITCondition() { 372 if (ITState.CurPosition == 1) { 373 ITState.Cond = ARMCC::getOppositeCondition(ITState.Cond); 374 } else { 375 ITState.Mask ^= 1 << (5 - ITState.CurPosition); 376 } 377 } 378 379 // Returns true if the current IT block is full (all 4 slots used). 380 bool isITBlockFull() { 381 return inITBlock() && (ITState.Mask & 1); 382 } 383 384 // Extend the current implicit IT block to have one more slot with the given 385 // condition code. 386 void extendImplicitITBlock(ARMCC::CondCodes Cond) { 387 assert(inImplicitITBlock()); 388 assert(!isITBlockFull()); 389 assert(Cond == ITState.Cond || 390 Cond == ARMCC::getOppositeCondition(ITState.Cond)); 391 unsigned TZ = countTrailingZeros(ITState.Mask); 392 unsigned NewMask = 0; 393 // Keep any existing condition bits. 394 NewMask |= ITState.Mask & (0xE << TZ); 395 // Insert the new condition bit. 396 NewMask |= (Cond != ITState.Cond) << TZ; 397 // Move the trailing 1 down one bit. 398 NewMask |= 1 << (TZ - 1); 399 ITState.Mask = NewMask; 400 } 401 402 // Create a new implicit IT block with a dummy condition code. 403 void startImplicitITBlock() { 404 assert(!inITBlock()); 405 ITState.Cond = ARMCC::AL; 406 ITState.Mask = 8; 407 ITState.CurPosition = 1; 408 ITState.IsExplicit = false; 409 } 410 411 // Create a new explicit IT block with the given condition and mask. 412 // The mask should be in the format used in ARMOperand and 413 // MCOperand, with a 1 implying 'e', regardless of the low bit of 414 // the condition. 415 void startExplicitITBlock(ARMCC::CondCodes Cond, unsigned Mask) { 416 assert(!inITBlock()); 417 ITState.Cond = Cond; 418 ITState.Mask = Mask; 419 ITState.CurPosition = 0; 420 ITState.IsExplicit = true; 421 } 422 423 struct { 424 unsigned Mask : 4; 425 unsigned CurPosition; 426 } VPTState; 427 bool inVPTBlock() { return VPTState.CurPosition != ~0U; } 428 void forwardVPTPosition() { 429 if (!inVPTBlock()) return; 430 unsigned TZ = countTrailingZeros(VPTState.Mask); 431 if (++VPTState.CurPosition == 5 - TZ) 432 VPTState.CurPosition = ~0U; 433 } 434 435 void Note(SMLoc L, const Twine &Msg, SMRange Range = None) { 436 return getParser().Note(L, Msg, Range); 437 } 438 439 bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) { 440 return getParser().Warning(L, Msg, Range); 441 } 442 443 bool Error(SMLoc L, const Twine &Msg, SMRange Range = None) { 444 return getParser().Error(L, Msg, Range); 445 } 446 447 bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands, 448 unsigned ListNo, bool IsARPop = false); 449 bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands, 450 unsigned ListNo); 451 452 int tryParseRegister(); 453 bool tryParseRegisterWithWriteBack(OperandVector &); 454 int tryParseShiftRegister(OperandVector &); 455 bool parseRegisterList(OperandVector &, bool EnforceOrder = true, 456 bool AllowRAAC = false); 457 bool parseMemory(OperandVector &); 458 bool parseOperand(OperandVector &, StringRef Mnemonic); 459 bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 460 bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 461 unsigned &ShiftAmount); 462 bool parseLiteralValues(unsigned Size, SMLoc L); 463 bool parseDirectiveThumb(SMLoc L); 464 bool parseDirectiveARM(SMLoc L); 465 bool parseDirectiveThumbFunc(SMLoc L); 466 bool parseDirectiveCode(SMLoc L); 467 bool parseDirectiveSyntax(SMLoc L); 468 bool parseDirectiveReq(StringRef Name, SMLoc L); 469 bool parseDirectiveUnreq(SMLoc L); 470 bool parseDirectiveArch(SMLoc L); 471 bool parseDirectiveEabiAttr(SMLoc L); 472 bool parseDirectiveCPU(SMLoc L); 473 bool parseDirectiveFPU(SMLoc L); 474 bool parseDirectiveFnStart(SMLoc L); 475 bool parseDirectiveFnEnd(SMLoc L); 476 bool parseDirectiveCantUnwind(SMLoc L); 477 bool parseDirectivePersonality(SMLoc L); 478 bool parseDirectiveHandlerData(SMLoc L); 479 bool parseDirectiveSetFP(SMLoc L); 480 bool parseDirectivePad(SMLoc L); 481 bool parseDirectiveRegSave(SMLoc L, bool IsVector); 482 bool parseDirectiveInst(SMLoc L, char Suffix = '\0'); 483 bool parseDirectiveLtorg(SMLoc L); 484 bool parseDirectiveEven(SMLoc L); 485 bool parseDirectivePersonalityIndex(SMLoc L); 486 bool parseDirectiveUnwindRaw(SMLoc L); 487 bool parseDirectiveTLSDescSeq(SMLoc L); 488 bool parseDirectiveMovSP(SMLoc L); 489 bool parseDirectiveObjectArch(SMLoc L); 490 bool parseDirectiveArchExtension(SMLoc L); 491 bool parseDirectiveAlign(SMLoc L); 492 bool parseDirectiveThumbSet(SMLoc L); 493 494 bool isMnemonicVPTPredicable(StringRef Mnemonic, StringRef ExtraToken); 495 StringRef splitMnemonic(StringRef Mnemonic, StringRef ExtraToken, 496 unsigned &PredicationCode, 497 unsigned &VPTPredicationCode, bool &CarrySetting, 498 unsigned &ProcessorIMod, StringRef &ITMask); 499 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef ExtraToken, 500 StringRef FullInst, bool &CanAcceptCarrySet, 501 bool &CanAcceptPredicationCode, 502 bool &CanAcceptVPTPredicationCode); 503 bool enableArchExtFeature(StringRef Name, SMLoc &ExtLoc); 504 505 void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting, 506 OperandVector &Operands); 507 bool CDEConvertDualRegOperand(StringRef Mnemonic, OperandVector &Operands); 508 509 bool isThumb() const { 510 // FIXME: Can tablegen auto-generate this? 511 return getSTI().getFeatureBits()[ARM::ModeThumb]; 512 } 513 514 bool isThumbOne() const { 515 return isThumb() && !getSTI().getFeatureBits()[ARM::FeatureThumb2]; 516 } 517 518 bool isThumbTwo() const { 519 return isThumb() && getSTI().getFeatureBits()[ARM::FeatureThumb2]; 520 } 521 522 bool hasThumb() const { 523 return getSTI().getFeatureBits()[ARM::HasV4TOps]; 524 } 525 526 bool hasThumb2() const { 527 return getSTI().getFeatureBits()[ARM::FeatureThumb2]; 528 } 529 530 bool hasV6Ops() const { 531 return getSTI().getFeatureBits()[ARM::HasV6Ops]; 532 } 533 534 bool hasV6T2Ops() const { 535 return getSTI().getFeatureBits()[ARM::HasV6T2Ops]; 536 } 537 538 bool hasV6MOps() const { 539 return getSTI().getFeatureBits()[ARM::HasV6MOps]; 540 } 541 542 bool hasV7Ops() const { 543 return getSTI().getFeatureBits()[ARM::HasV7Ops]; 544 } 545 546 bool hasV8Ops() const { 547 return getSTI().getFeatureBits()[ARM::HasV8Ops]; 548 } 549 550 bool hasV8MBaseline() const { 551 return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps]; 552 } 553 554 bool hasV8MMainline() const { 555 return getSTI().getFeatureBits()[ARM::HasV8MMainlineOps]; 556 } 557 bool hasV8_1MMainline() const { 558 return getSTI().getFeatureBits()[ARM::HasV8_1MMainlineOps]; 559 } 560 bool hasMVE() const { 561 return getSTI().getFeatureBits()[ARM::HasMVEIntegerOps]; 562 } 563 bool hasMVEFloat() const { 564 return getSTI().getFeatureBits()[ARM::HasMVEFloatOps]; 565 } 566 bool hasCDE() const { 567 return getSTI().getFeatureBits()[ARM::HasCDEOps]; 568 } 569 bool has8MSecExt() const { 570 return getSTI().getFeatureBits()[ARM::Feature8MSecExt]; 571 } 572 573 bool hasARM() const { 574 return !getSTI().getFeatureBits()[ARM::FeatureNoARM]; 575 } 576 577 bool hasDSP() const { 578 return getSTI().getFeatureBits()[ARM::FeatureDSP]; 579 } 580 581 bool hasD32() const { 582 return getSTI().getFeatureBits()[ARM::FeatureD32]; 583 } 584 585 bool hasV8_1aOps() const { 586 return getSTI().getFeatureBits()[ARM::HasV8_1aOps]; 587 } 588 589 bool hasRAS() const { 590 return getSTI().getFeatureBits()[ARM::FeatureRAS]; 591 } 592 593 void SwitchMode() { 594 MCSubtargetInfo &STI = copySTI(); 595 auto FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 596 setAvailableFeatures(FB); 597 } 598 599 void FixModeAfterArchChange(bool WasThumb, SMLoc Loc); 600 601 bool isMClass() const { 602 return getSTI().getFeatureBits()[ARM::FeatureMClass]; 603 } 604 605 /// @name Auto-generated Match Functions 606 /// { 607 608 #define GET_ASSEMBLER_HEADER 609 #include "ARMGenAsmMatcher.inc" 610 611 /// } 612 613 OperandMatchResultTy parseITCondCode(OperandVector &); 614 OperandMatchResultTy parseCoprocNumOperand(OperandVector &); 615 OperandMatchResultTy parseCoprocRegOperand(OperandVector &); 616 OperandMatchResultTy parseCoprocOptionOperand(OperandVector &); 617 OperandMatchResultTy parseMemBarrierOptOperand(OperandVector &); 618 OperandMatchResultTy parseTraceSyncBarrierOptOperand(OperandVector &); 619 OperandMatchResultTy parseInstSyncBarrierOptOperand(OperandVector &); 620 OperandMatchResultTy parseProcIFlagsOperand(OperandVector &); 621 OperandMatchResultTy parseMSRMaskOperand(OperandVector &); 622 OperandMatchResultTy parseBankedRegOperand(OperandVector &); 623 OperandMatchResultTy parsePKHImm(OperandVector &O, StringRef Op, int Low, 624 int High); 625 OperandMatchResultTy parsePKHLSLImm(OperandVector &O) { 626 return parsePKHImm(O, "lsl", 0, 31); 627 } 628 OperandMatchResultTy parsePKHASRImm(OperandVector &O) { 629 return parsePKHImm(O, "asr", 1, 32); 630 } 631 OperandMatchResultTy parseSetEndImm(OperandVector &); 632 OperandMatchResultTy parseShifterImm(OperandVector &); 633 OperandMatchResultTy parseRotImm(OperandVector &); 634 OperandMatchResultTy parseModImm(OperandVector &); 635 OperandMatchResultTy parseBitfield(OperandVector &); 636 OperandMatchResultTy parsePostIdxReg(OperandVector &); 637 OperandMatchResultTy parseAM3Offset(OperandVector &); 638 OperandMatchResultTy parseFPImm(OperandVector &); 639 OperandMatchResultTy parseVectorList(OperandVector &); 640 OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, 641 SMLoc &EndLoc); 642 643 // Asm Match Converter Methods 644 void cvtThumbMultiply(MCInst &Inst, const OperandVector &); 645 void cvtThumbBranches(MCInst &Inst, const OperandVector &); 646 void cvtMVEVMOVQtoDReg(MCInst &Inst, const OperandVector &); 647 648 bool validateInstruction(MCInst &Inst, const OperandVector &Ops); 649 bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out); 650 bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands); 651 bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands); 652 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic, OperandVector &Operands); 653 bool isITBlockTerminator(MCInst &Inst) const; 654 void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands); 655 bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands, 656 bool Load, bool ARMMode, bool Writeback); 657 658 public: 659 enum ARMMatchResultTy { 660 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 661 Match_RequiresNotITBlock, 662 Match_RequiresV6, 663 Match_RequiresThumb2, 664 Match_RequiresV8, 665 Match_RequiresFlagSetting, 666 #define GET_OPERAND_DIAGNOSTIC_TYPES 667 #include "ARMGenAsmMatcher.inc" 668 669 }; 670 671 ARMAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 672 const MCInstrInfo &MII, const MCTargetOptions &Options) 673 : MCTargetAsmParser(Options, STI, MII), UC(Parser), MS(STI) { 674 MCAsmParserExtension::Initialize(Parser); 675 676 // Cache the MCRegisterInfo. 677 MRI = getContext().getRegisterInfo(); 678 679 // Initialize the set of available features. 680 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 681 682 // Add build attributes based on the selected target. 683 if (AddBuildAttributes) 684 getTargetStreamer().emitTargetAttributes(STI); 685 686 // Not in an ITBlock to start with. 687 ITState.CurPosition = ~0U; 688 689 VPTState.CurPosition = ~0U; 690 691 NextSymbolIsThumb = false; 692 } 693 694 // Implementation of the MCTargetAsmParser interface: 695 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 696 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 697 SMLoc &EndLoc) override; 698 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 699 SMLoc NameLoc, OperandVector &Operands) override; 700 bool ParseDirective(AsmToken DirectiveID) override; 701 702 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 703 unsigned Kind) override; 704 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 705 706 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 707 OperandVector &Operands, MCStreamer &Out, 708 uint64_t &ErrorInfo, 709 bool MatchingInlineAsm) override; 710 unsigned MatchInstruction(OperandVector &Operands, MCInst &Inst, 711 SmallVectorImpl<NearMissInfo> &NearMisses, 712 bool MatchingInlineAsm, bool &EmitInITBlock, 713 MCStreamer &Out); 714 715 struct NearMissMessage { 716 SMLoc Loc; 717 SmallString<128> Message; 718 }; 719 720 const char *getCustomOperandDiag(ARMMatchResultTy MatchError); 721 722 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn, 723 SmallVectorImpl<NearMissMessage> &NearMissesOut, 724 SMLoc IDLoc, OperandVector &Operands); 725 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc, 726 OperandVector &Operands); 727 728 void doBeforeLabelEmit(MCSymbol *Symbol) override; 729 730 void onLabelParsed(MCSymbol *Symbol) override; 731 }; 732 733 /// ARMOperand - Instances of this class represent a parsed ARM machine 734 /// operand. 735 class ARMOperand : public MCParsedAsmOperand { 736 enum KindTy { 737 k_CondCode, 738 k_VPTPred, 739 k_CCOut, 740 k_ITCondMask, 741 k_CoprocNum, 742 k_CoprocReg, 743 k_CoprocOption, 744 k_Immediate, 745 k_MemBarrierOpt, 746 k_InstSyncBarrierOpt, 747 k_TraceSyncBarrierOpt, 748 k_Memory, 749 k_PostIndexRegister, 750 k_MSRMask, 751 k_BankedReg, 752 k_ProcIFlags, 753 k_VectorIndex, 754 k_Register, 755 k_RegisterList, 756 k_RegisterListWithAPSR, 757 k_DPRRegisterList, 758 k_SPRRegisterList, 759 k_FPSRegisterListWithVPR, 760 k_FPDRegisterListWithVPR, 761 k_VectorList, 762 k_VectorListAllLanes, 763 k_VectorListIndexed, 764 k_ShiftedRegister, 765 k_ShiftedImmediate, 766 k_ShifterImmediate, 767 k_RotateImmediate, 768 k_ModifiedImmediate, 769 k_ConstantPoolImmediate, 770 k_BitfieldDescriptor, 771 k_Token, 772 } Kind; 773 774 SMLoc StartLoc, EndLoc, AlignmentLoc; 775 SmallVector<unsigned, 8> Registers; 776 777 struct CCOp { 778 ARMCC::CondCodes Val; 779 }; 780 781 struct VCCOp { 782 ARMVCC::VPTCodes Val; 783 }; 784 785 struct CopOp { 786 unsigned Val; 787 }; 788 789 struct CoprocOptionOp { 790 unsigned Val; 791 }; 792 793 struct ITMaskOp { 794 unsigned Mask:4; 795 }; 796 797 struct MBOptOp { 798 ARM_MB::MemBOpt Val; 799 }; 800 801 struct ISBOptOp { 802 ARM_ISB::InstSyncBOpt Val; 803 }; 804 805 struct TSBOptOp { 806 ARM_TSB::TraceSyncBOpt Val; 807 }; 808 809 struct IFlagsOp { 810 ARM_PROC::IFlags Val; 811 }; 812 813 struct MMaskOp { 814 unsigned Val; 815 }; 816 817 struct BankedRegOp { 818 unsigned Val; 819 }; 820 821 struct TokOp { 822 const char *Data; 823 unsigned Length; 824 }; 825 826 struct RegOp { 827 unsigned RegNum; 828 }; 829 830 // A vector register list is a sequential list of 1 to 4 registers. 831 struct VectorListOp { 832 unsigned RegNum; 833 unsigned Count; 834 unsigned LaneIndex; 835 bool isDoubleSpaced; 836 }; 837 838 struct VectorIndexOp { 839 unsigned Val; 840 }; 841 842 struct ImmOp { 843 const MCExpr *Val; 844 }; 845 846 /// Combined record for all forms of ARM address expressions. 847 struct MemoryOp { 848 unsigned BaseRegNum; 849 // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 850 // was specified. 851 const MCExpr *OffsetImm; // Offset immediate value 852 unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 853 ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 854 unsigned ShiftImm; // shift for OffsetReg. 855 unsigned Alignment; // 0 = no alignment specified 856 // n = alignment in bytes (2, 4, 8, 16, or 32) 857 unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 858 }; 859 860 struct PostIdxRegOp { 861 unsigned RegNum; 862 bool isAdd; 863 ARM_AM::ShiftOpc ShiftTy; 864 unsigned ShiftImm; 865 }; 866 867 struct ShifterImmOp { 868 bool isASR; 869 unsigned Imm; 870 }; 871 872 struct RegShiftedRegOp { 873 ARM_AM::ShiftOpc ShiftTy; 874 unsigned SrcReg; 875 unsigned ShiftReg; 876 unsigned ShiftImm; 877 }; 878 879 struct RegShiftedImmOp { 880 ARM_AM::ShiftOpc ShiftTy; 881 unsigned SrcReg; 882 unsigned ShiftImm; 883 }; 884 885 struct RotImmOp { 886 unsigned Imm; 887 }; 888 889 struct ModImmOp { 890 unsigned Bits; 891 unsigned Rot; 892 }; 893 894 struct BitfieldOp { 895 unsigned LSB; 896 unsigned Width; 897 }; 898 899 union { 900 struct CCOp CC; 901 struct VCCOp VCC; 902 struct CopOp Cop; 903 struct CoprocOptionOp CoprocOption; 904 struct MBOptOp MBOpt; 905 struct ISBOptOp ISBOpt; 906 struct TSBOptOp TSBOpt; 907 struct ITMaskOp ITMask; 908 struct IFlagsOp IFlags; 909 struct MMaskOp MMask; 910 struct BankedRegOp BankedReg; 911 struct TokOp Tok; 912 struct RegOp Reg; 913 struct VectorListOp VectorList; 914 struct VectorIndexOp VectorIndex; 915 struct ImmOp Imm; 916 struct MemoryOp Memory; 917 struct PostIdxRegOp PostIdxReg; 918 struct ShifterImmOp ShifterImm; 919 struct RegShiftedRegOp RegShiftedReg; 920 struct RegShiftedImmOp RegShiftedImm; 921 struct RotImmOp RotImm; 922 struct ModImmOp ModImm; 923 struct BitfieldOp Bitfield; 924 }; 925 926 public: 927 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 928 929 /// getStartLoc - Get the location of the first token of this operand. 930 SMLoc getStartLoc() const override { return StartLoc; } 931 932 /// getEndLoc - Get the location of the last token of this operand. 933 SMLoc getEndLoc() const override { return EndLoc; } 934 935 /// getLocRange - Get the range between the first and last token of this 936 /// operand. 937 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 938 939 /// getAlignmentLoc - Get the location of the Alignment token of this operand. 940 SMLoc getAlignmentLoc() const { 941 assert(Kind == k_Memory && "Invalid access!"); 942 return AlignmentLoc; 943 } 944 945 ARMCC::CondCodes getCondCode() const { 946 assert(Kind == k_CondCode && "Invalid access!"); 947 return CC.Val; 948 } 949 950 ARMVCC::VPTCodes getVPTPred() const { 951 assert(isVPTPred() && "Invalid access!"); 952 return VCC.Val; 953 } 954 955 unsigned getCoproc() const { 956 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 957 return Cop.Val; 958 } 959 960 StringRef getToken() const { 961 assert(Kind == k_Token && "Invalid access!"); 962 return StringRef(Tok.Data, Tok.Length); 963 } 964 965 unsigned getReg() const override { 966 assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 967 return Reg.RegNum; 968 } 969 970 const SmallVectorImpl<unsigned> &getRegList() const { 971 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR || 972 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList || 973 Kind == k_FPSRegisterListWithVPR || 974 Kind == k_FPDRegisterListWithVPR) && 975 "Invalid access!"); 976 return Registers; 977 } 978 979 const MCExpr *getImm() const { 980 assert(isImm() && "Invalid access!"); 981 return Imm.Val; 982 } 983 984 const MCExpr *getConstantPoolImm() const { 985 assert(isConstantPoolImm() && "Invalid access!"); 986 return Imm.Val; 987 } 988 989 unsigned getVectorIndex() const { 990 assert(Kind == k_VectorIndex && "Invalid access!"); 991 return VectorIndex.Val; 992 } 993 994 ARM_MB::MemBOpt getMemBarrierOpt() const { 995 assert(Kind == k_MemBarrierOpt && "Invalid access!"); 996 return MBOpt.Val; 997 } 998 999 ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const { 1000 assert(Kind == k_InstSyncBarrierOpt && "Invalid access!"); 1001 return ISBOpt.Val; 1002 } 1003 1004 ARM_TSB::TraceSyncBOpt getTraceSyncBarrierOpt() const { 1005 assert(Kind == k_TraceSyncBarrierOpt && "Invalid access!"); 1006 return TSBOpt.Val; 1007 } 1008 1009 ARM_PROC::IFlags getProcIFlags() const { 1010 assert(Kind == k_ProcIFlags && "Invalid access!"); 1011 return IFlags.Val; 1012 } 1013 1014 unsigned getMSRMask() const { 1015 assert(Kind == k_MSRMask && "Invalid access!"); 1016 return MMask.Val; 1017 } 1018 1019 unsigned getBankedReg() const { 1020 assert(Kind == k_BankedReg && "Invalid access!"); 1021 return BankedReg.Val; 1022 } 1023 1024 bool isCoprocNum() const { return Kind == k_CoprocNum; } 1025 bool isCoprocReg() const { return Kind == k_CoprocReg; } 1026 bool isCoprocOption() const { return Kind == k_CoprocOption; } 1027 bool isCondCode() const { return Kind == k_CondCode; } 1028 bool isVPTPred() const { return Kind == k_VPTPred; } 1029 bool isCCOut() const { return Kind == k_CCOut; } 1030 bool isITMask() const { return Kind == k_ITCondMask; } 1031 bool isITCondCode() const { return Kind == k_CondCode; } 1032 bool isImm() const override { 1033 return Kind == k_Immediate; 1034 } 1035 1036 bool isARMBranchTarget() const { 1037 if (!isImm()) return false; 1038 1039 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) 1040 return CE->getValue() % 4 == 0; 1041 return true; 1042 } 1043 1044 1045 bool isThumbBranchTarget() const { 1046 if (!isImm()) return false; 1047 1048 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) 1049 return CE->getValue() % 2 == 0; 1050 return true; 1051 } 1052 1053 // checks whether this operand is an unsigned offset which fits is a field 1054 // of specified width and scaled by a specific number of bits 1055 template<unsigned width, unsigned scale> 1056 bool isUnsignedOffset() const { 1057 if (!isImm()) return false; 1058 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 1059 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1060 int64_t Val = CE->getValue(); 1061 int64_t Align = 1LL << scale; 1062 int64_t Max = Align * ((1LL << width) - 1); 1063 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max); 1064 } 1065 return false; 1066 } 1067 1068 // checks whether this operand is an signed offset which fits is a field 1069 // of specified width and scaled by a specific number of bits 1070 template<unsigned width, unsigned scale> 1071 bool isSignedOffset() const { 1072 if (!isImm()) return false; 1073 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 1074 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1075 int64_t Val = CE->getValue(); 1076 int64_t Align = 1LL << scale; 1077 int64_t Max = Align * ((1LL << (width-1)) - 1); 1078 int64_t Min = -Align * (1LL << (width-1)); 1079 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max); 1080 } 1081 return false; 1082 } 1083 1084 // checks whether this operand is an offset suitable for the LE / 1085 // LETP instructions in Arm v8.1M 1086 bool isLEOffset() const { 1087 if (!isImm()) return false; 1088 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 1089 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 1090 int64_t Val = CE->getValue(); 1091 return Val < 0 && Val >= -4094 && (Val & 1) == 0; 1092 } 1093 return false; 1094 } 1095 1096 // checks whether this operand is a memory operand computed as an offset 1097 // applied to PC. the offset may have 8 bits of magnitude and is represented 1098 // with two bits of shift. textually it may be either [pc, #imm], #imm or 1099 // relocable expression... 1100 bool isThumbMemPC() const { 1101 int64_t Val = 0; 1102 if (isImm()) { 1103 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 1104 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val); 1105 if (!CE) return false; 1106 Val = CE->getValue(); 1107 } 1108 else if (isGPRMem()) { 1109 if(!Memory.OffsetImm || Memory.OffsetRegNum) return false; 1110 if(Memory.BaseRegNum != ARM::PC) return false; 1111 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) 1112 Val = CE->getValue(); 1113 else 1114 return false; 1115 } 1116 else return false; 1117 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020); 1118 } 1119 1120 bool isFPImm() const { 1121 if (!isImm()) return false; 1122 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1123 if (!CE) return false; 1124 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue())); 1125 return Val != -1; 1126 } 1127 1128 template<int64_t N, int64_t M> 1129 bool isImmediate() const { 1130 if (!isImm()) return false; 1131 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1132 if (!CE) return false; 1133 int64_t Value = CE->getValue(); 1134 return Value >= N && Value <= M; 1135 } 1136 1137 template<int64_t N, int64_t M> 1138 bool isImmediateS4() const { 1139 if (!isImm()) return false; 1140 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1141 if (!CE) return false; 1142 int64_t Value = CE->getValue(); 1143 return ((Value & 3) == 0) && Value >= N && Value <= M; 1144 } 1145 template<int64_t N, int64_t M> 1146 bool isImmediateS2() const { 1147 if (!isImm()) return false; 1148 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1149 if (!CE) return false; 1150 int64_t Value = CE->getValue(); 1151 return ((Value & 1) == 0) && Value >= N && Value <= M; 1152 } 1153 bool isFBits16() const { 1154 return isImmediate<0, 17>(); 1155 } 1156 bool isFBits32() const { 1157 return isImmediate<1, 33>(); 1158 } 1159 bool isImm8s4() const { 1160 return isImmediateS4<-1020, 1020>(); 1161 } 1162 bool isImm7s4() const { 1163 return isImmediateS4<-508, 508>(); 1164 } 1165 bool isImm7Shift0() const { 1166 return isImmediate<-127, 127>(); 1167 } 1168 bool isImm7Shift1() const { 1169 return isImmediateS2<-255, 255>(); 1170 } 1171 bool isImm7Shift2() const { 1172 return isImmediateS4<-511, 511>(); 1173 } 1174 bool isImm7() const { 1175 return isImmediate<-127, 127>(); 1176 } 1177 bool isImm0_1020s4() const { 1178 return isImmediateS4<0, 1020>(); 1179 } 1180 bool isImm0_508s4() const { 1181 return isImmediateS4<0, 508>(); 1182 } 1183 bool isImm0_508s4Neg() const { 1184 if (!isImm()) return false; 1185 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1186 if (!CE) return false; 1187 int64_t Value = -CE->getValue(); 1188 // explicitly exclude zero. we want that to use the normal 0_508 version. 1189 return ((Value & 3) == 0) && Value > 0 && Value <= 508; 1190 } 1191 1192 bool isImm0_4095Neg() const { 1193 if (!isImm()) return false; 1194 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1195 if (!CE) return false; 1196 // isImm0_4095Neg is used with 32-bit immediates only. 1197 // 32-bit immediates are zero extended to 64-bit when parsed, 1198 // thus simple -CE->getValue() results in a big negative number, 1199 // not a small positive number as intended 1200 if ((CE->getValue() >> 32) > 0) return false; 1201 uint32_t Value = -static_cast<uint32_t>(CE->getValue()); 1202 return Value > 0 && Value < 4096; 1203 } 1204 1205 bool isImm0_7() const { 1206 return isImmediate<0, 7>(); 1207 } 1208 1209 bool isImm1_16() const { 1210 return isImmediate<1, 16>(); 1211 } 1212 1213 bool isImm1_32() const { 1214 return isImmediate<1, 32>(); 1215 } 1216 1217 bool isImm8_255() const { 1218 return isImmediate<8, 255>(); 1219 } 1220 1221 bool isImm256_65535Expr() const { 1222 if (!isImm()) return false; 1223 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1224 // If it's not a constant expression, it'll generate a fixup and be 1225 // handled later. 1226 if (!CE) return true; 1227 int64_t Value = CE->getValue(); 1228 return Value >= 256 && Value < 65536; 1229 } 1230 1231 bool isImm0_65535Expr() const { 1232 if (!isImm()) return false; 1233 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1234 // If it's not a constant expression, it'll generate a fixup and be 1235 // handled later. 1236 if (!CE) return true; 1237 int64_t Value = CE->getValue(); 1238 return Value >= 0 && Value < 65536; 1239 } 1240 1241 bool isImm24bit() const { 1242 return isImmediate<0, 0xffffff + 1>(); 1243 } 1244 1245 bool isImmThumbSR() const { 1246 return isImmediate<1, 33>(); 1247 } 1248 1249 template<int shift> 1250 bool isExpImmValue(uint64_t Value) const { 1251 uint64_t mask = (1 << shift) - 1; 1252 if ((Value & mask) != 0 || (Value >> shift) > 0xff) 1253 return false; 1254 return true; 1255 } 1256 1257 template<int shift> 1258 bool isExpImm() const { 1259 if (!isImm()) return false; 1260 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1261 if (!CE) return false; 1262 1263 return isExpImmValue<shift>(CE->getValue()); 1264 } 1265 1266 template<int shift, int size> 1267 bool isInvertedExpImm() const { 1268 if (!isImm()) return false; 1269 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1270 if (!CE) return false; 1271 1272 uint64_t OriginalValue = CE->getValue(); 1273 uint64_t InvertedValue = OriginalValue ^ (((uint64_t)1 << size) - 1); 1274 return isExpImmValue<shift>(InvertedValue); 1275 } 1276 1277 bool isPKHLSLImm() const { 1278 return isImmediate<0, 32>(); 1279 } 1280 1281 bool isPKHASRImm() const { 1282 return isImmediate<0, 33>(); 1283 } 1284 1285 bool isAdrLabel() const { 1286 // If we have an immediate that's not a constant, treat it as a label 1287 // reference needing a fixup. 1288 if (isImm() && !isa<MCConstantExpr>(getImm())) 1289 return true; 1290 1291 // If it is a constant, it must fit into a modified immediate encoding. 1292 if (!isImm()) return false; 1293 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1294 if (!CE) return false; 1295 int64_t Value = CE->getValue(); 1296 return (ARM_AM::getSOImmVal(Value) != -1 || 1297 ARM_AM::getSOImmVal(-Value) != -1); 1298 } 1299 1300 bool isT2SOImm() const { 1301 // If we have an immediate that's not a constant, treat it as an expression 1302 // needing a fixup. 1303 if (isImm() && !isa<MCConstantExpr>(getImm())) { 1304 // We want to avoid matching :upper16: and :lower16: as we want these 1305 // expressions to match in isImm0_65535Expr() 1306 const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(getImm()); 1307 return (!ARM16Expr || (ARM16Expr->getKind() != ARMMCExpr::VK_ARM_HI16 && 1308 ARM16Expr->getKind() != ARMMCExpr::VK_ARM_LO16)); 1309 } 1310 if (!isImm()) return false; 1311 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1312 if (!CE) return false; 1313 int64_t Value = CE->getValue(); 1314 return ARM_AM::getT2SOImmVal(Value) != -1; 1315 } 1316 1317 bool isT2SOImmNot() const { 1318 if (!isImm()) return false; 1319 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1320 if (!CE) return false; 1321 int64_t Value = CE->getValue(); 1322 return ARM_AM::getT2SOImmVal(Value) == -1 && 1323 ARM_AM::getT2SOImmVal(~Value) != -1; 1324 } 1325 1326 bool isT2SOImmNeg() const { 1327 if (!isImm()) return false; 1328 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1329 if (!CE) return false; 1330 int64_t Value = CE->getValue(); 1331 // Only use this when not representable as a plain so_imm. 1332 return ARM_AM::getT2SOImmVal(Value) == -1 && 1333 ARM_AM::getT2SOImmVal(-Value) != -1; 1334 } 1335 1336 bool isSetEndImm() const { 1337 if (!isImm()) return false; 1338 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1339 if (!CE) return false; 1340 int64_t Value = CE->getValue(); 1341 return Value == 1 || Value == 0; 1342 } 1343 1344 bool isReg() const override { return Kind == k_Register; } 1345 bool isRegList() const { return Kind == k_RegisterList; } 1346 bool isRegListWithAPSR() const { 1347 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList; 1348 } 1349 bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 1350 bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 1351 bool isFPSRegListWithVPR() const { return Kind == k_FPSRegisterListWithVPR; } 1352 bool isFPDRegListWithVPR() const { return Kind == k_FPDRegisterListWithVPR; } 1353 bool isToken() const override { return Kind == k_Token; } 1354 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 1355 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; } 1356 bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; } 1357 bool isMem() const override { 1358 return isGPRMem() || isMVEMem(); 1359 } 1360 bool isMVEMem() const { 1361 if (Kind != k_Memory) 1362 return false; 1363 if (Memory.BaseRegNum && 1364 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum) && 1365 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Memory.BaseRegNum)) 1366 return false; 1367 if (Memory.OffsetRegNum && 1368 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains( 1369 Memory.OffsetRegNum)) 1370 return false; 1371 return true; 1372 } 1373 bool isGPRMem() const { 1374 if (Kind != k_Memory) 1375 return false; 1376 if (Memory.BaseRegNum && 1377 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum)) 1378 return false; 1379 if (Memory.OffsetRegNum && 1380 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.OffsetRegNum)) 1381 return false; 1382 return true; 1383 } 1384 bool isShifterImm() const { return Kind == k_ShifterImmediate; } 1385 bool isRegShiftedReg() const { 1386 return Kind == k_ShiftedRegister && 1387 ARMMCRegisterClasses[ARM::GPRRegClassID].contains( 1388 RegShiftedReg.SrcReg) && 1389 ARMMCRegisterClasses[ARM::GPRRegClassID].contains( 1390 RegShiftedReg.ShiftReg); 1391 } 1392 bool isRegShiftedImm() const { 1393 return Kind == k_ShiftedImmediate && 1394 ARMMCRegisterClasses[ARM::GPRRegClassID].contains( 1395 RegShiftedImm.SrcReg); 1396 } 1397 bool isRotImm() const { return Kind == k_RotateImmediate; } 1398 1399 template<unsigned Min, unsigned Max> 1400 bool isPowerTwoInRange() const { 1401 if (!isImm()) return false; 1402 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1403 if (!CE) return false; 1404 int64_t Value = CE->getValue(); 1405 return Value > 0 && countPopulation((uint64_t)Value) == 1 && 1406 Value >= Min && Value <= Max; 1407 } 1408 bool isModImm() const { return Kind == k_ModifiedImmediate; } 1409 1410 bool isModImmNot() const { 1411 if (!isImm()) return false; 1412 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1413 if (!CE) return false; 1414 int64_t Value = CE->getValue(); 1415 return ARM_AM::getSOImmVal(~Value) != -1; 1416 } 1417 1418 bool isModImmNeg() const { 1419 if (!isImm()) return false; 1420 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1421 if (!CE) return false; 1422 int64_t Value = CE->getValue(); 1423 return ARM_AM::getSOImmVal(Value) == -1 && 1424 ARM_AM::getSOImmVal(-Value) != -1; 1425 } 1426 1427 bool isThumbModImmNeg1_7() const { 1428 if (!isImm()) return false; 1429 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1430 if (!CE) return false; 1431 int32_t Value = -(int32_t)CE->getValue(); 1432 return 0 < Value && Value < 8; 1433 } 1434 1435 bool isThumbModImmNeg8_255() const { 1436 if (!isImm()) return false; 1437 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1438 if (!CE) return false; 1439 int32_t Value = -(int32_t)CE->getValue(); 1440 return 7 < Value && Value < 256; 1441 } 1442 1443 bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; } 1444 bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 1445 bool isPostIdxRegShifted() const { 1446 return Kind == k_PostIndexRegister && 1447 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum); 1448 } 1449 bool isPostIdxReg() const { 1450 return isPostIdxRegShifted() && PostIdxReg.ShiftTy == ARM_AM::no_shift; 1451 } 1452 bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const { 1453 if (!isGPRMem()) 1454 return false; 1455 // No offset of any kind. 1456 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr && 1457 (alignOK || Memory.Alignment == Alignment); 1458 } 1459 bool isMemNoOffsetT2(bool alignOK = false, unsigned Alignment = 0) const { 1460 if (!isGPRMem()) 1461 return false; 1462 1463 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains( 1464 Memory.BaseRegNum)) 1465 return false; 1466 1467 // No offset of any kind. 1468 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr && 1469 (alignOK || Memory.Alignment == Alignment); 1470 } 1471 bool isMemNoOffsetT2NoSp(bool alignOK = false, unsigned Alignment = 0) const { 1472 if (!isGPRMem()) 1473 return false; 1474 1475 if (!ARMMCRegisterClasses[ARM::rGPRRegClassID].contains( 1476 Memory.BaseRegNum)) 1477 return false; 1478 1479 // No offset of any kind. 1480 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr && 1481 (alignOK || Memory.Alignment == Alignment); 1482 } 1483 bool isMemNoOffsetT(bool alignOK = false, unsigned Alignment = 0) const { 1484 if (!isGPRMem()) 1485 return false; 1486 1487 if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].contains( 1488 Memory.BaseRegNum)) 1489 return false; 1490 1491 // No offset of any kind. 1492 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr && 1493 (alignOK || Memory.Alignment == Alignment); 1494 } 1495 bool isMemPCRelImm12() const { 1496 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1497 return false; 1498 // Base register must be PC. 1499 if (Memory.BaseRegNum != ARM::PC) 1500 return false; 1501 // Immediate offset in range [-4095, 4095]. 1502 if (!Memory.OffsetImm) return true; 1503 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1504 int64_t Val = CE->getValue(); 1505 return (Val > -4096 && Val < 4096) || 1506 (Val == std::numeric_limits<int32_t>::min()); 1507 } 1508 return false; 1509 } 1510 1511 bool isAlignedMemory() const { 1512 return isMemNoOffset(true); 1513 } 1514 1515 bool isAlignedMemoryNone() const { 1516 return isMemNoOffset(false, 0); 1517 } 1518 1519 bool isDupAlignedMemoryNone() const { 1520 return isMemNoOffset(false, 0); 1521 } 1522 1523 bool isAlignedMemory16() const { 1524 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2. 1525 return true; 1526 return isMemNoOffset(false, 0); 1527 } 1528 1529 bool isDupAlignedMemory16() const { 1530 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2. 1531 return true; 1532 return isMemNoOffset(false, 0); 1533 } 1534 1535 bool isAlignedMemory32() const { 1536 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4. 1537 return true; 1538 return isMemNoOffset(false, 0); 1539 } 1540 1541 bool isDupAlignedMemory32() const { 1542 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4. 1543 return true; 1544 return isMemNoOffset(false, 0); 1545 } 1546 1547 bool isAlignedMemory64() const { 1548 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1549 return true; 1550 return isMemNoOffset(false, 0); 1551 } 1552 1553 bool isDupAlignedMemory64() const { 1554 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1555 return true; 1556 return isMemNoOffset(false, 0); 1557 } 1558 1559 bool isAlignedMemory64or128() const { 1560 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1561 return true; 1562 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16. 1563 return true; 1564 return isMemNoOffset(false, 0); 1565 } 1566 1567 bool isDupAlignedMemory64or128() const { 1568 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1569 return true; 1570 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16. 1571 return true; 1572 return isMemNoOffset(false, 0); 1573 } 1574 1575 bool isAlignedMemory64or128or256() const { 1576 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1577 return true; 1578 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16. 1579 return true; 1580 if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32. 1581 return true; 1582 return isMemNoOffset(false, 0); 1583 } 1584 1585 bool isAddrMode2() const { 1586 if (!isGPRMem() || Memory.Alignment != 0) return false; 1587 // Check for register offset. 1588 if (Memory.OffsetRegNum) return true; 1589 // Immediate offset in range [-4095, 4095]. 1590 if (!Memory.OffsetImm) return true; 1591 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1592 int64_t Val = CE->getValue(); 1593 return Val > -4096 && Val < 4096; 1594 } 1595 return false; 1596 } 1597 1598 bool isAM2OffsetImm() const { 1599 if (!isImm()) return false; 1600 // Immediate offset in range [-4095, 4095]. 1601 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1602 if (!CE) return false; 1603 int64_t Val = CE->getValue(); 1604 return (Val == std::numeric_limits<int32_t>::min()) || 1605 (Val > -4096 && Val < 4096); 1606 } 1607 1608 bool isAddrMode3() const { 1609 // If we have an immediate that's not a constant, treat it as a label 1610 // reference needing a fixup. If it is a constant, it's something else 1611 // and we reject it. 1612 if (isImm() && !isa<MCConstantExpr>(getImm())) 1613 return true; 1614 if (!isGPRMem() || Memory.Alignment != 0) return false; 1615 // No shifts are legal for AM3. 1616 if (Memory.ShiftType != ARM_AM::no_shift) return false; 1617 // Check for register offset. 1618 if (Memory.OffsetRegNum) return true; 1619 // Immediate offset in range [-255, 255]. 1620 if (!Memory.OffsetImm) return true; 1621 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1622 int64_t Val = CE->getValue(); 1623 // The #-0 offset is encoded as std::numeric_limits<int32_t>::min(), and 1624 // we have to check for this too. 1625 return (Val > -256 && Val < 256) || 1626 Val == std::numeric_limits<int32_t>::min(); 1627 } 1628 return false; 1629 } 1630 1631 bool isAM3Offset() const { 1632 if (isPostIdxReg()) 1633 return true; 1634 if (!isImm()) 1635 return false; 1636 // Immediate offset in range [-255, 255]. 1637 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1638 if (!CE) return false; 1639 int64_t Val = CE->getValue(); 1640 // Special case, #-0 is std::numeric_limits<int32_t>::min(). 1641 return (Val > -256 && Val < 256) || 1642 Val == std::numeric_limits<int32_t>::min(); 1643 } 1644 1645 bool isAddrMode5() const { 1646 // If we have an immediate that's not a constant, treat it as a label 1647 // reference needing a fixup. If it is a constant, it's something else 1648 // and we reject it. 1649 if (isImm() && !isa<MCConstantExpr>(getImm())) 1650 return true; 1651 if (!isGPRMem() || Memory.Alignment != 0) return false; 1652 // Check for register offset. 1653 if (Memory.OffsetRegNum) return false; 1654 // Immediate offset in range [-1020, 1020] and a multiple of 4. 1655 if (!Memory.OffsetImm) return true; 1656 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1657 int64_t Val = CE->getValue(); 1658 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 1659 Val == std::numeric_limits<int32_t>::min(); 1660 } 1661 return false; 1662 } 1663 1664 bool isAddrMode5FP16() const { 1665 // If we have an immediate that's not a constant, treat it as a label 1666 // reference needing a fixup. If it is a constant, it's something else 1667 // and we reject it. 1668 if (isImm() && !isa<MCConstantExpr>(getImm())) 1669 return true; 1670 if (!isGPRMem() || Memory.Alignment != 0) return false; 1671 // Check for register offset. 1672 if (Memory.OffsetRegNum) return false; 1673 // Immediate offset in range [-510, 510] and a multiple of 2. 1674 if (!Memory.OffsetImm) return true; 1675 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1676 int64_t Val = CE->getValue(); 1677 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) || 1678 Val == std::numeric_limits<int32_t>::min(); 1679 } 1680 return false; 1681 } 1682 1683 bool isMemTBB() const { 1684 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative || 1685 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 1686 return false; 1687 return true; 1688 } 1689 1690 bool isMemTBH() const { 1691 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative || 1692 Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 1693 Memory.Alignment != 0 ) 1694 return false; 1695 return true; 1696 } 1697 1698 bool isMemRegOffset() const { 1699 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0) 1700 return false; 1701 return true; 1702 } 1703 1704 bool isT2MemRegOffset() const { 1705 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative || 1706 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC) 1707 return false; 1708 // Only lsl #{0, 1, 2, 3} allowed. 1709 if (Memory.ShiftType == ARM_AM::no_shift) 1710 return true; 1711 if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 1712 return false; 1713 return true; 1714 } 1715 1716 bool isMemThumbRR() const { 1717 // Thumb reg+reg addressing is simple. Just two registers, a base and 1718 // an offset. No shifts, negations or any other complicating factors. 1719 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative || 1720 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 1721 return false; 1722 return isARMLowRegister(Memory.BaseRegNum) && 1723 (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 1724 } 1725 1726 bool isMemThumbRIs4() const { 1727 if (!isGPRMem() || Memory.OffsetRegNum != 0 || 1728 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1729 return false; 1730 // Immediate offset, multiple of 4 in range [0, 124]. 1731 if (!Memory.OffsetImm) return true; 1732 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1733 int64_t Val = CE->getValue(); 1734 return Val >= 0 && Val <= 124 && (Val % 4) == 0; 1735 } 1736 return false; 1737 } 1738 1739 bool isMemThumbRIs2() const { 1740 if (!isGPRMem() || Memory.OffsetRegNum != 0 || 1741 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1742 return false; 1743 // Immediate offset, multiple of 4 in range [0, 62]. 1744 if (!Memory.OffsetImm) return true; 1745 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1746 int64_t Val = CE->getValue(); 1747 return Val >= 0 && Val <= 62 && (Val % 2) == 0; 1748 } 1749 return false; 1750 } 1751 1752 bool isMemThumbRIs1() const { 1753 if (!isGPRMem() || Memory.OffsetRegNum != 0 || 1754 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1755 return false; 1756 // Immediate offset in range [0, 31]. 1757 if (!Memory.OffsetImm) return true; 1758 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1759 int64_t Val = CE->getValue(); 1760 return Val >= 0 && Val <= 31; 1761 } 1762 return false; 1763 } 1764 1765 bool isMemThumbSPI() const { 1766 if (!isGPRMem() || Memory.OffsetRegNum != 0 || 1767 Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 1768 return false; 1769 // Immediate offset, multiple of 4 in range [0, 1020]. 1770 if (!Memory.OffsetImm) return true; 1771 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1772 int64_t Val = CE->getValue(); 1773 return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 1774 } 1775 return false; 1776 } 1777 1778 bool isMemImm8s4Offset() const { 1779 // If we have an immediate that's not a constant, treat it as a label 1780 // reference needing a fixup. If it is a constant, it's something else 1781 // and we reject it. 1782 if (isImm() && !isa<MCConstantExpr>(getImm())) 1783 return true; 1784 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1785 return false; 1786 // Immediate offset a multiple of 4 in range [-1020, 1020]. 1787 if (!Memory.OffsetImm) return true; 1788 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1789 int64_t Val = CE->getValue(); 1790 // Special case, #-0 is std::numeric_limits<int32_t>::min(). 1791 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) || 1792 Val == std::numeric_limits<int32_t>::min(); 1793 } 1794 return false; 1795 } 1796 1797 bool isMemImm7s4Offset() const { 1798 // If we have an immediate that's not a constant, treat it as a label 1799 // reference needing a fixup. If it is a constant, it's something else 1800 // and we reject it. 1801 if (isImm() && !isa<MCConstantExpr>(getImm())) 1802 return true; 1803 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0 || 1804 !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains( 1805 Memory.BaseRegNum)) 1806 return false; 1807 // Immediate offset a multiple of 4 in range [-508, 508]. 1808 if (!Memory.OffsetImm) return true; 1809 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1810 int64_t Val = CE->getValue(); 1811 // Special case, #-0 is INT32_MIN. 1812 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN; 1813 } 1814 return false; 1815 } 1816 1817 bool isMemImm0_1020s4Offset() const { 1818 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1819 return false; 1820 // Immediate offset a multiple of 4 in range [0, 1020]. 1821 if (!Memory.OffsetImm) return true; 1822 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1823 int64_t Val = CE->getValue(); 1824 return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 1825 } 1826 return false; 1827 } 1828 1829 bool isMemImm8Offset() const { 1830 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1831 return false; 1832 // Base reg of PC isn't allowed for these encodings. 1833 if (Memory.BaseRegNum == ARM::PC) return false; 1834 // Immediate offset in range [-255, 255]. 1835 if (!Memory.OffsetImm) return true; 1836 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1837 int64_t Val = CE->getValue(); 1838 return (Val == std::numeric_limits<int32_t>::min()) || 1839 (Val > -256 && Val < 256); 1840 } 1841 return false; 1842 } 1843 1844 template<unsigned Bits, unsigned RegClassID> 1845 bool isMemImm7ShiftedOffset() const { 1846 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0 || 1847 !ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum)) 1848 return false; 1849 1850 // Expect an immediate offset equal to an element of the range 1851 // [-127, 127], shifted left by Bits. 1852 1853 if (!Memory.OffsetImm) return true; 1854 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1855 int64_t Val = CE->getValue(); 1856 1857 // INT32_MIN is a special-case value (indicating the encoding with 1858 // zero offset and the subtract bit set) 1859 if (Val == INT32_MIN) 1860 return true; 1861 1862 unsigned Divisor = 1U << Bits; 1863 1864 // Check that the low bits are zero 1865 if (Val % Divisor != 0) 1866 return false; 1867 1868 // Check that the remaining offset is within range. 1869 Val /= Divisor; 1870 return (Val >= -127 && Val <= 127); 1871 } 1872 return false; 1873 } 1874 1875 template <int shift> bool isMemRegRQOffset() const { 1876 if (!isMVEMem() || Memory.OffsetImm != 0 || Memory.Alignment != 0) 1877 return false; 1878 1879 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains( 1880 Memory.BaseRegNum)) 1881 return false; 1882 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains( 1883 Memory.OffsetRegNum)) 1884 return false; 1885 1886 if (shift == 0 && Memory.ShiftType != ARM_AM::no_shift) 1887 return false; 1888 1889 if (shift > 0 && 1890 (Memory.ShiftType != ARM_AM::uxtw || Memory.ShiftImm != shift)) 1891 return false; 1892 1893 return true; 1894 } 1895 1896 template <int shift> bool isMemRegQOffset() const { 1897 if (!isMVEMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1898 return false; 1899 1900 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains( 1901 Memory.BaseRegNum)) 1902 return false; 1903 1904 if (!Memory.OffsetImm) 1905 return true; 1906 static_assert(shift < 56, 1907 "Such that we dont shift by a value higher than 62"); 1908 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1909 int64_t Val = CE->getValue(); 1910 1911 // The value must be a multiple of (1 << shift) 1912 if ((Val & ((1U << shift) - 1)) != 0) 1913 return false; 1914 1915 // And be in the right range, depending on the amount that it is shifted 1916 // by. Shift 0, is equal to 7 unsigned bits, the sign bit is set 1917 // separately. 1918 int64_t Range = (1U << (7 + shift)) - 1; 1919 return (Val == INT32_MIN) || (Val > -Range && Val < Range); 1920 } 1921 return false; 1922 } 1923 1924 bool isMemPosImm8Offset() const { 1925 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1926 return false; 1927 // Immediate offset in range [0, 255]. 1928 if (!Memory.OffsetImm) return true; 1929 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1930 int64_t Val = CE->getValue(); 1931 return Val >= 0 && Val < 256; 1932 } 1933 return false; 1934 } 1935 1936 bool isMemNegImm8Offset() const { 1937 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1938 return false; 1939 // Base reg of PC isn't allowed for these encodings. 1940 if (Memory.BaseRegNum == ARM::PC) return false; 1941 // Immediate offset in range [-255, -1]. 1942 if (!Memory.OffsetImm) return false; 1943 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1944 int64_t Val = CE->getValue(); 1945 return (Val == std::numeric_limits<int32_t>::min()) || 1946 (Val > -256 && Val < 0); 1947 } 1948 return false; 1949 } 1950 1951 bool isMemUImm12Offset() const { 1952 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1953 return false; 1954 // Immediate offset in range [0, 4095]. 1955 if (!Memory.OffsetImm) return true; 1956 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1957 int64_t Val = CE->getValue(); 1958 return (Val >= 0 && Val < 4096); 1959 } 1960 return false; 1961 } 1962 1963 bool isMemImm12Offset() const { 1964 // If we have an immediate that's not a constant, treat it as a label 1965 // reference needing a fixup. If it is a constant, it's something else 1966 // and we reject it. 1967 1968 if (isImm() && !isa<MCConstantExpr>(getImm())) 1969 return true; 1970 1971 if (!isGPRMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1972 return false; 1973 // Immediate offset in range [-4095, 4095]. 1974 if (!Memory.OffsetImm) return true; 1975 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 1976 int64_t Val = CE->getValue(); 1977 return (Val > -4096 && Val < 4096) || 1978 (Val == std::numeric_limits<int32_t>::min()); 1979 } 1980 // If we have an immediate that's not a constant, treat it as a 1981 // symbolic expression needing a fixup. 1982 return true; 1983 } 1984 1985 bool isConstPoolAsmImm() const { 1986 // Delay processing of Constant Pool Immediate, this will turn into 1987 // a constant. Match no other operand 1988 return (isConstantPoolImm()); 1989 } 1990 1991 bool isPostIdxImm8() const { 1992 if (!isImm()) return false; 1993 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1994 if (!CE) return false; 1995 int64_t Val = CE->getValue(); 1996 return (Val > -256 && Val < 256) || 1997 (Val == std::numeric_limits<int32_t>::min()); 1998 } 1999 2000 bool isPostIdxImm8s4() const { 2001 if (!isImm()) return false; 2002 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2003 if (!CE) return false; 2004 int64_t Val = CE->getValue(); 2005 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 2006 (Val == std::numeric_limits<int32_t>::min()); 2007 } 2008 2009 bool isMSRMask() const { return Kind == k_MSRMask; } 2010 bool isBankedReg() const { return Kind == k_BankedReg; } 2011 bool isProcIFlags() const { return Kind == k_ProcIFlags; } 2012 2013 // NEON operands. 2014 bool isSingleSpacedVectorList() const { 2015 return Kind == k_VectorList && !VectorList.isDoubleSpaced; 2016 } 2017 2018 bool isDoubleSpacedVectorList() const { 2019 return Kind == k_VectorList && VectorList.isDoubleSpaced; 2020 } 2021 2022 bool isVecListOneD() const { 2023 if (!isSingleSpacedVectorList()) return false; 2024 return VectorList.Count == 1; 2025 } 2026 2027 bool isVecListTwoMQ() const { 2028 return isSingleSpacedVectorList() && VectorList.Count == 2 && 2029 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains( 2030 VectorList.RegNum); 2031 } 2032 2033 bool isVecListDPair() const { 2034 if (!isSingleSpacedVectorList()) return false; 2035 return (ARMMCRegisterClasses[ARM::DPairRegClassID] 2036 .contains(VectorList.RegNum)); 2037 } 2038 2039 bool isVecListThreeD() const { 2040 if (!isSingleSpacedVectorList()) return false; 2041 return VectorList.Count == 3; 2042 } 2043 2044 bool isVecListFourD() const { 2045 if (!isSingleSpacedVectorList()) return false; 2046 return VectorList.Count == 4; 2047 } 2048 2049 bool isVecListDPairSpaced() const { 2050 if (Kind != k_VectorList) return false; 2051 if (isSingleSpacedVectorList()) return false; 2052 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID] 2053 .contains(VectorList.RegNum)); 2054 } 2055 2056 bool isVecListThreeQ() const { 2057 if (!isDoubleSpacedVectorList()) return false; 2058 return VectorList.Count == 3; 2059 } 2060 2061 bool isVecListFourQ() const { 2062 if (!isDoubleSpacedVectorList()) return false; 2063 return VectorList.Count == 4; 2064 } 2065 2066 bool isVecListFourMQ() const { 2067 return isSingleSpacedVectorList() && VectorList.Count == 4 && 2068 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains( 2069 VectorList.RegNum); 2070 } 2071 2072 bool isSingleSpacedVectorAllLanes() const { 2073 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced; 2074 } 2075 2076 bool isDoubleSpacedVectorAllLanes() const { 2077 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced; 2078 } 2079 2080 bool isVecListOneDAllLanes() const { 2081 if (!isSingleSpacedVectorAllLanes()) return false; 2082 return VectorList.Count == 1; 2083 } 2084 2085 bool isVecListDPairAllLanes() const { 2086 if (!isSingleSpacedVectorAllLanes()) return false; 2087 return (ARMMCRegisterClasses[ARM::DPairRegClassID] 2088 .contains(VectorList.RegNum)); 2089 } 2090 2091 bool isVecListDPairSpacedAllLanes() const { 2092 if (!isDoubleSpacedVectorAllLanes()) return false; 2093 return VectorList.Count == 2; 2094 } 2095 2096 bool isVecListThreeDAllLanes() const { 2097 if (!isSingleSpacedVectorAllLanes()) return false; 2098 return VectorList.Count == 3; 2099 } 2100 2101 bool isVecListThreeQAllLanes() const { 2102 if (!isDoubleSpacedVectorAllLanes()) return false; 2103 return VectorList.Count == 3; 2104 } 2105 2106 bool isVecListFourDAllLanes() const { 2107 if (!isSingleSpacedVectorAllLanes()) return false; 2108 return VectorList.Count == 4; 2109 } 2110 2111 bool isVecListFourQAllLanes() const { 2112 if (!isDoubleSpacedVectorAllLanes()) return false; 2113 return VectorList.Count == 4; 2114 } 2115 2116 bool isSingleSpacedVectorIndexed() const { 2117 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced; 2118 } 2119 2120 bool isDoubleSpacedVectorIndexed() const { 2121 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced; 2122 } 2123 2124 bool isVecListOneDByteIndexed() const { 2125 if (!isSingleSpacedVectorIndexed()) return false; 2126 return VectorList.Count == 1 && VectorList.LaneIndex <= 7; 2127 } 2128 2129 bool isVecListOneDHWordIndexed() const { 2130 if (!isSingleSpacedVectorIndexed()) return false; 2131 return VectorList.Count == 1 && VectorList.LaneIndex <= 3; 2132 } 2133 2134 bool isVecListOneDWordIndexed() const { 2135 if (!isSingleSpacedVectorIndexed()) return false; 2136 return VectorList.Count == 1 && VectorList.LaneIndex <= 1; 2137 } 2138 2139 bool isVecListTwoDByteIndexed() const { 2140 if (!isSingleSpacedVectorIndexed()) return false; 2141 return VectorList.Count == 2 && VectorList.LaneIndex <= 7; 2142 } 2143 2144 bool isVecListTwoDHWordIndexed() const { 2145 if (!isSingleSpacedVectorIndexed()) return false; 2146 return VectorList.Count == 2 && VectorList.LaneIndex <= 3; 2147 } 2148 2149 bool isVecListTwoQWordIndexed() const { 2150 if (!isDoubleSpacedVectorIndexed()) return false; 2151 return VectorList.Count == 2 && VectorList.LaneIndex <= 1; 2152 } 2153 2154 bool isVecListTwoQHWordIndexed() const { 2155 if (!isDoubleSpacedVectorIndexed()) return false; 2156 return VectorList.Count == 2 && VectorList.LaneIndex <= 3; 2157 } 2158 2159 bool isVecListTwoDWordIndexed() const { 2160 if (!isSingleSpacedVectorIndexed()) return false; 2161 return VectorList.Count == 2 && VectorList.LaneIndex <= 1; 2162 } 2163 2164 bool isVecListThreeDByteIndexed() const { 2165 if (!isSingleSpacedVectorIndexed()) return false; 2166 return VectorList.Count == 3 && VectorList.LaneIndex <= 7; 2167 } 2168 2169 bool isVecListThreeDHWordIndexed() const { 2170 if (!isSingleSpacedVectorIndexed()) return false; 2171 return VectorList.Count == 3 && VectorList.LaneIndex <= 3; 2172 } 2173 2174 bool isVecListThreeQWordIndexed() const { 2175 if (!isDoubleSpacedVectorIndexed()) return false; 2176 return VectorList.Count == 3 && VectorList.LaneIndex <= 1; 2177 } 2178 2179 bool isVecListThreeQHWordIndexed() const { 2180 if (!isDoubleSpacedVectorIndexed()) return false; 2181 return VectorList.Count == 3 && VectorList.LaneIndex <= 3; 2182 } 2183 2184 bool isVecListThreeDWordIndexed() const { 2185 if (!isSingleSpacedVectorIndexed()) return false; 2186 return VectorList.Count == 3 && VectorList.LaneIndex <= 1; 2187 } 2188 2189 bool isVecListFourDByteIndexed() const { 2190 if (!isSingleSpacedVectorIndexed()) return false; 2191 return VectorList.Count == 4 && VectorList.LaneIndex <= 7; 2192 } 2193 2194 bool isVecListFourDHWordIndexed() const { 2195 if (!isSingleSpacedVectorIndexed()) return false; 2196 return VectorList.Count == 4 && VectorList.LaneIndex <= 3; 2197 } 2198 2199 bool isVecListFourQWordIndexed() const { 2200 if (!isDoubleSpacedVectorIndexed()) return false; 2201 return VectorList.Count == 4 && VectorList.LaneIndex <= 1; 2202 } 2203 2204 bool isVecListFourQHWordIndexed() const { 2205 if (!isDoubleSpacedVectorIndexed()) return false; 2206 return VectorList.Count == 4 && VectorList.LaneIndex <= 3; 2207 } 2208 2209 bool isVecListFourDWordIndexed() const { 2210 if (!isSingleSpacedVectorIndexed()) return false; 2211 return VectorList.Count == 4 && VectorList.LaneIndex <= 1; 2212 } 2213 2214 bool isVectorIndex() const { return Kind == k_VectorIndex; } 2215 2216 template <unsigned NumLanes> 2217 bool isVectorIndexInRange() const { 2218 if (Kind != k_VectorIndex) return false; 2219 return VectorIndex.Val < NumLanes; 2220 } 2221 2222 bool isVectorIndex8() const { return isVectorIndexInRange<8>(); } 2223 bool isVectorIndex16() const { return isVectorIndexInRange<4>(); } 2224 bool isVectorIndex32() const { return isVectorIndexInRange<2>(); } 2225 bool isVectorIndex64() const { return isVectorIndexInRange<1>(); } 2226 2227 template<int PermittedValue, int OtherPermittedValue> 2228 bool isMVEPairVectorIndex() const { 2229 if (Kind != k_VectorIndex) return false; 2230 return VectorIndex.Val == PermittedValue || 2231 VectorIndex.Val == OtherPermittedValue; 2232 } 2233 2234 bool isNEONi8splat() const { 2235 if (!isImm()) return false; 2236 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2237 // Must be a constant. 2238 if (!CE) return false; 2239 int64_t Value = CE->getValue(); 2240 // i8 value splatted across 8 bytes. The immediate is just the 8 byte 2241 // value. 2242 return Value >= 0 && Value < 256; 2243 } 2244 2245 bool isNEONi16splat() const { 2246 if (isNEONByteReplicate(2)) 2247 return false; // Leave that for bytes replication and forbid by default. 2248 if (!isImm()) 2249 return false; 2250 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2251 // Must be a constant. 2252 if (!CE) return false; 2253 unsigned Value = CE->getValue(); 2254 return ARM_AM::isNEONi16splat(Value); 2255 } 2256 2257 bool isNEONi16splatNot() const { 2258 if (!isImm()) 2259 return false; 2260 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2261 // Must be a constant. 2262 if (!CE) return false; 2263 unsigned Value = CE->getValue(); 2264 return ARM_AM::isNEONi16splat(~Value & 0xffff); 2265 } 2266 2267 bool isNEONi32splat() const { 2268 if (isNEONByteReplicate(4)) 2269 return false; // Leave that for bytes replication and forbid by default. 2270 if (!isImm()) 2271 return false; 2272 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2273 // Must be a constant. 2274 if (!CE) return false; 2275 unsigned Value = CE->getValue(); 2276 return ARM_AM::isNEONi32splat(Value); 2277 } 2278 2279 bool isNEONi32splatNot() const { 2280 if (!isImm()) 2281 return false; 2282 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2283 // Must be a constant. 2284 if (!CE) return false; 2285 unsigned Value = CE->getValue(); 2286 return ARM_AM::isNEONi32splat(~Value); 2287 } 2288 2289 static bool isValidNEONi32vmovImm(int64_t Value) { 2290 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 2291 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 2292 return ((Value & 0xffffffffffffff00) == 0) || 2293 ((Value & 0xffffffffffff00ff) == 0) || 2294 ((Value & 0xffffffffff00ffff) == 0) || 2295 ((Value & 0xffffffff00ffffff) == 0) || 2296 ((Value & 0xffffffffffff00ff) == 0xff) || 2297 ((Value & 0xffffffffff00ffff) == 0xffff); 2298 } 2299 2300 bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const { 2301 assert((Width == 8 || Width == 16 || Width == 32) && 2302 "Invalid element width"); 2303 assert(NumElems * Width <= 64 && "Invalid result width"); 2304 2305 if (!isImm()) 2306 return false; 2307 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2308 // Must be a constant. 2309 if (!CE) 2310 return false; 2311 int64_t Value = CE->getValue(); 2312 if (!Value) 2313 return false; // Don't bother with zero. 2314 if (Inv) 2315 Value = ~Value; 2316 2317 uint64_t Mask = (1ull << Width) - 1; 2318 uint64_t Elem = Value & Mask; 2319 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0) 2320 return false; 2321 if (Width == 32 && !isValidNEONi32vmovImm(Elem)) 2322 return false; 2323 2324 for (unsigned i = 1; i < NumElems; ++i) { 2325 Value >>= Width; 2326 if ((Value & Mask) != Elem) 2327 return false; 2328 } 2329 return true; 2330 } 2331 2332 bool isNEONByteReplicate(unsigned NumBytes) const { 2333 return isNEONReplicate(8, NumBytes, false); 2334 } 2335 2336 static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) { 2337 assert((FromW == 8 || FromW == 16 || FromW == 32) && 2338 "Invalid source width"); 2339 assert((ToW == 16 || ToW == 32 || ToW == 64) && 2340 "Invalid destination width"); 2341 assert(FromW < ToW && "ToW is not less than FromW"); 2342 } 2343 2344 template<unsigned FromW, unsigned ToW> 2345 bool isNEONmovReplicate() const { 2346 checkNeonReplicateArgs(FromW, ToW); 2347 if (ToW == 64 && isNEONi64splat()) 2348 return false; 2349 return isNEONReplicate(FromW, ToW / FromW, false); 2350 } 2351 2352 template<unsigned FromW, unsigned ToW> 2353 bool isNEONinvReplicate() const { 2354 checkNeonReplicateArgs(FromW, ToW); 2355 return isNEONReplicate(FromW, ToW / FromW, true); 2356 } 2357 2358 bool isNEONi32vmov() const { 2359 if (isNEONByteReplicate(4)) 2360 return false; // Let it to be classified as byte-replicate case. 2361 if (!isImm()) 2362 return false; 2363 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2364 // Must be a constant. 2365 if (!CE) 2366 return false; 2367 return isValidNEONi32vmovImm(CE->getValue()); 2368 } 2369 2370 bool isNEONi32vmovNeg() const { 2371 if (!isImm()) return false; 2372 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2373 // Must be a constant. 2374 if (!CE) return false; 2375 return isValidNEONi32vmovImm(~CE->getValue()); 2376 } 2377 2378 bool isNEONi64splat() const { 2379 if (!isImm()) return false; 2380 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2381 // Must be a constant. 2382 if (!CE) return false; 2383 uint64_t Value = CE->getValue(); 2384 // i64 value with each byte being either 0 or 0xff. 2385 for (unsigned i = 0; i < 8; ++i, Value >>= 8) 2386 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 2387 return true; 2388 } 2389 2390 template<int64_t Angle, int64_t Remainder> 2391 bool isComplexRotation() const { 2392 if (!isImm()) return false; 2393 2394 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2395 if (!CE) return false; 2396 uint64_t Value = CE->getValue(); 2397 2398 return (Value % Angle == Remainder && Value <= 270); 2399 } 2400 2401 bool isMVELongShift() const { 2402 if (!isImm()) return false; 2403 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2404 // Must be a constant. 2405 if (!CE) return false; 2406 uint64_t Value = CE->getValue(); 2407 return Value >= 1 && Value <= 32; 2408 } 2409 2410 bool isMveSaturateOp() const { 2411 if (!isImm()) return false; 2412 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2413 if (!CE) return false; 2414 uint64_t Value = CE->getValue(); 2415 return Value == 48 || Value == 64; 2416 } 2417 2418 bool isITCondCodeNoAL() const { 2419 if (!isITCondCode()) return false; 2420 ARMCC::CondCodes CC = getCondCode(); 2421 return CC != ARMCC::AL; 2422 } 2423 2424 bool isITCondCodeRestrictedI() const { 2425 if (!isITCondCode()) 2426 return false; 2427 ARMCC::CondCodes CC = getCondCode(); 2428 return CC == ARMCC::EQ || CC == ARMCC::NE; 2429 } 2430 2431 bool isITCondCodeRestrictedS() const { 2432 if (!isITCondCode()) 2433 return false; 2434 ARMCC::CondCodes CC = getCondCode(); 2435 return CC == ARMCC::LT || CC == ARMCC::GT || CC == ARMCC::LE || 2436 CC == ARMCC::GE; 2437 } 2438 2439 bool isITCondCodeRestrictedU() const { 2440 if (!isITCondCode()) 2441 return false; 2442 ARMCC::CondCodes CC = getCondCode(); 2443 return CC == ARMCC::HS || CC == ARMCC::HI; 2444 } 2445 2446 bool isITCondCodeRestrictedFP() const { 2447 if (!isITCondCode()) 2448 return false; 2449 ARMCC::CondCodes CC = getCondCode(); 2450 return CC == ARMCC::EQ || CC == ARMCC::NE || CC == ARMCC::LT || 2451 CC == ARMCC::GT || CC == ARMCC::LE || CC == ARMCC::GE; 2452 } 2453 2454 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 2455 // Add as immediates when possible. Null MCExpr = 0. 2456 if (!Expr) 2457 Inst.addOperand(MCOperand::createImm(0)); 2458 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 2459 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2460 else 2461 Inst.addOperand(MCOperand::createExpr(Expr)); 2462 } 2463 2464 void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const { 2465 assert(N == 1 && "Invalid number of operands!"); 2466 addExpr(Inst, getImm()); 2467 } 2468 2469 void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const { 2470 assert(N == 1 && "Invalid number of operands!"); 2471 addExpr(Inst, getImm()); 2472 } 2473 2474 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 2475 assert(N == 2 && "Invalid number of operands!"); 2476 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode()))); 2477 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 2478 Inst.addOperand(MCOperand::createReg(RegNum)); 2479 } 2480 2481 void addVPTPredNOperands(MCInst &Inst, unsigned N) const { 2482 assert(N == 3 && "Invalid number of operands!"); 2483 Inst.addOperand(MCOperand::createImm(unsigned(getVPTPred()))); 2484 unsigned RegNum = getVPTPred() == ARMVCC::None ? 0: ARM::P0; 2485 Inst.addOperand(MCOperand::createReg(RegNum)); 2486 Inst.addOperand(MCOperand::createReg(0)); 2487 } 2488 2489 void addVPTPredROperands(MCInst &Inst, unsigned N) const { 2490 assert(N == 4 && "Invalid number of operands!"); 2491 addVPTPredNOperands(Inst, N-1); 2492 unsigned RegNum; 2493 if (getVPTPred() == ARMVCC::None) { 2494 RegNum = 0; 2495 } else { 2496 unsigned NextOpIndex = Inst.getNumOperands(); 2497 const MCInstrDesc &MCID = ARMInsts[Inst.getOpcode()]; 2498 int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO); 2499 assert(TiedOp >= 0 && 2500 "Inactive register in vpred_r is not tied to an output!"); 2501 RegNum = Inst.getOperand(TiedOp).getReg(); 2502 } 2503 Inst.addOperand(MCOperand::createReg(RegNum)); 2504 } 2505 2506 void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 2507 assert(N == 1 && "Invalid number of operands!"); 2508 Inst.addOperand(MCOperand::createImm(getCoproc())); 2509 } 2510 2511 void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 2512 assert(N == 1 && "Invalid number of operands!"); 2513 Inst.addOperand(MCOperand::createImm(getCoproc())); 2514 } 2515 2516 void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 2517 assert(N == 1 && "Invalid number of operands!"); 2518 Inst.addOperand(MCOperand::createImm(CoprocOption.Val)); 2519 } 2520 2521 void addITMaskOperands(MCInst &Inst, unsigned N) const { 2522 assert(N == 1 && "Invalid number of operands!"); 2523 Inst.addOperand(MCOperand::createImm(ITMask.Mask)); 2524 } 2525 2526 void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 2527 assert(N == 1 && "Invalid number of operands!"); 2528 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode()))); 2529 } 2530 2531 void addITCondCodeInvOperands(MCInst &Inst, unsigned N) const { 2532 assert(N == 1 && "Invalid number of operands!"); 2533 Inst.addOperand(MCOperand::createImm(unsigned(ARMCC::getOppositeCondition(getCondCode())))); 2534 } 2535 2536 void addCCOutOperands(MCInst &Inst, unsigned N) const { 2537 assert(N == 1 && "Invalid number of operands!"); 2538 Inst.addOperand(MCOperand::createReg(getReg())); 2539 } 2540 2541 void addRegOperands(MCInst &Inst, unsigned N) const { 2542 assert(N == 1 && "Invalid number of operands!"); 2543 Inst.addOperand(MCOperand::createReg(getReg())); 2544 } 2545 2546 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 2547 assert(N == 3 && "Invalid number of operands!"); 2548 assert(isRegShiftedReg() && 2549 "addRegShiftedRegOperands() on non-RegShiftedReg!"); 2550 Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg)); 2551 Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg)); 2552 Inst.addOperand(MCOperand::createImm( 2553 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 2554 } 2555 2556 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 2557 assert(N == 2 && "Invalid number of operands!"); 2558 assert(isRegShiftedImm() && 2559 "addRegShiftedImmOperands() on non-RegShiftedImm!"); 2560 Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg)); 2561 // Shift of #32 is encoded as 0 where permitted 2562 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm); 2563 Inst.addOperand(MCOperand::createImm( 2564 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm))); 2565 } 2566 2567 void addShifterImmOperands(MCInst &Inst, unsigned N) const { 2568 assert(N == 1 && "Invalid number of operands!"); 2569 Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) | 2570 ShifterImm.Imm)); 2571 } 2572 2573 void addRegListOperands(MCInst &Inst, unsigned N) const { 2574 assert(N == 1 && "Invalid number of operands!"); 2575 const SmallVectorImpl<unsigned> &RegList = getRegList(); 2576 for (SmallVectorImpl<unsigned>::const_iterator 2577 I = RegList.begin(), E = RegList.end(); I != E; ++I) 2578 Inst.addOperand(MCOperand::createReg(*I)); 2579 } 2580 2581 void addRegListWithAPSROperands(MCInst &Inst, unsigned N) const { 2582 assert(N == 1 && "Invalid number of operands!"); 2583 const SmallVectorImpl<unsigned> &RegList = getRegList(); 2584 for (SmallVectorImpl<unsigned>::const_iterator 2585 I = RegList.begin(), E = RegList.end(); I != E; ++I) 2586 Inst.addOperand(MCOperand::createReg(*I)); 2587 } 2588 2589 void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 2590 addRegListOperands(Inst, N); 2591 } 2592 2593 void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 2594 addRegListOperands(Inst, N); 2595 } 2596 2597 void addFPSRegListWithVPROperands(MCInst &Inst, unsigned N) const { 2598 addRegListOperands(Inst, N); 2599 } 2600 2601 void addFPDRegListWithVPROperands(MCInst &Inst, unsigned N) const { 2602 addRegListOperands(Inst, N); 2603 } 2604 2605 void addRotImmOperands(MCInst &Inst, unsigned N) const { 2606 assert(N == 1 && "Invalid number of operands!"); 2607 // Encoded as val>>3. The printer handles display as 8, 16, 24. 2608 Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3)); 2609 } 2610 2611 void addModImmOperands(MCInst &Inst, unsigned N) const { 2612 assert(N == 1 && "Invalid number of operands!"); 2613 2614 // Support for fixups (MCFixup) 2615 if (isImm()) 2616 return addImmOperands(Inst, N); 2617 2618 Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7))); 2619 } 2620 2621 void addModImmNotOperands(MCInst &Inst, unsigned N) const { 2622 assert(N == 1 && "Invalid number of operands!"); 2623 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2624 uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue()); 2625 Inst.addOperand(MCOperand::createImm(Enc)); 2626 } 2627 2628 void addModImmNegOperands(MCInst &Inst, unsigned N) const { 2629 assert(N == 1 && "Invalid number of operands!"); 2630 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2631 uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue()); 2632 Inst.addOperand(MCOperand::createImm(Enc)); 2633 } 2634 2635 void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const { 2636 assert(N == 1 && "Invalid number of operands!"); 2637 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2638 uint32_t Val = -CE->getValue(); 2639 Inst.addOperand(MCOperand::createImm(Val)); 2640 } 2641 2642 void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const { 2643 assert(N == 1 && "Invalid number of operands!"); 2644 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2645 uint32_t Val = -CE->getValue(); 2646 Inst.addOperand(MCOperand::createImm(Val)); 2647 } 2648 2649 void addBitfieldOperands(MCInst &Inst, unsigned N) const { 2650 assert(N == 1 && "Invalid number of operands!"); 2651 // Munge the lsb/width into a bitfield mask. 2652 unsigned lsb = Bitfield.LSB; 2653 unsigned width = Bitfield.Width; 2654 // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 2655 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 2656 (32 - (lsb + width))); 2657 Inst.addOperand(MCOperand::createImm(Mask)); 2658 } 2659 2660 void addImmOperands(MCInst &Inst, unsigned N) const { 2661 assert(N == 1 && "Invalid number of operands!"); 2662 addExpr(Inst, getImm()); 2663 } 2664 2665 void addFBits16Operands(MCInst &Inst, unsigned N) const { 2666 assert(N == 1 && "Invalid number of operands!"); 2667 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2668 Inst.addOperand(MCOperand::createImm(16 - CE->getValue())); 2669 } 2670 2671 void addFBits32Operands(MCInst &Inst, unsigned N) const { 2672 assert(N == 1 && "Invalid number of operands!"); 2673 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2674 Inst.addOperand(MCOperand::createImm(32 - CE->getValue())); 2675 } 2676 2677 void addFPImmOperands(MCInst &Inst, unsigned N) const { 2678 assert(N == 1 && "Invalid number of operands!"); 2679 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2680 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue())); 2681 Inst.addOperand(MCOperand::createImm(Val)); 2682 } 2683 2684 void addImm8s4Operands(MCInst &Inst, unsigned N) const { 2685 assert(N == 1 && "Invalid number of operands!"); 2686 // FIXME: We really want to scale the value here, but the LDRD/STRD 2687 // instruction don't encode operands that way yet. 2688 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2689 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2690 } 2691 2692 void addImm7s4Operands(MCInst &Inst, unsigned N) const { 2693 assert(N == 1 && "Invalid number of operands!"); 2694 // FIXME: We really want to scale the value here, but the VSTR/VLDR_VSYSR 2695 // instruction don't encode operands that way yet. 2696 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2697 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2698 } 2699 2700 void addImm7Shift0Operands(MCInst &Inst, unsigned N) const { 2701 assert(N == 1 && "Invalid number of operands!"); 2702 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2703 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2704 } 2705 2706 void addImm7Shift1Operands(MCInst &Inst, unsigned N) const { 2707 assert(N == 1 && "Invalid number of operands!"); 2708 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2709 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2710 } 2711 2712 void addImm7Shift2Operands(MCInst &Inst, unsigned N) const { 2713 assert(N == 1 && "Invalid number of operands!"); 2714 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2715 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2716 } 2717 2718 void addImm7Operands(MCInst &Inst, unsigned N) const { 2719 assert(N == 1 && "Invalid number of operands!"); 2720 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2721 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2722 } 2723 2724 void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 2725 assert(N == 1 && "Invalid number of operands!"); 2726 // The immediate is scaled by four in the encoding and is stored 2727 // in the MCInst as such. Lop off the low two bits here. 2728 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2729 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4)); 2730 } 2731 2732 void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const { 2733 assert(N == 1 && "Invalid number of operands!"); 2734 // The immediate is scaled by four in the encoding and is stored 2735 // in the MCInst as such. Lop off the low two bits here. 2736 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2737 Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4))); 2738 } 2739 2740 void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 2741 assert(N == 1 && "Invalid number of operands!"); 2742 // The immediate is scaled by four in the encoding and is stored 2743 // in the MCInst as such. Lop off the low two bits here. 2744 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2745 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4)); 2746 } 2747 2748 void addImm1_16Operands(MCInst &Inst, unsigned N) const { 2749 assert(N == 1 && "Invalid number of operands!"); 2750 // The constant encodes as the immediate-1, and we store in the instruction 2751 // the bits as encoded, so subtract off one here. 2752 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2753 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1)); 2754 } 2755 2756 void addImm1_32Operands(MCInst &Inst, unsigned N) const { 2757 assert(N == 1 && "Invalid number of operands!"); 2758 // The constant encodes as the immediate-1, and we store in the instruction 2759 // the bits as encoded, so subtract off one here. 2760 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2761 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1)); 2762 } 2763 2764 void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 2765 assert(N == 1 && "Invalid number of operands!"); 2766 // The constant encodes as the immediate, except for 32, which encodes as 2767 // zero. 2768 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2769 unsigned Imm = CE->getValue(); 2770 Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm))); 2771 } 2772 2773 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 2774 assert(N == 1 && "Invalid number of operands!"); 2775 // An ASR value of 32 encodes as 0, so that's how we want to add it to 2776 // the instruction as well. 2777 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2778 int Val = CE->getValue(); 2779 Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val)); 2780 } 2781 2782 void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const { 2783 assert(N == 1 && "Invalid number of operands!"); 2784 // The operand is actually a t2_so_imm, but we have its bitwise 2785 // negation in the assembly source, so twiddle it here. 2786 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2787 Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue())); 2788 } 2789 2790 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const { 2791 assert(N == 1 && "Invalid number of operands!"); 2792 // The operand is actually a t2_so_imm, but we have its 2793 // negation in the assembly source, so twiddle it here. 2794 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2795 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue())); 2796 } 2797 2798 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const { 2799 assert(N == 1 && "Invalid number of operands!"); 2800 // The operand is actually an imm0_4095, but we have its 2801 // negation in the assembly source, so twiddle it here. 2802 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2803 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue())); 2804 } 2805 2806 void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const { 2807 if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) { 2808 Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2)); 2809 return; 2810 } 2811 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val); 2812 Inst.addOperand(MCOperand::createExpr(SR)); 2813 } 2814 2815 void addThumbMemPCOperands(MCInst &Inst, unsigned N) const { 2816 assert(N == 1 && "Invalid number of operands!"); 2817 if (isImm()) { 2818 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2819 if (CE) { 2820 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2821 return; 2822 } 2823 const MCSymbolRefExpr *SR = cast<MCSymbolRefExpr>(Imm.Val); 2824 Inst.addOperand(MCOperand::createExpr(SR)); 2825 return; 2826 } 2827 2828 assert(isGPRMem() && "Unknown value type!"); 2829 assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!"); 2830 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) 2831 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2832 else 2833 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 2834 } 2835 2836 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 2837 assert(N == 1 && "Invalid number of operands!"); 2838 Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt()))); 2839 } 2840 2841 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const { 2842 assert(N == 1 && "Invalid number of operands!"); 2843 Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt()))); 2844 } 2845 2846 void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const { 2847 assert(N == 1 && "Invalid number of operands!"); 2848 Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt()))); 2849 } 2850 2851 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 2852 assert(N == 1 && "Invalid number of operands!"); 2853 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2854 } 2855 2856 void addMemNoOffsetT2Operands(MCInst &Inst, unsigned N) const { 2857 assert(N == 1 && "Invalid number of operands!"); 2858 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2859 } 2860 2861 void addMemNoOffsetT2NoSpOperands(MCInst &Inst, unsigned N) const { 2862 assert(N == 1 && "Invalid number of operands!"); 2863 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2864 } 2865 2866 void addMemNoOffsetTOperands(MCInst &Inst, unsigned N) const { 2867 assert(N == 1 && "Invalid number of operands!"); 2868 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2869 } 2870 2871 void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const { 2872 assert(N == 1 && "Invalid number of operands!"); 2873 if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) 2874 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2875 else 2876 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 2877 } 2878 2879 void addAdrLabelOperands(MCInst &Inst, unsigned N) const { 2880 assert(N == 1 && "Invalid number of operands!"); 2881 assert(isImm() && "Not an immediate!"); 2882 2883 // If we have an immediate that's not a constant, treat it as a label 2884 // reference needing a fixup. 2885 if (!isa<MCConstantExpr>(getImm())) { 2886 Inst.addOperand(MCOperand::createExpr(getImm())); 2887 return; 2888 } 2889 2890 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 2891 int Val = CE->getValue(); 2892 Inst.addOperand(MCOperand::createImm(Val)); 2893 } 2894 2895 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 2896 assert(N == 2 && "Invalid number of operands!"); 2897 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2898 Inst.addOperand(MCOperand::createImm(Memory.Alignment)); 2899 } 2900 2901 void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const { 2902 addAlignedMemoryOperands(Inst, N); 2903 } 2904 2905 void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const { 2906 addAlignedMemoryOperands(Inst, N); 2907 } 2908 2909 void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const { 2910 addAlignedMemoryOperands(Inst, N); 2911 } 2912 2913 void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const { 2914 addAlignedMemoryOperands(Inst, N); 2915 } 2916 2917 void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const { 2918 addAlignedMemoryOperands(Inst, N); 2919 } 2920 2921 void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const { 2922 addAlignedMemoryOperands(Inst, N); 2923 } 2924 2925 void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const { 2926 addAlignedMemoryOperands(Inst, N); 2927 } 2928 2929 void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const { 2930 addAlignedMemoryOperands(Inst, N); 2931 } 2932 2933 void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const { 2934 addAlignedMemoryOperands(Inst, N); 2935 } 2936 2937 void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const { 2938 addAlignedMemoryOperands(Inst, N); 2939 } 2940 2941 void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const { 2942 addAlignedMemoryOperands(Inst, N); 2943 } 2944 2945 void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 2946 assert(N == 3 && "Invalid number of operands!"); 2947 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2948 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 2949 if (!Memory.OffsetRegNum) { 2950 if (!Memory.OffsetImm) 2951 Inst.addOperand(MCOperand::createImm(0)); 2952 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 2953 int32_t Val = CE->getValue(); 2954 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2955 // Special case for #-0 2956 if (Val == std::numeric_limits<int32_t>::min()) 2957 Val = 0; 2958 if (Val < 0) 2959 Val = -Val; 2960 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 2961 Inst.addOperand(MCOperand::createImm(Val)); 2962 } else 2963 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 2964 } else { 2965 // For register offset, we encode the shift type and negation flag 2966 // here. 2967 int32_t Val = 2968 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 2969 Memory.ShiftImm, Memory.ShiftType); 2970 Inst.addOperand(MCOperand::createImm(Val)); 2971 } 2972 } 2973 2974 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 2975 assert(N == 2 && "Invalid number of operands!"); 2976 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2977 assert(CE && "non-constant AM2OffsetImm operand!"); 2978 int32_t Val = CE->getValue(); 2979 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2980 // Special case for #-0 2981 if (Val == std::numeric_limits<int32_t>::min()) Val = 0; 2982 if (Val < 0) Val = -Val; 2983 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 2984 Inst.addOperand(MCOperand::createReg(0)); 2985 Inst.addOperand(MCOperand::createImm(Val)); 2986 } 2987 2988 void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 2989 assert(N == 3 && "Invalid number of operands!"); 2990 // If we have an immediate that's not a constant, treat it as a label 2991 // reference needing a fixup. If it is a constant, it's something else 2992 // and we reject it. 2993 if (isImm()) { 2994 Inst.addOperand(MCOperand::createExpr(getImm())); 2995 Inst.addOperand(MCOperand::createReg(0)); 2996 Inst.addOperand(MCOperand::createImm(0)); 2997 return; 2998 } 2999 3000 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3001 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 3002 if (!Memory.OffsetRegNum) { 3003 if (!Memory.OffsetImm) 3004 Inst.addOperand(MCOperand::createImm(0)); 3005 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 3006 int32_t Val = CE->getValue(); 3007 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 3008 // Special case for #-0 3009 if (Val == std::numeric_limits<int32_t>::min()) 3010 Val = 0; 3011 if (Val < 0) 3012 Val = -Val; 3013 Val = ARM_AM::getAM3Opc(AddSub, Val); 3014 Inst.addOperand(MCOperand::createImm(Val)); 3015 } else 3016 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 3017 } else { 3018 // For register offset, we encode the shift type and negation flag 3019 // here. 3020 int32_t Val = 3021 ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 3022 Inst.addOperand(MCOperand::createImm(Val)); 3023 } 3024 } 3025 3026 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 3027 assert(N == 2 && "Invalid number of operands!"); 3028 if (Kind == k_PostIndexRegister) { 3029 int32_t Val = 3030 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 3031 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum)); 3032 Inst.addOperand(MCOperand::createImm(Val)); 3033 return; 3034 } 3035 3036 // Constant offset. 3037 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 3038 int32_t Val = CE->getValue(); 3039 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 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::getAM3Opc(AddSub, Val); 3044 Inst.addOperand(MCOperand::createReg(0)); 3045 Inst.addOperand(MCOperand::createImm(Val)); 3046 } 3047 3048 void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 3049 assert(N == 2 && "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()) { 3054 Inst.addOperand(MCOperand::createExpr(getImm())); 3055 Inst.addOperand(MCOperand::createImm(0)); 3056 return; 3057 } 3058 3059 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3060 if (!Memory.OffsetImm) 3061 Inst.addOperand(MCOperand::createImm(0)); 3062 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 3063 // The lower two bits are always zero and as such are not encoded. 3064 int32_t Val = CE->getValue() / 4; 3065 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 3066 // Special case for #-0 3067 if (Val == std::numeric_limits<int32_t>::min()) 3068 Val = 0; 3069 if (Val < 0) 3070 Val = -Val; 3071 Val = ARM_AM::getAM5Opc(AddSub, Val); 3072 Inst.addOperand(MCOperand::createImm(Val)); 3073 } else 3074 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 3075 } 3076 3077 void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const { 3078 assert(N == 2 && "Invalid number of operands!"); 3079 // If we have an immediate that's not a constant, treat it as a label 3080 // reference needing a fixup. If it is a constant, it's something else 3081 // and we reject it. 3082 if (isImm()) { 3083 Inst.addOperand(MCOperand::createExpr(getImm())); 3084 Inst.addOperand(MCOperand::createImm(0)); 3085 return; 3086 } 3087 3088 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3089 // The lower bit is always zero and as such is not encoded. 3090 if (!Memory.OffsetImm) 3091 Inst.addOperand(MCOperand::createImm(0)); 3092 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) { 3093 int32_t Val = CE->getValue() / 2; 3094 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 3095 // Special case for #-0 3096 if (Val == std::numeric_limits<int32_t>::min()) 3097 Val = 0; 3098 if (Val < 0) 3099 Val = -Val; 3100 Val = ARM_AM::getAM5FP16Opc(AddSub, Val); 3101 Inst.addOperand(MCOperand::createImm(Val)); 3102 } else 3103 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 3104 } 3105 3106 void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 3107 assert(N == 2 && "Invalid number of operands!"); 3108 // If we have an immediate that's not a constant, treat it as a label 3109 // reference needing a fixup. If it is a constant, it's something else 3110 // and we reject it. 3111 if (isImm()) { 3112 Inst.addOperand(MCOperand::createExpr(getImm())); 3113 Inst.addOperand(MCOperand::createImm(0)); 3114 return; 3115 } 3116 3117 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3118 addExpr(Inst, Memory.OffsetImm); 3119 } 3120 3121 void addMemImm7s4OffsetOperands(MCInst &Inst, unsigned N) const { 3122 assert(N == 2 && "Invalid number of operands!"); 3123 // If we have an immediate that's not a constant, treat it as a label 3124 // reference needing a fixup. If it is a constant, it's something else 3125 // and we reject it. 3126 if (isImm()) { 3127 Inst.addOperand(MCOperand::createExpr(getImm())); 3128 Inst.addOperand(MCOperand::createImm(0)); 3129 return; 3130 } 3131 3132 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3133 addExpr(Inst, Memory.OffsetImm); 3134 } 3135 3136 void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 3137 assert(N == 2 && "Invalid number of operands!"); 3138 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3139 if (!Memory.OffsetImm) 3140 Inst.addOperand(MCOperand::createImm(0)); 3141 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) 3142 // The lower two bits are always zero and as such are not encoded. 3143 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4)); 3144 else 3145 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 3146 } 3147 3148 void addMemImmOffsetOperands(MCInst &Inst, unsigned N) const { 3149 assert(N == 2 && "Invalid number of operands!"); 3150 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3151 addExpr(Inst, Memory.OffsetImm); 3152 } 3153 3154 void addMemRegRQOffsetOperands(MCInst &Inst, unsigned N) const { 3155 assert(N == 2 && "Invalid number of operands!"); 3156 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3157 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 3158 } 3159 3160 void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 3161 assert(N == 2 && "Invalid number of operands!"); 3162 // If this is an immediate, it's a label reference. 3163 if (isImm()) { 3164 addExpr(Inst, getImm()); 3165 Inst.addOperand(MCOperand::createImm(0)); 3166 return; 3167 } 3168 3169 // Otherwise, it's a normal memory reg+offset. 3170 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3171 addExpr(Inst, Memory.OffsetImm); 3172 } 3173 3174 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 3175 assert(N == 2 && "Invalid number of operands!"); 3176 // If this is an immediate, it's a label reference. 3177 if (isImm()) { 3178 addExpr(Inst, getImm()); 3179 Inst.addOperand(MCOperand::createImm(0)); 3180 return; 3181 } 3182 3183 // Otherwise, it's a normal memory reg+offset. 3184 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3185 addExpr(Inst, Memory.OffsetImm); 3186 } 3187 3188 void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const { 3189 assert(N == 1 && "Invalid number of operands!"); 3190 // This is container for the immediate that we will create the constant 3191 // pool from 3192 addExpr(Inst, getConstantPoolImm()); 3193 } 3194 3195 void addMemTBBOperands(MCInst &Inst, unsigned N) const { 3196 assert(N == 2 && "Invalid number of operands!"); 3197 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3198 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 3199 } 3200 3201 void addMemTBHOperands(MCInst &Inst, unsigned N) const { 3202 assert(N == 2 && "Invalid number of operands!"); 3203 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3204 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 3205 } 3206 3207 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 3208 assert(N == 3 && "Invalid number of operands!"); 3209 unsigned Val = 3210 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 3211 Memory.ShiftImm, Memory.ShiftType); 3212 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3213 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 3214 Inst.addOperand(MCOperand::createImm(Val)); 3215 } 3216 3217 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 3218 assert(N == 3 && "Invalid number of operands!"); 3219 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3220 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 3221 Inst.addOperand(MCOperand::createImm(Memory.ShiftImm)); 3222 } 3223 3224 void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 3225 assert(N == 2 && "Invalid number of operands!"); 3226 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3227 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 3228 } 3229 3230 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 3231 assert(N == 2 && "Invalid number of operands!"); 3232 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3233 if (!Memory.OffsetImm) 3234 Inst.addOperand(MCOperand::createImm(0)); 3235 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) 3236 // The lower two bits are always zero and as such are not encoded. 3237 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4)); 3238 else 3239 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 3240 } 3241 3242 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 3243 assert(N == 2 && "Invalid number of operands!"); 3244 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3245 if (!Memory.OffsetImm) 3246 Inst.addOperand(MCOperand::createImm(0)); 3247 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) 3248 Inst.addOperand(MCOperand::createImm(CE->getValue() / 2)); 3249 else 3250 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 3251 } 3252 3253 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 3254 assert(N == 2 && "Invalid number of operands!"); 3255 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3256 addExpr(Inst, Memory.OffsetImm); 3257 } 3258 3259 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 3260 assert(N == 2 && "Invalid number of operands!"); 3261 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 3262 if (!Memory.OffsetImm) 3263 Inst.addOperand(MCOperand::createImm(0)); 3264 else if (const auto *CE = dyn_cast<MCConstantExpr>(Memory.OffsetImm)) 3265 // The lower two bits are always zero and as such are not encoded. 3266 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4)); 3267 else 3268 Inst.addOperand(MCOperand::createExpr(Memory.OffsetImm)); 3269 } 3270 3271 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 3272 assert(N == 1 && "Invalid number of operands!"); 3273 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 3274 assert(CE && "non-constant post-idx-imm8 operand!"); 3275 int Imm = CE->getValue(); 3276 bool isAdd = Imm >= 0; 3277 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0; 3278 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 3279 Inst.addOperand(MCOperand::createImm(Imm)); 3280 } 3281 3282 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 3283 assert(N == 1 && "Invalid number of operands!"); 3284 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 3285 assert(CE && "non-constant post-idx-imm8s4 operand!"); 3286 int Imm = CE->getValue(); 3287 bool isAdd = Imm >= 0; 3288 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0; 3289 // Immediate is scaled by 4. 3290 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 3291 Inst.addOperand(MCOperand::createImm(Imm)); 3292 } 3293 3294 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 3295 assert(N == 2 && "Invalid number of operands!"); 3296 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum)); 3297 Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd)); 3298 } 3299 3300 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 3301 assert(N == 2 && "Invalid number of operands!"); 3302 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum)); 3303 // The sign, shift type, and shift amount are encoded in a single operand 3304 // using the AM2 encoding helpers. 3305 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 3306 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 3307 PostIdxReg.ShiftTy); 3308 Inst.addOperand(MCOperand::createImm(Imm)); 3309 } 3310 3311 void addPowerTwoOperands(MCInst &Inst, unsigned N) const { 3312 assert(N == 1 && "Invalid number of operands!"); 3313 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3314 Inst.addOperand(MCOperand::createImm(CE->getValue())); 3315 } 3316 3317 void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 3318 assert(N == 1 && "Invalid number of operands!"); 3319 Inst.addOperand(MCOperand::createImm(unsigned(getMSRMask()))); 3320 } 3321 3322 void addBankedRegOperands(MCInst &Inst, unsigned N) const { 3323 assert(N == 1 && "Invalid number of operands!"); 3324 Inst.addOperand(MCOperand::createImm(unsigned(getBankedReg()))); 3325 } 3326 3327 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 3328 assert(N == 1 && "Invalid number of operands!"); 3329 Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags()))); 3330 } 3331 3332 void addVecListOperands(MCInst &Inst, unsigned N) const { 3333 assert(N == 1 && "Invalid number of operands!"); 3334 Inst.addOperand(MCOperand::createReg(VectorList.RegNum)); 3335 } 3336 3337 void addMVEVecListOperands(MCInst &Inst, unsigned N) const { 3338 assert(N == 1 && "Invalid number of operands!"); 3339 3340 // When we come here, the VectorList field will identify a range 3341 // of q-registers by its base register and length, and it will 3342 // have already been error-checked to be the expected length of 3343 // range and contain only q-regs in the range q0-q7. So we can 3344 // count on the base register being in the range q0-q6 (for 2 3345 // regs) or q0-q4 (for 4) 3346 // 3347 // The MVE instructions taking a register range of this kind will 3348 // need an operand in the MQQPR or MQQQQPR class, representing the 3349 // entire range as a unit. So we must translate into that class, 3350 // by finding the index of the base register in the MQPR reg 3351 // class, and returning the super-register at the corresponding 3352 // index in the target class. 3353 3354 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID]; 3355 const MCRegisterClass *RC_out = 3356 (VectorList.Count == 2) ? &ARMMCRegisterClasses[ARM::MQQPRRegClassID] 3357 : &ARMMCRegisterClasses[ARM::MQQQQPRRegClassID]; 3358 3359 unsigned I, E = RC_out->getNumRegs(); 3360 for (I = 0; I < E; I++) 3361 if (RC_in->getRegister(I) == VectorList.RegNum) 3362 break; 3363 assert(I < E && "Invalid vector list start register!"); 3364 3365 Inst.addOperand(MCOperand::createReg(RC_out->getRegister(I))); 3366 } 3367 3368 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const { 3369 assert(N == 2 && "Invalid number of operands!"); 3370 Inst.addOperand(MCOperand::createReg(VectorList.RegNum)); 3371 Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex)); 3372 } 3373 3374 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 3375 assert(N == 1 && "Invalid number of operands!"); 3376 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 3377 } 3378 3379 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 3380 assert(N == 1 && "Invalid number of operands!"); 3381 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 3382 } 3383 3384 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 3385 assert(N == 1 && "Invalid number of operands!"); 3386 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 3387 } 3388 3389 void addVectorIndex64Operands(MCInst &Inst, unsigned N) const { 3390 assert(N == 1 && "Invalid number of operands!"); 3391 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 3392 } 3393 3394 void addMVEVectorIndexOperands(MCInst &Inst, unsigned N) const { 3395 assert(N == 1 && "Invalid number of operands!"); 3396 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 3397 } 3398 3399 void addMVEPairVectorIndexOperands(MCInst &Inst, unsigned N) const { 3400 assert(N == 1 && "Invalid number of operands!"); 3401 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 3402 } 3403 3404 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 3405 assert(N == 1 && "Invalid number of operands!"); 3406 // The immediate encodes the type of constant as well as the value. 3407 // Mask in that this is an i8 splat. 3408 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3409 Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00)); 3410 } 3411 3412 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 3413 assert(N == 1 && "Invalid number of operands!"); 3414 // The immediate encodes the type of constant as well as the value. 3415 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3416 unsigned Value = CE->getValue(); 3417 Value = ARM_AM::encodeNEONi16splat(Value); 3418 Inst.addOperand(MCOperand::createImm(Value)); 3419 } 3420 3421 void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const { 3422 assert(N == 1 && "Invalid number of operands!"); 3423 // The immediate encodes the type of constant as well as the value. 3424 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3425 unsigned Value = CE->getValue(); 3426 Value = ARM_AM::encodeNEONi16splat(~Value & 0xffff); 3427 Inst.addOperand(MCOperand::createImm(Value)); 3428 } 3429 3430 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 3431 assert(N == 1 && "Invalid number of operands!"); 3432 // The immediate encodes the type of constant as well as the value. 3433 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3434 unsigned Value = CE->getValue(); 3435 Value = ARM_AM::encodeNEONi32splat(Value); 3436 Inst.addOperand(MCOperand::createImm(Value)); 3437 } 3438 3439 void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const { 3440 assert(N == 1 && "Invalid number of operands!"); 3441 // The immediate encodes the type of constant as well as the value. 3442 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3443 unsigned Value = CE->getValue(); 3444 Value = ARM_AM::encodeNEONi32splat(~Value); 3445 Inst.addOperand(MCOperand::createImm(Value)); 3446 } 3447 3448 void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const { 3449 // The immediate encodes the type of constant as well as the value. 3450 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3451 assert((Inst.getOpcode() == ARM::VMOVv8i8 || 3452 Inst.getOpcode() == ARM::VMOVv16i8) && 3453 "All instructions that wants to replicate non-zero byte " 3454 "always must be replaced with VMOVv8i8 or VMOVv16i8."); 3455 unsigned Value = CE->getValue(); 3456 if (Inv) 3457 Value = ~Value; 3458 unsigned B = Value & 0xff; 3459 B |= 0xe00; // cmode = 0b1110 3460 Inst.addOperand(MCOperand::createImm(B)); 3461 } 3462 3463 void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const { 3464 assert(N == 1 && "Invalid number of operands!"); 3465 addNEONi8ReplicateOperands(Inst, true); 3466 } 3467 3468 static unsigned encodeNeonVMOVImmediate(unsigned Value) { 3469 if (Value >= 256 && Value <= 0xffff) 3470 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 3471 else if (Value > 0xffff && Value <= 0xffffff) 3472 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 3473 else if (Value > 0xffffff) 3474 Value = (Value >> 24) | 0x600; 3475 return Value; 3476 } 3477 3478 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 3479 assert(N == 1 && "Invalid number of operands!"); 3480 // The immediate encodes the type of constant as well as the value. 3481 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3482 unsigned Value = encodeNeonVMOVImmediate(CE->getValue()); 3483 Inst.addOperand(MCOperand::createImm(Value)); 3484 } 3485 3486 void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const { 3487 assert(N == 1 && "Invalid number of operands!"); 3488 addNEONi8ReplicateOperands(Inst, false); 3489 } 3490 3491 void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const { 3492 assert(N == 1 && "Invalid number of operands!"); 3493 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3494 assert((Inst.getOpcode() == ARM::VMOVv4i16 || 3495 Inst.getOpcode() == ARM::VMOVv8i16 || 3496 Inst.getOpcode() == ARM::VMVNv4i16 || 3497 Inst.getOpcode() == ARM::VMVNv8i16) && 3498 "All instructions that want to replicate non-zero half-word " 3499 "always must be replaced with V{MOV,MVN}v{4,8}i16."); 3500 uint64_t Value = CE->getValue(); 3501 unsigned Elem = Value & 0xffff; 3502 if (Elem >= 256) 3503 Elem = (Elem >> 8) | 0x200; 3504 Inst.addOperand(MCOperand::createImm(Elem)); 3505 } 3506 3507 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const { 3508 assert(N == 1 && "Invalid number of operands!"); 3509 // The immediate encodes the type of constant as well as the value. 3510 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3511 unsigned Value = encodeNeonVMOVImmediate(~CE->getValue()); 3512 Inst.addOperand(MCOperand::createImm(Value)); 3513 } 3514 3515 void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const { 3516 assert(N == 1 && "Invalid number of operands!"); 3517 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3518 assert((Inst.getOpcode() == ARM::VMOVv2i32 || 3519 Inst.getOpcode() == ARM::VMOVv4i32 || 3520 Inst.getOpcode() == ARM::VMVNv2i32 || 3521 Inst.getOpcode() == ARM::VMVNv4i32) && 3522 "All instructions that want to replicate non-zero word " 3523 "always must be replaced with V{MOV,MVN}v{2,4}i32."); 3524 uint64_t Value = CE->getValue(); 3525 unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff); 3526 Inst.addOperand(MCOperand::createImm(Elem)); 3527 } 3528 3529 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 3530 assert(N == 1 && "Invalid number of operands!"); 3531 // The immediate encodes the type of constant as well as the value. 3532 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3533 uint64_t Value = CE->getValue(); 3534 unsigned Imm = 0; 3535 for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 3536 Imm |= (Value & 1) << i; 3537 } 3538 Inst.addOperand(MCOperand::createImm(Imm | 0x1e00)); 3539 } 3540 3541 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const { 3542 assert(N == 1 && "Invalid number of operands!"); 3543 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3544 Inst.addOperand(MCOperand::createImm(CE->getValue() / 90)); 3545 } 3546 3547 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const { 3548 assert(N == 1 && "Invalid number of operands!"); 3549 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3550 Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180)); 3551 } 3552 3553 void addMveSaturateOperands(MCInst &Inst, unsigned N) const { 3554 assert(N == 1 && "Invalid number of operands!"); 3555 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm()); 3556 unsigned Imm = CE->getValue(); 3557 assert((Imm == 48 || Imm == 64) && "Invalid saturate operand"); 3558 Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0)); 3559 } 3560 3561 void print(raw_ostream &OS) const override; 3562 3563 static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S) { 3564 auto Op = std::make_unique<ARMOperand>(k_ITCondMask); 3565 Op->ITMask.Mask = Mask; 3566 Op->StartLoc = S; 3567 Op->EndLoc = S; 3568 return Op; 3569 } 3570 3571 static std::unique_ptr<ARMOperand> CreateCondCode(ARMCC::CondCodes CC, 3572 SMLoc S) { 3573 auto Op = std::make_unique<ARMOperand>(k_CondCode); 3574 Op->CC.Val = CC; 3575 Op->StartLoc = S; 3576 Op->EndLoc = S; 3577 return Op; 3578 } 3579 3580 static std::unique_ptr<ARMOperand> CreateVPTPred(ARMVCC::VPTCodes CC, 3581 SMLoc S) { 3582 auto Op = std::make_unique<ARMOperand>(k_VPTPred); 3583 Op->VCC.Val = CC; 3584 Op->StartLoc = S; 3585 Op->EndLoc = S; 3586 return Op; 3587 } 3588 3589 static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S) { 3590 auto Op = std::make_unique<ARMOperand>(k_CoprocNum); 3591 Op->Cop.Val = CopVal; 3592 Op->StartLoc = S; 3593 Op->EndLoc = S; 3594 return Op; 3595 } 3596 3597 static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S) { 3598 auto Op = std::make_unique<ARMOperand>(k_CoprocReg); 3599 Op->Cop.Val = CopVal; 3600 Op->StartLoc = S; 3601 Op->EndLoc = S; 3602 return Op; 3603 } 3604 3605 static std::unique_ptr<ARMOperand> CreateCoprocOption(unsigned Val, SMLoc S, 3606 SMLoc E) { 3607 auto Op = std::make_unique<ARMOperand>(k_CoprocOption); 3608 Op->Cop.Val = Val; 3609 Op->StartLoc = S; 3610 Op->EndLoc = E; 3611 return Op; 3612 } 3613 3614 static std::unique_ptr<ARMOperand> CreateCCOut(unsigned RegNum, SMLoc S) { 3615 auto Op = std::make_unique<ARMOperand>(k_CCOut); 3616 Op->Reg.RegNum = RegNum; 3617 Op->StartLoc = S; 3618 Op->EndLoc = S; 3619 return Op; 3620 } 3621 3622 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S) { 3623 auto Op = std::make_unique<ARMOperand>(k_Token); 3624 Op->Tok.Data = Str.data(); 3625 Op->Tok.Length = Str.size(); 3626 Op->StartLoc = S; 3627 Op->EndLoc = S; 3628 return Op; 3629 } 3630 3631 static std::unique_ptr<ARMOperand> CreateReg(unsigned RegNum, SMLoc S, 3632 SMLoc E) { 3633 auto Op = std::make_unique<ARMOperand>(k_Register); 3634 Op->Reg.RegNum = RegNum; 3635 Op->StartLoc = S; 3636 Op->EndLoc = E; 3637 return Op; 3638 } 3639 3640 static std::unique_ptr<ARMOperand> 3641 CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, unsigned SrcReg, 3642 unsigned ShiftReg, unsigned ShiftImm, SMLoc S, 3643 SMLoc E) { 3644 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister); 3645 Op->RegShiftedReg.ShiftTy = ShTy; 3646 Op->RegShiftedReg.SrcReg = SrcReg; 3647 Op->RegShiftedReg.ShiftReg = ShiftReg; 3648 Op->RegShiftedReg.ShiftImm = ShiftImm; 3649 Op->StartLoc = S; 3650 Op->EndLoc = E; 3651 return Op; 3652 } 3653 3654 static std::unique_ptr<ARMOperand> 3655 CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, unsigned SrcReg, 3656 unsigned ShiftImm, SMLoc S, SMLoc E) { 3657 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate); 3658 Op->RegShiftedImm.ShiftTy = ShTy; 3659 Op->RegShiftedImm.SrcReg = SrcReg; 3660 Op->RegShiftedImm.ShiftImm = ShiftImm; 3661 Op->StartLoc = S; 3662 Op->EndLoc = E; 3663 return Op; 3664 } 3665 3666 static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm, 3667 SMLoc S, SMLoc E) { 3668 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate); 3669 Op->ShifterImm.isASR = isASR; 3670 Op->ShifterImm.Imm = Imm; 3671 Op->StartLoc = S; 3672 Op->EndLoc = E; 3673 return Op; 3674 } 3675 3676 static std::unique_ptr<ARMOperand> CreateRotImm(unsigned Imm, SMLoc S, 3677 SMLoc E) { 3678 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate); 3679 Op->RotImm.Imm = Imm; 3680 Op->StartLoc = S; 3681 Op->EndLoc = E; 3682 return Op; 3683 } 3684 3685 static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot, 3686 SMLoc S, SMLoc E) { 3687 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate); 3688 Op->ModImm.Bits = Bits; 3689 Op->ModImm.Rot = Rot; 3690 Op->StartLoc = S; 3691 Op->EndLoc = E; 3692 return Op; 3693 } 3694 3695 static std::unique_ptr<ARMOperand> 3696 CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E) { 3697 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate); 3698 Op->Imm.Val = Val; 3699 Op->StartLoc = S; 3700 Op->EndLoc = E; 3701 return Op; 3702 } 3703 3704 static std::unique_ptr<ARMOperand> 3705 CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) { 3706 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor); 3707 Op->Bitfield.LSB = LSB; 3708 Op->Bitfield.Width = Width; 3709 Op->StartLoc = S; 3710 Op->EndLoc = E; 3711 return Op; 3712 } 3713 3714 static std::unique_ptr<ARMOperand> 3715 CreateRegList(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs, 3716 SMLoc StartLoc, SMLoc EndLoc) { 3717 assert(Regs.size() > 0 && "RegList contains no registers?"); 3718 KindTy Kind = k_RegisterList; 3719 3720 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains( 3721 Regs.front().second)) { 3722 if (Regs.back().second == ARM::VPR) 3723 Kind = k_FPDRegisterListWithVPR; 3724 else 3725 Kind = k_DPRRegisterList; 3726 } else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains( 3727 Regs.front().second)) { 3728 if (Regs.back().second == ARM::VPR) 3729 Kind = k_FPSRegisterListWithVPR; 3730 else 3731 Kind = k_SPRRegisterList; 3732 } 3733 3734 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR) 3735 Kind = k_RegisterListWithAPSR; 3736 3737 assert(llvm::is_sorted(Regs) && "Register list must be sorted by encoding"); 3738 3739 auto Op = std::make_unique<ARMOperand>(Kind); 3740 for (const auto &P : Regs) 3741 Op->Registers.push_back(P.second); 3742 3743 Op->StartLoc = StartLoc; 3744 Op->EndLoc = EndLoc; 3745 return Op; 3746 } 3747 3748 static std::unique_ptr<ARMOperand> CreateVectorList(unsigned RegNum, 3749 unsigned Count, 3750 bool isDoubleSpaced, 3751 SMLoc S, SMLoc E) { 3752 auto Op = std::make_unique<ARMOperand>(k_VectorList); 3753 Op->VectorList.RegNum = RegNum; 3754 Op->VectorList.Count = Count; 3755 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 3756 Op->StartLoc = S; 3757 Op->EndLoc = E; 3758 return Op; 3759 } 3760 3761 static std::unique_ptr<ARMOperand> 3762 CreateVectorListAllLanes(unsigned RegNum, unsigned Count, bool isDoubleSpaced, 3763 SMLoc S, SMLoc E) { 3764 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes); 3765 Op->VectorList.RegNum = RegNum; 3766 Op->VectorList.Count = Count; 3767 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 3768 Op->StartLoc = S; 3769 Op->EndLoc = E; 3770 return Op; 3771 } 3772 3773 static std::unique_ptr<ARMOperand> 3774 CreateVectorListIndexed(unsigned RegNum, unsigned Count, unsigned Index, 3775 bool isDoubleSpaced, SMLoc S, SMLoc E) { 3776 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed); 3777 Op->VectorList.RegNum = RegNum; 3778 Op->VectorList.Count = Count; 3779 Op->VectorList.LaneIndex = Index; 3780 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 3781 Op->StartLoc = S; 3782 Op->EndLoc = E; 3783 return Op; 3784 } 3785 3786 static std::unique_ptr<ARMOperand> 3787 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) { 3788 auto Op = std::make_unique<ARMOperand>(k_VectorIndex); 3789 Op->VectorIndex.Val = Idx; 3790 Op->StartLoc = S; 3791 Op->EndLoc = E; 3792 return Op; 3793 } 3794 3795 static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S, 3796 SMLoc E) { 3797 auto Op = std::make_unique<ARMOperand>(k_Immediate); 3798 Op->Imm.Val = Val; 3799 Op->StartLoc = S; 3800 Op->EndLoc = E; 3801 return Op; 3802 } 3803 3804 static std::unique_ptr<ARMOperand> 3805 CreateMem(unsigned BaseRegNum, const MCExpr *OffsetImm, unsigned OffsetRegNum, 3806 ARM_AM::ShiftOpc ShiftType, unsigned ShiftImm, unsigned Alignment, 3807 bool isNegative, SMLoc S, SMLoc E, SMLoc AlignmentLoc = SMLoc()) { 3808 auto Op = std::make_unique<ARMOperand>(k_Memory); 3809 Op->Memory.BaseRegNum = BaseRegNum; 3810 Op->Memory.OffsetImm = OffsetImm; 3811 Op->Memory.OffsetRegNum = OffsetRegNum; 3812 Op->Memory.ShiftType = ShiftType; 3813 Op->Memory.ShiftImm = ShiftImm; 3814 Op->Memory.Alignment = Alignment; 3815 Op->Memory.isNegative = isNegative; 3816 Op->StartLoc = S; 3817 Op->EndLoc = E; 3818 Op->AlignmentLoc = AlignmentLoc; 3819 return Op; 3820 } 3821 3822 static std::unique_ptr<ARMOperand> 3823 CreatePostIdxReg(unsigned RegNum, bool isAdd, ARM_AM::ShiftOpc ShiftTy, 3824 unsigned ShiftImm, SMLoc S, SMLoc E) { 3825 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister); 3826 Op->PostIdxReg.RegNum = RegNum; 3827 Op->PostIdxReg.isAdd = isAdd; 3828 Op->PostIdxReg.ShiftTy = ShiftTy; 3829 Op->PostIdxReg.ShiftImm = ShiftImm; 3830 Op->StartLoc = S; 3831 Op->EndLoc = E; 3832 return Op; 3833 } 3834 3835 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, 3836 SMLoc S) { 3837 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt); 3838 Op->MBOpt.Val = Opt; 3839 Op->StartLoc = S; 3840 Op->EndLoc = S; 3841 return Op; 3842 } 3843 3844 static std::unique_ptr<ARMOperand> 3845 CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S) { 3846 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt); 3847 Op->ISBOpt.Val = Opt; 3848 Op->StartLoc = S; 3849 Op->EndLoc = S; 3850 return Op; 3851 } 3852 3853 static std::unique_ptr<ARMOperand> 3854 CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S) { 3855 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt); 3856 Op->TSBOpt.Val = Opt; 3857 Op->StartLoc = S; 3858 Op->EndLoc = S; 3859 return Op; 3860 } 3861 3862 static std::unique_ptr<ARMOperand> CreateProcIFlags(ARM_PROC::IFlags IFlags, 3863 SMLoc S) { 3864 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags); 3865 Op->IFlags.Val = IFlags; 3866 Op->StartLoc = S; 3867 Op->EndLoc = S; 3868 return Op; 3869 } 3870 3871 static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S) { 3872 auto Op = std::make_unique<ARMOperand>(k_MSRMask); 3873 Op->MMask.Val = MMask; 3874 Op->StartLoc = S; 3875 Op->EndLoc = S; 3876 return Op; 3877 } 3878 3879 static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S) { 3880 auto Op = std::make_unique<ARMOperand>(k_BankedReg); 3881 Op->BankedReg.Val = Reg; 3882 Op->StartLoc = S; 3883 Op->EndLoc = S; 3884 return Op; 3885 } 3886 }; 3887 3888 } // end anonymous namespace. 3889 3890 void ARMOperand::print(raw_ostream &OS) const { 3891 auto RegName = [](unsigned Reg) { 3892 if (Reg) 3893 return ARMInstPrinter::getRegisterName(Reg); 3894 else 3895 return "noreg"; 3896 }; 3897 3898 switch (Kind) { 3899 case k_CondCode: 3900 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 3901 break; 3902 case k_VPTPred: 3903 OS << "<ARMVCC::" << ARMVPTPredToString(getVPTPred()) << ">"; 3904 break; 3905 case k_CCOut: 3906 OS << "<ccout " << RegName(getReg()) << ">"; 3907 break; 3908 case k_ITCondMask: { 3909 static const char *const MaskStr[] = { 3910 "(invalid)", "(tttt)", "(ttt)", "(ttte)", 3911 "(tt)", "(ttet)", "(tte)", "(ttee)", 3912 "(t)", "(tett)", "(tet)", "(tete)", 3913 "(te)", "(teet)", "(tee)", "(teee)", 3914 }; 3915 assert((ITMask.Mask & 0xf) == ITMask.Mask); 3916 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 3917 break; 3918 } 3919 case k_CoprocNum: 3920 OS << "<coprocessor number: " << getCoproc() << ">"; 3921 break; 3922 case k_CoprocReg: 3923 OS << "<coprocessor register: " << getCoproc() << ">"; 3924 break; 3925 case k_CoprocOption: 3926 OS << "<coprocessor option: " << CoprocOption.Val << ">"; 3927 break; 3928 case k_MSRMask: 3929 OS << "<mask: " << getMSRMask() << ">"; 3930 break; 3931 case k_BankedReg: 3932 OS << "<banked reg: " << getBankedReg() << ">"; 3933 break; 3934 case k_Immediate: 3935 OS << *getImm(); 3936 break; 3937 case k_MemBarrierOpt: 3938 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">"; 3939 break; 3940 case k_InstSyncBarrierOpt: 3941 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">"; 3942 break; 3943 case k_TraceSyncBarrierOpt: 3944 OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">"; 3945 break; 3946 case k_Memory: 3947 OS << "<memory"; 3948 if (Memory.BaseRegNum) 3949 OS << " base:" << RegName(Memory.BaseRegNum); 3950 if (Memory.OffsetImm) 3951 OS << " offset-imm:" << *Memory.OffsetImm; 3952 if (Memory.OffsetRegNum) 3953 OS << " offset-reg:" << (Memory.isNegative ? "-" : "") 3954 << RegName(Memory.OffsetRegNum); 3955 if (Memory.ShiftType != ARM_AM::no_shift) { 3956 OS << " shift-type:" << ARM_AM::getShiftOpcStr(Memory.ShiftType); 3957 OS << " shift-imm:" << Memory.ShiftImm; 3958 } 3959 if (Memory.Alignment) 3960 OS << " alignment:" << Memory.Alignment; 3961 OS << ">"; 3962 break; 3963 case k_PostIndexRegister: 3964 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 3965 << RegName(PostIdxReg.RegNum); 3966 if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 3967 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 3968 << PostIdxReg.ShiftImm; 3969 OS << ">"; 3970 break; 3971 case k_ProcIFlags: { 3972 OS << "<ARM_PROC::"; 3973 unsigned IFlags = getProcIFlags(); 3974 for (int i=2; i >= 0; --i) 3975 if (IFlags & (1 << i)) 3976 OS << ARM_PROC::IFlagsToString(1 << i); 3977 OS << ">"; 3978 break; 3979 } 3980 case k_Register: 3981 OS << "<register " << RegName(getReg()) << ">"; 3982 break; 3983 case k_ShifterImmediate: 3984 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 3985 << " #" << ShifterImm.Imm << ">"; 3986 break; 3987 case k_ShiftedRegister: 3988 OS << "<so_reg_reg " << RegName(RegShiftedReg.SrcReg) << " " 3989 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) << " " 3990 << RegName(RegShiftedReg.ShiftReg) << ">"; 3991 break; 3992 case k_ShiftedImmediate: 3993 OS << "<so_reg_imm " << RegName(RegShiftedImm.SrcReg) << " " 3994 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) << " #" 3995 << RegShiftedImm.ShiftImm << ">"; 3996 break; 3997 case k_RotateImmediate: 3998 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 3999 break; 4000 case k_ModifiedImmediate: 4001 OS << "<mod_imm #" << ModImm.Bits << ", #" 4002 << ModImm.Rot << ")>"; 4003 break; 4004 case k_ConstantPoolImmediate: 4005 OS << "<constant_pool_imm #" << *getConstantPoolImm(); 4006 break; 4007 case k_BitfieldDescriptor: 4008 OS << "<bitfield " << "lsb: " << Bitfield.LSB 4009 << ", width: " << Bitfield.Width << ">"; 4010 break; 4011 case k_RegisterList: 4012 case k_RegisterListWithAPSR: 4013 case k_DPRRegisterList: 4014 case k_SPRRegisterList: 4015 case k_FPSRegisterListWithVPR: 4016 case k_FPDRegisterListWithVPR: { 4017 OS << "<register_list "; 4018 4019 const SmallVectorImpl<unsigned> &RegList = getRegList(); 4020 for (SmallVectorImpl<unsigned>::const_iterator 4021 I = RegList.begin(), E = RegList.end(); I != E; ) { 4022 OS << RegName(*I); 4023 if (++I < E) OS << ", "; 4024 } 4025 4026 OS << ">"; 4027 break; 4028 } 4029 case k_VectorList: 4030 OS << "<vector_list " << VectorList.Count << " * " 4031 << RegName(VectorList.RegNum) << ">"; 4032 break; 4033 case k_VectorListAllLanes: 4034 OS << "<vector_list(all lanes) " << VectorList.Count << " * " 4035 << RegName(VectorList.RegNum) << ">"; 4036 break; 4037 case k_VectorListIndexed: 4038 OS << "<vector_list(lane " << VectorList.LaneIndex << ") " 4039 << VectorList.Count << " * " << RegName(VectorList.RegNum) << ">"; 4040 break; 4041 case k_Token: 4042 OS << "'" << getToken() << "'"; 4043 break; 4044 case k_VectorIndex: 4045 OS << "<vectorindex " << getVectorIndex() << ">"; 4046 break; 4047 } 4048 } 4049 4050 /// @name Auto-generated Match Functions 4051 /// { 4052 4053 static unsigned MatchRegisterName(StringRef Name); 4054 4055 /// } 4056 4057 bool ARMAsmParser::ParseRegister(unsigned &RegNo, 4058 SMLoc &StartLoc, SMLoc &EndLoc) { 4059 const AsmToken &Tok = getParser().getTok(); 4060 StartLoc = Tok.getLoc(); 4061 EndLoc = Tok.getEndLoc(); 4062 RegNo = tryParseRegister(); 4063 4064 return (RegNo == (unsigned)-1); 4065 } 4066 4067 OperandMatchResultTy ARMAsmParser::tryParseRegister(unsigned &RegNo, 4068 SMLoc &StartLoc, 4069 SMLoc &EndLoc) { 4070 if (ParseRegister(RegNo, StartLoc, EndLoc)) 4071 return MatchOperand_NoMatch; 4072 return MatchOperand_Success; 4073 } 4074 4075 /// Try to parse a register name. The token must be an Identifier when called, 4076 /// and if it is a register name the token is eaten and the register number is 4077 /// returned. Otherwise return -1. 4078 int ARMAsmParser::tryParseRegister() { 4079 MCAsmParser &Parser = getParser(); 4080 const AsmToken &Tok = Parser.getTok(); 4081 if (Tok.isNot(AsmToken::Identifier)) return -1; 4082 4083 std::string lowerCase = Tok.getString().lower(); 4084 unsigned RegNum = MatchRegisterName(lowerCase); 4085 if (!RegNum) { 4086 RegNum = StringSwitch<unsigned>(lowerCase) 4087 .Case("r13", ARM::SP) 4088 .Case("r14", ARM::LR) 4089 .Case("r15", ARM::PC) 4090 .Case("ip", ARM::R12) 4091 // Additional register name aliases for 'gas' compatibility. 4092 .Case("a1", ARM::R0) 4093 .Case("a2", ARM::R1) 4094 .Case("a3", ARM::R2) 4095 .Case("a4", ARM::R3) 4096 .Case("v1", ARM::R4) 4097 .Case("v2", ARM::R5) 4098 .Case("v3", ARM::R6) 4099 .Case("v4", ARM::R7) 4100 .Case("v5", ARM::R8) 4101 .Case("v6", ARM::R9) 4102 .Case("v7", ARM::R10) 4103 .Case("v8", ARM::R11) 4104 .Case("sb", ARM::R9) 4105 .Case("sl", ARM::R10) 4106 .Case("fp", ARM::R11) 4107 .Default(0); 4108 } 4109 if (!RegNum) { 4110 // Check for aliases registered via .req. Canonicalize to lower case. 4111 // That's more consistent since register names are case insensitive, and 4112 // it's how the original entry was passed in from MC/MCParser/AsmParser. 4113 StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase); 4114 // If no match, return failure. 4115 if (Entry == RegisterReqs.end()) 4116 return -1; 4117 Parser.Lex(); // Eat identifier token. 4118 return Entry->getValue(); 4119 } 4120 4121 // Some FPUs only have 16 D registers, so D16-D31 are invalid 4122 if (!hasD32() && RegNum >= ARM::D16 && RegNum <= ARM::D31) 4123 return -1; 4124 4125 Parser.Lex(); // Eat identifier token. 4126 4127 return RegNum; 4128 } 4129 4130 // Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 4131 // If a recoverable error occurs, return 1. If an irrecoverable error 4132 // occurs, return -1. An irrecoverable error is one where tokens have been 4133 // consumed in the process of trying to parse the shifter (i.e., when it is 4134 // indeed a shifter operand, but malformed). 4135 int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) { 4136 MCAsmParser &Parser = getParser(); 4137 SMLoc S = Parser.getTok().getLoc(); 4138 const AsmToken &Tok = Parser.getTok(); 4139 if (Tok.isNot(AsmToken::Identifier)) 4140 return -1; 4141 4142 std::string lowerCase = Tok.getString().lower(); 4143 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 4144 .Case("asl", ARM_AM::lsl) 4145 .Case("lsl", ARM_AM::lsl) 4146 .Case("lsr", ARM_AM::lsr) 4147 .Case("asr", ARM_AM::asr) 4148 .Case("ror", ARM_AM::ror) 4149 .Case("rrx", ARM_AM::rrx) 4150 .Default(ARM_AM::no_shift); 4151 4152 if (ShiftTy == ARM_AM::no_shift) 4153 return 1; 4154 4155 Parser.Lex(); // Eat the operator. 4156 4157 // The source register for the shift has already been added to the 4158 // operand list, so we need to pop it off and combine it into the shifted 4159 // register operand instead. 4160 std::unique_ptr<ARMOperand> PrevOp( 4161 (ARMOperand *)Operands.pop_back_val().release()); 4162 if (!PrevOp->isReg()) 4163 return Error(PrevOp->getStartLoc(), "shift must be of a register"); 4164 int SrcReg = PrevOp->getReg(); 4165 4166 SMLoc EndLoc; 4167 int64_t Imm = 0; 4168 int ShiftReg = 0; 4169 if (ShiftTy == ARM_AM::rrx) { 4170 // RRX Doesn't have an explicit shift amount. The encoder expects 4171 // the shift register to be the same as the source register. Seems odd, 4172 // but OK. 4173 ShiftReg = SrcReg; 4174 } else { 4175 // Figure out if this is shifted by a constant or a register (for non-RRX). 4176 if (Parser.getTok().is(AsmToken::Hash) || 4177 Parser.getTok().is(AsmToken::Dollar)) { 4178 Parser.Lex(); // Eat hash. 4179 SMLoc ImmLoc = Parser.getTok().getLoc(); 4180 const MCExpr *ShiftExpr = nullptr; 4181 if (getParser().parseExpression(ShiftExpr, EndLoc)) { 4182 Error(ImmLoc, "invalid immediate shift value"); 4183 return -1; 4184 } 4185 // The expression must be evaluatable as an immediate. 4186 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 4187 if (!CE) { 4188 Error(ImmLoc, "invalid immediate shift value"); 4189 return -1; 4190 } 4191 // Range check the immediate. 4192 // lsl, ror: 0 <= imm <= 31 4193 // lsr, asr: 0 <= imm <= 32 4194 Imm = CE->getValue(); 4195 if (Imm < 0 || 4196 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 4197 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 4198 Error(ImmLoc, "immediate shift value out of range"); 4199 return -1; 4200 } 4201 // shift by zero is a nop. Always send it through as lsl. 4202 // ('as' compatibility) 4203 if (Imm == 0) 4204 ShiftTy = ARM_AM::lsl; 4205 } else if (Parser.getTok().is(AsmToken::Identifier)) { 4206 SMLoc L = Parser.getTok().getLoc(); 4207 EndLoc = Parser.getTok().getEndLoc(); 4208 ShiftReg = tryParseRegister(); 4209 if (ShiftReg == -1) { 4210 Error(L, "expected immediate or register in shift operand"); 4211 return -1; 4212 } 4213 } else { 4214 Error(Parser.getTok().getLoc(), 4215 "expected immediate or register in shift operand"); 4216 return -1; 4217 } 4218 } 4219 4220 if (ShiftReg && ShiftTy != ARM_AM::rrx) 4221 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 4222 ShiftReg, Imm, 4223 S, EndLoc)); 4224 else 4225 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 4226 S, EndLoc)); 4227 4228 return 0; 4229 } 4230 4231 /// Try to parse a register name. The token must be an Identifier when called. 4232 /// If it's a register, an AsmOperand is created. Another AsmOperand is created 4233 /// if there is a "writeback". 'true' if it's not a register. 4234 /// 4235 /// TODO this is likely to change to allow different register types and or to 4236 /// parse for a specific register type. 4237 bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) { 4238 MCAsmParser &Parser = getParser(); 4239 SMLoc RegStartLoc = Parser.getTok().getLoc(); 4240 SMLoc RegEndLoc = Parser.getTok().getEndLoc(); 4241 int RegNo = tryParseRegister(); 4242 if (RegNo == -1) 4243 return true; 4244 4245 Operands.push_back(ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc)); 4246 4247 const AsmToken &ExclaimTok = Parser.getTok(); 4248 if (ExclaimTok.is(AsmToken::Exclaim)) { 4249 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 4250 ExclaimTok.getLoc())); 4251 Parser.Lex(); // Eat exclaim token 4252 return false; 4253 } 4254 4255 // Also check for an index operand. This is only legal for vector registers, 4256 // but that'll get caught OK in operand matching, so we don't need to 4257 // explicitly filter everything else out here. 4258 if (Parser.getTok().is(AsmToken::LBrac)) { 4259 SMLoc SIdx = Parser.getTok().getLoc(); 4260 Parser.Lex(); // Eat left bracket token. 4261 4262 const MCExpr *ImmVal; 4263 if (getParser().parseExpression(ImmVal)) 4264 return true; 4265 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 4266 if (!MCE) 4267 return TokError("immediate value expected for vector index"); 4268 4269 if (Parser.getTok().isNot(AsmToken::RBrac)) 4270 return Error(Parser.getTok().getLoc(), "']' expected"); 4271 4272 SMLoc E = Parser.getTok().getEndLoc(); 4273 Parser.Lex(); // Eat right bracket token. 4274 4275 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 4276 SIdx, E, 4277 getContext())); 4278 } 4279 4280 return false; 4281 } 4282 4283 /// MatchCoprocessorOperandName - Try to parse an coprocessor related 4284 /// instruction with a symbolic operand name. 4285 /// We accept "crN" syntax for GAS compatibility. 4286 /// <operand-name> ::= <prefix><number> 4287 /// If CoprocOp is 'c', then: 4288 /// <prefix> ::= c | cr 4289 /// If CoprocOp is 'p', then : 4290 /// <prefix> ::= p 4291 /// <number> ::= integer in range [0, 15] 4292 static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 4293 // Use the same layout as the tablegen'erated register name matcher. Ugly, 4294 // but efficient. 4295 if (Name.size() < 2 || Name[0] != CoprocOp) 4296 return -1; 4297 Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front(); 4298 4299 switch (Name.size()) { 4300 default: return -1; 4301 case 1: 4302 switch (Name[0]) { 4303 default: return -1; 4304 case '0': return 0; 4305 case '1': return 1; 4306 case '2': return 2; 4307 case '3': return 3; 4308 case '4': return 4; 4309 case '5': return 5; 4310 case '6': return 6; 4311 case '7': return 7; 4312 case '8': return 8; 4313 case '9': return 9; 4314 } 4315 case 2: 4316 if (Name[0] != '1') 4317 return -1; 4318 switch (Name[1]) { 4319 default: return -1; 4320 // CP10 and CP11 are VFP/NEON and so vector instructions should be used. 4321 // However, old cores (v5/v6) did use them in that way. 4322 case '0': return 10; 4323 case '1': return 11; 4324 case '2': return 12; 4325 case '3': return 13; 4326 case '4': return 14; 4327 case '5': return 15; 4328 } 4329 } 4330 } 4331 4332 /// parseITCondCode - Try to parse a condition code for an IT instruction. 4333 OperandMatchResultTy 4334 ARMAsmParser::parseITCondCode(OperandVector &Operands) { 4335 MCAsmParser &Parser = getParser(); 4336 SMLoc S = Parser.getTok().getLoc(); 4337 const AsmToken &Tok = Parser.getTok(); 4338 if (!Tok.is(AsmToken::Identifier)) 4339 return MatchOperand_NoMatch; 4340 unsigned CC = ARMCondCodeFromString(Tok.getString()); 4341 if (CC == ~0U) 4342 return MatchOperand_NoMatch; 4343 Parser.Lex(); // Eat the token. 4344 4345 Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 4346 4347 return MatchOperand_Success; 4348 } 4349 4350 /// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 4351 /// token must be an Identifier when called, and if it is a coprocessor 4352 /// number, the token is eaten and the operand is added to the operand list. 4353 OperandMatchResultTy 4354 ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) { 4355 MCAsmParser &Parser = getParser(); 4356 SMLoc S = Parser.getTok().getLoc(); 4357 const AsmToken &Tok = Parser.getTok(); 4358 if (Tok.isNot(AsmToken::Identifier)) 4359 return MatchOperand_NoMatch; 4360 4361 int Num = MatchCoprocessorOperandName(Tok.getString().lower(), 'p'); 4362 if (Num == -1) 4363 return MatchOperand_NoMatch; 4364 if (!isValidCoprocessorNumber(Num, getSTI().getFeatureBits())) 4365 return MatchOperand_NoMatch; 4366 4367 Parser.Lex(); // Eat identifier token. 4368 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 4369 return MatchOperand_Success; 4370 } 4371 4372 /// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 4373 /// token must be an Identifier when called, and if it is a coprocessor 4374 /// number, the token is eaten and the operand is added to the operand list. 4375 OperandMatchResultTy 4376 ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) { 4377 MCAsmParser &Parser = getParser(); 4378 SMLoc S = Parser.getTok().getLoc(); 4379 const AsmToken &Tok = Parser.getTok(); 4380 if (Tok.isNot(AsmToken::Identifier)) 4381 return MatchOperand_NoMatch; 4382 4383 int Reg = MatchCoprocessorOperandName(Tok.getString().lower(), 'c'); 4384 if (Reg == -1) 4385 return MatchOperand_NoMatch; 4386 4387 Parser.Lex(); // Eat identifier token. 4388 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 4389 return MatchOperand_Success; 4390 } 4391 4392 /// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 4393 /// coproc_option : '{' imm0_255 '}' 4394 OperandMatchResultTy 4395 ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) { 4396 MCAsmParser &Parser = getParser(); 4397 SMLoc S = Parser.getTok().getLoc(); 4398 4399 // If this isn't a '{', this isn't a coprocessor immediate operand. 4400 if (Parser.getTok().isNot(AsmToken::LCurly)) 4401 return MatchOperand_NoMatch; 4402 Parser.Lex(); // Eat the '{' 4403 4404 const MCExpr *Expr; 4405 SMLoc Loc = Parser.getTok().getLoc(); 4406 if (getParser().parseExpression(Expr)) { 4407 Error(Loc, "illegal expression"); 4408 return MatchOperand_ParseFail; 4409 } 4410 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 4411 if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 4412 Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 4413 return MatchOperand_ParseFail; 4414 } 4415 int Val = CE->getValue(); 4416 4417 // Check for and consume the closing '}' 4418 if (Parser.getTok().isNot(AsmToken::RCurly)) 4419 return MatchOperand_ParseFail; 4420 SMLoc E = Parser.getTok().getEndLoc(); 4421 Parser.Lex(); // Eat the '}' 4422 4423 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 4424 return MatchOperand_Success; 4425 } 4426 4427 // For register list parsing, we need to map from raw GPR register numbering 4428 // to the enumeration values. The enumeration values aren't sorted by 4429 // register number due to our using "sp", "lr" and "pc" as canonical names. 4430 static unsigned getNextRegister(unsigned Reg) { 4431 // If this is a GPR, we need to do it manually, otherwise we can rely 4432 // on the sort ordering of the enumeration since the other reg-classes 4433 // are sane. 4434 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 4435 return Reg + 1; 4436 switch(Reg) { 4437 default: llvm_unreachable("Invalid GPR number!"); 4438 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 4439 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 4440 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 4441 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 4442 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 4443 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 4444 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 4445 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 4446 } 4447 } 4448 4449 // Insert an <Encoding, Register> pair in an ordered vector. Return true on 4450 // success, or false, if duplicate encoding found. 4451 static bool 4452 insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs, 4453 unsigned Enc, unsigned Reg) { 4454 Regs.emplace_back(Enc, Reg); 4455 for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) { 4456 if (J->first == Enc) { 4457 Regs.erase(J.base()); 4458 return false; 4459 } 4460 if (J->first < Enc) 4461 break; 4462 std::swap(*I, *J); 4463 } 4464 return true; 4465 } 4466 4467 /// Parse a register list. 4468 bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder, 4469 bool AllowRAAC) { 4470 MCAsmParser &Parser = getParser(); 4471 if (Parser.getTok().isNot(AsmToken::LCurly)) 4472 return TokError("Token is not a Left Curly Brace"); 4473 SMLoc S = Parser.getTok().getLoc(); 4474 Parser.Lex(); // Eat '{' token. 4475 SMLoc RegLoc = Parser.getTok().getLoc(); 4476 4477 // Check the first register in the list to see what register class 4478 // this is a list of. 4479 int Reg = tryParseRegister(); 4480 if (Reg == -1) 4481 return Error(RegLoc, "register expected"); 4482 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE) 4483 return Error(RegLoc, "pseudo-register not allowed"); 4484 // The reglist instructions have at most 16 registers, so reserve 4485 // space for that many. 4486 int EReg = 0; 4487 SmallVector<std::pair<unsigned, unsigned>, 16> Registers; 4488 4489 // Allow Q regs and just interpret them as the two D sub-registers. 4490 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 4491 Reg = getDRegFromQReg(Reg); 4492 EReg = MRI->getEncodingValue(Reg); 4493 Registers.emplace_back(EReg, Reg); 4494 ++Reg; 4495 } 4496 const MCRegisterClass *RC; 4497 if (Reg == ARM::RA_AUTH_CODE || 4498 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 4499 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 4500 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 4501 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 4502 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 4503 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 4504 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg)) 4505 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID]; 4506 else 4507 return Error(RegLoc, "invalid register in register list"); 4508 4509 // Store the register. 4510 EReg = MRI->getEncodingValue(Reg); 4511 Registers.emplace_back(EReg, Reg); 4512 4513 // This starts immediately after the first register token in the list, 4514 // so we can see either a comma or a minus (range separator) as a legal 4515 // next token. 4516 while (Parser.getTok().is(AsmToken::Comma) || 4517 Parser.getTok().is(AsmToken::Minus)) { 4518 if (Parser.getTok().is(AsmToken::Minus)) { 4519 if (Reg == ARM::RA_AUTH_CODE) 4520 return Error(RegLoc, "pseudo-register not allowed"); 4521 Parser.Lex(); // Eat the minus. 4522 SMLoc AfterMinusLoc = Parser.getTok().getLoc(); 4523 int EndReg = tryParseRegister(); 4524 if (EndReg == -1) 4525 return Error(AfterMinusLoc, "register expected"); 4526 if (EndReg == ARM::RA_AUTH_CODE) 4527 return Error(AfterMinusLoc, "pseudo-register not allowed"); 4528 // Allow Q regs and just interpret them as the two D sub-registers. 4529 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 4530 EndReg = getDRegFromQReg(EndReg) + 1; 4531 // If the register is the same as the start reg, there's nothing 4532 // more to do. 4533 if (Reg == EndReg) 4534 continue; 4535 // The register must be in the same register class as the first. 4536 if ((Reg == ARM::RA_AUTH_CODE && 4537 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) || 4538 (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg))) 4539 return Error(AfterMinusLoc, "invalid register in register list"); 4540 // Ranges must go from low to high. 4541 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg)) 4542 return Error(AfterMinusLoc, "bad range in register list"); 4543 4544 // Add all the registers in the range to the register list. 4545 while (Reg != EndReg) { 4546 Reg = getNextRegister(Reg); 4547 EReg = MRI->getEncodingValue(Reg); 4548 if (!insertNoDuplicates(Registers, EReg, Reg)) { 4549 Warning(AfterMinusLoc, StringRef("duplicated register (") + 4550 ARMInstPrinter::getRegisterName(Reg) + 4551 ") in register list"); 4552 } 4553 } 4554 continue; 4555 } 4556 Parser.Lex(); // Eat the comma. 4557 RegLoc = Parser.getTok().getLoc(); 4558 int OldReg = Reg; 4559 const AsmToken RegTok = Parser.getTok(); 4560 Reg = tryParseRegister(); 4561 if (Reg == -1) 4562 return Error(RegLoc, "register expected"); 4563 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE) 4564 return Error(RegLoc, "pseudo-register not allowed"); 4565 // Allow Q regs and just interpret them as the two D sub-registers. 4566 bool isQReg = false; 4567 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 4568 Reg = getDRegFromQReg(Reg); 4569 isQReg = true; 4570 } 4571 if (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg) && 4572 RC->getID() == ARMMCRegisterClasses[ARM::GPRRegClassID].getID() && 4573 ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg)) { 4574 // switch the register classes, as GPRwithAPSRnospRegClassID is a partial 4575 // subset of GPRRegClassId except it contains APSR as well. 4576 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID]; 4577 } 4578 if (Reg == ARM::VPR && 4579 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] || 4580 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] || 4581 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) { 4582 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID]; 4583 EReg = MRI->getEncodingValue(Reg); 4584 if (!insertNoDuplicates(Registers, EReg, Reg)) { 4585 Warning(RegLoc, "duplicated register (" + RegTok.getString() + 4586 ") in register list"); 4587 } 4588 continue; 4589 } 4590 // The register must be in the same register class as the first. 4591 if ((Reg == ARM::RA_AUTH_CODE && 4592 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) || 4593 (Reg != ARM::RA_AUTH_CODE && !RC->contains(Reg))) 4594 return Error(RegLoc, "invalid register in register list"); 4595 // In most cases, the list must be monotonically increasing. An 4596 // exception is CLRM, which is order-independent anyway, so 4597 // there's no potential for confusion if you write clrm {r2,r1} 4598 // instead of clrm {r1,r2}. 4599 if (EnforceOrder && 4600 MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) { 4601 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 4602 Warning(RegLoc, "register list not in ascending order"); 4603 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg)) 4604 return Error(RegLoc, "register list not in ascending order"); 4605 } 4606 // VFP register lists must also be contiguous. 4607 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 4608 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] && 4609 Reg != OldReg + 1) 4610 return Error(RegLoc, "non-contiguous register range"); 4611 EReg = MRI->getEncodingValue(Reg); 4612 if (!insertNoDuplicates(Registers, EReg, Reg)) { 4613 Warning(RegLoc, "duplicated register (" + RegTok.getString() + 4614 ") in register list"); 4615 } 4616 if (isQReg) { 4617 EReg = MRI->getEncodingValue(++Reg); 4618 Registers.emplace_back(EReg, Reg); 4619 } 4620 } 4621 4622 if (Parser.getTok().isNot(AsmToken::RCurly)) 4623 return Error(Parser.getTok().getLoc(), "'}' expected"); 4624 SMLoc E = Parser.getTok().getEndLoc(); 4625 Parser.Lex(); // Eat '}' token. 4626 4627 // Push the register list operand. 4628 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 4629 4630 // The ARM system instruction variants for LDM/STM have a '^' token here. 4631 if (Parser.getTok().is(AsmToken::Caret)) { 4632 Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc())); 4633 Parser.Lex(); // Eat '^' token. 4634 } 4635 4636 return false; 4637 } 4638 4639 // Helper function to parse the lane index for vector lists. 4640 OperandMatchResultTy ARMAsmParser:: 4641 parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, SMLoc &EndLoc) { 4642 MCAsmParser &Parser = getParser(); 4643 Index = 0; // Always return a defined index value. 4644 if (Parser.getTok().is(AsmToken::LBrac)) { 4645 Parser.Lex(); // Eat the '['. 4646 if (Parser.getTok().is(AsmToken::RBrac)) { 4647 // "Dn[]" is the 'all lanes' syntax. 4648 LaneKind = AllLanes; 4649 EndLoc = Parser.getTok().getEndLoc(); 4650 Parser.Lex(); // Eat the ']'. 4651 return MatchOperand_Success; 4652 } 4653 4654 // There's an optional '#' token here. Normally there wouldn't be, but 4655 // inline assemble puts one in, and it's friendly to accept that. 4656 if (Parser.getTok().is(AsmToken::Hash)) 4657 Parser.Lex(); // Eat '#' or '$'. 4658 4659 const MCExpr *LaneIndex; 4660 SMLoc Loc = Parser.getTok().getLoc(); 4661 if (getParser().parseExpression(LaneIndex)) { 4662 Error(Loc, "illegal expression"); 4663 return MatchOperand_ParseFail; 4664 } 4665 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex); 4666 if (!CE) { 4667 Error(Loc, "lane index must be empty or an integer"); 4668 return MatchOperand_ParseFail; 4669 } 4670 if (Parser.getTok().isNot(AsmToken::RBrac)) { 4671 Error(Parser.getTok().getLoc(), "']' expected"); 4672 return MatchOperand_ParseFail; 4673 } 4674 EndLoc = Parser.getTok().getEndLoc(); 4675 Parser.Lex(); // Eat the ']'. 4676 int64_t Val = CE->getValue(); 4677 4678 // FIXME: Make this range check context sensitive for .8, .16, .32. 4679 if (Val < 0 || Val > 7) { 4680 Error(Parser.getTok().getLoc(), "lane index out of range"); 4681 return MatchOperand_ParseFail; 4682 } 4683 Index = Val; 4684 LaneKind = IndexedLane; 4685 return MatchOperand_Success; 4686 } 4687 LaneKind = NoLanes; 4688 return MatchOperand_Success; 4689 } 4690 4691 // parse a vector register list 4692 OperandMatchResultTy 4693 ARMAsmParser::parseVectorList(OperandVector &Operands) { 4694 MCAsmParser &Parser = getParser(); 4695 VectorLaneTy LaneKind; 4696 unsigned LaneIndex; 4697 SMLoc S = Parser.getTok().getLoc(); 4698 // As an extension (to match gas), support a plain D register or Q register 4699 // (without encosing curly braces) as a single or double entry list, 4700 // respectively. 4701 if (!hasMVE() && Parser.getTok().is(AsmToken::Identifier)) { 4702 SMLoc E = Parser.getTok().getEndLoc(); 4703 int Reg = tryParseRegister(); 4704 if (Reg == -1) 4705 return MatchOperand_NoMatch; 4706 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) { 4707 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E); 4708 if (Res != MatchOperand_Success) 4709 return Res; 4710 switch (LaneKind) { 4711 case NoLanes: 4712 Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E)); 4713 break; 4714 case AllLanes: 4715 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false, 4716 S, E)); 4717 break; 4718 case IndexedLane: 4719 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1, 4720 LaneIndex, 4721 false, S, E)); 4722 break; 4723 } 4724 return MatchOperand_Success; 4725 } 4726 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 4727 Reg = getDRegFromQReg(Reg); 4728 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E); 4729 if (Res != MatchOperand_Success) 4730 return Res; 4731 switch (LaneKind) { 4732 case NoLanes: 4733 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0, 4734 &ARMMCRegisterClasses[ARM::DPairRegClassID]); 4735 Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E)); 4736 break; 4737 case AllLanes: 4738 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0, 4739 &ARMMCRegisterClasses[ARM::DPairRegClassID]); 4740 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false, 4741 S, E)); 4742 break; 4743 case IndexedLane: 4744 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2, 4745 LaneIndex, 4746 false, S, E)); 4747 break; 4748 } 4749 return MatchOperand_Success; 4750 } 4751 Error(S, "vector register expected"); 4752 return MatchOperand_ParseFail; 4753 } 4754 4755 if (Parser.getTok().isNot(AsmToken::LCurly)) 4756 return MatchOperand_NoMatch; 4757 4758 Parser.Lex(); // Eat '{' token. 4759 SMLoc RegLoc = Parser.getTok().getLoc(); 4760 4761 int Reg = tryParseRegister(); 4762 if (Reg == -1) { 4763 Error(RegLoc, "register expected"); 4764 return MatchOperand_ParseFail; 4765 } 4766 unsigned Count = 1; 4767 int Spacing = 0; 4768 unsigned FirstReg = Reg; 4769 4770 if (hasMVE() && !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg)) { 4771 Error(Parser.getTok().getLoc(), "vector register in range Q0-Q7 expected"); 4772 return MatchOperand_ParseFail; 4773 } 4774 // The list is of D registers, but we also allow Q regs and just interpret 4775 // them as the two D sub-registers. 4776 else if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 4777 FirstReg = Reg = getDRegFromQReg(Reg); 4778 Spacing = 1; // double-spacing requires explicit D registers, otherwise 4779 // it's ambiguous with four-register single spaced. 4780 ++Reg; 4781 ++Count; 4782 } 4783 4784 SMLoc E; 4785 if (parseVectorLane(LaneKind, LaneIndex, E) != MatchOperand_Success) 4786 return MatchOperand_ParseFail; 4787 4788 while (Parser.getTok().is(AsmToken::Comma) || 4789 Parser.getTok().is(AsmToken::Minus)) { 4790 if (Parser.getTok().is(AsmToken::Minus)) { 4791 if (!Spacing) 4792 Spacing = 1; // Register range implies a single spaced list. 4793 else if (Spacing == 2) { 4794 Error(Parser.getTok().getLoc(), 4795 "sequential registers in double spaced list"); 4796 return MatchOperand_ParseFail; 4797 } 4798 Parser.Lex(); // Eat the minus. 4799 SMLoc AfterMinusLoc = Parser.getTok().getLoc(); 4800 int EndReg = tryParseRegister(); 4801 if (EndReg == -1) { 4802 Error(AfterMinusLoc, "register expected"); 4803 return MatchOperand_ParseFail; 4804 } 4805 // Allow Q regs and just interpret them as the two D sub-registers. 4806 if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 4807 EndReg = getDRegFromQReg(EndReg) + 1; 4808 // If the register is the same as the start reg, there's nothing 4809 // more to do. 4810 if (Reg == EndReg) 4811 continue; 4812 // The register must be in the same register class as the first. 4813 if ((hasMVE() && 4814 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(EndReg)) || 4815 (!hasMVE() && 4816 !ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg))) { 4817 Error(AfterMinusLoc, "invalid register in register list"); 4818 return MatchOperand_ParseFail; 4819 } 4820 // Ranges must go from low to high. 4821 if (Reg > EndReg) { 4822 Error(AfterMinusLoc, "bad range in register list"); 4823 return MatchOperand_ParseFail; 4824 } 4825 // Parse the lane specifier if present. 4826 VectorLaneTy NextLaneKind; 4827 unsigned NextLaneIndex; 4828 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != 4829 MatchOperand_Success) 4830 return MatchOperand_ParseFail; 4831 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 4832 Error(AfterMinusLoc, "mismatched lane index in register list"); 4833 return MatchOperand_ParseFail; 4834 } 4835 4836 // Add all the registers in the range to the register list. 4837 Count += EndReg - Reg; 4838 Reg = EndReg; 4839 continue; 4840 } 4841 Parser.Lex(); // Eat the comma. 4842 RegLoc = Parser.getTok().getLoc(); 4843 int OldReg = Reg; 4844 Reg = tryParseRegister(); 4845 if (Reg == -1) { 4846 Error(RegLoc, "register expected"); 4847 return MatchOperand_ParseFail; 4848 } 4849 4850 if (hasMVE()) { 4851 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Reg)) { 4852 Error(RegLoc, "vector register in range Q0-Q7 expected"); 4853 return MatchOperand_ParseFail; 4854 } 4855 Spacing = 1; 4856 } 4857 // vector register lists must be contiguous. 4858 // It's OK to use the enumeration values directly here rather, as the 4859 // VFP register classes have the enum sorted properly. 4860 // 4861 // The list is of D registers, but we also allow Q regs and just interpret 4862 // them as the two D sub-registers. 4863 else if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 4864 if (!Spacing) 4865 Spacing = 1; // Register range implies a single spaced list. 4866 else if (Spacing == 2) { 4867 Error(RegLoc, 4868 "invalid register in double-spaced list (must be 'D' register')"); 4869 return MatchOperand_ParseFail; 4870 } 4871 Reg = getDRegFromQReg(Reg); 4872 if (Reg != OldReg + 1) { 4873 Error(RegLoc, "non-contiguous register range"); 4874 return MatchOperand_ParseFail; 4875 } 4876 ++Reg; 4877 Count += 2; 4878 // Parse the lane specifier if present. 4879 VectorLaneTy NextLaneKind; 4880 unsigned NextLaneIndex; 4881 SMLoc LaneLoc = Parser.getTok().getLoc(); 4882 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != 4883 MatchOperand_Success) 4884 return MatchOperand_ParseFail; 4885 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 4886 Error(LaneLoc, "mismatched lane index in register list"); 4887 return MatchOperand_ParseFail; 4888 } 4889 continue; 4890 } 4891 // Normal D register. 4892 // Figure out the register spacing (single or double) of the list if 4893 // we don't know it already. 4894 if (!Spacing) 4895 Spacing = 1 + (Reg == OldReg + 2); 4896 4897 // Just check that it's contiguous and keep going. 4898 if (Reg != OldReg + Spacing) { 4899 Error(RegLoc, "non-contiguous register range"); 4900 return MatchOperand_ParseFail; 4901 } 4902 ++Count; 4903 // Parse the lane specifier if present. 4904 VectorLaneTy NextLaneKind; 4905 unsigned NextLaneIndex; 4906 SMLoc EndLoc = Parser.getTok().getLoc(); 4907 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != MatchOperand_Success) 4908 return MatchOperand_ParseFail; 4909 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 4910 Error(EndLoc, "mismatched lane index in register list"); 4911 return MatchOperand_ParseFail; 4912 } 4913 } 4914 4915 if (Parser.getTok().isNot(AsmToken::RCurly)) { 4916 Error(Parser.getTok().getLoc(), "'}' expected"); 4917 return MatchOperand_ParseFail; 4918 } 4919 E = Parser.getTok().getEndLoc(); 4920 Parser.Lex(); // Eat '}' token. 4921 4922 switch (LaneKind) { 4923 case NoLanes: 4924 case AllLanes: { 4925 // Two-register operands have been converted to the 4926 // composite register classes. 4927 if (Count == 2 && !hasMVE()) { 4928 const MCRegisterClass *RC = (Spacing == 1) ? 4929 &ARMMCRegisterClasses[ARM::DPairRegClassID] : 4930 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID]; 4931 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC); 4932 } 4933 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList : 4934 ARMOperand::CreateVectorListAllLanes); 4935 Operands.push_back(Create(FirstReg, Count, (Spacing == 2), S, E)); 4936 break; 4937 } 4938 case IndexedLane: 4939 Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count, 4940 LaneIndex, 4941 (Spacing == 2), 4942 S, E)); 4943 break; 4944 } 4945 return MatchOperand_Success; 4946 } 4947 4948 /// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 4949 OperandMatchResultTy 4950 ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) { 4951 MCAsmParser &Parser = getParser(); 4952 SMLoc S = Parser.getTok().getLoc(); 4953 const AsmToken &Tok = Parser.getTok(); 4954 unsigned Opt; 4955 4956 if (Tok.is(AsmToken::Identifier)) { 4957 StringRef OptStr = Tok.getString(); 4958 4959 Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()).lower()) 4960 .Case("sy", ARM_MB::SY) 4961 .Case("st", ARM_MB::ST) 4962 .Case("ld", ARM_MB::LD) 4963 .Case("sh", ARM_MB::ISH) 4964 .Case("ish", ARM_MB::ISH) 4965 .Case("shst", ARM_MB::ISHST) 4966 .Case("ishst", ARM_MB::ISHST) 4967 .Case("ishld", ARM_MB::ISHLD) 4968 .Case("nsh", ARM_MB::NSH) 4969 .Case("un", ARM_MB::NSH) 4970 .Case("nshst", ARM_MB::NSHST) 4971 .Case("nshld", ARM_MB::NSHLD) 4972 .Case("unst", ARM_MB::NSHST) 4973 .Case("osh", ARM_MB::OSH) 4974 .Case("oshst", ARM_MB::OSHST) 4975 .Case("oshld", ARM_MB::OSHLD) 4976 .Default(~0U); 4977 4978 // ishld, oshld, nshld and ld are only available from ARMv8. 4979 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD || 4980 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD)) 4981 Opt = ~0U; 4982 4983 if (Opt == ~0U) 4984 return MatchOperand_NoMatch; 4985 4986 Parser.Lex(); // Eat identifier token. 4987 } else if (Tok.is(AsmToken::Hash) || 4988 Tok.is(AsmToken::Dollar) || 4989 Tok.is(AsmToken::Integer)) { 4990 if (Parser.getTok().isNot(AsmToken::Integer)) 4991 Parser.Lex(); // Eat '#' or '$'. 4992 SMLoc Loc = Parser.getTok().getLoc(); 4993 4994 const MCExpr *MemBarrierID; 4995 if (getParser().parseExpression(MemBarrierID)) { 4996 Error(Loc, "illegal expression"); 4997 return MatchOperand_ParseFail; 4998 } 4999 5000 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID); 5001 if (!CE) { 5002 Error(Loc, "constant expression expected"); 5003 return MatchOperand_ParseFail; 5004 } 5005 5006 int Val = CE->getValue(); 5007 if (Val & ~0xf) { 5008 Error(Loc, "immediate value out of range"); 5009 return MatchOperand_ParseFail; 5010 } 5011 5012 Opt = ARM_MB::RESERVED_0 + Val; 5013 } else 5014 return MatchOperand_ParseFail; 5015 5016 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 5017 return MatchOperand_Success; 5018 } 5019 5020 OperandMatchResultTy 5021 ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) { 5022 MCAsmParser &Parser = getParser(); 5023 SMLoc S = Parser.getTok().getLoc(); 5024 const AsmToken &Tok = Parser.getTok(); 5025 5026 if (Tok.isNot(AsmToken::Identifier)) 5027 return MatchOperand_NoMatch; 5028 5029 if (!Tok.getString().equals_insensitive("csync")) 5030 return MatchOperand_NoMatch; 5031 5032 Parser.Lex(); // Eat identifier token. 5033 5034 Operands.push_back(ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S)); 5035 return MatchOperand_Success; 5036 } 5037 5038 /// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options. 5039 OperandMatchResultTy 5040 ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) { 5041 MCAsmParser &Parser = getParser(); 5042 SMLoc S = Parser.getTok().getLoc(); 5043 const AsmToken &Tok = Parser.getTok(); 5044 unsigned Opt; 5045 5046 if (Tok.is(AsmToken::Identifier)) { 5047 StringRef OptStr = Tok.getString(); 5048 5049 if (OptStr.equals_insensitive("sy")) 5050 Opt = ARM_ISB::SY; 5051 else 5052 return MatchOperand_NoMatch; 5053 5054 Parser.Lex(); // Eat identifier token. 5055 } else if (Tok.is(AsmToken::Hash) || 5056 Tok.is(AsmToken::Dollar) || 5057 Tok.is(AsmToken::Integer)) { 5058 if (Parser.getTok().isNot(AsmToken::Integer)) 5059 Parser.Lex(); // Eat '#' or '$'. 5060 SMLoc Loc = Parser.getTok().getLoc(); 5061 5062 const MCExpr *ISBarrierID; 5063 if (getParser().parseExpression(ISBarrierID)) { 5064 Error(Loc, "illegal expression"); 5065 return MatchOperand_ParseFail; 5066 } 5067 5068 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID); 5069 if (!CE) { 5070 Error(Loc, "constant expression expected"); 5071 return MatchOperand_ParseFail; 5072 } 5073 5074 int Val = CE->getValue(); 5075 if (Val & ~0xf) { 5076 Error(Loc, "immediate value out of range"); 5077 return MatchOperand_ParseFail; 5078 } 5079 5080 Opt = ARM_ISB::RESERVED_0 + Val; 5081 } else 5082 return MatchOperand_ParseFail; 5083 5084 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt( 5085 (ARM_ISB::InstSyncBOpt)Opt, S)); 5086 return MatchOperand_Success; 5087 } 5088 5089 5090 /// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 5091 OperandMatchResultTy 5092 ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) { 5093 MCAsmParser &Parser = getParser(); 5094 SMLoc S = Parser.getTok().getLoc(); 5095 const AsmToken &Tok = Parser.getTok(); 5096 if (!Tok.is(AsmToken::Identifier)) 5097 return MatchOperand_NoMatch; 5098 StringRef IFlagsStr = Tok.getString(); 5099 5100 // An iflags string of "none" is interpreted to mean that none of the AIF 5101 // bits are set. Not a terribly useful instruction, but a valid encoding. 5102 unsigned IFlags = 0; 5103 if (IFlagsStr != "none") { 5104 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 5105 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1).lower()) 5106 .Case("a", ARM_PROC::A) 5107 .Case("i", ARM_PROC::I) 5108 .Case("f", ARM_PROC::F) 5109 .Default(~0U); 5110 5111 // If some specific iflag is already set, it means that some letter is 5112 // present more than once, this is not acceptable. 5113 if (Flag == ~0U || (IFlags & Flag)) 5114 return MatchOperand_NoMatch; 5115 5116 IFlags |= Flag; 5117 } 5118 } 5119 5120 Parser.Lex(); // Eat identifier token. 5121 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 5122 return MatchOperand_Success; 5123 } 5124 5125 /// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 5126 OperandMatchResultTy 5127 ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) { 5128 MCAsmParser &Parser = getParser(); 5129 SMLoc S = Parser.getTok().getLoc(); 5130 const AsmToken &Tok = Parser.getTok(); 5131 5132 if (Tok.is(AsmToken::Integer)) { 5133 int64_t Val = Tok.getIntVal(); 5134 if (Val > 255 || Val < 0) { 5135 return MatchOperand_NoMatch; 5136 } 5137 unsigned SYSmvalue = Val & 0xFF; 5138 Parser.Lex(); 5139 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S)); 5140 return MatchOperand_Success; 5141 } 5142 5143 if (!Tok.is(AsmToken::Identifier)) 5144 return MatchOperand_NoMatch; 5145 StringRef Mask = Tok.getString(); 5146 5147 if (isMClass()) { 5148 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower()); 5149 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits())) 5150 return MatchOperand_NoMatch; 5151 5152 unsigned SYSmvalue = TheReg->Encoding & 0xFFF; 5153 5154 Parser.Lex(); // Eat identifier token. 5155 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S)); 5156 return MatchOperand_Success; 5157 } 5158 5159 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 5160 size_t Start = 0, Next = Mask.find('_'); 5161 StringRef Flags = ""; 5162 std::string SpecReg = Mask.slice(Start, Next).lower(); 5163 if (Next != StringRef::npos) 5164 Flags = Mask.slice(Next+1, Mask.size()); 5165 5166 // FlagsVal contains the complete mask: 5167 // 3-0: Mask 5168 // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 5169 unsigned FlagsVal = 0; 5170 5171 if (SpecReg == "apsr") { 5172 FlagsVal = StringSwitch<unsigned>(Flags) 5173 .Case("nzcvq", 0x8) // same as CPSR_f 5174 .Case("g", 0x4) // same as CPSR_s 5175 .Case("nzcvqg", 0xc) // same as CPSR_fs 5176 .Default(~0U); 5177 5178 if (FlagsVal == ~0U) { 5179 if (!Flags.empty()) 5180 return MatchOperand_NoMatch; 5181 else 5182 FlagsVal = 8; // No flag 5183 } 5184 } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 5185 // cpsr_all is an alias for cpsr_fc, as is plain cpsr. 5186 if (Flags == "all" || Flags == "") 5187 Flags = "fc"; 5188 for (int i = 0, e = Flags.size(); i != e; ++i) { 5189 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 5190 .Case("c", 1) 5191 .Case("x", 2) 5192 .Case("s", 4) 5193 .Case("f", 8) 5194 .Default(~0U); 5195 5196 // If some specific flag is already set, it means that some letter is 5197 // present more than once, this is not acceptable. 5198 if (Flag == ~0U || (FlagsVal & Flag)) 5199 return MatchOperand_NoMatch; 5200 FlagsVal |= Flag; 5201 } 5202 } else // No match for special register. 5203 return MatchOperand_NoMatch; 5204 5205 // Special register without flags is NOT equivalent to "fc" flags. 5206 // NOTE: This is a divergence from gas' behavior. Uncommenting the following 5207 // two lines would enable gas compatibility at the expense of breaking 5208 // round-tripping. 5209 // 5210 // if (!FlagsVal) 5211 // FlagsVal = 0x9; 5212 5213 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 5214 if (SpecReg == "spsr") 5215 FlagsVal |= 16; 5216 5217 Parser.Lex(); // Eat identifier token. 5218 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 5219 return MatchOperand_Success; 5220 } 5221 5222 /// parseBankedRegOperand - Try to parse a banked register (e.g. "lr_irq") for 5223 /// use in the MRS/MSR instructions added to support virtualization. 5224 OperandMatchResultTy 5225 ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) { 5226 MCAsmParser &Parser = getParser(); 5227 SMLoc S = Parser.getTok().getLoc(); 5228 const AsmToken &Tok = Parser.getTok(); 5229 if (!Tok.is(AsmToken::Identifier)) 5230 return MatchOperand_NoMatch; 5231 StringRef RegName = Tok.getString(); 5232 5233 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.lower()); 5234 if (!TheReg) 5235 return MatchOperand_NoMatch; 5236 unsigned Encoding = TheReg->Encoding; 5237 5238 Parser.Lex(); // Eat identifier token. 5239 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S)); 5240 return MatchOperand_Success; 5241 } 5242 5243 OperandMatchResultTy 5244 ARMAsmParser::parsePKHImm(OperandVector &Operands, StringRef Op, int Low, 5245 int High) { 5246 MCAsmParser &Parser = getParser(); 5247 const AsmToken &Tok = Parser.getTok(); 5248 if (Tok.isNot(AsmToken::Identifier)) { 5249 Error(Parser.getTok().getLoc(), Op + " operand expected."); 5250 return MatchOperand_ParseFail; 5251 } 5252 StringRef ShiftName = Tok.getString(); 5253 std::string LowerOp = Op.lower(); 5254 std::string UpperOp = Op.upper(); 5255 if (ShiftName != LowerOp && ShiftName != UpperOp) { 5256 Error(Parser.getTok().getLoc(), Op + " operand expected."); 5257 return MatchOperand_ParseFail; 5258 } 5259 Parser.Lex(); // Eat shift type token. 5260 5261 // There must be a '#' and a shift amount. 5262 if (Parser.getTok().isNot(AsmToken::Hash) && 5263 Parser.getTok().isNot(AsmToken::Dollar)) { 5264 Error(Parser.getTok().getLoc(), "'#' expected"); 5265 return MatchOperand_ParseFail; 5266 } 5267 Parser.Lex(); // Eat hash token. 5268 5269 const MCExpr *ShiftAmount; 5270 SMLoc Loc = Parser.getTok().getLoc(); 5271 SMLoc EndLoc; 5272 if (getParser().parseExpression(ShiftAmount, EndLoc)) { 5273 Error(Loc, "illegal expression"); 5274 return MatchOperand_ParseFail; 5275 } 5276 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 5277 if (!CE) { 5278 Error(Loc, "constant expression expected"); 5279 return MatchOperand_ParseFail; 5280 } 5281 int Val = CE->getValue(); 5282 if (Val < Low || Val > High) { 5283 Error(Loc, "immediate value out of range"); 5284 return MatchOperand_ParseFail; 5285 } 5286 5287 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc)); 5288 5289 return MatchOperand_Success; 5290 } 5291 5292 OperandMatchResultTy 5293 ARMAsmParser::parseSetEndImm(OperandVector &Operands) { 5294 MCAsmParser &Parser = getParser(); 5295 const AsmToken &Tok = Parser.getTok(); 5296 SMLoc S = Tok.getLoc(); 5297 if (Tok.isNot(AsmToken::Identifier)) { 5298 Error(S, "'be' or 'le' operand expected"); 5299 return MatchOperand_ParseFail; 5300 } 5301 int Val = StringSwitch<int>(Tok.getString().lower()) 5302 .Case("be", 1) 5303 .Case("le", 0) 5304 .Default(-1); 5305 Parser.Lex(); // Eat the token. 5306 5307 if (Val == -1) { 5308 Error(S, "'be' or 'le' operand expected"); 5309 return MatchOperand_ParseFail; 5310 } 5311 Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::create(Val, 5312 getContext()), 5313 S, Tok.getEndLoc())); 5314 return MatchOperand_Success; 5315 } 5316 5317 /// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 5318 /// instructions. Legal values are: 5319 /// lsl #n 'n' in [0,31] 5320 /// asr #n 'n' in [1,32] 5321 /// n == 32 encoded as n == 0. 5322 OperandMatchResultTy 5323 ARMAsmParser::parseShifterImm(OperandVector &Operands) { 5324 MCAsmParser &Parser = getParser(); 5325 const AsmToken &Tok = Parser.getTok(); 5326 SMLoc S = Tok.getLoc(); 5327 if (Tok.isNot(AsmToken::Identifier)) { 5328 Error(S, "shift operator 'asr' or 'lsl' expected"); 5329 return MatchOperand_ParseFail; 5330 } 5331 StringRef ShiftName = Tok.getString(); 5332 bool isASR; 5333 if (ShiftName == "lsl" || ShiftName == "LSL") 5334 isASR = false; 5335 else if (ShiftName == "asr" || ShiftName == "ASR") 5336 isASR = true; 5337 else { 5338 Error(S, "shift operator 'asr' or 'lsl' expected"); 5339 return MatchOperand_ParseFail; 5340 } 5341 Parser.Lex(); // Eat the operator. 5342 5343 // A '#' and a shift amount. 5344 if (Parser.getTok().isNot(AsmToken::Hash) && 5345 Parser.getTok().isNot(AsmToken::Dollar)) { 5346 Error(Parser.getTok().getLoc(), "'#' expected"); 5347 return MatchOperand_ParseFail; 5348 } 5349 Parser.Lex(); // Eat hash token. 5350 SMLoc ExLoc = Parser.getTok().getLoc(); 5351 5352 const MCExpr *ShiftAmount; 5353 SMLoc EndLoc; 5354 if (getParser().parseExpression(ShiftAmount, EndLoc)) { 5355 Error(ExLoc, "malformed shift expression"); 5356 return MatchOperand_ParseFail; 5357 } 5358 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 5359 if (!CE) { 5360 Error(ExLoc, "shift amount must be an immediate"); 5361 return MatchOperand_ParseFail; 5362 } 5363 5364 int64_t Val = CE->getValue(); 5365 if (isASR) { 5366 // Shift amount must be in [1,32] 5367 if (Val < 1 || Val > 32) { 5368 Error(ExLoc, "'asr' shift amount must be in range [1,32]"); 5369 return MatchOperand_ParseFail; 5370 } 5371 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 5372 if (isThumb() && Val == 32) { 5373 Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode"); 5374 return MatchOperand_ParseFail; 5375 } 5376 if (Val == 32) Val = 0; 5377 } else { 5378 // Shift amount must be in [1,32] 5379 if (Val < 0 || Val > 31) { 5380 Error(ExLoc, "'lsr' shift amount must be in range [0,31]"); 5381 return MatchOperand_ParseFail; 5382 } 5383 } 5384 5385 Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc)); 5386 5387 return MatchOperand_Success; 5388 } 5389 5390 /// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 5391 /// of instructions. Legal values are: 5392 /// ror #n 'n' in {0, 8, 16, 24} 5393 OperandMatchResultTy 5394 ARMAsmParser::parseRotImm(OperandVector &Operands) { 5395 MCAsmParser &Parser = getParser(); 5396 const AsmToken &Tok = Parser.getTok(); 5397 SMLoc S = Tok.getLoc(); 5398 if (Tok.isNot(AsmToken::Identifier)) 5399 return MatchOperand_NoMatch; 5400 StringRef ShiftName = Tok.getString(); 5401 if (ShiftName != "ror" && ShiftName != "ROR") 5402 return MatchOperand_NoMatch; 5403 Parser.Lex(); // Eat the operator. 5404 5405 // A '#' and a rotate amount. 5406 if (Parser.getTok().isNot(AsmToken::Hash) && 5407 Parser.getTok().isNot(AsmToken::Dollar)) { 5408 Error(Parser.getTok().getLoc(), "'#' expected"); 5409 return MatchOperand_ParseFail; 5410 } 5411 Parser.Lex(); // Eat hash token. 5412 SMLoc ExLoc = Parser.getTok().getLoc(); 5413 5414 const MCExpr *ShiftAmount; 5415 SMLoc EndLoc; 5416 if (getParser().parseExpression(ShiftAmount, EndLoc)) { 5417 Error(ExLoc, "malformed rotate expression"); 5418 return MatchOperand_ParseFail; 5419 } 5420 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 5421 if (!CE) { 5422 Error(ExLoc, "rotate amount must be an immediate"); 5423 return MatchOperand_ParseFail; 5424 } 5425 5426 int64_t Val = CE->getValue(); 5427 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 5428 // normally, zero is represented in asm by omitting the rotate operand 5429 // entirely. 5430 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 5431 Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24"); 5432 return MatchOperand_ParseFail; 5433 } 5434 5435 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc)); 5436 5437 return MatchOperand_Success; 5438 } 5439 5440 OperandMatchResultTy 5441 ARMAsmParser::parseModImm(OperandVector &Operands) { 5442 MCAsmParser &Parser = getParser(); 5443 MCAsmLexer &Lexer = getLexer(); 5444 int64_t Imm1, Imm2; 5445 5446 SMLoc S = Parser.getTok().getLoc(); 5447 5448 // 1) A mod_imm operand can appear in the place of a register name: 5449 // add r0, #mod_imm 5450 // add r0, r0, #mod_imm 5451 // to correctly handle the latter, we bail out as soon as we see an 5452 // identifier. 5453 // 5454 // 2) Similarly, we do not want to parse into complex operands: 5455 // mov r0, #mod_imm 5456 // mov r0, :lower16:(_foo) 5457 if (Parser.getTok().is(AsmToken::Identifier) || 5458 Parser.getTok().is(AsmToken::Colon)) 5459 return MatchOperand_NoMatch; 5460 5461 // Hash (dollar) is optional as per the ARMARM 5462 if (Parser.getTok().is(AsmToken::Hash) || 5463 Parser.getTok().is(AsmToken::Dollar)) { 5464 // Avoid parsing into complex operands (#:) 5465 if (Lexer.peekTok().is(AsmToken::Colon)) 5466 return MatchOperand_NoMatch; 5467 5468 // Eat the hash (dollar) 5469 Parser.Lex(); 5470 } 5471 5472 SMLoc Sx1, Ex1; 5473 Sx1 = Parser.getTok().getLoc(); 5474 const MCExpr *Imm1Exp; 5475 if (getParser().parseExpression(Imm1Exp, Ex1)) { 5476 Error(Sx1, "malformed expression"); 5477 return MatchOperand_ParseFail; 5478 } 5479 5480 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp); 5481 5482 if (CE) { 5483 // Immediate must fit within 32-bits 5484 Imm1 = CE->getValue(); 5485 int Enc = ARM_AM::getSOImmVal(Imm1); 5486 if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) { 5487 // We have a match! 5488 Operands.push_back(ARMOperand::CreateModImm((Enc & 0xFF), 5489 (Enc & 0xF00) >> 7, 5490 Sx1, Ex1)); 5491 return MatchOperand_Success; 5492 } 5493 5494 // We have parsed an immediate which is not for us, fallback to a plain 5495 // immediate. This can happen for instruction aliases. For an example, 5496 // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform 5497 // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite 5498 // instruction with a mod_imm operand. The alias is defined such that the 5499 // parser method is shared, that's why we have to do this here. 5500 if (Parser.getTok().is(AsmToken::EndOfStatement)) { 5501 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1)); 5502 return MatchOperand_Success; 5503 } 5504 } else { 5505 // Operands like #(l1 - l2) can only be evaluated at a later stage (via an 5506 // MCFixup). Fallback to a plain immediate. 5507 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1)); 5508 return MatchOperand_Success; 5509 } 5510 5511 // From this point onward, we expect the input to be a (#bits, #rot) pair 5512 if (Parser.getTok().isNot(AsmToken::Comma)) { 5513 Error(Sx1, "expected modified immediate operand: #[0, 255], #even[0-30]"); 5514 return MatchOperand_ParseFail; 5515 } 5516 5517 if (Imm1 & ~0xFF) { 5518 Error(Sx1, "immediate operand must a number in the range [0, 255]"); 5519 return MatchOperand_ParseFail; 5520 } 5521 5522 // Eat the comma 5523 Parser.Lex(); 5524 5525 // Repeat for #rot 5526 SMLoc Sx2, Ex2; 5527 Sx2 = Parser.getTok().getLoc(); 5528 5529 // Eat the optional hash (dollar) 5530 if (Parser.getTok().is(AsmToken::Hash) || 5531 Parser.getTok().is(AsmToken::Dollar)) 5532 Parser.Lex(); 5533 5534 const MCExpr *Imm2Exp; 5535 if (getParser().parseExpression(Imm2Exp, Ex2)) { 5536 Error(Sx2, "malformed expression"); 5537 return MatchOperand_ParseFail; 5538 } 5539 5540 CE = dyn_cast<MCConstantExpr>(Imm2Exp); 5541 5542 if (CE) { 5543 Imm2 = CE->getValue(); 5544 if (!(Imm2 & ~0x1E)) { 5545 // We have a match! 5546 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2)); 5547 return MatchOperand_Success; 5548 } 5549 Error(Sx2, "immediate operand must an even number in the range [0, 30]"); 5550 return MatchOperand_ParseFail; 5551 } else { 5552 Error(Sx2, "constant expression expected"); 5553 return MatchOperand_ParseFail; 5554 } 5555 } 5556 5557 OperandMatchResultTy 5558 ARMAsmParser::parseBitfield(OperandVector &Operands) { 5559 MCAsmParser &Parser = getParser(); 5560 SMLoc S = Parser.getTok().getLoc(); 5561 // The bitfield descriptor is really two operands, the LSB and the width. 5562 if (Parser.getTok().isNot(AsmToken::Hash) && 5563 Parser.getTok().isNot(AsmToken::Dollar)) { 5564 Error(Parser.getTok().getLoc(), "'#' expected"); 5565 return MatchOperand_ParseFail; 5566 } 5567 Parser.Lex(); // Eat hash token. 5568 5569 const MCExpr *LSBExpr; 5570 SMLoc E = Parser.getTok().getLoc(); 5571 if (getParser().parseExpression(LSBExpr)) { 5572 Error(E, "malformed immediate expression"); 5573 return MatchOperand_ParseFail; 5574 } 5575 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 5576 if (!CE) { 5577 Error(E, "'lsb' operand must be an immediate"); 5578 return MatchOperand_ParseFail; 5579 } 5580 5581 int64_t LSB = CE->getValue(); 5582 // The LSB must be in the range [0,31] 5583 if (LSB < 0 || LSB > 31) { 5584 Error(E, "'lsb' operand must be in the range [0,31]"); 5585 return MatchOperand_ParseFail; 5586 } 5587 E = Parser.getTok().getLoc(); 5588 5589 // Expect another immediate operand. 5590 if (Parser.getTok().isNot(AsmToken::Comma)) { 5591 Error(Parser.getTok().getLoc(), "too few operands"); 5592 return MatchOperand_ParseFail; 5593 } 5594 Parser.Lex(); // Eat hash token. 5595 if (Parser.getTok().isNot(AsmToken::Hash) && 5596 Parser.getTok().isNot(AsmToken::Dollar)) { 5597 Error(Parser.getTok().getLoc(), "'#' expected"); 5598 return MatchOperand_ParseFail; 5599 } 5600 Parser.Lex(); // Eat hash token. 5601 5602 const MCExpr *WidthExpr; 5603 SMLoc EndLoc; 5604 if (getParser().parseExpression(WidthExpr, EndLoc)) { 5605 Error(E, "malformed immediate expression"); 5606 return MatchOperand_ParseFail; 5607 } 5608 CE = dyn_cast<MCConstantExpr>(WidthExpr); 5609 if (!CE) { 5610 Error(E, "'width' operand must be an immediate"); 5611 return MatchOperand_ParseFail; 5612 } 5613 5614 int64_t Width = CE->getValue(); 5615 // The LSB must be in the range [1,32-lsb] 5616 if (Width < 1 || Width > 32 - LSB) { 5617 Error(E, "'width' operand must be in the range [1,32-lsb]"); 5618 return MatchOperand_ParseFail; 5619 } 5620 5621 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc)); 5622 5623 return MatchOperand_Success; 5624 } 5625 5626 OperandMatchResultTy 5627 ARMAsmParser::parsePostIdxReg(OperandVector &Operands) { 5628 // Check for a post-index addressing register operand. Specifically: 5629 // postidx_reg := '+' register {, shift} 5630 // | '-' register {, shift} 5631 // | register {, shift} 5632 5633 // This method must return MatchOperand_NoMatch without consuming any tokens 5634 // in the case where there is no match, as other alternatives take other 5635 // parse methods. 5636 MCAsmParser &Parser = getParser(); 5637 AsmToken Tok = Parser.getTok(); 5638 SMLoc S = Tok.getLoc(); 5639 bool haveEaten = false; 5640 bool isAdd = true; 5641 if (Tok.is(AsmToken::Plus)) { 5642 Parser.Lex(); // Eat the '+' token. 5643 haveEaten = true; 5644 } else if (Tok.is(AsmToken::Minus)) { 5645 Parser.Lex(); // Eat the '-' token. 5646 isAdd = false; 5647 haveEaten = true; 5648 } 5649 5650 SMLoc E = Parser.getTok().getEndLoc(); 5651 int Reg = tryParseRegister(); 5652 if (Reg == -1) { 5653 if (!haveEaten) 5654 return MatchOperand_NoMatch; 5655 Error(Parser.getTok().getLoc(), "register expected"); 5656 return MatchOperand_ParseFail; 5657 } 5658 5659 ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 5660 unsigned ShiftImm = 0; 5661 if (Parser.getTok().is(AsmToken::Comma)) { 5662 Parser.Lex(); // Eat the ','. 5663 if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 5664 return MatchOperand_ParseFail; 5665 5666 // FIXME: Only approximates end...may include intervening whitespace. 5667 E = Parser.getTok().getLoc(); 5668 } 5669 5670 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 5671 ShiftImm, S, E)); 5672 5673 return MatchOperand_Success; 5674 } 5675 5676 OperandMatchResultTy 5677 ARMAsmParser::parseAM3Offset(OperandVector &Operands) { 5678 // Check for a post-index addressing register operand. Specifically: 5679 // am3offset := '+' register 5680 // | '-' register 5681 // | register 5682 // | # imm 5683 // | # + imm 5684 // | # - imm 5685 5686 // This method must return MatchOperand_NoMatch without consuming any tokens 5687 // in the case where there is no match, as other alternatives take other 5688 // parse methods. 5689 MCAsmParser &Parser = getParser(); 5690 AsmToken Tok = Parser.getTok(); 5691 SMLoc S = Tok.getLoc(); 5692 5693 // Do immediates first, as we always parse those if we have a '#'. 5694 if (Parser.getTok().is(AsmToken::Hash) || 5695 Parser.getTok().is(AsmToken::Dollar)) { 5696 Parser.Lex(); // Eat '#' or '$'. 5697 // Explicitly look for a '-', as we need to encode negative zero 5698 // differently. 5699 bool isNegative = Parser.getTok().is(AsmToken::Minus); 5700 const MCExpr *Offset; 5701 SMLoc E; 5702 if (getParser().parseExpression(Offset, E)) 5703 return MatchOperand_ParseFail; 5704 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 5705 if (!CE) { 5706 Error(S, "constant expression expected"); 5707 return MatchOperand_ParseFail; 5708 } 5709 // Negative zero is encoded as the flag value 5710 // std::numeric_limits<int32_t>::min(). 5711 int32_t Val = CE->getValue(); 5712 if (isNegative && Val == 0) 5713 Val = std::numeric_limits<int32_t>::min(); 5714 5715 Operands.push_back( 5716 ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S, E)); 5717 5718 return MatchOperand_Success; 5719 } 5720 5721 bool haveEaten = false; 5722 bool isAdd = true; 5723 if (Tok.is(AsmToken::Plus)) { 5724 Parser.Lex(); // Eat the '+' token. 5725 haveEaten = true; 5726 } else if (Tok.is(AsmToken::Minus)) { 5727 Parser.Lex(); // Eat the '-' token. 5728 isAdd = false; 5729 haveEaten = true; 5730 } 5731 5732 Tok = Parser.getTok(); 5733 int Reg = tryParseRegister(); 5734 if (Reg == -1) { 5735 if (!haveEaten) 5736 return MatchOperand_NoMatch; 5737 Error(Tok.getLoc(), "register expected"); 5738 return MatchOperand_ParseFail; 5739 } 5740 5741 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 5742 0, S, Tok.getEndLoc())); 5743 5744 return MatchOperand_Success; 5745 } 5746 5747 /// Convert parsed operands to MCInst. Needed here because this instruction 5748 /// only has two register operands, but multiplication is commutative so 5749 /// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN". 5750 void ARMAsmParser::cvtThumbMultiply(MCInst &Inst, 5751 const OperandVector &Operands) { 5752 ((ARMOperand &)*Operands[3]).addRegOperands(Inst, 1); 5753 ((ARMOperand &)*Operands[1]).addCCOutOperands(Inst, 1); 5754 // If we have a three-operand form, make sure to set Rn to be the operand 5755 // that isn't the same as Rd. 5756 unsigned RegOp = 4; 5757 if (Operands.size() == 6 && 5758 ((ARMOperand &)*Operands[4]).getReg() == 5759 ((ARMOperand &)*Operands[3]).getReg()) 5760 RegOp = 5; 5761 ((ARMOperand &)*Operands[RegOp]).addRegOperands(Inst, 1); 5762 Inst.addOperand(Inst.getOperand(0)); 5763 ((ARMOperand &)*Operands[2]).addCondCodeOperands(Inst, 2); 5764 } 5765 5766 void ARMAsmParser::cvtThumbBranches(MCInst &Inst, 5767 const OperandVector &Operands) { 5768 int CondOp = -1, ImmOp = -1; 5769 switch(Inst.getOpcode()) { 5770 case ARM::tB: 5771 case ARM::tBcc: CondOp = 1; ImmOp = 2; break; 5772 5773 case ARM::t2B: 5774 case ARM::t2Bcc: CondOp = 1; ImmOp = 3; break; 5775 5776 default: llvm_unreachable("Unexpected instruction in cvtThumbBranches"); 5777 } 5778 // first decide whether or not the branch should be conditional 5779 // by looking at it's location relative to an IT block 5780 if(inITBlock()) { 5781 // inside an IT block we cannot have any conditional branches. any 5782 // such instructions needs to be converted to unconditional form 5783 switch(Inst.getOpcode()) { 5784 case ARM::tBcc: Inst.setOpcode(ARM::tB); break; 5785 case ARM::t2Bcc: Inst.setOpcode(ARM::t2B); break; 5786 } 5787 } else { 5788 // outside IT blocks we can only have unconditional branches with AL 5789 // condition code or conditional branches with non-AL condition code 5790 unsigned Cond = static_cast<ARMOperand &>(*Operands[CondOp]).getCondCode(); 5791 switch(Inst.getOpcode()) { 5792 case ARM::tB: 5793 case ARM::tBcc: 5794 Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc); 5795 break; 5796 case ARM::t2B: 5797 case ARM::t2Bcc: 5798 Inst.setOpcode(Cond == ARMCC::AL ? ARM::t2B : ARM::t2Bcc); 5799 break; 5800 } 5801 } 5802 5803 // now decide on encoding size based on branch target range 5804 switch(Inst.getOpcode()) { 5805 // classify tB as either t2B or t1B based on range of immediate operand 5806 case ARM::tB: { 5807 ARMOperand &op = static_cast<ARMOperand &>(*Operands[ImmOp]); 5808 if (!op.isSignedOffset<11, 1>() && isThumb() && hasV8MBaseline()) 5809 Inst.setOpcode(ARM::t2B); 5810 break; 5811 } 5812 // classify tBcc as either t2Bcc or t1Bcc based on range of immediate operand 5813 case ARM::tBcc: { 5814 ARMOperand &op = static_cast<ARMOperand &>(*Operands[ImmOp]); 5815 if (!op.isSignedOffset<8, 1>() && isThumb() && hasV8MBaseline()) 5816 Inst.setOpcode(ARM::t2Bcc); 5817 break; 5818 } 5819 } 5820 ((ARMOperand &)*Operands[ImmOp]).addImmOperands(Inst, 1); 5821 ((ARMOperand &)*Operands[CondOp]).addCondCodeOperands(Inst, 2); 5822 } 5823 5824 void ARMAsmParser::cvtMVEVMOVQtoDReg( 5825 MCInst &Inst, const OperandVector &Operands) { 5826 5827 // mnemonic, condition code, Rt, Rt2, Qd, idx, Qd again, idx2 5828 assert(Operands.size() == 8); 5829 5830 ((ARMOperand &)*Operands[2]).addRegOperands(Inst, 1); // Rt 5831 ((ARMOperand &)*Operands[3]).addRegOperands(Inst, 1); // Rt2 5832 ((ARMOperand &)*Operands[4]).addRegOperands(Inst, 1); // Qd 5833 ((ARMOperand &)*Operands[5]).addMVEPairVectorIndexOperands(Inst, 1); // idx 5834 // skip second copy of Qd in Operands[6] 5835 ((ARMOperand &)*Operands[7]).addMVEPairVectorIndexOperands(Inst, 1); // idx2 5836 ((ARMOperand &)*Operands[1]).addCondCodeOperands(Inst, 2); // condition code 5837 } 5838 5839 /// Parse an ARM memory expression, return false if successful else return true 5840 /// or an error. The first token must be a '[' when called. 5841 bool ARMAsmParser::parseMemory(OperandVector &Operands) { 5842 MCAsmParser &Parser = getParser(); 5843 SMLoc S, E; 5844 if (Parser.getTok().isNot(AsmToken::LBrac)) 5845 return TokError("Token is not a Left Bracket"); 5846 S = Parser.getTok().getLoc(); 5847 Parser.Lex(); // Eat left bracket token. 5848 5849 const AsmToken &BaseRegTok = Parser.getTok(); 5850 int BaseRegNum = tryParseRegister(); 5851 if (BaseRegNum == -1) 5852 return Error(BaseRegTok.getLoc(), "register expected"); 5853 5854 // The next token must either be a comma, a colon or a closing bracket. 5855 const AsmToken &Tok = Parser.getTok(); 5856 if (!Tok.is(AsmToken::Colon) && !Tok.is(AsmToken::Comma) && 5857 !Tok.is(AsmToken::RBrac)) 5858 return Error(Tok.getLoc(), "malformed memory operand"); 5859 5860 if (Tok.is(AsmToken::RBrac)) { 5861 E = Tok.getEndLoc(); 5862 Parser.Lex(); // Eat right bracket token. 5863 5864 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, 0, 5865 ARM_AM::no_shift, 0, 0, false, 5866 S, E)); 5867 5868 // If there's a pre-indexing writeback marker, '!', just add it as a token 5869 // operand. It's rather odd, but syntactically valid. 5870 if (Parser.getTok().is(AsmToken::Exclaim)) { 5871 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 5872 Parser.Lex(); // Eat the '!'. 5873 } 5874 5875 return false; 5876 } 5877 5878 assert((Tok.is(AsmToken::Colon) || Tok.is(AsmToken::Comma)) && 5879 "Lost colon or comma in memory operand?!"); 5880 if (Tok.is(AsmToken::Comma)) { 5881 Parser.Lex(); // Eat the comma. 5882 } 5883 5884 // If we have a ':', it's an alignment specifier. 5885 if (Parser.getTok().is(AsmToken::Colon)) { 5886 Parser.Lex(); // Eat the ':'. 5887 E = Parser.getTok().getLoc(); 5888 SMLoc AlignmentLoc = Tok.getLoc(); 5889 5890 const MCExpr *Expr; 5891 if (getParser().parseExpression(Expr)) 5892 return true; 5893 5894 // The expression has to be a constant. Memory references with relocations 5895 // don't come through here, as they use the <label> forms of the relevant 5896 // instructions. 5897 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 5898 if (!CE) 5899 return Error (E, "constant expression expected"); 5900 5901 unsigned Align = 0; 5902 switch (CE->getValue()) { 5903 default: 5904 return Error(E, 5905 "alignment specifier must be 16, 32, 64, 128, or 256 bits"); 5906 case 16: Align = 2; break; 5907 case 32: Align = 4; break; 5908 case 64: Align = 8; break; 5909 case 128: Align = 16; break; 5910 case 256: Align = 32; break; 5911 } 5912 5913 // Now we should have the closing ']' 5914 if (Parser.getTok().isNot(AsmToken::RBrac)) 5915 return Error(Parser.getTok().getLoc(), "']' expected"); 5916 E = Parser.getTok().getEndLoc(); 5917 Parser.Lex(); // Eat right bracket token. 5918 5919 // Don't worry about range checking the value here. That's handled by 5920 // the is*() predicates. 5921 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, 0, 5922 ARM_AM::no_shift, 0, Align, 5923 false, S, E, AlignmentLoc)); 5924 5925 // If there's a pre-indexing writeback marker, '!', just add it as a token 5926 // operand. 5927 if (Parser.getTok().is(AsmToken::Exclaim)) { 5928 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 5929 Parser.Lex(); // Eat the '!'. 5930 } 5931 5932 return false; 5933 } 5934 5935 // If we have a '#' or '$', it's an immediate offset, else assume it's a 5936 // register offset. Be friendly and also accept a plain integer or expression 5937 // (without a leading hash) for gas compatibility. 5938 if (Parser.getTok().is(AsmToken::Hash) || 5939 Parser.getTok().is(AsmToken::Dollar) || 5940 Parser.getTok().is(AsmToken::LParen) || 5941 Parser.getTok().is(AsmToken::Integer)) { 5942 if (Parser.getTok().is(AsmToken::Hash) || 5943 Parser.getTok().is(AsmToken::Dollar)) 5944 Parser.Lex(); // Eat '#' or '$' 5945 E = Parser.getTok().getLoc(); 5946 5947 bool isNegative = getParser().getTok().is(AsmToken::Minus); 5948 const MCExpr *Offset, *AdjustedOffset; 5949 if (getParser().parseExpression(Offset)) 5950 return true; 5951 5952 if (const auto *CE = dyn_cast<MCConstantExpr>(Offset)) { 5953 // If the constant was #-0, represent it as 5954 // std::numeric_limits<int32_t>::min(). 5955 int32_t Val = CE->getValue(); 5956 if (isNegative && Val == 0) 5957 CE = MCConstantExpr::create(std::numeric_limits<int32_t>::min(), 5958 getContext()); 5959 // Don't worry about range checking the value here. That's handled by 5960 // the is*() predicates. 5961 AdjustedOffset = CE; 5962 } else 5963 AdjustedOffset = Offset; 5964 Operands.push_back(ARMOperand::CreateMem( 5965 BaseRegNum, AdjustedOffset, 0, ARM_AM::no_shift, 0, 0, false, S, E)); 5966 5967 // Now we should have the closing ']' 5968 if (Parser.getTok().isNot(AsmToken::RBrac)) 5969 return Error(Parser.getTok().getLoc(), "']' expected"); 5970 E = Parser.getTok().getEndLoc(); 5971 Parser.Lex(); // Eat right bracket token. 5972 5973 // If there's a pre-indexing writeback marker, '!', just add it as a token 5974 // operand. 5975 if (Parser.getTok().is(AsmToken::Exclaim)) { 5976 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 5977 Parser.Lex(); // Eat the '!'. 5978 } 5979 5980 return false; 5981 } 5982 5983 // The register offset is optionally preceded by a '+' or '-' 5984 bool isNegative = false; 5985 if (Parser.getTok().is(AsmToken::Minus)) { 5986 isNegative = true; 5987 Parser.Lex(); // Eat the '-'. 5988 } else if (Parser.getTok().is(AsmToken::Plus)) { 5989 // Nothing to do. 5990 Parser.Lex(); // Eat the '+'. 5991 } 5992 5993 E = Parser.getTok().getLoc(); 5994 int OffsetRegNum = tryParseRegister(); 5995 if (OffsetRegNum == -1) 5996 return Error(E, "register expected"); 5997 5998 // If there's a shift operator, handle it. 5999 ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 6000 unsigned ShiftImm = 0; 6001 if (Parser.getTok().is(AsmToken::Comma)) { 6002 Parser.Lex(); // Eat the ','. 6003 if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 6004 return true; 6005 } 6006 6007 // Now we should have the closing ']' 6008 if (Parser.getTok().isNot(AsmToken::RBrac)) 6009 return Error(Parser.getTok().getLoc(), "']' expected"); 6010 E = Parser.getTok().getEndLoc(); 6011 Parser.Lex(); // Eat right bracket token. 6012 6013 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, OffsetRegNum, 6014 ShiftType, ShiftImm, 0, isNegative, 6015 S, E)); 6016 6017 // If there's a pre-indexing writeback marker, '!', just add it as a token 6018 // operand. 6019 if (Parser.getTok().is(AsmToken::Exclaim)) { 6020 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 6021 Parser.Lex(); // Eat the '!'. 6022 } 6023 6024 return false; 6025 } 6026 6027 /// parseMemRegOffsetShift - one of these two: 6028 /// ( lsl | lsr | asr | ror ) , # shift_amount 6029 /// rrx 6030 /// return true if it parses a shift otherwise it returns false. 6031 bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 6032 unsigned &Amount) { 6033 MCAsmParser &Parser = getParser(); 6034 SMLoc Loc = Parser.getTok().getLoc(); 6035 const AsmToken &Tok = Parser.getTok(); 6036 if (Tok.isNot(AsmToken::Identifier)) 6037 return Error(Loc, "illegal shift operator"); 6038 StringRef ShiftName = Tok.getString(); 6039 if (ShiftName == "lsl" || ShiftName == "LSL" || 6040 ShiftName == "asl" || ShiftName == "ASL") 6041 St = ARM_AM::lsl; 6042 else if (ShiftName == "lsr" || ShiftName == "LSR") 6043 St = ARM_AM::lsr; 6044 else if (ShiftName == "asr" || ShiftName == "ASR") 6045 St = ARM_AM::asr; 6046 else if (ShiftName == "ror" || ShiftName == "ROR") 6047 St = ARM_AM::ror; 6048 else if (ShiftName == "rrx" || ShiftName == "RRX") 6049 St = ARM_AM::rrx; 6050 else if (ShiftName == "uxtw" || ShiftName == "UXTW") 6051 St = ARM_AM::uxtw; 6052 else 6053 return Error(Loc, "illegal shift operator"); 6054 Parser.Lex(); // Eat shift type token. 6055 6056 // rrx stands alone. 6057 Amount = 0; 6058 if (St != ARM_AM::rrx) { 6059 Loc = Parser.getTok().getLoc(); 6060 // A '#' and a shift amount. 6061 const AsmToken &HashTok = Parser.getTok(); 6062 if (HashTok.isNot(AsmToken::Hash) && 6063 HashTok.isNot(AsmToken::Dollar)) 6064 return Error(HashTok.getLoc(), "'#' expected"); 6065 Parser.Lex(); // Eat hash token. 6066 6067 const MCExpr *Expr; 6068 if (getParser().parseExpression(Expr)) 6069 return true; 6070 // Range check the immediate. 6071 // lsl, ror: 0 <= imm <= 31 6072 // lsr, asr: 0 <= imm <= 32 6073 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 6074 if (!CE) 6075 return Error(Loc, "shift amount must be an immediate"); 6076 int64_t Imm = CE->getValue(); 6077 if (Imm < 0 || 6078 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 6079 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 6080 return Error(Loc, "immediate shift value out of range"); 6081 // If <ShiftTy> #0, turn it into a no_shift. 6082 if (Imm == 0) 6083 St = ARM_AM::lsl; 6084 // For consistency, treat lsr #32 and asr #32 as having immediate value 0. 6085 if (Imm == 32) 6086 Imm = 0; 6087 Amount = Imm; 6088 } 6089 6090 return false; 6091 } 6092 6093 /// parseFPImm - A floating point immediate expression operand. 6094 OperandMatchResultTy 6095 ARMAsmParser::parseFPImm(OperandVector &Operands) { 6096 MCAsmParser &Parser = getParser(); 6097 // Anything that can accept a floating point constant as an operand 6098 // needs to go through here, as the regular parseExpression is 6099 // integer only. 6100 // 6101 // This routine still creates a generic Immediate operand, containing 6102 // a bitcast of the 64-bit floating point value. The various operands 6103 // that accept floats can check whether the value is valid for them 6104 // via the standard is*() predicates. 6105 6106 SMLoc S = Parser.getTok().getLoc(); 6107 6108 if (Parser.getTok().isNot(AsmToken::Hash) && 6109 Parser.getTok().isNot(AsmToken::Dollar)) 6110 return MatchOperand_NoMatch; 6111 6112 // Disambiguate the VMOV forms that can accept an FP immediate. 6113 // vmov.f32 <sreg>, #imm 6114 // vmov.f64 <dreg>, #imm 6115 // vmov.f32 <dreg>, #imm @ vector f32x2 6116 // vmov.f32 <qreg>, #imm @ vector f32x4 6117 // 6118 // There are also the NEON VMOV instructions which expect an 6119 // integer constant. Make sure we don't try to parse an FPImm 6120 // for these: 6121 // vmov.i{8|16|32|64} <dreg|qreg>, #imm 6122 ARMOperand &TyOp = static_cast<ARMOperand &>(*Operands[2]); 6123 bool isVmovf = TyOp.isToken() && 6124 (TyOp.getToken() == ".f32" || TyOp.getToken() == ".f64" || 6125 TyOp.getToken() == ".f16"); 6126 ARMOperand &Mnemonic = static_cast<ARMOperand &>(*Operands[0]); 6127 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() == "fconstd" || 6128 Mnemonic.getToken() == "fconsts"); 6129 if (!(isVmovf || isFconst)) 6130 return MatchOperand_NoMatch; 6131 6132 Parser.Lex(); // Eat '#' or '$'. 6133 6134 // Handle negation, as that still comes through as a separate token. 6135 bool isNegative = false; 6136 if (Parser.getTok().is(AsmToken::Minus)) { 6137 isNegative = true; 6138 Parser.Lex(); 6139 } 6140 const AsmToken &Tok = Parser.getTok(); 6141 SMLoc Loc = Tok.getLoc(); 6142 if (Tok.is(AsmToken::Real) && isVmovf) { 6143 APFloat RealVal(APFloat::IEEEsingle(), Tok.getString()); 6144 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 6145 // If we had a '-' in front, toggle the sign bit. 6146 IntVal ^= (uint64_t)isNegative << 31; 6147 Parser.Lex(); // Eat the token. 6148 Operands.push_back(ARMOperand::CreateImm( 6149 MCConstantExpr::create(IntVal, getContext()), 6150 S, Parser.getTok().getLoc())); 6151 return MatchOperand_Success; 6152 } 6153 // Also handle plain integers. Instructions which allow floating point 6154 // immediates also allow a raw encoded 8-bit value. 6155 if (Tok.is(AsmToken::Integer) && isFconst) { 6156 int64_t Val = Tok.getIntVal(); 6157 Parser.Lex(); // Eat the token. 6158 if (Val > 255 || Val < 0) { 6159 Error(Loc, "encoded floating point value out of range"); 6160 return MatchOperand_ParseFail; 6161 } 6162 float RealVal = ARM_AM::getFPImmFloat(Val); 6163 Val = APFloat(RealVal).bitcastToAPInt().getZExtValue(); 6164 6165 Operands.push_back(ARMOperand::CreateImm( 6166 MCConstantExpr::create(Val, getContext()), S, 6167 Parser.getTok().getLoc())); 6168 return MatchOperand_Success; 6169 } 6170 6171 Error(Loc, "invalid floating point immediate"); 6172 return MatchOperand_ParseFail; 6173 } 6174 6175 /// Parse a arm instruction operand. For now this parses the operand regardless 6176 /// of the mnemonic. 6177 bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 6178 MCAsmParser &Parser = getParser(); 6179 SMLoc S, E; 6180 6181 // Check if the current operand has a custom associated parser, if so, try to 6182 // custom parse the operand, or fallback to the general approach. 6183 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 6184 if (ResTy == MatchOperand_Success) 6185 return false; 6186 // If there wasn't a custom match, try the generic matcher below. Otherwise, 6187 // there was a match, but an error occurred, in which case, just return that 6188 // the operand parsing failed. 6189 if (ResTy == MatchOperand_ParseFail) 6190 return true; 6191 6192 switch (getLexer().getKind()) { 6193 default: 6194 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 6195 return true; 6196 case AsmToken::Identifier: { 6197 // If we've seen a branch mnemonic, the next operand must be a label. This 6198 // is true even if the label is a register name. So "br r1" means branch to 6199 // label "r1". 6200 bool ExpectLabel = Mnemonic == "b" || Mnemonic == "bl"; 6201 if (!ExpectLabel) { 6202 if (!tryParseRegisterWithWriteBack(Operands)) 6203 return false; 6204 int Res = tryParseShiftRegister(Operands); 6205 if (Res == 0) // success 6206 return false; 6207 else if (Res == -1) // irrecoverable error 6208 return true; 6209 // If this is VMRS, check for the apsr_nzcv operand. 6210 if (Mnemonic == "vmrs" && 6211 Parser.getTok().getString().equals_insensitive("apsr_nzcv")) { 6212 S = Parser.getTok().getLoc(); 6213 Parser.Lex(); 6214 Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S)); 6215 return false; 6216 } 6217 } 6218 6219 // Fall though for the Identifier case that is not a register or a 6220 // special name. 6221 LLVM_FALLTHROUGH; 6222 } 6223 case AsmToken::LParen: // parenthesized expressions like (_strcmp-4) 6224 case AsmToken::Integer: // things like 1f and 2b as a branch targets 6225 case AsmToken::String: // quoted label names. 6226 case AsmToken::Dot: { // . as a branch target 6227 // This was not a register so parse other operands that start with an 6228 // identifier (like labels) as expressions and create them as immediates. 6229 const MCExpr *IdVal; 6230 S = Parser.getTok().getLoc(); 6231 if (getParser().parseExpression(IdVal)) 6232 return true; 6233 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6234 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 6235 return false; 6236 } 6237 case AsmToken::LBrac: 6238 return parseMemory(Operands); 6239 case AsmToken::LCurly: 6240 return parseRegisterList(Operands, !Mnemonic.startswith("clr")); 6241 case AsmToken::Dollar: 6242 case AsmToken::Hash: { 6243 // #42 -> immediate 6244 // $ 42 -> immediate 6245 // $foo -> symbol name 6246 // $42 -> symbol name 6247 S = Parser.getTok().getLoc(); 6248 6249 // Favor the interpretation of $-prefixed operands as symbol names. 6250 // Cases where immediates are explicitly expected are handled by their 6251 // specific ParseMethod implementations. 6252 auto AdjacentToken = getLexer().peekTok(/*ShouldSkipSpace=*/false); 6253 bool ExpectIdentifier = Parser.getTok().is(AsmToken::Dollar) && 6254 (AdjacentToken.is(AsmToken::Identifier) || 6255 AdjacentToken.is(AsmToken::Integer)); 6256 if (!ExpectIdentifier) { 6257 // Token is not part of identifier. Drop leading $ or # before parsing 6258 // expression. 6259 Parser.Lex(); 6260 } 6261 6262 if (Parser.getTok().isNot(AsmToken::Colon)) { 6263 bool IsNegative = Parser.getTok().is(AsmToken::Minus); 6264 const MCExpr *ImmVal; 6265 if (getParser().parseExpression(ImmVal)) 6266 return true; 6267 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 6268 if (CE) { 6269 int32_t Val = CE->getValue(); 6270 if (IsNegative && Val == 0) 6271 ImmVal = MCConstantExpr::create(std::numeric_limits<int32_t>::min(), 6272 getContext()); 6273 } 6274 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6275 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 6276 6277 // There can be a trailing '!' on operands that we want as a separate 6278 // '!' Token operand. Handle that here. For example, the compatibility 6279 // alias for 'srsdb sp!, #imm' is 'srsdb #imm!'. 6280 if (Parser.getTok().is(AsmToken::Exclaim)) { 6281 Operands.push_back(ARMOperand::CreateToken(Parser.getTok().getString(), 6282 Parser.getTok().getLoc())); 6283 Parser.Lex(); // Eat exclaim token 6284 } 6285 return false; 6286 } 6287 // w/ a ':' after the '#', it's just like a plain ':'. 6288 LLVM_FALLTHROUGH; 6289 } 6290 case AsmToken::Colon: { 6291 S = Parser.getTok().getLoc(); 6292 // ":lower16:" and ":upper16:" expression prefixes 6293 // FIXME: Check it's an expression prefix, 6294 // e.g. (FOO - :lower16:BAR) isn't legal. 6295 ARMMCExpr::VariantKind RefKind; 6296 if (parsePrefix(RefKind)) 6297 return true; 6298 6299 const MCExpr *SubExprVal; 6300 if (getParser().parseExpression(SubExprVal)) 6301 return true; 6302 6303 const MCExpr *ExprVal = ARMMCExpr::create(RefKind, SubExprVal, 6304 getContext()); 6305 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6306 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 6307 return false; 6308 } 6309 case AsmToken::Equal: { 6310 S = Parser.getTok().getLoc(); 6311 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val) 6312 return Error(S, "unexpected token in operand"); 6313 Parser.Lex(); // Eat '=' 6314 const MCExpr *SubExprVal; 6315 if (getParser().parseExpression(SubExprVal)) 6316 return true; 6317 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6318 6319 // execute-only: we assume that assembly programmers know what they are 6320 // doing and allow literal pool creation here 6321 Operands.push_back(ARMOperand::CreateConstantPoolImm(SubExprVal, S, E)); 6322 return false; 6323 } 6324 } 6325 } 6326 6327 // parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 6328 // :lower16: and :upper16:. 6329 bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 6330 MCAsmParser &Parser = getParser(); 6331 RefKind = ARMMCExpr::VK_ARM_None; 6332 6333 // consume an optional '#' (GNU compatibility) 6334 if (getLexer().is(AsmToken::Hash)) 6335 Parser.Lex(); 6336 6337 // :lower16: and :upper16: modifiers 6338 assert(getLexer().is(AsmToken::Colon) && "expected a :"); 6339 Parser.Lex(); // Eat ':' 6340 6341 if (getLexer().isNot(AsmToken::Identifier)) { 6342 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 6343 return true; 6344 } 6345 6346 enum { 6347 COFF = (1 << MCContext::IsCOFF), 6348 ELF = (1 << MCContext::IsELF), 6349 MACHO = (1 << MCContext::IsMachO), 6350 WASM = (1 << MCContext::IsWasm), 6351 }; 6352 static const struct PrefixEntry { 6353 const char *Spelling; 6354 ARMMCExpr::VariantKind VariantKind; 6355 uint8_t SupportedFormats; 6356 } PrefixEntries[] = { 6357 { "lower16", ARMMCExpr::VK_ARM_LO16, COFF | ELF | MACHO }, 6358 { "upper16", ARMMCExpr::VK_ARM_HI16, COFF | ELF | MACHO }, 6359 }; 6360 6361 StringRef IDVal = Parser.getTok().getIdentifier(); 6362 6363 const auto &Prefix = 6364 llvm::find_if(PrefixEntries, [&IDVal](const PrefixEntry &PE) { 6365 return PE.Spelling == IDVal; 6366 }); 6367 if (Prefix == std::end(PrefixEntries)) { 6368 Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 6369 return true; 6370 } 6371 6372 uint8_t CurrentFormat; 6373 switch (getContext().getObjectFileType()) { 6374 case MCContext::IsMachO: 6375 CurrentFormat = MACHO; 6376 break; 6377 case MCContext::IsELF: 6378 CurrentFormat = ELF; 6379 break; 6380 case MCContext::IsCOFF: 6381 CurrentFormat = COFF; 6382 break; 6383 case MCContext::IsWasm: 6384 CurrentFormat = WASM; 6385 break; 6386 case MCContext::IsGOFF: 6387 case MCContext::IsXCOFF: 6388 llvm_unreachable("unexpected object format"); 6389 break; 6390 } 6391 6392 if (~Prefix->SupportedFormats & CurrentFormat) { 6393 Error(Parser.getTok().getLoc(), 6394 "cannot represent relocation in the current file format"); 6395 return true; 6396 } 6397 6398 RefKind = Prefix->VariantKind; 6399 Parser.Lex(); 6400 6401 if (getLexer().isNot(AsmToken::Colon)) { 6402 Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 6403 return true; 6404 } 6405 Parser.Lex(); // Eat the last ':' 6406 6407 return false; 6408 } 6409 6410 /// Given a mnemonic, split out possible predication code and carry 6411 /// setting letters to form a canonical mnemonic and flags. 6412 // 6413 // FIXME: Would be nice to autogen this. 6414 // FIXME: This is a bit of a maze of special cases. 6415 StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 6416 StringRef ExtraToken, 6417 unsigned &PredicationCode, 6418 unsigned &VPTPredicationCode, 6419 bool &CarrySetting, 6420 unsigned &ProcessorIMod, 6421 StringRef &ITMask) { 6422 PredicationCode = ARMCC::AL; 6423 VPTPredicationCode = ARMVCC::None; 6424 CarrySetting = false; 6425 ProcessorIMod = 0; 6426 6427 // Ignore some mnemonics we know aren't predicated forms. 6428 // 6429 // FIXME: Would be nice to autogen this. 6430 if ((Mnemonic == "movs" && isThumb()) || 6431 Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 6432 Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 6433 Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 6434 Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 6435 Mnemonic == "vaclt" || Mnemonic == "vacle" || Mnemonic == "hlt" || 6436 Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 6437 Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 6438 Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" || 6439 Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || 6440 Mnemonic == "vcvta" || Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || 6441 Mnemonic == "vcvtm" || Mnemonic == "vrinta" || Mnemonic == "vrintn" || 6442 Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic == "hvc" || 6443 Mnemonic.startswith("vsel") || Mnemonic == "vins" || Mnemonic == "vmovx" || 6444 Mnemonic == "bxns" || Mnemonic == "blxns" || 6445 Mnemonic == "vdot" || Mnemonic == "vmmla" || 6446 Mnemonic == "vudot" || Mnemonic == "vsdot" || 6447 Mnemonic == "vcmla" || Mnemonic == "vcadd" || 6448 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || 6449 Mnemonic == "wls" || Mnemonic == "le" || Mnemonic == "dls" || 6450 Mnemonic == "csel" || Mnemonic == "csinc" || 6451 Mnemonic == "csinv" || Mnemonic == "csneg" || Mnemonic == "cinc" || 6452 Mnemonic == "cinv" || Mnemonic == "cneg" || Mnemonic == "cset" || 6453 Mnemonic == "csetm" || 6454 Mnemonic == "aut" || Mnemonic == "pac" || Mnemonic == "pacbti" || 6455 Mnemonic == "bti") 6456 return Mnemonic; 6457 6458 // First, split out any predication code. Ignore mnemonics we know aren't 6459 // predicated but do have a carry-set and so weren't caught above. 6460 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 6461 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 6462 Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 6463 Mnemonic != "sbcs" && Mnemonic != "rscs" && 6464 !(hasMVE() && 6465 (Mnemonic == "vmine" || 6466 Mnemonic == "vshle" || Mnemonic == "vshlt" || Mnemonic == "vshllt" || 6467 Mnemonic == "vrshle" || Mnemonic == "vrshlt" || 6468 Mnemonic == "vmvne" || Mnemonic == "vorne" || 6469 Mnemonic == "vnege" || Mnemonic == "vnegt" || 6470 Mnemonic == "vmule" || Mnemonic == "vmult" || 6471 Mnemonic == "vrintne" || 6472 Mnemonic == "vcmult" || Mnemonic == "vcmule" || 6473 Mnemonic == "vpsele" || Mnemonic == "vpselt" || 6474 Mnemonic.startswith("vq")))) { 6475 unsigned CC = ARMCondCodeFromString(Mnemonic.substr(Mnemonic.size()-2)); 6476 if (CC != ~0U) { 6477 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 6478 PredicationCode = CC; 6479 } 6480 } 6481 6482 // Next, determine if we have a carry setting bit. We explicitly ignore all 6483 // the instructions we know end in 's'. 6484 if (Mnemonic.endswith("s") && 6485 !(Mnemonic == "cps" || Mnemonic == "mls" || 6486 Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 6487 Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 6488 Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 6489 Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" || 6490 Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" || 6491 Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" || 6492 Mnemonic == "fmuls" || Mnemonic == "fcmps" || Mnemonic == "fcmpzs" || 6493 Mnemonic == "vfms" || Mnemonic == "vfnms" || Mnemonic == "fconsts" || 6494 Mnemonic == "bxns" || Mnemonic == "blxns" || Mnemonic == "vfmas" || 6495 Mnemonic == "vmlas" || 6496 (Mnemonic == "movs" && isThumb()))) { 6497 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 6498 CarrySetting = true; 6499 } 6500 6501 // The "cps" instruction can have a interrupt mode operand which is glued into 6502 // the mnemonic. Check if this is the case, split it and parse the imod op 6503 if (Mnemonic.startswith("cps")) { 6504 // Split out any imod code. 6505 unsigned IMod = 6506 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 6507 .Case("ie", ARM_PROC::IE) 6508 .Case("id", ARM_PROC::ID) 6509 .Default(~0U); 6510 if (IMod != ~0U) { 6511 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 6512 ProcessorIMod = IMod; 6513 } 6514 } 6515 6516 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic != "vmovlt" && 6517 Mnemonic != "vshllt" && Mnemonic != "vrshrnt" && Mnemonic != "vshrnt" && 6518 Mnemonic != "vqrshrunt" && Mnemonic != "vqshrunt" && 6519 Mnemonic != "vqrshrnt" && Mnemonic != "vqshrnt" && Mnemonic != "vmullt" && 6520 Mnemonic != "vqmovnt" && Mnemonic != "vqmovunt" && 6521 Mnemonic != "vqmovnt" && Mnemonic != "vmovnt" && Mnemonic != "vqdmullt" && 6522 Mnemonic != "vpnot" && Mnemonic != "vcvtt" && Mnemonic != "vcvt") { 6523 unsigned CC = ARMVectorCondCodeFromString(Mnemonic.substr(Mnemonic.size()-1)); 6524 if (CC != ~0U) { 6525 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-1); 6526 VPTPredicationCode = CC; 6527 } 6528 return Mnemonic; 6529 } 6530 6531 // The "it" instruction has the condition mask on the end of the mnemonic. 6532 if (Mnemonic.startswith("it")) { 6533 ITMask = Mnemonic.slice(2, Mnemonic.size()); 6534 Mnemonic = Mnemonic.slice(0, 2); 6535 } 6536 6537 if (Mnemonic.startswith("vpst")) { 6538 ITMask = Mnemonic.slice(4, Mnemonic.size()); 6539 Mnemonic = Mnemonic.slice(0, 4); 6540 } 6541 else if (Mnemonic.startswith("vpt")) { 6542 ITMask = Mnemonic.slice(3, Mnemonic.size()); 6543 Mnemonic = Mnemonic.slice(0, 3); 6544 } 6545 6546 return Mnemonic; 6547 } 6548 6549 /// Given a canonical mnemonic, determine if the instruction ever allows 6550 /// inclusion of carry set or predication code operands. 6551 // 6552 // FIXME: It would be nice to autogen this. 6553 void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic, 6554 StringRef ExtraToken, 6555 StringRef FullInst, 6556 bool &CanAcceptCarrySet, 6557 bool &CanAcceptPredicationCode, 6558 bool &CanAcceptVPTPredicationCode) { 6559 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken); 6560 6561 CanAcceptCarrySet = 6562 Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 6563 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 6564 Mnemonic == "add" || Mnemonic == "adc" || Mnemonic == "mul" || 6565 Mnemonic == "bic" || Mnemonic == "asr" || Mnemonic == "orr" || 6566 Mnemonic == "mvn" || Mnemonic == "rsb" || Mnemonic == "rsc" || 6567 Mnemonic == "orn" || Mnemonic == "sbc" || Mnemonic == "eor" || 6568 Mnemonic == "neg" || Mnemonic == "vfm" || Mnemonic == "vfnm" || 6569 (!isThumb() && 6570 (Mnemonic == "smull" || Mnemonic == "mov" || Mnemonic == "mla" || 6571 Mnemonic == "smlal" || Mnemonic == "umlal" || Mnemonic == "umull")); 6572 6573 if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" || 6574 Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" || 6575 Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic == "udf" || 6576 Mnemonic.startswith("crc32") || Mnemonic.startswith("cps") || 6577 Mnemonic.startswith("vsel") || Mnemonic == "vmaxnm" || 6578 Mnemonic == "vminnm" || Mnemonic == "vcvta" || Mnemonic == "vcvtn" || 6579 Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || Mnemonic == "vrinta" || 6580 Mnemonic == "vrintn" || Mnemonic == "vrintp" || Mnemonic == "vrintm" || 6581 Mnemonic.startswith("aes") || Mnemonic == "hvc" || Mnemonic == "setpan" || 6582 Mnemonic.startswith("sha1") || Mnemonic.startswith("sha256") || 6583 (FullInst.startswith("vmull") && FullInst.endswith(".p64")) || 6584 Mnemonic == "vmovx" || Mnemonic == "vins" || 6585 Mnemonic == "vudot" || Mnemonic == "vsdot" || 6586 Mnemonic == "vcmla" || Mnemonic == "vcadd" || 6587 Mnemonic == "vfmal" || Mnemonic == "vfmsl" || 6588 Mnemonic == "vfmat" || Mnemonic == "vfmab" || 6589 Mnemonic == "vdot" || Mnemonic == "vmmla" || 6590 Mnemonic == "sb" || Mnemonic == "ssbb" || 6591 Mnemonic == "pssbb" || Mnemonic == "vsmmla" || 6592 Mnemonic == "vummla" || Mnemonic == "vusmmla" || 6593 Mnemonic == "vusdot" || Mnemonic == "vsudot" || 6594 Mnemonic == "bfcsel" || Mnemonic == "wls" || 6595 Mnemonic == "dls" || Mnemonic == "le" || Mnemonic == "csel" || 6596 Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" || 6597 Mnemonic == "cinc" || Mnemonic == "cinv" || Mnemonic == "cneg" || 6598 Mnemonic == "cset" || Mnemonic == "csetm" || 6599 (hasCDE() && MS.isCDEInstr(Mnemonic) && 6600 !MS.isITPredicableCDEInstr(Mnemonic)) || 6601 Mnemonic.startswith("vpt") || Mnemonic.startswith("vpst") || 6602 Mnemonic == "pac" || Mnemonic == "pacbti" || Mnemonic == "aut" || 6603 Mnemonic == "bti" || 6604 (hasMVE() && 6605 (Mnemonic.startswith("vst2") || Mnemonic.startswith("vld2") || 6606 Mnemonic.startswith("vst4") || Mnemonic.startswith("vld4") || 6607 Mnemonic.startswith("wlstp") || Mnemonic.startswith("dlstp") || 6608 Mnemonic.startswith("letp")))) { 6609 // These mnemonics are never predicable 6610 CanAcceptPredicationCode = false; 6611 } else if (!isThumb()) { 6612 // Some instructions are only predicable in Thumb mode 6613 CanAcceptPredicationCode = 6614 Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" && 6615 Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" && 6616 Mnemonic != "dmb" && Mnemonic != "dfb" && Mnemonic != "dsb" && 6617 Mnemonic != "isb" && Mnemonic != "pld" && Mnemonic != "pli" && 6618 Mnemonic != "pldw" && Mnemonic != "ldc2" && Mnemonic != "ldc2l" && 6619 Mnemonic != "stc2" && Mnemonic != "stc2l" && 6620 Mnemonic != "tsb" && 6621 !Mnemonic.startswith("rfe") && !Mnemonic.startswith("srs"); 6622 } else if (isThumbOne()) { 6623 if (hasV6MOps()) 6624 CanAcceptPredicationCode = Mnemonic != "movs"; 6625 else 6626 CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs"; 6627 } else 6628 CanAcceptPredicationCode = true; 6629 } 6630 6631 // Some Thumb instructions have two operand forms that are not 6632 // available as three operand, convert to two operand form if possible. 6633 // 6634 // FIXME: We would really like to be able to tablegen'erate this. 6635 void ARMAsmParser::tryConvertingToTwoOperandForm(StringRef Mnemonic, 6636 bool CarrySetting, 6637 OperandVector &Operands) { 6638 if (Operands.size() != 6) 6639 return; 6640 6641 const auto &Op3 = static_cast<ARMOperand &>(*Operands[3]); 6642 auto &Op4 = static_cast<ARMOperand &>(*Operands[4]); 6643 if (!Op3.isReg() || !Op4.isReg()) 6644 return; 6645 6646 auto Op3Reg = Op3.getReg(); 6647 auto Op4Reg = Op4.getReg(); 6648 6649 // For most Thumb2 cases we just generate the 3 operand form and reduce 6650 // it in processInstruction(), but the 3 operand form of ADD (t2ADDrr) 6651 // won't accept SP or PC so we do the transformation here taking care 6652 // with immediate range in the 'add sp, sp #imm' case. 6653 auto &Op5 = static_cast<ARMOperand &>(*Operands[5]); 6654 if (isThumbTwo()) { 6655 if (Mnemonic != "add") 6656 return; 6657 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC || 6658 (Op5.isReg() && Op5.getReg() == ARM::PC); 6659 if (!TryTransform) { 6660 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP || 6661 (Op5.isReg() && Op5.getReg() == ARM::SP)) && 6662 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP && 6663 Op5.isImm() && !Op5.isImm0_508s4()); 6664 } 6665 if (!TryTransform) 6666 return; 6667 } else if (!isThumbOne()) 6668 return; 6669 6670 if (!(Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" || 6671 Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" || 6672 Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" || 6673 Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic")) 6674 return; 6675 6676 // If first 2 operands of a 3 operand instruction are the same 6677 // then transform to 2 operand version of the same instruction 6678 // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1' 6679 bool Transform = Op3Reg == Op4Reg; 6680 6681 // For communtative operations, we might be able to transform if we swap 6682 // Op4 and Op5. The 'ADD Rdm, SP, Rdm' form is already handled specially 6683 // as tADDrsp. 6684 const ARMOperand *LastOp = &Op5; 6685 bool Swap = false; 6686 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() && 6687 ((Mnemonic == "add" && Op4Reg != ARM::SP) || 6688 Mnemonic == "and" || Mnemonic == "eor" || 6689 Mnemonic == "adc" || Mnemonic == "orr")) { 6690 Swap = true; 6691 LastOp = &Op4; 6692 Transform = true; 6693 } 6694 6695 // If both registers are the same then remove one of them from 6696 // the operand list, with certain exceptions. 6697 if (Transform) { 6698 // Don't transform 'adds Rd, Rd, Rm' or 'sub{s} Rd, Rd, Rm' because the 6699 // 2 operand forms don't exist. 6700 if (((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub") && 6701 LastOp->isReg()) 6702 Transform = false; 6703 6704 // Don't transform 'add/sub{s} Rd, Rd, #imm' if the immediate fits into 6705 // 3-bits because the ARMARM says not to. 6706 if ((Mnemonic == "add" || Mnemonic == "sub") && LastOp->isImm0_7()) 6707 Transform = false; 6708 } 6709 6710 if (Transform) { 6711 if (Swap) 6712 std::swap(Op4, Op5); 6713 Operands.erase(Operands.begin() + 3); 6714 } 6715 } 6716 6717 bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 6718 OperandVector &Operands) { 6719 // FIXME: This is all horribly hacky. We really need a better way to deal 6720 // with optional operands like this in the matcher table. 6721 6722 // The 'mov' mnemonic is special. One variant has a cc_out operand, while 6723 // another does not. Specifically, the MOVW instruction does not. So we 6724 // special case it here and remove the defaulted (non-setting) cc_out 6725 // operand if that's the instruction we're trying to match. 6726 // 6727 // We do this as post-processing of the explicit operands rather than just 6728 // conditionally adding the cc_out in the first place because we need 6729 // to check the type of the parsed immediate operand. 6730 if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 6731 !static_cast<ARMOperand &>(*Operands[4]).isModImm() && 6732 static_cast<ARMOperand &>(*Operands[4]).isImm0_65535Expr() && 6733 static_cast<ARMOperand &>(*Operands[1]).getReg() == 0) 6734 return true; 6735 6736 // Register-register 'add' for thumb does not have a cc_out operand 6737 // when there are only two register operands. 6738 if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 6739 static_cast<ARMOperand &>(*Operands[3]).isReg() && 6740 static_cast<ARMOperand &>(*Operands[4]).isReg() && 6741 static_cast<ARMOperand &>(*Operands[1]).getReg() == 0) 6742 return true; 6743 // Register-register 'add' for thumb does not have a cc_out operand 6744 // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 6745 // have to check the immediate range here since Thumb2 has a variant 6746 // that can handle a different range and has a cc_out operand. 6747 if (((isThumb() && Mnemonic == "add") || 6748 (isThumbTwo() && Mnemonic == "sub")) && 6749 Operands.size() == 6 && static_cast<ARMOperand &>(*Operands[3]).isReg() && 6750 static_cast<ARMOperand &>(*Operands[4]).isReg() && 6751 static_cast<ARMOperand &>(*Operands[4]).getReg() == ARM::SP && 6752 static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 && 6753 ((Mnemonic == "add" && static_cast<ARMOperand &>(*Operands[5]).isReg()) || 6754 static_cast<ARMOperand &>(*Operands[5]).isImm0_1020s4())) 6755 return true; 6756 // For Thumb2, add/sub immediate does not have a cc_out operand for the 6757 // imm0_4095 variant. That's the least-preferred variant when 6758 // selecting via the generic "add" mnemonic, so to know that we 6759 // should remove the cc_out operand, we have to explicitly check that 6760 // it's not one of the other variants. Ugh. 6761 if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 6762 Operands.size() == 6 && static_cast<ARMOperand &>(*Operands[3]).isReg() && 6763 static_cast<ARMOperand &>(*Operands[4]).isReg() && 6764 static_cast<ARMOperand &>(*Operands[5]).isImm()) { 6765 // Nest conditions rather than one big 'if' statement for readability. 6766 // 6767 // If both registers are low, we're in an IT block, and the immediate is 6768 // in range, we should use encoding T1 instead, which has a cc_out. 6769 if (inITBlock() && 6770 isARMLowRegister(static_cast<ARMOperand &>(*Operands[3]).getReg()) && 6771 isARMLowRegister(static_cast<ARMOperand &>(*Operands[4]).getReg()) && 6772 static_cast<ARMOperand &>(*Operands[5]).isImm0_7()) 6773 return false; 6774 // Check against T3. If the second register is the PC, this is an 6775 // alternate form of ADR, which uses encoding T4, so check for that too. 6776 if (static_cast<ARMOperand &>(*Operands[4]).getReg() != ARM::PC && 6777 (static_cast<ARMOperand &>(*Operands[5]).isT2SOImm() || 6778 static_cast<ARMOperand &>(*Operands[5]).isT2SOImmNeg())) 6779 return false; 6780 6781 // Otherwise, we use encoding T4, which does not have a cc_out 6782 // operand. 6783 return true; 6784 } 6785 6786 // The thumb2 multiply instruction doesn't have a CCOut register, so 6787 // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 6788 // use the 16-bit encoding or not. 6789 if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 6790 static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 && 6791 static_cast<ARMOperand &>(*Operands[3]).isReg() && 6792 static_cast<ARMOperand &>(*Operands[4]).isReg() && 6793 static_cast<ARMOperand &>(*Operands[5]).isReg() && 6794 // If the registers aren't low regs, the destination reg isn't the 6795 // same as one of the source regs, or the cc_out operand is zero 6796 // outside of an IT block, we have to use the 32-bit encoding, so 6797 // remove the cc_out operand. 6798 (!isARMLowRegister(static_cast<ARMOperand &>(*Operands[3]).getReg()) || 6799 !isARMLowRegister(static_cast<ARMOperand &>(*Operands[4]).getReg()) || 6800 !isARMLowRegister(static_cast<ARMOperand &>(*Operands[5]).getReg()) || 6801 !inITBlock() || (static_cast<ARMOperand &>(*Operands[3]).getReg() != 6802 static_cast<ARMOperand &>(*Operands[5]).getReg() && 6803 static_cast<ARMOperand &>(*Operands[3]).getReg() != 6804 static_cast<ARMOperand &>(*Operands[4]).getReg()))) 6805 return true; 6806 6807 // Also check the 'mul' syntax variant that doesn't specify an explicit 6808 // destination register. 6809 if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 && 6810 static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 && 6811 static_cast<ARMOperand &>(*Operands[3]).isReg() && 6812 static_cast<ARMOperand &>(*Operands[4]).isReg() && 6813 // If the registers aren't low regs or the cc_out operand is zero 6814 // outside of an IT block, we have to use the 32-bit encoding, so 6815 // remove the cc_out operand. 6816 (!isARMLowRegister(static_cast<ARMOperand &>(*Operands[3]).getReg()) || 6817 !isARMLowRegister(static_cast<ARMOperand &>(*Operands[4]).getReg()) || 6818 !inITBlock())) 6819 return true; 6820 6821 // Register-register 'add/sub' for thumb does not have a cc_out operand 6822 // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 6823 // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 6824 // right, this will result in better diagnostics (which operand is off) 6825 // anyway. 6826 if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 6827 (Operands.size() == 5 || Operands.size() == 6) && 6828 static_cast<ARMOperand &>(*Operands[3]).isReg() && 6829 static_cast<ARMOperand &>(*Operands[3]).getReg() == ARM::SP && 6830 static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 && 6831 (static_cast<ARMOperand &>(*Operands[4]).isImm() || 6832 (Operands.size() == 6 && 6833 static_cast<ARMOperand &>(*Operands[5]).isImm()))) { 6834 // Thumb2 (add|sub){s}{p}.w GPRnopc, sp, #{T2SOImm} has cc_out 6835 return (!(isThumbTwo() && 6836 (static_cast<ARMOperand &>(*Operands[4]).isT2SOImm() || 6837 static_cast<ARMOperand &>(*Operands[4]).isT2SOImmNeg()))); 6838 } 6839 // Fixme: Should join all the thumb+thumb2 (add|sub) in a single if case 6840 // Thumb2 ADD r0, #4095 -> ADDW r0, r0, #4095 (T4) 6841 // Thumb2 SUB r0, #4095 -> SUBW r0, r0, #4095 6842 if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 6843 (Operands.size() == 5) && 6844 static_cast<ARMOperand &>(*Operands[3]).isReg() && 6845 static_cast<ARMOperand &>(*Operands[3]).getReg() != ARM::SP && 6846 static_cast<ARMOperand &>(*Operands[3]).getReg() != ARM::PC && 6847 static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 && 6848 static_cast<ARMOperand &>(*Operands[4]).isImm()) { 6849 const ARMOperand &IMM = static_cast<ARMOperand &>(*Operands[4]); 6850 if (IMM.isT2SOImm() || IMM.isT2SOImmNeg()) 6851 return false; // add.w / sub.w 6852 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IMM.getImm())) { 6853 const int64_t Value = CE->getValue(); 6854 // Thumb1 imm8 sub / add 6855 if ((Value < ((1 << 7) - 1) << 2) && inITBlock() && (!(Value & 3)) && 6856 isARMLowRegister(static_cast<ARMOperand &>(*Operands[3]).getReg())) 6857 return false; 6858 return true; // Thumb2 T4 addw / subw 6859 } 6860 } 6861 return false; 6862 } 6863 6864 bool ARMAsmParser::shouldOmitPredicateOperand(StringRef Mnemonic, 6865 OperandVector &Operands) { 6866 // VRINT{Z, X} have a predicate operand in VFP, but not in NEON 6867 unsigned RegIdx = 3; 6868 if ((((Mnemonic == "vrintz" || Mnemonic == "vrintx") && !hasMVE()) || 6869 Mnemonic == "vrintr") && 6870 (static_cast<ARMOperand &>(*Operands[2]).getToken() == ".f32" || 6871 static_cast<ARMOperand &>(*Operands[2]).getToken() == ".f16")) { 6872 if (static_cast<ARMOperand &>(*Operands[3]).isToken() && 6873 (static_cast<ARMOperand &>(*Operands[3]).getToken() == ".f32" || 6874 static_cast<ARMOperand &>(*Operands[3]).getToken() == ".f16")) 6875 RegIdx = 4; 6876 6877 if (static_cast<ARMOperand &>(*Operands[RegIdx]).isReg() && 6878 (ARMMCRegisterClasses[ARM::DPRRegClassID].contains( 6879 static_cast<ARMOperand &>(*Operands[RegIdx]).getReg()) || 6880 ARMMCRegisterClasses[ARM::QPRRegClassID].contains( 6881 static_cast<ARMOperand &>(*Operands[RegIdx]).getReg()))) 6882 return true; 6883 } 6884 return false; 6885 } 6886 6887 bool ARMAsmParser::shouldOmitVectorPredicateOperand(StringRef Mnemonic, 6888 OperandVector &Operands) { 6889 if (!hasMVE() || Operands.size() < 3) 6890 return true; 6891 6892 if (Mnemonic.startswith("vld2") || Mnemonic.startswith("vld4") || 6893 Mnemonic.startswith("vst2") || Mnemonic.startswith("vst4")) 6894 return true; 6895 6896 if (Mnemonic.startswith("vctp") || Mnemonic.startswith("vpnot")) 6897 return false; 6898 6899 if (Mnemonic.startswith("vmov") && 6900 !(Mnemonic.startswith("vmovl") || Mnemonic.startswith("vmovn") || 6901 Mnemonic.startswith("vmovx"))) { 6902 for (auto &Operand : Operands) { 6903 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() || 6904 ((*Operand).isReg() && 6905 (ARMMCRegisterClasses[ARM::SPRRegClassID].contains( 6906 (*Operand).getReg()) || 6907 ARMMCRegisterClasses[ARM::DPRRegClassID].contains( 6908 (*Operand).getReg())))) { 6909 return true; 6910 } 6911 } 6912 return false; 6913 } else { 6914 for (auto &Operand : Operands) { 6915 // We check the larger class QPR instead of just the legal class 6916 // MQPR, to more accurately report errors when using Q registers 6917 // outside of the allowed range. 6918 if (static_cast<ARMOperand &>(*Operand).isVectorIndex() || 6919 (Operand->isReg() && 6920 (ARMMCRegisterClasses[ARM::QPRRegClassID].contains( 6921 Operand->getReg())))) 6922 return false; 6923 } 6924 return true; 6925 } 6926 } 6927 6928 static bool isDataTypeToken(StringRef Tok) { 6929 return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" || 6930 Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" || 6931 Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" || 6932 Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" || 6933 Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" || 6934 Tok == ".f" || Tok == ".d"; 6935 } 6936 6937 // FIXME: This bit should probably be handled via an explicit match class 6938 // in the .td files that matches the suffix instead of having it be 6939 // a literal string token the way it is now. 6940 static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) { 6941 return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm"); 6942 } 6943 6944 static void applyMnemonicAliases(StringRef &Mnemonic, 6945 const FeatureBitset &Features, 6946 unsigned VariantID); 6947 6948 // The GNU assembler has aliases of ldrd and strd with the second register 6949 // omitted. We don't have a way to do that in tablegen, so fix it up here. 6950 // 6951 // We have to be careful to not emit an invalid Rt2 here, because the rest of 6952 // the assembly parser could then generate confusing diagnostics refering to 6953 // it. If we do find anything that prevents us from doing the transformation we 6954 // bail out, and let the assembly parser report an error on the instruction as 6955 // it is written. 6956 void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic, 6957 OperandVector &Operands) { 6958 if (Mnemonic != "ldrd" && Mnemonic != "strd") 6959 return; 6960 if (Operands.size() < 4) 6961 return; 6962 6963 ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[2]); 6964 ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]); 6965 6966 if (!Op2.isReg()) 6967 return; 6968 if (!Op3.isGPRMem()) 6969 return; 6970 6971 const MCRegisterClass &GPR = MRI->getRegClass(ARM::GPRRegClassID); 6972 if (!GPR.contains(Op2.getReg())) 6973 return; 6974 6975 unsigned RtEncoding = MRI->getEncodingValue(Op2.getReg()); 6976 if (!isThumb() && (RtEncoding & 1)) { 6977 // In ARM mode, the registers must be from an aligned pair, this 6978 // restriction does not apply in Thumb mode. 6979 return; 6980 } 6981 if (Op2.getReg() == ARM::PC) 6982 return; 6983 unsigned PairedReg = GPR.getRegister(RtEncoding + 1); 6984 if (!PairedReg || PairedReg == ARM::PC || 6985 (PairedReg == ARM::SP && !hasV8Ops())) 6986 return; 6987 6988 Operands.insert( 6989 Operands.begin() + 3, 6990 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(), Op2.getEndLoc())); 6991 } 6992 6993 // Dual-register instruction have the following syntax: 6994 // <mnemonic> <predicate>? <coproc>, <Rdest>, <Rdest+1>, <Rsrc>, ..., #imm 6995 // This function tries to remove <Rdest+1> and replace <Rdest> with a pair 6996 // operand. If the conversion fails an error is diagnosed, and the function 6997 // returns true. 6998 bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic, 6999 OperandVector &Operands) { 7000 assert(MS.isCDEDualRegInstr(Mnemonic)); 7001 bool isPredicable = 7002 Mnemonic == "cx1da" || Mnemonic == "cx2da" || Mnemonic == "cx3da"; 7003 size_t NumPredOps = isPredicable ? 1 : 0; 7004 7005 if (Operands.size() <= 3 + NumPredOps) 7006 return false; 7007 7008 StringRef Op2Diag( 7009 "operand must be an even-numbered register in the range [r0, r10]"); 7010 7011 const MCParsedAsmOperand &Op2 = *Operands[2 + NumPredOps]; 7012 if (!Op2.isReg()) 7013 return Error(Op2.getStartLoc(), Op2Diag); 7014 7015 unsigned RNext; 7016 unsigned RPair; 7017 switch (Op2.getReg()) { 7018 default: 7019 return Error(Op2.getStartLoc(), Op2Diag); 7020 case ARM::R0: 7021 RNext = ARM::R1; 7022 RPair = ARM::R0_R1; 7023 break; 7024 case ARM::R2: 7025 RNext = ARM::R3; 7026 RPair = ARM::R2_R3; 7027 break; 7028 case ARM::R4: 7029 RNext = ARM::R5; 7030 RPair = ARM::R4_R5; 7031 break; 7032 case ARM::R6: 7033 RNext = ARM::R7; 7034 RPair = ARM::R6_R7; 7035 break; 7036 case ARM::R8: 7037 RNext = ARM::R9; 7038 RPair = ARM::R8_R9; 7039 break; 7040 case ARM::R10: 7041 RNext = ARM::R11; 7042 RPair = ARM::R10_R11; 7043 break; 7044 } 7045 7046 const MCParsedAsmOperand &Op3 = *Operands[3 + NumPredOps]; 7047 if (!Op3.isReg() || Op3.getReg() != RNext) 7048 return Error(Op3.getStartLoc(), "operand must be a consecutive register"); 7049 7050 Operands.erase(Operands.begin() + 3 + NumPredOps); 7051 Operands[2 + NumPredOps] = 7052 ARMOperand::CreateReg(RPair, Op2.getStartLoc(), Op2.getEndLoc()); 7053 return false; 7054 } 7055 7056 /// Parse an arm instruction mnemonic followed by its operands. 7057 bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 7058 SMLoc NameLoc, OperandVector &Operands) { 7059 MCAsmParser &Parser = getParser(); 7060 7061 // Apply mnemonic aliases before doing anything else, as the destination 7062 // mnemonic may include suffices and we want to handle them normally. 7063 // The generic tblgen'erated code does this later, at the start of 7064 // MatchInstructionImpl(), but that's too late for aliases that include 7065 // any sort of suffix. 7066 const FeatureBitset &AvailableFeatures = getAvailableFeatures(); 7067 unsigned AssemblerDialect = getParser().getAssemblerDialect(); 7068 applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect); 7069 7070 // First check for the ARM-specific .req directive. 7071 if (Parser.getTok().is(AsmToken::Identifier) && 7072 Parser.getTok().getIdentifier().lower() == ".req") { 7073 parseDirectiveReq(Name, NameLoc); 7074 // We always return 'error' for this, as we're done with this 7075 // statement and don't need to match the 'instruction." 7076 return true; 7077 } 7078 7079 // Create the leading tokens for the mnemonic, split by '.' characters. 7080 size_t Start = 0, Next = Name.find('.'); 7081 StringRef Mnemonic = Name.slice(Start, Next); 7082 StringRef ExtraToken = Name.slice(Next, Name.find(' ', Next + 1)); 7083 7084 // Split out the predication code and carry setting flag from the mnemonic. 7085 unsigned PredicationCode; 7086 unsigned VPTPredicationCode; 7087 unsigned ProcessorIMod; 7088 bool CarrySetting; 7089 StringRef ITMask; 7090 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode, 7091 CarrySetting, ProcessorIMod, ITMask); 7092 7093 // In Thumb1, only the branch (B) instruction can be predicated. 7094 if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 7095 return Error(NameLoc, "conditional execution not supported in Thumb1"); 7096 } 7097 7098 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 7099 7100 // Handle the mask for IT and VPT instructions. In ARMOperand and 7101 // MCOperand, this is stored in a format independent of the 7102 // condition code: the lowest set bit indicates the end of the 7103 // encoding, and above that, a 1 bit indicates 'else', and an 0 7104 // indicates 'then'. E.g. 7105 // IT -> 1000 7106 // ITx -> x100 (ITT -> 0100, ITE -> 1100) 7107 // ITxy -> xy10 (e.g. ITET -> 1010) 7108 // ITxyz -> xyz1 (e.g. ITEET -> 1101) 7109 // Note: See the ARM::PredBlockMask enum in 7110 // /lib/Target/ARM/Utils/ARMBaseInfo.h 7111 if (Mnemonic == "it" || Mnemonic.startswith("vpt") || 7112 Mnemonic.startswith("vpst")) { 7113 SMLoc Loc = Mnemonic == "it" ? SMLoc::getFromPointer(NameLoc.getPointer() + 2) : 7114 Mnemonic == "vpt" ? SMLoc::getFromPointer(NameLoc.getPointer() + 3) : 7115 SMLoc::getFromPointer(NameLoc.getPointer() + 4); 7116 if (ITMask.size() > 3) { 7117 if (Mnemonic == "it") 7118 return Error(Loc, "too many conditions on IT instruction"); 7119 return Error(Loc, "too many conditions on VPT instruction"); 7120 } 7121 unsigned Mask = 8; 7122 for (unsigned i = ITMask.size(); i != 0; --i) { 7123 char pos = ITMask[i - 1]; 7124 if (pos != 't' && pos != 'e') { 7125 return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 7126 } 7127 Mask >>= 1; 7128 if (ITMask[i - 1] == 'e') 7129 Mask |= 8; 7130 } 7131 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 7132 } 7133 7134 // FIXME: This is all a pretty gross hack. We should automatically handle 7135 // optional operands like this via tblgen. 7136 7137 // Next, add the CCOut and ConditionCode operands, if needed. 7138 // 7139 // For mnemonics which can ever incorporate a carry setting bit or predication 7140 // code, our matching model involves us always generating CCOut and 7141 // ConditionCode operands to match the mnemonic "as written" and then we let 7142 // the matcher deal with finding the right instruction or generating an 7143 // appropriate error. 7144 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode; 7145 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet, 7146 CanAcceptPredicationCode, CanAcceptVPTPredicationCode); 7147 7148 // If we had a carry-set on an instruction that can't do that, issue an 7149 // error. 7150 if (!CanAcceptCarrySet && CarrySetting) { 7151 return Error(NameLoc, "instruction '" + Mnemonic + 7152 "' can not set flags, but 's' suffix specified"); 7153 } 7154 // If we had a predication code on an instruction that can't do that, issue an 7155 // error. 7156 if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 7157 return Error(NameLoc, "instruction '" + Mnemonic + 7158 "' is not predicable, but condition code specified"); 7159 } 7160 7161 // If we had a VPT predication code on an instruction that can't do that, issue an 7162 // error. 7163 if (!CanAcceptVPTPredicationCode && VPTPredicationCode != ARMVCC::None) { 7164 return Error(NameLoc, "instruction '" + Mnemonic + 7165 "' is not VPT predicable, but VPT code T/E is specified"); 7166 } 7167 7168 // Add the carry setting operand, if necessary. 7169 if (CanAcceptCarrySet) { 7170 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 7171 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 7172 Loc)); 7173 } 7174 7175 // Add the predication code operand, if necessary. 7176 if (CanAcceptPredicationCode) { 7177 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 7178 CarrySetting); 7179 Operands.push_back(ARMOperand::CreateCondCode( 7180 ARMCC::CondCodes(PredicationCode), Loc)); 7181 } 7182 7183 // Add the VPT predication code operand, if necessary. 7184 // FIXME: We don't add them for the instructions filtered below as these can 7185 // have custom operands which need special parsing. This parsing requires 7186 // the operand to be in the same place in the OperandVector as their 7187 // definition in tblgen. Since these instructions may also have the 7188 // scalar predication operand we do not add the vector one and leave until 7189 // now to fix it up. 7190 if (CanAcceptVPTPredicationCode && Mnemonic != "vmov" && 7191 !Mnemonic.startswith("vcmp") && 7192 !(Mnemonic.startswith("vcvt") && Mnemonic != "vcvta" && 7193 Mnemonic != "vcvtn" && Mnemonic != "vcvtp" && Mnemonic != "vcvtm")) { 7194 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 7195 CarrySetting); 7196 Operands.push_back(ARMOperand::CreateVPTPred( 7197 ARMVCC::VPTCodes(VPTPredicationCode), Loc)); 7198 } 7199 7200 // Add the processor imod operand, if necessary. 7201 if (ProcessorIMod) { 7202 Operands.push_back(ARMOperand::CreateImm( 7203 MCConstantExpr::create(ProcessorIMod, getContext()), 7204 NameLoc, NameLoc)); 7205 } else if (Mnemonic == "cps" && isMClass()) { 7206 return Error(NameLoc, "instruction 'cps' requires effect for M-class"); 7207 } 7208 7209 // Add the remaining tokens in the mnemonic. 7210 while (Next != StringRef::npos) { 7211 Start = Next; 7212 Next = Name.find('.', Start + 1); 7213 ExtraToken = Name.slice(Start, Next); 7214 7215 // Some NEON instructions have an optional datatype suffix that is 7216 // completely ignored. Check for that. 7217 if (isDataTypeToken(ExtraToken) && 7218 doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken)) 7219 continue; 7220 7221 // For for ARM mode generate an error if the .n qualifier is used. 7222 if (ExtraToken == ".n" && !isThumb()) { 7223 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 7224 return Error(Loc, "instruction with .n (narrow) qualifier not allowed in " 7225 "arm mode"); 7226 } 7227 7228 // The .n qualifier is always discarded as that is what the tables 7229 // and matcher expect. In ARM mode the .w qualifier has no effect, 7230 // so discard it to avoid errors that can be caused by the matcher. 7231 if (ExtraToken != ".n" && (isThumb() || ExtraToken != ".w")) { 7232 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 7233 Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 7234 } 7235 } 7236 7237 // Read the remaining operands. 7238 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7239 // Read the first operand. 7240 if (parseOperand(Operands, Mnemonic)) { 7241 return true; 7242 } 7243 7244 while (parseOptionalToken(AsmToken::Comma)) { 7245 // Parse and remember the operand. 7246 if (parseOperand(Operands, Mnemonic)) { 7247 return true; 7248 } 7249 } 7250 } 7251 7252 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list")) 7253 return true; 7254 7255 tryConvertingToTwoOperandForm(Mnemonic, CarrySetting, Operands); 7256 7257 if (hasCDE() && MS.isCDEInstr(Mnemonic)) { 7258 // Dual-register instructions use even-odd register pairs as their 7259 // destination operand, in assembly such pair is spelled as two 7260 // consecutive registers, without any special syntax. ConvertDualRegOperand 7261 // tries to convert such operand into register pair, e.g. r2, r3 -> r2_r3. 7262 // It returns true, if an error message has been emitted. If the function 7263 // returns false, the function either succeeded or an error (e.g. missing 7264 // operand) will be diagnosed elsewhere. 7265 if (MS.isCDEDualRegInstr(Mnemonic)) { 7266 bool GotError = CDEConvertDualRegOperand(Mnemonic, Operands); 7267 if (GotError) 7268 return GotError; 7269 } 7270 } 7271 7272 // Some instructions, mostly Thumb, have forms for the same mnemonic that 7273 // do and don't have a cc_out optional-def operand. With some spot-checks 7274 // of the operand list, we can figure out which variant we're trying to 7275 // parse and adjust accordingly before actually matching. We shouldn't ever 7276 // try to remove a cc_out operand that was explicitly set on the 7277 // mnemonic, of course (CarrySetting == true). Reason number #317 the 7278 // table driven matcher doesn't fit well with the ARM instruction set. 7279 if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) 7280 Operands.erase(Operands.begin() + 1); 7281 7282 // Some instructions have the same mnemonic, but don't always 7283 // have a predicate. Distinguish them here and delete the 7284 // appropriate predicate if needed. This could be either the scalar 7285 // predication code or the vector predication code. 7286 if (PredicationCode == ARMCC::AL && 7287 shouldOmitPredicateOperand(Mnemonic, Operands)) 7288 Operands.erase(Operands.begin() + 1); 7289 7290 7291 if (hasMVE()) { 7292 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands) && 7293 Mnemonic == "vmov" && PredicationCode == ARMCC::LT) { 7294 // Very nasty hack to deal with the vector predicated variant of vmovlt 7295 // the scalar predicated vmov with condition 'lt'. We can not tell them 7296 // apart until we have parsed their operands. 7297 Operands.erase(Operands.begin() + 1); 7298 Operands.erase(Operands.begin()); 7299 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer()); 7300 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 7301 Mnemonic.size() - 1 + CarrySetting); 7302 Operands.insert(Operands.begin(), 7303 ARMOperand::CreateVPTPred(ARMVCC::None, PLoc)); 7304 Operands.insert(Operands.begin(), 7305 ARMOperand::CreateToken(StringRef("vmovlt"), MLoc)); 7306 } else if (Mnemonic == "vcvt" && PredicationCode == ARMCC::NE && 7307 !shouldOmitVectorPredicateOperand(Mnemonic, Operands)) { 7308 // Another nasty hack to deal with the ambiguity between vcvt with scalar 7309 // predication 'ne' and vcvtn with vector predication 'e'. As above we 7310 // can only distinguish between the two after we have parsed their 7311 // operands. 7312 Operands.erase(Operands.begin() + 1); 7313 Operands.erase(Operands.begin()); 7314 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer()); 7315 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 7316 Mnemonic.size() - 1 + CarrySetting); 7317 Operands.insert(Operands.begin(), 7318 ARMOperand::CreateVPTPred(ARMVCC::Else, PLoc)); 7319 Operands.insert(Operands.begin(), 7320 ARMOperand::CreateToken(StringRef("vcvtn"), MLoc)); 7321 } else if (Mnemonic == "vmul" && PredicationCode == ARMCC::LT && 7322 !shouldOmitVectorPredicateOperand(Mnemonic, Operands)) { 7323 // Another hack, this time to distinguish between scalar predicated vmul 7324 // with 'lt' predication code and the vector instruction vmullt with 7325 // vector predication code "none" 7326 Operands.erase(Operands.begin() + 1); 7327 Operands.erase(Operands.begin()); 7328 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer()); 7329 Operands.insert(Operands.begin(), 7330 ARMOperand::CreateToken(StringRef("vmullt"), MLoc)); 7331 } 7332 // For vmov and vcmp, as mentioned earlier, we did not add the vector 7333 // predication code, since these may contain operands that require 7334 // special parsing. So now we have to see if they require vector 7335 // predication and replace the scalar one with the vector predication 7336 // operand if that is the case. 7337 else if (Mnemonic == "vmov" || Mnemonic.startswith("vcmp") || 7338 (Mnemonic.startswith("vcvt") && !Mnemonic.startswith("vcvta") && 7339 !Mnemonic.startswith("vcvtn") && !Mnemonic.startswith("vcvtp") && 7340 !Mnemonic.startswith("vcvtm"))) { 7341 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands)) { 7342 // We could not split the vector predicate off vcvt because it might 7343 // have been the scalar vcvtt instruction. Now we know its a vector 7344 // instruction, we still need to check whether its the vector 7345 // predicated vcvt with 'Then' predication or the vector vcvtt. We can 7346 // distinguish the two based on the suffixes, if it is any of 7347 // ".f16.f32", ".f32.f16", ".f16.f64" or ".f64.f16" then it is the vcvtt. 7348 if (Mnemonic.startswith("vcvtt") && Operands.size() >= 4) { 7349 auto Sz1 = static_cast<ARMOperand &>(*Operands[2]); 7350 auto Sz2 = static_cast<ARMOperand &>(*Operands[3]); 7351 if (!(Sz1.isToken() && Sz1.getToken().startswith(".f") && 7352 Sz2.isToken() && Sz2.getToken().startswith(".f"))) { 7353 Operands.erase(Operands.begin()); 7354 SMLoc MLoc = SMLoc::getFromPointer(NameLoc.getPointer()); 7355 VPTPredicationCode = ARMVCC::Then; 7356 7357 Mnemonic = Mnemonic.substr(0, 4); 7358 Operands.insert(Operands.begin(), 7359 ARMOperand::CreateToken(Mnemonic, MLoc)); 7360 } 7361 } 7362 Operands.erase(Operands.begin() + 1); 7363 SMLoc PLoc = SMLoc::getFromPointer(NameLoc.getPointer() + 7364 Mnemonic.size() + CarrySetting); 7365 Operands.insert(Operands.begin() + 1, 7366 ARMOperand::CreateVPTPred( 7367 ARMVCC::VPTCodes(VPTPredicationCode), PLoc)); 7368 } 7369 } else if (CanAcceptVPTPredicationCode) { 7370 // For all other instructions, make sure only one of the two 7371 // predication operands is left behind, depending on whether we should 7372 // use the vector predication. 7373 if (shouldOmitVectorPredicateOperand(Mnemonic, Operands)) { 7374 if (CanAcceptPredicationCode) 7375 Operands.erase(Operands.begin() + 2); 7376 else 7377 Operands.erase(Operands.begin() + 1); 7378 } else if (CanAcceptPredicationCode && PredicationCode == ARMCC::AL) { 7379 Operands.erase(Operands.begin() + 1); 7380 } 7381 } 7382 } 7383 7384 if (VPTPredicationCode != ARMVCC::None) { 7385 bool usedVPTPredicationCode = false; 7386 for (unsigned I = 1; I < Operands.size(); ++I) 7387 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred()) 7388 usedVPTPredicationCode = true; 7389 if (!usedVPTPredicationCode) { 7390 // If we have a VPT predication code and we haven't just turned it 7391 // into an operand, then it was a mistake for splitMnemonic to 7392 // separate it from the rest of the mnemonic in the first place, 7393 // and this may lead to wrong disassembly (e.g. scalar floating 7394 // point VCMPE is actually a different instruction from VCMP, so 7395 // we mustn't treat them the same). In that situation, glue it 7396 // back on. 7397 Mnemonic = Name.slice(0, Mnemonic.size() + 1); 7398 Operands.erase(Operands.begin()); 7399 Operands.insert(Operands.begin(), 7400 ARMOperand::CreateToken(Mnemonic, NameLoc)); 7401 } 7402 } 7403 7404 // ARM mode 'blx' need special handling, as the register operand version 7405 // is predicable, but the label operand version is not. So, we can't rely 7406 // on the Mnemonic based checking to correctly figure out when to put 7407 // a k_CondCode operand in the list. If we're trying to match the label 7408 // version, remove the k_CondCode operand here. 7409 if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 7410 static_cast<ARMOperand &>(*Operands[2]).isImm()) 7411 Operands.erase(Operands.begin() + 1); 7412 7413 // Adjust operands of ldrexd/strexd to MCK_GPRPair. 7414 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint, 7415 // a single GPRPair reg operand is used in the .td file to replace the two 7416 // GPRs. However, when parsing from asm, the two GRPs cannot be 7417 // automatically 7418 // expressed as a GPRPair, so we have to manually merge them. 7419 // FIXME: We would really like to be able to tablegen'erate this. 7420 if (!isThumb() && Operands.size() > 4 && 7421 (Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" || 7422 Mnemonic == "stlexd")) { 7423 bool isLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd"); 7424 unsigned Idx = isLoad ? 2 : 3; 7425 ARMOperand &Op1 = static_cast<ARMOperand &>(*Operands[Idx]); 7426 ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[Idx + 1]); 7427 7428 const MCRegisterClass &MRC = MRI->getRegClass(ARM::GPRRegClassID); 7429 // Adjust only if Op1 and Op2 are GPRs. 7430 if (Op1.isReg() && Op2.isReg() && MRC.contains(Op1.getReg()) && 7431 MRC.contains(Op2.getReg())) { 7432 unsigned Reg1 = Op1.getReg(); 7433 unsigned Reg2 = Op2.getReg(); 7434 unsigned Rt = MRI->getEncodingValue(Reg1); 7435 unsigned Rt2 = MRI->getEncodingValue(Reg2); 7436 7437 // Rt2 must be Rt + 1 and Rt must be even. 7438 if (Rt + 1 != Rt2 || (Rt & 1)) { 7439 return Error(Op2.getStartLoc(), 7440 isLoad ? "destination operands must be sequential" 7441 : "source operands must be sequential"); 7442 } 7443 unsigned NewReg = MRI->getMatchingSuperReg( 7444 Reg1, ARM::gsub_0, &(MRI->getRegClass(ARM::GPRPairRegClassID))); 7445 Operands[Idx] = 7446 ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc()); 7447 Operands.erase(Operands.begin() + Idx + 1); 7448 } 7449 } 7450 7451 // GNU Assembler extension (compatibility). 7452 fixupGNULDRDAlias(Mnemonic, Operands); 7453 7454 // FIXME: As said above, this is all a pretty gross hack. This instruction 7455 // does not fit with other "subs" and tblgen. 7456 // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction 7457 // so the Mnemonic is the original name "subs" and delete the predicate 7458 // operand so it will match the table entry. 7459 if (isThumbTwo() && Mnemonic == "sub" && Operands.size() == 6 && 7460 static_cast<ARMOperand &>(*Operands[3]).isReg() && 7461 static_cast<ARMOperand &>(*Operands[3]).getReg() == ARM::PC && 7462 static_cast<ARMOperand &>(*Operands[4]).isReg() && 7463 static_cast<ARMOperand &>(*Operands[4]).getReg() == ARM::LR && 7464 static_cast<ARMOperand &>(*Operands[5]).isImm()) { 7465 Operands.front() = ARMOperand::CreateToken(Name, NameLoc); 7466 Operands.erase(Operands.begin() + 1); 7467 } 7468 return false; 7469 } 7470 7471 // Validate context-sensitive operand constraints. 7472 7473 // return 'true' if register list contains non-low GPR registers, 7474 // 'false' otherwise. If Reg is in the register list or is HiReg, set 7475 // 'containsReg' to true. 7476 static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo, 7477 unsigned Reg, unsigned HiReg, 7478 bool &containsReg) { 7479 containsReg = false; 7480 for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 7481 unsigned OpReg = Inst.getOperand(i).getReg(); 7482 if (OpReg == Reg) 7483 containsReg = true; 7484 // Anything other than a low register isn't legal here. 7485 if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 7486 return true; 7487 } 7488 return false; 7489 } 7490 7491 // Check if the specified regisgter is in the register list of the inst, 7492 // starting at the indicated operand number. 7493 static bool listContainsReg(const MCInst &Inst, unsigned OpNo, unsigned Reg) { 7494 for (unsigned i = OpNo, e = Inst.getNumOperands(); i < e; ++i) { 7495 unsigned OpReg = Inst.getOperand(i).getReg(); 7496 if (OpReg == Reg) 7497 return true; 7498 } 7499 return false; 7500 } 7501 7502 // Return true if instruction has the interesting property of being 7503 // allowed in IT blocks, but not being predicable. 7504 static bool instIsBreakpoint(const MCInst &Inst) { 7505 return Inst.getOpcode() == ARM::tBKPT || 7506 Inst.getOpcode() == ARM::BKPT || 7507 Inst.getOpcode() == ARM::tHLT || 7508 Inst.getOpcode() == ARM::HLT; 7509 } 7510 7511 bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst, 7512 const OperandVector &Operands, 7513 unsigned ListNo, bool IsARPop) { 7514 const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[ListNo]); 7515 bool HasWritebackToken = Op.isToken() && Op.getToken() == "!"; 7516 7517 bool ListContainsSP = listContainsReg(Inst, ListNo, ARM::SP); 7518 bool ListContainsLR = listContainsReg(Inst, ListNo, ARM::LR); 7519 bool ListContainsPC = listContainsReg(Inst, ListNo, ARM::PC); 7520 7521 if (!IsARPop && ListContainsSP) 7522 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(), 7523 "SP may not be in the register list"); 7524 else if (ListContainsPC && ListContainsLR) 7525 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(), 7526 "PC and LR may not be in the register list simultaneously"); 7527 return false; 7528 } 7529 7530 bool ARMAsmParser::validatetSTMRegList(const MCInst &Inst, 7531 const OperandVector &Operands, 7532 unsigned ListNo) { 7533 const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[ListNo]); 7534 bool HasWritebackToken = Op.isToken() && Op.getToken() == "!"; 7535 7536 bool ListContainsSP = listContainsReg(Inst, ListNo, ARM::SP); 7537 bool ListContainsPC = listContainsReg(Inst, ListNo, ARM::PC); 7538 7539 if (ListContainsSP && ListContainsPC) 7540 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(), 7541 "SP and PC may not be in the register list"); 7542 else if (ListContainsSP) 7543 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(), 7544 "SP may not be in the register list"); 7545 else if (ListContainsPC) 7546 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(), 7547 "PC may not be in the register list"); 7548 return false; 7549 } 7550 7551 bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst, 7552 const OperandVector &Operands, 7553 bool Load, bool ARMMode, bool Writeback) { 7554 unsigned RtIndex = Load || !Writeback ? 0 : 1; 7555 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(RtIndex).getReg()); 7556 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(RtIndex + 1).getReg()); 7557 7558 if (ARMMode) { 7559 // Rt can't be R14. 7560 if (Rt == 14) 7561 return Error(Operands[3]->getStartLoc(), 7562 "Rt can't be R14"); 7563 7564 // Rt must be even-numbered. 7565 if ((Rt & 1) == 1) 7566 return Error(Operands[3]->getStartLoc(), 7567 "Rt must be even-numbered"); 7568 7569 // Rt2 must be Rt + 1. 7570 if (Rt2 != Rt + 1) { 7571 if (Load) 7572 return Error(Operands[3]->getStartLoc(), 7573 "destination operands must be sequential"); 7574 else 7575 return Error(Operands[3]->getStartLoc(), 7576 "source operands must be sequential"); 7577 } 7578 7579 // FIXME: Diagnose m == 15 7580 // FIXME: Diagnose ldrd with m == t || m == t2. 7581 } 7582 7583 if (!ARMMode && Load) { 7584 if (Rt2 == Rt) 7585 return Error(Operands[3]->getStartLoc(), 7586 "destination operands can't be identical"); 7587 } 7588 7589 if (Writeback) { 7590 unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg()); 7591 7592 if (Rn == Rt || Rn == Rt2) { 7593 if (Load) 7594 return Error(Operands[3]->getStartLoc(), 7595 "base register needs to be different from destination " 7596 "registers"); 7597 else 7598 return Error(Operands[3]->getStartLoc(), 7599 "source register and base register can't be identical"); 7600 } 7601 7602 // FIXME: Diagnose ldrd/strd with writeback and n == 15. 7603 // (Except the immediate form of ldrd?) 7604 } 7605 7606 return false; 7607 } 7608 7609 static int findFirstVectorPredOperandIdx(const MCInstrDesc &MCID) { 7610 for (unsigned i = 0; i < MCID.NumOperands; ++i) { 7611 if (ARM::isVpred(MCID.OpInfo[i].OperandType)) 7612 return i; 7613 } 7614 return -1; 7615 } 7616 7617 static bool isVectorPredicable(const MCInstrDesc &MCID) { 7618 return findFirstVectorPredOperandIdx(MCID) != -1; 7619 } 7620 7621 // FIXME: We would really like to be able to tablegen'erate this. 7622 bool ARMAsmParser::validateInstruction(MCInst &Inst, 7623 const OperandVector &Operands) { 7624 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 7625 SMLoc Loc = Operands[0]->getStartLoc(); 7626 7627 // Check the IT block state first. 7628 // NOTE: BKPT and HLT instructions have the interesting property of being 7629 // allowed in IT blocks, but not being predicable. They just always execute. 7630 if (inITBlock() && !instIsBreakpoint(Inst)) { 7631 // The instruction must be predicable. 7632 if (!MCID.isPredicable()) 7633 return Error(Loc, "instructions in IT block must be predicable"); 7634 ARMCC::CondCodes Cond = ARMCC::CondCodes( 7635 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm()); 7636 if (Cond != currentITCond()) { 7637 // Find the condition code Operand to get its SMLoc information. 7638 SMLoc CondLoc; 7639 for (unsigned I = 1; I < Operands.size(); ++I) 7640 if (static_cast<ARMOperand &>(*Operands[I]).isCondCode()) 7641 CondLoc = Operands[I]->getStartLoc(); 7642 return Error(CondLoc, "incorrect condition in IT block; got '" + 7643 StringRef(ARMCondCodeToString(Cond)) + 7644 "', but expected '" + 7645 ARMCondCodeToString(currentITCond()) + "'"); 7646 } 7647 // Check for non-'al' condition codes outside of the IT block. 7648 } else if (isThumbTwo() && MCID.isPredicable() && 7649 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 7650 ARMCC::AL && Inst.getOpcode() != ARM::tBcc && 7651 Inst.getOpcode() != ARM::t2Bcc && 7652 Inst.getOpcode() != ARM::t2BFic) { 7653 return Error(Loc, "predicated instructions must be in IT block"); 7654 } else if (!isThumb() && !useImplicitITARM() && MCID.isPredicable() && 7655 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 7656 ARMCC::AL) { 7657 return Warning(Loc, "predicated instructions should be in IT block"); 7658 } else if (!MCID.isPredicable()) { 7659 // Check the instruction doesn't have a predicate operand anyway 7660 // that it's not allowed to use. Sometimes this happens in order 7661 // to keep instructions the same shape even though one cannot 7662 // legally be predicated, e.g. vmul.f16 vs vmul.f32. 7663 for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i) { 7664 if (MCID.OpInfo[i].isPredicate()) { 7665 if (Inst.getOperand(i).getImm() != ARMCC::AL) 7666 return Error(Loc, "instruction is not predicable"); 7667 break; 7668 } 7669 } 7670 } 7671 7672 // PC-setting instructions in an IT block, but not the last instruction of 7673 // the block, are UNPREDICTABLE. 7674 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) { 7675 return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block"); 7676 } 7677 7678 if (inVPTBlock() && !instIsBreakpoint(Inst)) { 7679 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition); 7680 if (!isVectorPredicable(MCID)) 7681 return Error(Loc, "instruction in VPT block must be predicable"); 7682 unsigned Pred = Inst.getOperand(findFirstVectorPredOperandIdx(MCID)).getImm(); 7683 unsigned VPTPred = Bit ? ARMVCC::Else : ARMVCC::Then; 7684 if (Pred != VPTPred) { 7685 SMLoc PredLoc; 7686 for (unsigned I = 1; I < Operands.size(); ++I) 7687 if (static_cast<ARMOperand &>(*Operands[I]).isVPTPred()) 7688 PredLoc = Operands[I]->getStartLoc(); 7689 return Error(PredLoc, "incorrect predication in VPT block; got '" + 7690 StringRef(ARMVPTPredToString(ARMVCC::VPTCodes(Pred))) + 7691 "', but expected '" + 7692 ARMVPTPredToString(ARMVCC::VPTCodes(VPTPred)) + "'"); 7693 } 7694 } 7695 else if (isVectorPredicable(MCID) && 7696 Inst.getOperand(findFirstVectorPredOperandIdx(MCID)).getImm() != 7697 ARMVCC::None) 7698 return Error(Loc, "VPT predicated instructions must be in VPT block"); 7699 7700 const unsigned Opcode = Inst.getOpcode(); 7701 switch (Opcode) { 7702 case ARM::t2IT: { 7703 // Encoding is unpredictable if it ever results in a notional 'NV' 7704 // predicate. Since we don't parse 'NV' directly this means an 'AL' 7705 // predicate with an "else" mask bit. 7706 unsigned Cond = Inst.getOperand(0).getImm(); 7707 unsigned Mask = Inst.getOperand(1).getImm(); 7708 7709 // Conditions only allowing a 't' are those with no set bit except 7710 // the lowest-order one that indicates the end of the sequence. In 7711 // other words, powers of 2. 7712 if (Cond == ARMCC::AL && countPopulation(Mask) != 1) 7713 return Error(Loc, "unpredictable IT predicate sequence"); 7714 break; 7715 } 7716 case ARM::LDRD: 7717 if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/true, 7718 /*Writeback*/false)) 7719 return true; 7720 break; 7721 case ARM::LDRD_PRE: 7722 case ARM::LDRD_POST: 7723 if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/true, 7724 /*Writeback*/true)) 7725 return true; 7726 break; 7727 case ARM::t2LDRDi8: 7728 if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/false, 7729 /*Writeback*/false)) 7730 return true; 7731 break; 7732 case ARM::t2LDRD_PRE: 7733 case ARM::t2LDRD_POST: 7734 if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/false, 7735 /*Writeback*/true)) 7736 return true; 7737 break; 7738 case ARM::t2BXJ: { 7739 const unsigned RmReg = Inst.getOperand(0).getReg(); 7740 // Rm = SP is no longer unpredictable in v8-A 7741 if (RmReg == ARM::SP && !hasV8Ops()) 7742 return Error(Operands[2]->getStartLoc(), 7743 "r13 (SP) is an unpredictable operand to BXJ"); 7744 return false; 7745 } 7746 case ARM::STRD: 7747 if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/true, 7748 /*Writeback*/false)) 7749 return true; 7750 break; 7751 case ARM::STRD_PRE: 7752 case ARM::STRD_POST: 7753 if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/true, 7754 /*Writeback*/true)) 7755 return true; 7756 break; 7757 case ARM::t2STRD_PRE: 7758 case ARM::t2STRD_POST: 7759 if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/false, 7760 /*Writeback*/true)) 7761 return true; 7762 break; 7763 case ARM::STR_PRE_IMM: 7764 case ARM::STR_PRE_REG: 7765 case ARM::t2STR_PRE: 7766 case ARM::STR_POST_IMM: 7767 case ARM::STR_POST_REG: 7768 case ARM::t2STR_POST: 7769 case ARM::STRH_PRE: 7770 case ARM::t2STRH_PRE: 7771 case ARM::STRH_POST: 7772 case ARM::t2STRH_POST: 7773 case ARM::STRB_PRE_IMM: 7774 case ARM::STRB_PRE_REG: 7775 case ARM::t2STRB_PRE: 7776 case ARM::STRB_POST_IMM: 7777 case ARM::STRB_POST_REG: 7778 case ARM::t2STRB_POST: { 7779 // Rt must be different from Rn. 7780 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 7781 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg()); 7782 7783 if (Rt == Rn) 7784 return Error(Operands[3]->getStartLoc(), 7785 "source register and base register can't be identical"); 7786 return false; 7787 } 7788 case ARM::t2LDR_PRE_imm: 7789 case ARM::t2LDR_POST_imm: 7790 case ARM::t2STR_PRE_imm: 7791 case ARM::t2STR_POST_imm: { 7792 // Rt must be different from Rn. 7793 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 7794 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 7795 7796 if (Rt == Rn) 7797 return Error(Operands[3]->getStartLoc(), 7798 "destination register and base register can't be identical"); 7799 if (Inst.getOpcode() == ARM::t2LDR_POST_imm || 7800 Inst.getOpcode() == ARM::t2STR_POST_imm) { 7801 int Imm = Inst.getOperand(2).getImm(); 7802 if (Imm > 255 || Imm < -255) 7803 return Error(Operands[5]->getStartLoc(), 7804 "operand must be in range [-255, 255]"); 7805 } 7806 if (Inst.getOpcode() == ARM::t2STR_PRE_imm || 7807 Inst.getOpcode() == ARM::t2STR_POST_imm) { 7808 if (Inst.getOperand(0).getReg() == ARM::PC) { 7809 return Error(Operands[3]->getStartLoc(), 7810 "operand must be a register in range [r0, r14]"); 7811 } 7812 } 7813 return false; 7814 } 7815 case ARM::LDR_PRE_IMM: 7816 case ARM::LDR_PRE_REG: 7817 case ARM::t2LDR_PRE: 7818 case ARM::LDR_POST_IMM: 7819 case ARM::LDR_POST_REG: 7820 case ARM::t2LDR_POST: 7821 case ARM::LDRH_PRE: 7822 case ARM::t2LDRH_PRE: 7823 case ARM::LDRH_POST: 7824 case ARM::t2LDRH_POST: 7825 case ARM::LDRSH_PRE: 7826 case ARM::t2LDRSH_PRE: 7827 case ARM::LDRSH_POST: 7828 case ARM::t2LDRSH_POST: 7829 case ARM::LDRB_PRE_IMM: 7830 case ARM::LDRB_PRE_REG: 7831 case ARM::t2LDRB_PRE: 7832 case ARM::LDRB_POST_IMM: 7833 case ARM::LDRB_POST_REG: 7834 case ARM::t2LDRB_POST: 7835 case ARM::LDRSB_PRE: 7836 case ARM::t2LDRSB_PRE: 7837 case ARM::LDRSB_POST: 7838 case ARM::t2LDRSB_POST: { 7839 // Rt must be different from Rn. 7840 const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 7841 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg()); 7842 7843 if (Rt == Rn) 7844 return Error(Operands[3]->getStartLoc(), 7845 "destination register and base register can't be identical"); 7846 return false; 7847 } 7848 7849 case ARM::MVE_VLDRBU8_rq: 7850 case ARM::MVE_VLDRBU16_rq: 7851 case ARM::MVE_VLDRBS16_rq: 7852 case ARM::MVE_VLDRBU32_rq: 7853 case ARM::MVE_VLDRBS32_rq: 7854 case ARM::MVE_VLDRHU16_rq: 7855 case ARM::MVE_VLDRHU16_rq_u: 7856 case ARM::MVE_VLDRHU32_rq: 7857 case ARM::MVE_VLDRHU32_rq_u: 7858 case ARM::MVE_VLDRHS32_rq: 7859 case ARM::MVE_VLDRHS32_rq_u: 7860 case ARM::MVE_VLDRWU32_rq: 7861 case ARM::MVE_VLDRWU32_rq_u: 7862 case ARM::MVE_VLDRDU64_rq: 7863 case ARM::MVE_VLDRDU64_rq_u: 7864 case ARM::MVE_VLDRWU32_qi: 7865 case ARM::MVE_VLDRWU32_qi_pre: 7866 case ARM::MVE_VLDRDU64_qi: 7867 case ARM::MVE_VLDRDU64_qi_pre: { 7868 // Qd must be different from Qm. 7869 unsigned QdIdx = 0, QmIdx = 2; 7870 bool QmIsPointer = false; 7871 switch (Opcode) { 7872 case ARM::MVE_VLDRWU32_qi: 7873 case ARM::MVE_VLDRDU64_qi: 7874 QmIdx = 1; 7875 QmIsPointer = true; 7876 break; 7877 case ARM::MVE_VLDRWU32_qi_pre: 7878 case ARM::MVE_VLDRDU64_qi_pre: 7879 QdIdx = 1; 7880 QmIsPointer = true; 7881 break; 7882 } 7883 7884 const unsigned Qd = MRI->getEncodingValue(Inst.getOperand(QdIdx).getReg()); 7885 const unsigned Qm = MRI->getEncodingValue(Inst.getOperand(QmIdx).getReg()); 7886 7887 if (Qd == Qm) { 7888 return Error(Operands[3]->getStartLoc(), 7889 Twine("destination vector register and vector ") + 7890 (QmIsPointer ? "pointer" : "offset") + 7891 " register can't be identical"); 7892 } 7893 return false; 7894 } 7895 7896 case ARM::SBFX: 7897 case ARM::t2SBFX: 7898 case ARM::UBFX: 7899 case ARM::t2UBFX: { 7900 // Width must be in range [1, 32-lsb]. 7901 unsigned LSB = Inst.getOperand(2).getImm(); 7902 unsigned Widthm1 = Inst.getOperand(3).getImm(); 7903 if (Widthm1 >= 32 - LSB) 7904 return Error(Operands[5]->getStartLoc(), 7905 "bitfield width must be in range [1,32-lsb]"); 7906 return false; 7907 } 7908 // Notionally handles ARM::tLDMIA_UPD too. 7909 case ARM::tLDMIA: { 7910 // If we're parsing Thumb2, the .w variant is available and handles 7911 // most cases that are normally illegal for a Thumb1 LDM instruction. 7912 // We'll make the transformation in processInstruction() if necessary. 7913 // 7914 // Thumb LDM instructions are writeback iff the base register is not 7915 // in the register list. 7916 unsigned Rn = Inst.getOperand(0).getReg(); 7917 bool HasWritebackToken = 7918 (static_cast<ARMOperand &>(*Operands[3]).isToken() && 7919 static_cast<ARMOperand &>(*Operands[3]).getToken() == "!"); 7920 bool ListContainsBase; 7921 if (checkLowRegisterList(Inst, 3, Rn, 0, ListContainsBase) && !isThumbTwo()) 7922 return Error(Operands[3 + HasWritebackToken]->getStartLoc(), 7923 "registers must be in range r0-r7"); 7924 // If we should have writeback, then there should be a '!' token. 7925 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo()) 7926 return Error(Operands[2]->getStartLoc(), 7927 "writeback operator '!' expected"); 7928 // If we should not have writeback, there must not be a '!'. This is 7929 // true even for the 32-bit wide encodings. 7930 if (ListContainsBase && HasWritebackToken) 7931 return Error(Operands[3]->getStartLoc(), 7932 "writeback operator '!' not allowed when base register " 7933 "in register list"); 7934 7935 if (validatetLDMRegList(Inst, Operands, 3)) 7936 return true; 7937 break; 7938 } 7939 case ARM::LDMIA_UPD: 7940 case ARM::LDMDB_UPD: 7941 case ARM::LDMIB_UPD: 7942 case ARM::LDMDA_UPD: 7943 // ARM variants loading and updating the same register are only officially 7944 // UNPREDICTABLE on v7 upwards. Goodness knows what they did before. 7945 if (!hasV7Ops()) 7946 break; 7947 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 7948 return Error(Operands.back()->getStartLoc(), 7949 "writeback register not allowed in register list"); 7950 break; 7951 case ARM::t2LDMIA: 7952 case ARM::t2LDMDB: 7953 if (validatetLDMRegList(Inst, Operands, 3)) 7954 return true; 7955 break; 7956 case ARM::t2STMIA: 7957 case ARM::t2STMDB: 7958 if (validatetSTMRegList(Inst, Operands, 3)) 7959 return true; 7960 break; 7961 case ARM::t2LDMIA_UPD: 7962 case ARM::t2LDMDB_UPD: 7963 case ARM::t2STMIA_UPD: 7964 case ARM::t2STMDB_UPD: 7965 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 7966 return Error(Operands.back()->getStartLoc(), 7967 "writeback register not allowed in register list"); 7968 7969 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) { 7970 if (validatetLDMRegList(Inst, Operands, 3)) 7971 return true; 7972 } else { 7973 if (validatetSTMRegList(Inst, Operands, 3)) 7974 return true; 7975 } 7976 break; 7977 7978 case ARM::sysLDMIA_UPD: 7979 case ARM::sysLDMDA_UPD: 7980 case ARM::sysLDMDB_UPD: 7981 case ARM::sysLDMIB_UPD: 7982 if (!listContainsReg(Inst, 3, ARM::PC)) 7983 return Error(Operands[4]->getStartLoc(), 7984 "writeback register only allowed on system LDM " 7985 "if PC in register-list"); 7986 break; 7987 case ARM::sysSTMIA_UPD: 7988 case ARM::sysSTMDA_UPD: 7989 case ARM::sysSTMDB_UPD: 7990 case ARM::sysSTMIB_UPD: 7991 return Error(Operands[2]->getStartLoc(), 7992 "system STM cannot have writeback register"); 7993 case ARM::tMUL: 7994 // The second source operand must be the same register as the destination 7995 // operand. 7996 // 7997 // In this case, we must directly check the parsed operands because the 7998 // cvtThumbMultiply() function is written in such a way that it guarantees 7999 // this first statement is always true for the new Inst. Essentially, the 8000 // destination is unconditionally copied into the second source operand 8001 // without checking to see if it matches what we actually parsed. 8002 if (Operands.size() == 6 && (((ARMOperand &)*Operands[3]).getReg() != 8003 ((ARMOperand &)*Operands[5]).getReg()) && 8004 (((ARMOperand &)*Operands[3]).getReg() != 8005 ((ARMOperand &)*Operands[4]).getReg())) { 8006 return Error(Operands[3]->getStartLoc(), 8007 "destination register must match source register"); 8008 } 8009 break; 8010 8011 // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2, 8012 // so only issue a diagnostic for thumb1. The instructions will be 8013 // switched to the t2 encodings in processInstruction() if necessary. 8014 case ARM::tPOP: { 8015 bool ListContainsBase; 8016 if (checkLowRegisterList(Inst, 2, 0, ARM::PC, ListContainsBase) && 8017 !isThumbTwo()) 8018 return Error(Operands[2]->getStartLoc(), 8019 "registers must be in range r0-r7 or pc"); 8020 if (validatetLDMRegList(Inst, Operands, 2, !isMClass())) 8021 return true; 8022 break; 8023 } 8024 case ARM::tPUSH: { 8025 bool ListContainsBase; 8026 if (checkLowRegisterList(Inst, 2, 0, ARM::LR, ListContainsBase) && 8027 !isThumbTwo()) 8028 return Error(Operands[2]->getStartLoc(), 8029 "registers must be in range r0-r7 or lr"); 8030 if (validatetSTMRegList(Inst, Operands, 2)) 8031 return true; 8032 break; 8033 } 8034 case ARM::tSTMIA_UPD: { 8035 bool ListContainsBase, InvalidLowList; 8036 InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(), 8037 0, ListContainsBase); 8038 if (InvalidLowList && !isThumbTwo()) 8039 return Error(Operands[4]->getStartLoc(), 8040 "registers must be in range r0-r7"); 8041 8042 // This would be converted to a 32-bit stm, but that's not valid if the 8043 // writeback register is in the list. 8044 if (InvalidLowList && ListContainsBase) 8045 return Error(Operands[4]->getStartLoc(), 8046 "writeback operator '!' not allowed when base register " 8047 "in register list"); 8048 8049 if (validatetSTMRegList(Inst, Operands, 4)) 8050 return true; 8051 break; 8052 } 8053 case ARM::tADDrSP: 8054 // If the non-SP source operand and the destination operand are not the 8055 // same, we need thumb2 (for the wide encoding), or we have an error. 8056 if (!isThumbTwo() && 8057 Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) { 8058 return Error(Operands[4]->getStartLoc(), 8059 "source register must be the same as destination"); 8060 } 8061 break; 8062 8063 case ARM::t2ADDrr: 8064 case ARM::t2ADDrs: 8065 case ARM::t2SUBrr: 8066 case ARM::t2SUBrs: 8067 if (Inst.getOperand(0).getReg() == ARM::SP && 8068 Inst.getOperand(1).getReg() != ARM::SP) 8069 return Error(Operands[4]->getStartLoc(), 8070 "source register must be sp if destination is sp"); 8071 break; 8072 8073 // Final range checking for Thumb unconditional branch instructions. 8074 case ARM::tB: 8075 if (!(static_cast<ARMOperand &>(*Operands[2])).isSignedOffset<11, 1>()) 8076 return Error(Operands[2]->getStartLoc(), "branch target out of range"); 8077 break; 8078 case ARM::t2B: { 8079 int op = (Operands[2]->isImm()) ? 2 : 3; 8080 ARMOperand &Operand = static_cast<ARMOperand &>(*Operands[op]); 8081 // Delay the checks of symbolic expressions until they are resolved. 8082 if (!isa<MCBinaryExpr>(Operand.getImm()) && 8083 !Operand.isSignedOffset<24, 1>()) 8084 return Error(Operands[op]->getStartLoc(), "branch target out of range"); 8085 break; 8086 } 8087 // Final range checking for Thumb conditional branch instructions. 8088 case ARM::tBcc: 8089 if (!static_cast<ARMOperand &>(*Operands[2]).isSignedOffset<8, 1>()) 8090 return Error(Operands[2]->getStartLoc(), "branch target out of range"); 8091 break; 8092 case ARM::t2Bcc: { 8093 int Op = (Operands[2]->isImm()) ? 2 : 3; 8094 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>()) 8095 return Error(Operands[Op]->getStartLoc(), "branch target out of range"); 8096 break; 8097 } 8098 case ARM::tCBZ: 8099 case ARM::tCBNZ: { 8100 if (!static_cast<ARMOperand &>(*Operands[2]).isUnsignedOffset<6, 1>()) 8101 return Error(Operands[2]->getStartLoc(), "branch target out of range"); 8102 break; 8103 } 8104 case ARM::MOVi16: 8105 case ARM::MOVTi16: 8106 case ARM::t2MOVi16: 8107 case ARM::t2MOVTi16: 8108 { 8109 // We want to avoid misleadingly allowing something like "mov r0, <symbol>" 8110 // especially when we turn it into a movw and the expression <symbol> does 8111 // not have a :lower16: or :upper16 as part of the expression. We don't 8112 // want the behavior of silently truncating, which can be unexpected and 8113 // lead to bugs that are difficult to find since this is an easy mistake 8114 // to make. 8115 int i = (Operands[3]->isImm()) ? 3 : 4; 8116 ARMOperand &Op = static_cast<ARMOperand &>(*Operands[i]); 8117 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()); 8118 if (CE) break; 8119 const MCExpr *E = dyn_cast<MCExpr>(Op.getImm()); 8120 if (!E) break; 8121 const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(E); 8122 if (!ARM16Expr || (ARM16Expr->getKind() != ARMMCExpr::VK_ARM_HI16 && 8123 ARM16Expr->getKind() != ARMMCExpr::VK_ARM_LO16)) 8124 return Error( 8125 Op.getStartLoc(), 8126 "immediate expression for mov requires :lower16: or :upper16"); 8127 break; 8128 } 8129 case ARM::HINT: 8130 case ARM::t2HINT: { 8131 unsigned Imm8 = Inst.getOperand(0).getImm(); 8132 unsigned Pred = Inst.getOperand(1).getImm(); 8133 // ESB is not predicable (pred must be AL). Without the RAS extension, this 8134 // behaves as any other unallocated hint. 8135 if (Imm8 == 0x10 && Pred != ARMCC::AL && hasRAS()) 8136 return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not " 8137 "predicable, but condition " 8138 "code specified"); 8139 if (Imm8 == 0x14 && Pred != ARMCC::AL) 8140 return Error(Operands[1]->getStartLoc(), "instruction 'csdb' is not " 8141 "predicable, but condition " 8142 "code specified"); 8143 break; 8144 } 8145 case ARM::t2BFi: 8146 case ARM::t2BFr: 8147 case ARM::t2BFLi: 8148 case ARM::t2BFLr: { 8149 if (!static_cast<ARMOperand &>(*Operands[2]).isUnsignedOffset<4, 1>() || 8150 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0)) 8151 return Error(Operands[2]->getStartLoc(), 8152 "branch location out of range or not a multiple of 2"); 8153 8154 if (Opcode == ARM::t2BFi) { 8155 if (!static_cast<ARMOperand &>(*Operands[3]).isSignedOffset<16, 1>()) 8156 return Error(Operands[3]->getStartLoc(), 8157 "branch target out of range or not a multiple of 2"); 8158 } else if (Opcode == ARM::t2BFLi) { 8159 if (!static_cast<ARMOperand &>(*Operands[3]).isSignedOffset<18, 1>()) 8160 return Error(Operands[3]->getStartLoc(), 8161 "branch target out of range or not a multiple of 2"); 8162 } 8163 break; 8164 } 8165 case ARM::t2BFic: { 8166 if (!static_cast<ARMOperand &>(*Operands[1]).isUnsignedOffset<4, 1>() || 8167 (Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == 0)) 8168 return Error(Operands[1]->getStartLoc(), 8169 "branch location out of range or not a multiple of 2"); 8170 8171 if (!static_cast<ARMOperand &>(*Operands[2]).isSignedOffset<16, 1>()) 8172 return Error(Operands[2]->getStartLoc(), 8173 "branch target out of range or not a multiple of 2"); 8174 8175 assert(Inst.getOperand(0).isImm() == Inst.getOperand(2).isImm() && 8176 "branch location and else branch target should either both be " 8177 "immediates or both labels"); 8178 8179 if (Inst.getOperand(0).isImm() && Inst.getOperand(2).isImm()) { 8180 int Diff = Inst.getOperand(2).getImm() - Inst.getOperand(0).getImm(); 8181 if (Diff != 4 && Diff != 2) 8182 return Error( 8183 Operands[3]->getStartLoc(), 8184 "else branch target must be 2 or 4 greater than the branch location"); 8185 } 8186 break; 8187 } 8188 case ARM::t2CLRM: { 8189 for (unsigned i = 2; i < Inst.getNumOperands(); i++) { 8190 if (Inst.getOperand(i).isReg() && 8191 !ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains( 8192 Inst.getOperand(i).getReg())) { 8193 return Error(Operands[2]->getStartLoc(), 8194 "invalid register in register list. Valid registers are " 8195 "r0-r12, lr/r14 and APSR."); 8196 } 8197 } 8198 break; 8199 } 8200 case ARM::DSB: 8201 case ARM::t2DSB: { 8202 8203 if (Inst.getNumOperands() < 2) 8204 break; 8205 8206 unsigned Option = Inst.getOperand(0).getImm(); 8207 unsigned Pred = Inst.getOperand(1).getImm(); 8208 8209 // SSBB and PSSBB (DSB #0|#4) are not predicable (pred must be AL). 8210 if (Option == 0 && Pred != ARMCC::AL) 8211 return Error(Operands[1]->getStartLoc(), 8212 "instruction 'ssbb' is not predicable, but condition code " 8213 "specified"); 8214 if (Option == 4 && Pred != ARMCC::AL) 8215 return Error(Operands[1]->getStartLoc(), 8216 "instruction 'pssbb' is not predicable, but condition code " 8217 "specified"); 8218 break; 8219 } 8220 case ARM::VMOVRRS: { 8221 // Source registers must be sequential. 8222 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(2).getReg()); 8223 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(3).getReg()); 8224 if (Sm1 != Sm + 1) 8225 return Error(Operands[5]->getStartLoc(), 8226 "source operands must be sequential"); 8227 break; 8228 } 8229 case ARM::VMOVSRR: { 8230 // Destination registers must be sequential. 8231 const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 8232 const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 8233 if (Sm1 != Sm + 1) 8234 return Error(Operands[3]->getStartLoc(), 8235 "destination operands must be sequential"); 8236 break; 8237 } 8238 case ARM::VLDMDIA: 8239 case ARM::VSTMDIA: { 8240 ARMOperand &Op = static_cast<ARMOperand&>(*Operands[3]); 8241 auto &RegList = Op.getRegList(); 8242 if (RegList.size() < 1 || RegList.size() > 16) 8243 return Error(Operands[3]->getStartLoc(), 8244 "list of registers must be at least 1 and at most 16"); 8245 break; 8246 } 8247 case ARM::MVE_VQDMULLs32bh: 8248 case ARM::MVE_VQDMULLs32th: 8249 case ARM::MVE_VCMULf32: 8250 case ARM::MVE_VMULLBs32: 8251 case ARM::MVE_VMULLTs32: 8252 case ARM::MVE_VMULLBu32: 8253 case ARM::MVE_VMULLTu32: { 8254 if (Operands[3]->getReg() == Operands[4]->getReg()) { 8255 return Error (Operands[3]->getStartLoc(), 8256 "Qd register and Qn register can't be identical"); 8257 } 8258 if (Operands[3]->getReg() == Operands[5]->getReg()) { 8259 return Error (Operands[3]->getStartLoc(), 8260 "Qd register and Qm register can't be identical"); 8261 } 8262 break; 8263 } 8264 case ARM::MVE_VMOV_rr_q: { 8265 if (Operands[4]->getReg() != Operands[6]->getReg()) 8266 return Error (Operands[4]->getStartLoc(), "Q-registers must be the same"); 8267 if (static_cast<ARMOperand &>(*Operands[5]).getVectorIndex() != 8268 static_cast<ARMOperand &>(*Operands[7]).getVectorIndex() + 2) 8269 return Error (Operands[5]->getStartLoc(), "Q-register indexes must be 2 and 0 or 3 and 1"); 8270 break; 8271 } 8272 case ARM::MVE_VMOV_q_rr: { 8273 if (Operands[2]->getReg() != Operands[4]->getReg()) 8274 return Error (Operands[2]->getStartLoc(), "Q-registers must be the same"); 8275 if (static_cast<ARMOperand &>(*Operands[3]).getVectorIndex() != 8276 static_cast<ARMOperand &>(*Operands[5]).getVectorIndex() + 2) 8277 return Error (Operands[3]->getStartLoc(), "Q-register indexes must be 2 and 0 or 3 and 1"); 8278 break; 8279 } 8280 case ARM::UMAAL: 8281 case ARM::UMLAL: 8282 case ARM::UMULL: 8283 case ARM::t2UMAAL: 8284 case ARM::t2UMLAL: 8285 case ARM::t2UMULL: 8286 case ARM::SMLAL: 8287 case ARM::SMLALBB: 8288 case ARM::SMLALBT: 8289 case ARM::SMLALD: 8290 case ARM::SMLALDX: 8291 case ARM::SMLALTB: 8292 case ARM::SMLALTT: 8293 case ARM::SMLSLD: 8294 case ARM::SMLSLDX: 8295 case ARM::SMULL: 8296 case ARM::t2SMLAL: 8297 case ARM::t2SMLALBB: 8298 case ARM::t2SMLALBT: 8299 case ARM::t2SMLALD: 8300 case ARM::t2SMLALDX: 8301 case ARM::t2SMLALTB: 8302 case ARM::t2SMLALTT: 8303 case ARM::t2SMLSLD: 8304 case ARM::t2SMLSLDX: 8305 case ARM::t2SMULL: { 8306 unsigned RdHi = Inst.getOperand(0).getReg(); 8307 unsigned RdLo = Inst.getOperand(1).getReg(); 8308 if(RdHi == RdLo) { 8309 return Error(Loc, 8310 "unpredictable instruction, RdHi and RdLo must be different"); 8311 } 8312 break; 8313 } 8314 8315 case ARM::CDE_CX1: 8316 case ARM::CDE_CX1A: 8317 case ARM::CDE_CX1D: 8318 case ARM::CDE_CX1DA: 8319 case ARM::CDE_CX2: 8320 case ARM::CDE_CX2A: 8321 case ARM::CDE_CX2D: 8322 case ARM::CDE_CX2DA: 8323 case ARM::CDE_CX3: 8324 case ARM::CDE_CX3A: 8325 case ARM::CDE_CX3D: 8326 case ARM::CDE_CX3DA: 8327 case ARM::CDE_VCX1_vec: 8328 case ARM::CDE_VCX1_fpsp: 8329 case ARM::CDE_VCX1_fpdp: 8330 case ARM::CDE_VCX1A_vec: 8331 case ARM::CDE_VCX1A_fpsp: 8332 case ARM::CDE_VCX1A_fpdp: 8333 case ARM::CDE_VCX2_vec: 8334 case ARM::CDE_VCX2_fpsp: 8335 case ARM::CDE_VCX2_fpdp: 8336 case ARM::CDE_VCX2A_vec: 8337 case ARM::CDE_VCX2A_fpsp: 8338 case ARM::CDE_VCX2A_fpdp: 8339 case ARM::CDE_VCX3_vec: 8340 case ARM::CDE_VCX3_fpsp: 8341 case ARM::CDE_VCX3_fpdp: 8342 case ARM::CDE_VCX3A_vec: 8343 case ARM::CDE_VCX3A_fpsp: 8344 case ARM::CDE_VCX3A_fpdp: { 8345 assert(Inst.getOperand(1).isImm() && 8346 "CDE operand 1 must be a coprocessor ID"); 8347 int64_t Coproc = Inst.getOperand(1).getImm(); 8348 if (Coproc < 8 && !ARM::isCDECoproc(Coproc, *STI)) 8349 return Error(Operands[1]->getStartLoc(), 8350 "coprocessor must be configured as CDE"); 8351 else if (Coproc >= 8) 8352 return Error(Operands[1]->getStartLoc(), 8353 "coprocessor must be in the range [p0, p7]"); 8354 break; 8355 } 8356 8357 case ARM::t2CDP: 8358 case ARM::t2CDP2: 8359 case ARM::t2LDC2L_OFFSET: 8360 case ARM::t2LDC2L_OPTION: 8361 case ARM::t2LDC2L_POST: 8362 case ARM::t2LDC2L_PRE: 8363 case ARM::t2LDC2_OFFSET: 8364 case ARM::t2LDC2_OPTION: 8365 case ARM::t2LDC2_POST: 8366 case ARM::t2LDC2_PRE: 8367 case ARM::t2LDCL_OFFSET: 8368 case ARM::t2LDCL_OPTION: 8369 case ARM::t2LDCL_POST: 8370 case ARM::t2LDCL_PRE: 8371 case ARM::t2LDC_OFFSET: 8372 case ARM::t2LDC_OPTION: 8373 case ARM::t2LDC_POST: 8374 case ARM::t2LDC_PRE: 8375 case ARM::t2MCR: 8376 case ARM::t2MCR2: 8377 case ARM::t2MCRR: 8378 case ARM::t2MCRR2: 8379 case ARM::t2MRC: 8380 case ARM::t2MRC2: 8381 case ARM::t2MRRC: 8382 case ARM::t2MRRC2: 8383 case ARM::t2STC2L_OFFSET: 8384 case ARM::t2STC2L_OPTION: 8385 case ARM::t2STC2L_POST: 8386 case ARM::t2STC2L_PRE: 8387 case ARM::t2STC2_OFFSET: 8388 case ARM::t2STC2_OPTION: 8389 case ARM::t2STC2_POST: 8390 case ARM::t2STC2_PRE: 8391 case ARM::t2STCL_OFFSET: 8392 case ARM::t2STCL_OPTION: 8393 case ARM::t2STCL_POST: 8394 case ARM::t2STCL_PRE: 8395 case ARM::t2STC_OFFSET: 8396 case ARM::t2STC_OPTION: 8397 case ARM::t2STC_POST: 8398 case ARM::t2STC_PRE: { 8399 unsigned Opcode = Inst.getOpcode(); 8400 // Inst.getOperand indexes operands in the (oops ...) and (iops ...) dags, 8401 // CopInd is the index of the coprocessor operand. 8402 size_t CopInd = 0; 8403 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2) 8404 CopInd = 2; 8405 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2) 8406 CopInd = 1; 8407 assert(Inst.getOperand(CopInd).isImm() && 8408 "Operand must be a coprocessor ID"); 8409 int64_t Coproc = Inst.getOperand(CopInd).getImm(); 8410 // Operands[2] is the coprocessor operand at syntactic level 8411 if (ARM::isCDECoproc(Coproc, *STI)) 8412 return Error(Operands[2]->getStartLoc(), 8413 "coprocessor must be configured as GCP"); 8414 break; 8415 } 8416 } 8417 8418 return false; 8419 } 8420 8421 static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) { 8422 switch(Opc) { 8423 default: llvm_unreachable("unexpected opcode!"); 8424 // VST1LN 8425 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD; 8426 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD; 8427 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD; 8428 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD; 8429 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD; 8430 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD; 8431 case ARM::VST1LNdAsm_8: Spacing = 1; return ARM::VST1LNd8; 8432 case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16; 8433 case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32; 8434 8435 // VST2LN 8436 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD; 8437 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD; 8438 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD; 8439 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD; 8440 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD; 8441 8442 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD; 8443 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD; 8444 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD; 8445 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD; 8446 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD; 8447 8448 case ARM::VST2LNdAsm_8: Spacing = 1; return ARM::VST2LNd8; 8449 case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16; 8450 case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32; 8451 case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16; 8452 case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32; 8453 8454 // VST3LN 8455 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD; 8456 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD; 8457 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD; 8458 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD; 8459 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD; 8460 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD; 8461 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD; 8462 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD; 8463 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD; 8464 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD; 8465 case ARM::VST3LNdAsm_8: Spacing = 1; return ARM::VST3LNd8; 8466 case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16; 8467 case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32; 8468 case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16; 8469 case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32; 8470 8471 // VST3 8472 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1; return ARM::VST3d8_UPD; 8473 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD; 8474 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD; 8475 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2; return ARM::VST3q8_UPD; 8476 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD; 8477 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD; 8478 case ARM::VST3dWB_register_Asm_8: Spacing = 1; return ARM::VST3d8_UPD; 8479 case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD; 8480 case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD; 8481 case ARM::VST3qWB_register_Asm_8: Spacing = 2; return ARM::VST3q8_UPD; 8482 case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD; 8483 case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD; 8484 case ARM::VST3dAsm_8: Spacing = 1; return ARM::VST3d8; 8485 case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16; 8486 case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32; 8487 case ARM::VST3qAsm_8: Spacing = 2; return ARM::VST3q8; 8488 case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16; 8489 case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32; 8490 8491 // VST4LN 8492 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD; 8493 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD; 8494 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD; 8495 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD; 8496 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD; 8497 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD; 8498 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD; 8499 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD; 8500 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD; 8501 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD; 8502 case ARM::VST4LNdAsm_8: Spacing = 1; return ARM::VST4LNd8; 8503 case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16; 8504 case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32; 8505 case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16; 8506 case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32; 8507 8508 // VST4 8509 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1; return ARM::VST4d8_UPD; 8510 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD; 8511 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD; 8512 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2; return ARM::VST4q8_UPD; 8513 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD; 8514 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD; 8515 case ARM::VST4dWB_register_Asm_8: Spacing = 1; return ARM::VST4d8_UPD; 8516 case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD; 8517 case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD; 8518 case ARM::VST4qWB_register_Asm_8: Spacing = 2; return ARM::VST4q8_UPD; 8519 case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD; 8520 case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD; 8521 case ARM::VST4dAsm_8: Spacing = 1; return ARM::VST4d8; 8522 case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16; 8523 case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32; 8524 case ARM::VST4qAsm_8: Spacing = 2; return ARM::VST4q8; 8525 case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16; 8526 case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32; 8527 } 8528 } 8529 8530 static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) { 8531 switch(Opc) { 8532 default: llvm_unreachable("unexpected opcode!"); 8533 // VLD1LN 8534 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD; 8535 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD; 8536 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD; 8537 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD; 8538 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD; 8539 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD; 8540 case ARM::VLD1LNdAsm_8: Spacing = 1; return ARM::VLD1LNd8; 8541 case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16; 8542 case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32; 8543 8544 // VLD2LN 8545 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD; 8546 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD; 8547 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD; 8548 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD; 8549 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD; 8550 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD; 8551 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD; 8552 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD; 8553 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD; 8554 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD; 8555 case ARM::VLD2LNdAsm_8: Spacing = 1; return ARM::VLD2LNd8; 8556 case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16; 8557 case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32; 8558 case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16; 8559 case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32; 8560 8561 // VLD3DUP 8562 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD; 8563 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD; 8564 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD; 8565 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD; 8566 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD; 8567 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD; 8568 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD; 8569 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD; 8570 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD; 8571 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD; 8572 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD; 8573 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD; 8574 case ARM::VLD3DUPdAsm_8: Spacing = 1; return ARM::VLD3DUPd8; 8575 case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16; 8576 case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32; 8577 case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8; 8578 case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16; 8579 case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32; 8580 8581 // VLD3LN 8582 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD; 8583 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD; 8584 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD; 8585 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD; 8586 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD; 8587 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD; 8588 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD; 8589 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD; 8590 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD; 8591 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD; 8592 case ARM::VLD3LNdAsm_8: Spacing = 1; return ARM::VLD3LNd8; 8593 case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16; 8594 case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32; 8595 case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16; 8596 case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32; 8597 8598 // VLD3 8599 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD; 8600 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD; 8601 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD; 8602 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD; 8603 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD; 8604 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD; 8605 case ARM::VLD3dWB_register_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD; 8606 case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD; 8607 case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD; 8608 case ARM::VLD3qWB_register_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD; 8609 case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD; 8610 case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD; 8611 case ARM::VLD3dAsm_8: Spacing = 1; return ARM::VLD3d8; 8612 case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16; 8613 case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32; 8614 case ARM::VLD3qAsm_8: Spacing = 2; return ARM::VLD3q8; 8615 case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16; 8616 case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32; 8617 8618 // VLD4LN 8619 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD; 8620 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD; 8621 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD; 8622 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD; 8623 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD; 8624 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD; 8625 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD; 8626 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD; 8627 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD; 8628 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD; 8629 case ARM::VLD4LNdAsm_8: Spacing = 1; return ARM::VLD4LNd8; 8630 case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16; 8631 case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32; 8632 case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16; 8633 case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32; 8634 8635 // VLD4DUP 8636 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD; 8637 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD; 8638 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD; 8639 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD; 8640 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD; 8641 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD; 8642 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD; 8643 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD; 8644 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD; 8645 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD; 8646 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD; 8647 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD; 8648 case ARM::VLD4DUPdAsm_8: Spacing = 1; return ARM::VLD4DUPd8; 8649 case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16; 8650 case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32; 8651 case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8; 8652 case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16; 8653 case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32; 8654 8655 // VLD4 8656 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD; 8657 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD; 8658 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD; 8659 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD; 8660 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD; 8661 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD; 8662 case ARM::VLD4dWB_register_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD; 8663 case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD; 8664 case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD; 8665 case ARM::VLD4qWB_register_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD; 8666 case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD; 8667 case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD; 8668 case ARM::VLD4dAsm_8: Spacing = 1; return ARM::VLD4d8; 8669 case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16; 8670 case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32; 8671 case ARM::VLD4qAsm_8: Spacing = 2; return ARM::VLD4q8; 8672 case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16; 8673 case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32; 8674 } 8675 } 8676 8677 bool ARMAsmParser::processInstruction(MCInst &Inst, 8678 const OperandVector &Operands, 8679 MCStreamer &Out) { 8680 // Check if we have the wide qualifier, because if it's present we 8681 // must avoid selecting a 16-bit thumb instruction. 8682 bool HasWideQualifier = false; 8683 for (auto &Op : Operands) { 8684 ARMOperand &ARMOp = static_cast<ARMOperand&>(*Op); 8685 if (ARMOp.isToken() && ARMOp.getToken() == ".w") { 8686 HasWideQualifier = true; 8687 break; 8688 } 8689 } 8690 8691 switch (Inst.getOpcode()) { 8692 // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction. 8693 case ARM::LDRT_POST: 8694 case ARM::LDRBT_POST: { 8695 const unsigned Opcode = 8696 (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM 8697 : ARM::LDRBT_POST_IMM; 8698 MCInst TmpInst; 8699 TmpInst.setOpcode(Opcode); 8700 TmpInst.addOperand(Inst.getOperand(0)); 8701 TmpInst.addOperand(Inst.getOperand(1)); 8702 TmpInst.addOperand(Inst.getOperand(1)); 8703 TmpInst.addOperand(MCOperand::createReg(0)); 8704 TmpInst.addOperand(MCOperand::createImm(0)); 8705 TmpInst.addOperand(Inst.getOperand(2)); 8706 TmpInst.addOperand(Inst.getOperand(3)); 8707 Inst = TmpInst; 8708 return true; 8709 } 8710 // Alias for 'ldr{sb,h,sh}t Rt, [Rn] {, #imm}' for ommitted immediate. 8711 case ARM::LDRSBTii: 8712 case ARM::LDRHTii: 8713 case ARM::LDRSHTii: { 8714 MCInst TmpInst; 8715 8716 if (Inst.getOpcode() == ARM::LDRSBTii) 8717 TmpInst.setOpcode(ARM::LDRSBTi); 8718 else if (Inst.getOpcode() == ARM::LDRHTii) 8719 TmpInst.setOpcode(ARM::LDRHTi); 8720 else if (Inst.getOpcode() == ARM::LDRSHTii) 8721 TmpInst.setOpcode(ARM::LDRSHTi); 8722 TmpInst.addOperand(Inst.getOperand(0)); 8723 TmpInst.addOperand(Inst.getOperand(1)); 8724 TmpInst.addOperand(Inst.getOperand(1)); 8725 TmpInst.addOperand(MCOperand::createImm(256)); 8726 TmpInst.addOperand(Inst.getOperand(2)); 8727 Inst = TmpInst; 8728 return true; 8729 } 8730 // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction. 8731 case ARM::STRT_POST: 8732 case ARM::STRBT_POST: { 8733 const unsigned Opcode = 8734 (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM 8735 : ARM::STRBT_POST_IMM; 8736 MCInst TmpInst; 8737 TmpInst.setOpcode(Opcode); 8738 TmpInst.addOperand(Inst.getOperand(1)); 8739 TmpInst.addOperand(Inst.getOperand(0)); 8740 TmpInst.addOperand(Inst.getOperand(1)); 8741 TmpInst.addOperand(MCOperand::createReg(0)); 8742 TmpInst.addOperand(MCOperand::createImm(0)); 8743 TmpInst.addOperand(Inst.getOperand(2)); 8744 TmpInst.addOperand(Inst.getOperand(3)); 8745 Inst = TmpInst; 8746 return true; 8747 } 8748 // Alias for alternate form of 'ADR Rd, #imm' instruction. 8749 case ARM::ADDri: { 8750 if (Inst.getOperand(1).getReg() != ARM::PC || 8751 Inst.getOperand(5).getReg() != 0 || 8752 !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm())) 8753 return false; 8754 MCInst TmpInst; 8755 TmpInst.setOpcode(ARM::ADR); 8756 TmpInst.addOperand(Inst.getOperand(0)); 8757 if (Inst.getOperand(2).isImm()) { 8758 // Immediate (mod_imm) will be in its encoded form, we must unencode it 8759 // before passing it to the ADR instruction. 8760 unsigned Enc = Inst.getOperand(2).getImm(); 8761 TmpInst.addOperand(MCOperand::createImm( 8762 ARM_AM::rotr32(Enc & 0xFF, (Enc & 0xF00) >> 7))); 8763 } else { 8764 // Turn PC-relative expression into absolute expression. 8765 // Reading PC provides the start of the current instruction + 8 and 8766 // the transform to adr is biased by that. 8767 MCSymbol *Dot = getContext().createTempSymbol(); 8768 Out.emitLabel(Dot); 8769 const MCExpr *OpExpr = Inst.getOperand(2).getExpr(); 8770 const MCExpr *InstPC = MCSymbolRefExpr::create(Dot, 8771 MCSymbolRefExpr::VK_None, 8772 getContext()); 8773 const MCExpr *Const8 = MCConstantExpr::create(8, getContext()); 8774 const MCExpr *ReadPC = MCBinaryExpr::createAdd(InstPC, Const8, 8775 getContext()); 8776 const MCExpr *FixupAddr = MCBinaryExpr::createAdd(ReadPC, OpExpr, 8777 getContext()); 8778 TmpInst.addOperand(MCOperand::createExpr(FixupAddr)); 8779 } 8780 TmpInst.addOperand(Inst.getOperand(3)); 8781 TmpInst.addOperand(Inst.getOperand(4)); 8782 Inst = TmpInst; 8783 return true; 8784 } 8785 // Aliases for imm syntax of LDR instructions. 8786 case ARM::t2LDR_PRE_imm: 8787 case ARM::t2LDR_POST_imm: { 8788 MCInst TmpInst; 8789 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2LDR_PRE_imm ? ARM::t2LDR_PRE 8790 : ARM::t2LDR_POST); 8791 TmpInst.addOperand(Inst.getOperand(0)); // Rt 8792 TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb 8793 TmpInst.addOperand(Inst.getOperand(1)); // Rn 8794 TmpInst.addOperand(Inst.getOperand(2)); // imm 8795 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 8796 Inst = TmpInst; 8797 return true; 8798 } 8799 // Aliases for imm syntax of STR instructions. 8800 case ARM::t2STR_PRE_imm: 8801 case ARM::t2STR_POST_imm: { 8802 MCInst TmpInst; 8803 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2STR_PRE_imm ? ARM::t2STR_PRE 8804 : ARM::t2STR_POST); 8805 TmpInst.addOperand(Inst.getOperand(4)); // Rt_wb 8806 TmpInst.addOperand(Inst.getOperand(0)); // Rt 8807 TmpInst.addOperand(Inst.getOperand(1)); // Rn 8808 TmpInst.addOperand(Inst.getOperand(2)); // imm 8809 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 8810 Inst = TmpInst; 8811 return true; 8812 } 8813 // Aliases for alternate PC+imm syntax of LDR instructions. 8814 case ARM::t2LDRpcrel: 8815 // Select the narrow version if the immediate will fit. 8816 if (Inst.getOperand(1).getImm() > 0 && 8817 Inst.getOperand(1).getImm() <= 0xff && 8818 !HasWideQualifier) 8819 Inst.setOpcode(ARM::tLDRpci); 8820 else 8821 Inst.setOpcode(ARM::t2LDRpci); 8822 return true; 8823 case ARM::t2LDRBpcrel: 8824 Inst.setOpcode(ARM::t2LDRBpci); 8825 return true; 8826 case ARM::t2LDRHpcrel: 8827 Inst.setOpcode(ARM::t2LDRHpci); 8828 return true; 8829 case ARM::t2LDRSBpcrel: 8830 Inst.setOpcode(ARM::t2LDRSBpci); 8831 return true; 8832 case ARM::t2LDRSHpcrel: 8833 Inst.setOpcode(ARM::t2LDRSHpci); 8834 return true; 8835 case ARM::LDRConstPool: 8836 case ARM::tLDRConstPool: 8837 case ARM::t2LDRConstPool: { 8838 // Pseudo instruction ldr rt, =immediate is converted to a 8839 // MOV rt, immediate if immediate is known and representable 8840 // otherwise we create a constant pool entry that we load from. 8841 MCInst TmpInst; 8842 if (Inst.getOpcode() == ARM::LDRConstPool) 8843 TmpInst.setOpcode(ARM::LDRi12); 8844 else if (Inst.getOpcode() == ARM::tLDRConstPool) 8845 TmpInst.setOpcode(ARM::tLDRpci); 8846 else if (Inst.getOpcode() == ARM::t2LDRConstPool) 8847 TmpInst.setOpcode(ARM::t2LDRpci); 8848 const ARMOperand &PoolOperand = 8849 (HasWideQualifier ? 8850 static_cast<ARMOperand &>(*Operands[4]) : 8851 static_cast<ARMOperand &>(*Operands[3])); 8852 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm(); 8853 // If SubExprVal is a constant we may be able to use a MOV 8854 if (isa<MCConstantExpr>(SubExprVal) && 8855 Inst.getOperand(0).getReg() != ARM::PC && 8856 Inst.getOperand(0).getReg() != ARM::SP) { 8857 int64_t Value = 8858 (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue(); 8859 bool UseMov = true; 8860 bool MovHasS = true; 8861 if (Inst.getOpcode() == ARM::LDRConstPool) { 8862 // ARM Constant 8863 if (ARM_AM::getSOImmVal(Value) != -1) { 8864 Value = ARM_AM::getSOImmVal(Value); 8865 TmpInst.setOpcode(ARM::MOVi); 8866 } 8867 else if (ARM_AM::getSOImmVal(~Value) != -1) { 8868 Value = ARM_AM::getSOImmVal(~Value); 8869 TmpInst.setOpcode(ARM::MVNi); 8870 } 8871 else if (hasV6T2Ops() && 8872 Value >=0 && Value < 65536) { 8873 TmpInst.setOpcode(ARM::MOVi16); 8874 MovHasS = false; 8875 } 8876 else 8877 UseMov = false; 8878 } 8879 else { 8880 // Thumb/Thumb2 Constant 8881 if (hasThumb2() && 8882 ARM_AM::getT2SOImmVal(Value) != -1) 8883 TmpInst.setOpcode(ARM::t2MOVi); 8884 else if (hasThumb2() && 8885 ARM_AM::getT2SOImmVal(~Value) != -1) { 8886 TmpInst.setOpcode(ARM::t2MVNi); 8887 Value = ~Value; 8888 } 8889 else if (hasV8MBaseline() && 8890 Value >=0 && Value < 65536) { 8891 TmpInst.setOpcode(ARM::t2MOVi16); 8892 MovHasS = false; 8893 } 8894 else 8895 UseMov = false; 8896 } 8897 if (UseMov) { 8898 TmpInst.addOperand(Inst.getOperand(0)); // Rt 8899 TmpInst.addOperand(MCOperand::createImm(Value)); // Immediate 8900 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 8901 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 8902 if (MovHasS) 8903 TmpInst.addOperand(MCOperand::createReg(0)); // S 8904 Inst = TmpInst; 8905 return true; 8906 } 8907 } 8908 // No opportunity to use MOV/MVN create constant pool 8909 const MCExpr *CPLoc = 8910 getTargetStreamer().addConstantPoolEntry(SubExprVal, 8911 PoolOperand.getStartLoc()); 8912 TmpInst.addOperand(Inst.getOperand(0)); // Rt 8913 TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool 8914 if (TmpInst.getOpcode() == ARM::LDRi12) 8915 TmpInst.addOperand(MCOperand::createImm(0)); // unused offset 8916 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 8917 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 8918 Inst = TmpInst; 8919 return true; 8920 } 8921 // Handle NEON VST complex aliases. 8922 case ARM::VST1LNdWB_register_Asm_8: 8923 case ARM::VST1LNdWB_register_Asm_16: 8924 case ARM::VST1LNdWB_register_Asm_32: { 8925 MCInst TmpInst; 8926 // Shuffle the operands around so the lane index operand is in the 8927 // right place. 8928 unsigned Spacing; 8929 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 8930 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 8931 TmpInst.addOperand(Inst.getOperand(2)); // Rn 8932 TmpInst.addOperand(Inst.getOperand(3)); // alignment 8933 TmpInst.addOperand(Inst.getOperand(4)); // Rm 8934 TmpInst.addOperand(Inst.getOperand(0)); // Vd 8935 TmpInst.addOperand(Inst.getOperand(1)); // lane 8936 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 8937 TmpInst.addOperand(Inst.getOperand(6)); 8938 Inst = TmpInst; 8939 return true; 8940 } 8941 8942 case ARM::VST2LNdWB_register_Asm_8: 8943 case ARM::VST2LNdWB_register_Asm_16: 8944 case ARM::VST2LNdWB_register_Asm_32: 8945 case ARM::VST2LNqWB_register_Asm_16: 8946 case ARM::VST2LNqWB_register_Asm_32: { 8947 MCInst TmpInst; 8948 // Shuffle the operands around so the lane index operand is in the 8949 // right place. 8950 unsigned Spacing; 8951 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 8952 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 8953 TmpInst.addOperand(Inst.getOperand(2)); // Rn 8954 TmpInst.addOperand(Inst.getOperand(3)); // alignment 8955 TmpInst.addOperand(Inst.getOperand(4)); // Rm 8956 TmpInst.addOperand(Inst.getOperand(0)); // Vd 8957 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 8958 Spacing)); 8959 TmpInst.addOperand(Inst.getOperand(1)); // lane 8960 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 8961 TmpInst.addOperand(Inst.getOperand(6)); 8962 Inst = TmpInst; 8963 return true; 8964 } 8965 8966 case ARM::VST3LNdWB_register_Asm_8: 8967 case ARM::VST3LNdWB_register_Asm_16: 8968 case ARM::VST3LNdWB_register_Asm_32: 8969 case ARM::VST3LNqWB_register_Asm_16: 8970 case ARM::VST3LNqWB_register_Asm_32: { 8971 MCInst TmpInst; 8972 // Shuffle the operands around so the lane index operand is in the 8973 // right place. 8974 unsigned Spacing; 8975 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 8976 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 8977 TmpInst.addOperand(Inst.getOperand(2)); // Rn 8978 TmpInst.addOperand(Inst.getOperand(3)); // alignment 8979 TmpInst.addOperand(Inst.getOperand(4)); // Rm 8980 TmpInst.addOperand(Inst.getOperand(0)); // Vd 8981 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 8982 Spacing)); 8983 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 8984 Spacing * 2)); 8985 TmpInst.addOperand(Inst.getOperand(1)); // lane 8986 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 8987 TmpInst.addOperand(Inst.getOperand(6)); 8988 Inst = TmpInst; 8989 return true; 8990 } 8991 8992 case ARM::VST4LNdWB_register_Asm_8: 8993 case ARM::VST4LNdWB_register_Asm_16: 8994 case ARM::VST4LNdWB_register_Asm_32: 8995 case ARM::VST4LNqWB_register_Asm_16: 8996 case ARM::VST4LNqWB_register_Asm_32: { 8997 MCInst TmpInst; 8998 // Shuffle the operands around so the lane index operand is in the 8999 // right place. 9000 unsigned Spacing; 9001 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9002 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9003 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9004 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9005 TmpInst.addOperand(Inst.getOperand(4)); // Rm 9006 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9007 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9008 Spacing)); 9009 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9010 Spacing * 2)); 9011 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9012 Spacing * 3)); 9013 TmpInst.addOperand(Inst.getOperand(1)); // lane 9014 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 9015 TmpInst.addOperand(Inst.getOperand(6)); 9016 Inst = TmpInst; 9017 return true; 9018 } 9019 9020 case ARM::VST1LNdWB_fixed_Asm_8: 9021 case ARM::VST1LNdWB_fixed_Asm_16: 9022 case ARM::VST1LNdWB_fixed_Asm_32: { 9023 MCInst TmpInst; 9024 // Shuffle the operands around so the lane index operand is in the 9025 // right place. 9026 unsigned Spacing; 9027 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9028 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9029 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9030 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9031 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9032 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9033 TmpInst.addOperand(Inst.getOperand(1)); // lane 9034 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9035 TmpInst.addOperand(Inst.getOperand(5)); 9036 Inst = TmpInst; 9037 return true; 9038 } 9039 9040 case ARM::VST2LNdWB_fixed_Asm_8: 9041 case ARM::VST2LNdWB_fixed_Asm_16: 9042 case ARM::VST2LNdWB_fixed_Asm_32: 9043 case ARM::VST2LNqWB_fixed_Asm_16: 9044 case ARM::VST2LNqWB_fixed_Asm_32: { 9045 MCInst TmpInst; 9046 // Shuffle the operands around so the lane index operand is in the 9047 // right place. 9048 unsigned Spacing; 9049 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9050 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9051 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9052 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9053 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9054 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9055 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9056 Spacing)); 9057 TmpInst.addOperand(Inst.getOperand(1)); // lane 9058 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9059 TmpInst.addOperand(Inst.getOperand(5)); 9060 Inst = TmpInst; 9061 return true; 9062 } 9063 9064 case ARM::VST3LNdWB_fixed_Asm_8: 9065 case ARM::VST3LNdWB_fixed_Asm_16: 9066 case ARM::VST3LNdWB_fixed_Asm_32: 9067 case ARM::VST3LNqWB_fixed_Asm_16: 9068 case ARM::VST3LNqWB_fixed_Asm_32: { 9069 MCInst TmpInst; 9070 // Shuffle the operands around so the lane index operand is in the 9071 // right place. 9072 unsigned Spacing; 9073 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9074 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9075 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9076 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9077 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9078 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9079 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9080 Spacing)); 9081 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9082 Spacing * 2)); 9083 TmpInst.addOperand(Inst.getOperand(1)); // lane 9084 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9085 TmpInst.addOperand(Inst.getOperand(5)); 9086 Inst = TmpInst; 9087 return true; 9088 } 9089 9090 case ARM::VST4LNdWB_fixed_Asm_8: 9091 case ARM::VST4LNdWB_fixed_Asm_16: 9092 case ARM::VST4LNdWB_fixed_Asm_32: 9093 case ARM::VST4LNqWB_fixed_Asm_16: 9094 case ARM::VST4LNqWB_fixed_Asm_32: { 9095 MCInst TmpInst; 9096 // Shuffle the operands around so the lane index operand is in the 9097 // right place. 9098 unsigned Spacing; 9099 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9100 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9101 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9102 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9103 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9104 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9105 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9106 Spacing)); 9107 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9108 Spacing * 2)); 9109 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9110 Spacing * 3)); 9111 TmpInst.addOperand(Inst.getOperand(1)); // lane 9112 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9113 TmpInst.addOperand(Inst.getOperand(5)); 9114 Inst = TmpInst; 9115 return true; 9116 } 9117 9118 case ARM::VST1LNdAsm_8: 9119 case ARM::VST1LNdAsm_16: 9120 case ARM::VST1LNdAsm_32: { 9121 MCInst TmpInst; 9122 // Shuffle the operands around so the lane index operand is in the 9123 // right place. 9124 unsigned Spacing; 9125 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9126 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9127 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9128 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9129 TmpInst.addOperand(Inst.getOperand(1)); // lane 9130 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9131 TmpInst.addOperand(Inst.getOperand(5)); 9132 Inst = TmpInst; 9133 return true; 9134 } 9135 9136 case ARM::VST2LNdAsm_8: 9137 case ARM::VST2LNdAsm_16: 9138 case ARM::VST2LNdAsm_32: 9139 case ARM::VST2LNqAsm_16: 9140 case ARM::VST2LNqAsm_32: { 9141 MCInst TmpInst; 9142 // Shuffle the operands around so the lane index operand is in the 9143 // right place. 9144 unsigned Spacing; 9145 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9146 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9147 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9148 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9149 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9150 Spacing)); 9151 TmpInst.addOperand(Inst.getOperand(1)); // lane 9152 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9153 TmpInst.addOperand(Inst.getOperand(5)); 9154 Inst = TmpInst; 9155 return true; 9156 } 9157 9158 case ARM::VST3LNdAsm_8: 9159 case ARM::VST3LNdAsm_16: 9160 case ARM::VST3LNdAsm_32: 9161 case ARM::VST3LNqAsm_16: 9162 case ARM::VST3LNqAsm_32: { 9163 MCInst TmpInst; 9164 // Shuffle the operands around so the lane index operand is in the 9165 // right place. 9166 unsigned Spacing; 9167 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9168 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9169 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9170 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9171 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9172 Spacing)); 9173 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9174 Spacing * 2)); 9175 TmpInst.addOperand(Inst.getOperand(1)); // lane 9176 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9177 TmpInst.addOperand(Inst.getOperand(5)); 9178 Inst = TmpInst; 9179 return true; 9180 } 9181 9182 case ARM::VST4LNdAsm_8: 9183 case ARM::VST4LNdAsm_16: 9184 case ARM::VST4LNdAsm_32: 9185 case ARM::VST4LNqAsm_16: 9186 case ARM::VST4LNqAsm_32: { 9187 MCInst TmpInst; 9188 // Shuffle the operands around so the lane index operand is in the 9189 // right place. 9190 unsigned Spacing; 9191 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9192 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9193 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9194 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9195 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9196 Spacing)); 9197 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9198 Spacing * 2)); 9199 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9200 Spacing * 3)); 9201 TmpInst.addOperand(Inst.getOperand(1)); // lane 9202 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9203 TmpInst.addOperand(Inst.getOperand(5)); 9204 Inst = TmpInst; 9205 return true; 9206 } 9207 9208 // Handle NEON VLD complex aliases. 9209 case ARM::VLD1LNdWB_register_Asm_8: 9210 case ARM::VLD1LNdWB_register_Asm_16: 9211 case ARM::VLD1LNdWB_register_Asm_32: { 9212 MCInst TmpInst; 9213 // Shuffle the operands around so the lane index operand is in the 9214 // right place. 9215 unsigned Spacing; 9216 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9217 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9218 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9219 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9220 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9221 TmpInst.addOperand(Inst.getOperand(4)); // Rm 9222 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9223 TmpInst.addOperand(Inst.getOperand(1)); // lane 9224 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 9225 TmpInst.addOperand(Inst.getOperand(6)); 9226 Inst = TmpInst; 9227 return true; 9228 } 9229 9230 case ARM::VLD2LNdWB_register_Asm_8: 9231 case ARM::VLD2LNdWB_register_Asm_16: 9232 case ARM::VLD2LNdWB_register_Asm_32: 9233 case ARM::VLD2LNqWB_register_Asm_16: 9234 case ARM::VLD2LNqWB_register_Asm_32: { 9235 MCInst TmpInst; 9236 // Shuffle the operands around so the lane index operand is in the 9237 // right place. 9238 unsigned Spacing; 9239 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9240 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9241 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9242 Spacing)); 9243 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9244 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9245 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9246 TmpInst.addOperand(Inst.getOperand(4)); // Rm 9247 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9248 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9249 Spacing)); 9250 TmpInst.addOperand(Inst.getOperand(1)); // lane 9251 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 9252 TmpInst.addOperand(Inst.getOperand(6)); 9253 Inst = TmpInst; 9254 return true; 9255 } 9256 9257 case ARM::VLD3LNdWB_register_Asm_8: 9258 case ARM::VLD3LNdWB_register_Asm_16: 9259 case ARM::VLD3LNdWB_register_Asm_32: 9260 case ARM::VLD3LNqWB_register_Asm_16: 9261 case ARM::VLD3LNqWB_register_Asm_32: { 9262 MCInst TmpInst; 9263 // Shuffle the operands around so the lane index operand is in the 9264 // right place. 9265 unsigned Spacing; 9266 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9267 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9268 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9269 Spacing)); 9270 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9271 Spacing * 2)); 9272 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9273 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9274 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9275 TmpInst.addOperand(Inst.getOperand(4)); // Rm 9276 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9277 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9278 Spacing)); 9279 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9280 Spacing * 2)); 9281 TmpInst.addOperand(Inst.getOperand(1)); // lane 9282 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 9283 TmpInst.addOperand(Inst.getOperand(6)); 9284 Inst = TmpInst; 9285 return true; 9286 } 9287 9288 case ARM::VLD4LNdWB_register_Asm_8: 9289 case ARM::VLD4LNdWB_register_Asm_16: 9290 case ARM::VLD4LNdWB_register_Asm_32: 9291 case ARM::VLD4LNqWB_register_Asm_16: 9292 case ARM::VLD4LNqWB_register_Asm_32: { 9293 MCInst TmpInst; 9294 // Shuffle the operands around so the lane index operand is in the 9295 // right place. 9296 unsigned Spacing; 9297 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9298 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9299 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9300 Spacing)); 9301 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9302 Spacing * 2)); 9303 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9304 Spacing * 3)); 9305 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9306 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9307 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9308 TmpInst.addOperand(Inst.getOperand(4)); // Rm 9309 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9310 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9311 Spacing)); 9312 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9313 Spacing * 2)); 9314 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9315 Spacing * 3)); 9316 TmpInst.addOperand(Inst.getOperand(1)); // lane 9317 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 9318 TmpInst.addOperand(Inst.getOperand(6)); 9319 Inst = TmpInst; 9320 return true; 9321 } 9322 9323 case ARM::VLD1LNdWB_fixed_Asm_8: 9324 case ARM::VLD1LNdWB_fixed_Asm_16: 9325 case ARM::VLD1LNdWB_fixed_Asm_32: { 9326 MCInst TmpInst; 9327 // Shuffle the operands around so the lane index operand is in the 9328 // right place. 9329 unsigned Spacing; 9330 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9331 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9332 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9333 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9334 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9335 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9336 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9337 TmpInst.addOperand(Inst.getOperand(1)); // lane 9338 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9339 TmpInst.addOperand(Inst.getOperand(5)); 9340 Inst = TmpInst; 9341 return true; 9342 } 9343 9344 case ARM::VLD2LNdWB_fixed_Asm_8: 9345 case ARM::VLD2LNdWB_fixed_Asm_16: 9346 case ARM::VLD2LNdWB_fixed_Asm_32: 9347 case ARM::VLD2LNqWB_fixed_Asm_16: 9348 case ARM::VLD2LNqWB_fixed_Asm_32: { 9349 MCInst TmpInst; 9350 // Shuffle the operands around so the lane index operand is in the 9351 // right place. 9352 unsigned Spacing; 9353 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9354 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9355 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9356 Spacing)); 9357 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9358 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9359 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9360 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9361 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9362 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9363 Spacing)); 9364 TmpInst.addOperand(Inst.getOperand(1)); // lane 9365 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9366 TmpInst.addOperand(Inst.getOperand(5)); 9367 Inst = TmpInst; 9368 return true; 9369 } 9370 9371 case ARM::VLD3LNdWB_fixed_Asm_8: 9372 case ARM::VLD3LNdWB_fixed_Asm_16: 9373 case ARM::VLD3LNdWB_fixed_Asm_32: 9374 case ARM::VLD3LNqWB_fixed_Asm_16: 9375 case ARM::VLD3LNqWB_fixed_Asm_32: { 9376 MCInst TmpInst; 9377 // Shuffle the operands around so the lane index operand is in the 9378 // right place. 9379 unsigned Spacing; 9380 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9381 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9382 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9383 Spacing)); 9384 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9385 Spacing * 2)); 9386 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9387 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9388 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9389 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9390 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9391 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9392 Spacing)); 9393 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9394 Spacing * 2)); 9395 TmpInst.addOperand(Inst.getOperand(1)); // lane 9396 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9397 TmpInst.addOperand(Inst.getOperand(5)); 9398 Inst = TmpInst; 9399 return true; 9400 } 9401 9402 case ARM::VLD4LNdWB_fixed_Asm_8: 9403 case ARM::VLD4LNdWB_fixed_Asm_16: 9404 case ARM::VLD4LNdWB_fixed_Asm_32: 9405 case ARM::VLD4LNqWB_fixed_Asm_16: 9406 case ARM::VLD4LNqWB_fixed_Asm_32: { 9407 MCInst TmpInst; 9408 // Shuffle the operands around so the lane index operand is in the 9409 // right place. 9410 unsigned Spacing; 9411 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9412 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9413 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9414 Spacing)); 9415 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9416 Spacing * 2)); 9417 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9418 Spacing * 3)); 9419 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 9420 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9421 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9422 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9423 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9424 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9425 Spacing)); 9426 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9427 Spacing * 2)); 9428 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9429 Spacing * 3)); 9430 TmpInst.addOperand(Inst.getOperand(1)); // lane 9431 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9432 TmpInst.addOperand(Inst.getOperand(5)); 9433 Inst = TmpInst; 9434 return true; 9435 } 9436 9437 case ARM::VLD1LNdAsm_8: 9438 case ARM::VLD1LNdAsm_16: 9439 case ARM::VLD1LNdAsm_32: { 9440 MCInst TmpInst; 9441 // Shuffle the operands around so the lane index operand is in the 9442 // right place. 9443 unsigned Spacing; 9444 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9445 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9446 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9447 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9448 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9449 TmpInst.addOperand(Inst.getOperand(1)); // lane 9450 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9451 TmpInst.addOperand(Inst.getOperand(5)); 9452 Inst = TmpInst; 9453 return true; 9454 } 9455 9456 case ARM::VLD2LNdAsm_8: 9457 case ARM::VLD2LNdAsm_16: 9458 case ARM::VLD2LNdAsm_32: 9459 case ARM::VLD2LNqAsm_16: 9460 case ARM::VLD2LNqAsm_32: { 9461 MCInst TmpInst; 9462 // Shuffle the operands around so the lane index operand is in the 9463 // right place. 9464 unsigned Spacing; 9465 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9466 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9467 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9468 Spacing)); 9469 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9470 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9471 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9472 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9473 Spacing)); 9474 TmpInst.addOperand(Inst.getOperand(1)); // lane 9475 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9476 TmpInst.addOperand(Inst.getOperand(5)); 9477 Inst = TmpInst; 9478 return true; 9479 } 9480 9481 case ARM::VLD3LNdAsm_8: 9482 case ARM::VLD3LNdAsm_16: 9483 case ARM::VLD3LNdAsm_32: 9484 case ARM::VLD3LNqAsm_16: 9485 case ARM::VLD3LNqAsm_32: { 9486 MCInst TmpInst; 9487 // Shuffle the operands around so the lane index operand is in the 9488 // right place. 9489 unsigned Spacing; 9490 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9491 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9492 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9493 Spacing)); 9494 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9495 Spacing * 2)); 9496 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9497 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9498 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9499 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9500 Spacing)); 9501 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9502 Spacing * 2)); 9503 TmpInst.addOperand(Inst.getOperand(1)); // lane 9504 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9505 TmpInst.addOperand(Inst.getOperand(5)); 9506 Inst = TmpInst; 9507 return true; 9508 } 9509 9510 case ARM::VLD4LNdAsm_8: 9511 case ARM::VLD4LNdAsm_16: 9512 case ARM::VLD4LNdAsm_32: 9513 case ARM::VLD4LNqAsm_16: 9514 case ARM::VLD4LNqAsm_32: { 9515 MCInst TmpInst; 9516 // Shuffle the operands around so the lane index operand is in the 9517 // right place. 9518 unsigned Spacing; 9519 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9520 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9521 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9522 Spacing)); 9523 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9524 Spacing * 2)); 9525 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9526 Spacing * 3)); 9527 TmpInst.addOperand(Inst.getOperand(2)); // Rn 9528 TmpInst.addOperand(Inst.getOperand(3)); // alignment 9529 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 9530 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9531 Spacing)); 9532 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9533 Spacing * 2)); 9534 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9535 Spacing * 3)); 9536 TmpInst.addOperand(Inst.getOperand(1)); // lane 9537 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9538 TmpInst.addOperand(Inst.getOperand(5)); 9539 Inst = TmpInst; 9540 return true; 9541 } 9542 9543 // VLD3DUP single 3-element structure to all lanes instructions. 9544 case ARM::VLD3DUPdAsm_8: 9545 case ARM::VLD3DUPdAsm_16: 9546 case ARM::VLD3DUPdAsm_32: 9547 case ARM::VLD3DUPqAsm_8: 9548 case ARM::VLD3DUPqAsm_16: 9549 case ARM::VLD3DUPqAsm_32: { 9550 MCInst TmpInst; 9551 unsigned Spacing; 9552 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9553 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9554 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9555 Spacing)); 9556 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9557 Spacing * 2)); 9558 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9559 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9560 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9561 TmpInst.addOperand(Inst.getOperand(4)); 9562 Inst = TmpInst; 9563 return true; 9564 } 9565 9566 case ARM::VLD3DUPdWB_fixed_Asm_8: 9567 case ARM::VLD3DUPdWB_fixed_Asm_16: 9568 case ARM::VLD3DUPdWB_fixed_Asm_32: 9569 case ARM::VLD3DUPqWB_fixed_Asm_8: 9570 case ARM::VLD3DUPqWB_fixed_Asm_16: 9571 case ARM::VLD3DUPqWB_fixed_Asm_32: { 9572 MCInst TmpInst; 9573 unsigned Spacing; 9574 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9575 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9576 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9577 Spacing)); 9578 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9579 Spacing * 2)); 9580 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9581 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9582 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9583 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9584 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9585 TmpInst.addOperand(Inst.getOperand(4)); 9586 Inst = TmpInst; 9587 return true; 9588 } 9589 9590 case ARM::VLD3DUPdWB_register_Asm_8: 9591 case ARM::VLD3DUPdWB_register_Asm_16: 9592 case ARM::VLD3DUPdWB_register_Asm_32: 9593 case ARM::VLD3DUPqWB_register_Asm_8: 9594 case ARM::VLD3DUPqWB_register_Asm_16: 9595 case ARM::VLD3DUPqWB_register_Asm_32: { 9596 MCInst TmpInst; 9597 unsigned Spacing; 9598 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9599 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9600 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9601 Spacing)); 9602 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9603 Spacing * 2)); 9604 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9605 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9606 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9607 TmpInst.addOperand(Inst.getOperand(3)); // Rm 9608 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9609 TmpInst.addOperand(Inst.getOperand(5)); 9610 Inst = TmpInst; 9611 return true; 9612 } 9613 9614 // VLD3 multiple 3-element structure instructions. 9615 case ARM::VLD3dAsm_8: 9616 case ARM::VLD3dAsm_16: 9617 case ARM::VLD3dAsm_32: 9618 case ARM::VLD3qAsm_8: 9619 case ARM::VLD3qAsm_16: 9620 case ARM::VLD3qAsm_32: { 9621 MCInst TmpInst; 9622 unsigned Spacing; 9623 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9624 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9625 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9626 Spacing)); 9627 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9628 Spacing * 2)); 9629 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9630 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9631 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9632 TmpInst.addOperand(Inst.getOperand(4)); 9633 Inst = TmpInst; 9634 return true; 9635 } 9636 9637 case ARM::VLD3dWB_fixed_Asm_8: 9638 case ARM::VLD3dWB_fixed_Asm_16: 9639 case ARM::VLD3dWB_fixed_Asm_32: 9640 case ARM::VLD3qWB_fixed_Asm_8: 9641 case ARM::VLD3qWB_fixed_Asm_16: 9642 case ARM::VLD3qWB_fixed_Asm_32: { 9643 MCInst TmpInst; 9644 unsigned Spacing; 9645 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9646 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9647 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9648 Spacing)); 9649 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9650 Spacing * 2)); 9651 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9652 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9653 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9654 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9655 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9656 TmpInst.addOperand(Inst.getOperand(4)); 9657 Inst = TmpInst; 9658 return true; 9659 } 9660 9661 case ARM::VLD3dWB_register_Asm_8: 9662 case ARM::VLD3dWB_register_Asm_16: 9663 case ARM::VLD3dWB_register_Asm_32: 9664 case ARM::VLD3qWB_register_Asm_8: 9665 case ARM::VLD3qWB_register_Asm_16: 9666 case ARM::VLD3qWB_register_Asm_32: { 9667 MCInst TmpInst; 9668 unsigned Spacing; 9669 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9670 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9671 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9672 Spacing)); 9673 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9674 Spacing * 2)); 9675 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9676 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9677 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9678 TmpInst.addOperand(Inst.getOperand(3)); // Rm 9679 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9680 TmpInst.addOperand(Inst.getOperand(5)); 9681 Inst = TmpInst; 9682 return true; 9683 } 9684 9685 // VLD4DUP single 3-element structure to all lanes instructions. 9686 case ARM::VLD4DUPdAsm_8: 9687 case ARM::VLD4DUPdAsm_16: 9688 case ARM::VLD4DUPdAsm_32: 9689 case ARM::VLD4DUPqAsm_8: 9690 case ARM::VLD4DUPqAsm_16: 9691 case ARM::VLD4DUPqAsm_32: { 9692 MCInst TmpInst; 9693 unsigned Spacing; 9694 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9695 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9696 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9697 Spacing)); 9698 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9699 Spacing * 2)); 9700 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9701 Spacing * 3)); 9702 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9703 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9704 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9705 TmpInst.addOperand(Inst.getOperand(4)); 9706 Inst = TmpInst; 9707 return true; 9708 } 9709 9710 case ARM::VLD4DUPdWB_fixed_Asm_8: 9711 case ARM::VLD4DUPdWB_fixed_Asm_16: 9712 case ARM::VLD4DUPdWB_fixed_Asm_32: 9713 case ARM::VLD4DUPqWB_fixed_Asm_8: 9714 case ARM::VLD4DUPqWB_fixed_Asm_16: 9715 case ARM::VLD4DUPqWB_fixed_Asm_32: { 9716 MCInst TmpInst; 9717 unsigned Spacing; 9718 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9719 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9720 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9721 Spacing)); 9722 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9723 Spacing * 2)); 9724 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9725 Spacing * 3)); 9726 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9727 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9728 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9729 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9730 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9731 TmpInst.addOperand(Inst.getOperand(4)); 9732 Inst = TmpInst; 9733 return true; 9734 } 9735 9736 case ARM::VLD4DUPdWB_register_Asm_8: 9737 case ARM::VLD4DUPdWB_register_Asm_16: 9738 case ARM::VLD4DUPdWB_register_Asm_32: 9739 case ARM::VLD4DUPqWB_register_Asm_8: 9740 case ARM::VLD4DUPqWB_register_Asm_16: 9741 case ARM::VLD4DUPqWB_register_Asm_32: { 9742 MCInst TmpInst; 9743 unsigned Spacing; 9744 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9745 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9746 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9747 Spacing)); 9748 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9749 Spacing * 2)); 9750 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9751 Spacing * 3)); 9752 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9753 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9754 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9755 TmpInst.addOperand(Inst.getOperand(3)); // Rm 9756 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9757 TmpInst.addOperand(Inst.getOperand(5)); 9758 Inst = TmpInst; 9759 return true; 9760 } 9761 9762 // VLD4 multiple 4-element structure instructions. 9763 case ARM::VLD4dAsm_8: 9764 case ARM::VLD4dAsm_16: 9765 case ARM::VLD4dAsm_32: 9766 case ARM::VLD4qAsm_8: 9767 case ARM::VLD4qAsm_16: 9768 case ARM::VLD4qAsm_32: { 9769 MCInst TmpInst; 9770 unsigned Spacing; 9771 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9772 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9773 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9774 Spacing)); 9775 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9776 Spacing * 2)); 9777 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9778 Spacing * 3)); 9779 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9780 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9781 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9782 TmpInst.addOperand(Inst.getOperand(4)); 9783 Inst = TmpInst; 9784 return true; 9785 } 9786 9787 case ARM::VLD4dWB_fixed_Asm_8: 9788 case ARM::VLD4dWB_fixed_Asm_16: 9789 case ARM::VLD4dWB_fixed_Asm_32: 9790 case ARM::VLD4qWB_fixed_Asm_8: 9791 case ARM::VLD4qWB_fixed_Asm_16: 9792 case ARM::VLD4qWB_fixed_Asm_32: { 9793 MCInst TmpInst; 9794 unsigned Spacing; 9795 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9796 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9797 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9798 Spacing)); 9799 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9800 Spacing * 2)); 9801 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9802 Spacing * 3)); 9803 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9804 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9805 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9806 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9807 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9808 TmpInst.addOperand(Inst.getOperand(4)); 9809 Inst = TmpInst; 9810 return true; 9811 } 9812 9813 case ARM::VLD4dWB_register_Asm_8: 9814 case ARM::VLD4dWB_register_Asm_16: 9815 case ARM::VLD4dWB_register_Asm_32: 9816 case ARM::VLD4qWB_register_Asm_8: 9817 case ARM::VLD4qWB_register_Asm_16: 9818 case ARM::VLD4qWB_register_Asm_32: { 9819 MCInst TmpInst; 9820 unsigned Spacing; 9821 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 9822 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9823 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9824 Spacing)); 9825 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9826 Spacing * 2)); 9827 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9828 Spacing * 3)); 9829 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9830 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9831 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9832 TmpInst.addOperand(Inst.getOperand(3)); // Rm 9833 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9834 TmpInst.addOperand(Inst.getOperand(5)); 9835 Inst = TmpInst; 9836 return true; 9837 } 9838 9839 // VST3 multiple 3-element structure instructions. 9840 case ARM::VST3dAsm_8: 9841 case ARM::VST3dAsm_16: 9842 case ARM::VST3dAsm_32: 9843 case ARM::VST3qAsm_8: 9844 case ARM::VST3qAsm_16: 9845 case ARM::VST3qAsm_32: { 9846 MCInst TmpInst; 9847 unsigned Spacing; 9848 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9849 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9850 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9851 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9852 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9853 Spacing)); 9854 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9855 Spacing * 2)); 9856 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9857 TmpInst.addOperand(Inst.getOperand(4)); 9858 Inst = TmpInst; 9859 return true; 9860 } 9861 9862 case ARM::VST3dWB_fixed_Asm_8: 9863 case ARM::VST3dWB_fixed_Asm_16: 9864 case ARM::VST3dWB_fixed_Asm_32: 9865 case ARM::VST3qWB_fixed_Asm_8: 9866 case ARM::VST3qWB_fixed_Asm_16: 9867 case ARM::VST3qWB_fixed_Asm_32: { 9868 MCInst TmpInst; 9869 unsigned Spacing; 9870 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9871 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9872 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9873 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9874 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9875 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9876 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9877 Spacing)); 9878 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9879 Spacing * 2)); 9880 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9881 TmpInst.addOperand(Inst.getOperand(4)); 9882 Inst = TmpInst; 9883 return true; 9884 } 9885 9886 case ARM::VST3dWB_register_Asm_8: 9887 case ARM::VST3dWB_register_Asm_16: 9888 case ARM::VST3dWB_register_Asm_32: 9889 case ARM::VST3qWB_register_Asm_8: 9890 case ARM::VST3qWB_register_Asm_16: 9891 case ARM::VST3qWB_register_Asm_32: { 9892 MCInst TmpInst; 9893 unsigned Spacing; 9894 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9895 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9896 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9897 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9898 TmpInst.addOperand(Inst.getOperand(3)); // Rm 9899 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9900 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9901 Spacing)); 9902 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9903 Spacing * 2)); 9904 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9905 TmpInst.addOperand(Inst.getOperand(5)); 9906 Inst = TmpInst; 9907 return true; 9908 } 9909 9910 // VST4 multiple 3-element structure instructions. 9911 case ARM::VST4dAsm_8: 9912 case ARM::VST4dAsm_16: 9913 case ARM::VST4dAsm_32: 9914 case ARM::VST4qAsm_8: 9915 case ARM::VST4qAsm_16: 9916 case ARM::VST4qAsm_32: { 9917 MCInst TmpInst; 9918 unsigned Spacing; 9919 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9920 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9921 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9922 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9923 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9924 Spacing)); 9925 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9926 Spacing * 2)); 9927 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9928 Spacing * 3)); 9929 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9930 TmpInst.addOperand(Inst.getOperand(4)); 9931 Inst = TmpInst; 9932 return true; 9933 } 9934 9935 case ARM::VST4dWB_fixed_Asm_8: 9936 case ARM::VST4dWB_fixed_Asm_16: 9937 case ARM::VST4dWB_fixed_Asm_32: 9938 case ARM::VST4qWB_fixed_Asm_8: 9939 case ARM::VST4qWB_fixed_Asm_16: 9940 case ARM::VST4qWB_fixed_Asm_32: { 9941 MCInst TmpInst; 9942 unsigned Spacing; 9943 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9944 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9945 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9946 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9947 TmpInst.addOperand(MCOperand::createReg(0)); // Rm 9948 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9949 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9950 Spacing)); 9951 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9952 Spacing * 2)); 9953 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9954 Spacing * 3)); 9955 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 9956 TmpInst.addOperand(Inst.getOperand(4)); 9957 Inst = TmpInst; 9958 return true; 9959 } 9960 9961 case ARM::VST4dWB_register_Asm_8: 9962 case ARM::VST4dWB_register_Asm_16: 9963 case ARM::VST4dWB_register_Asm_32: 9964 case ARM::VST4qWB_register_Asm_8: 9965 case ARM::VST4qWB_register_Asm_16: 9966 case ARM::VST4qWB_register_Asm_32: { 9967 MCInst TmpInst; 9968 unsigned Spacing; 9969 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 9970 TmpInst.addOperand(Inst.getOperand(1)); // Rn 9971 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 9972 TmpInst.addOperand(Inst.getOperand(2)); // alignment 9973 TmpInst.addOperand(Inst.getOperand(3)); // Rm 9974 TmpInst.addOperand(Inst.getOperand(0)); // Vd 9975 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9976 Spacing)); 9977 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9978 Spacing * 2)); 9979 TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() + 9980 Spacing * 3)); 9981 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 9982 TmpInst.addOperand(Inst.getOperand(5)); 9983 Inst = TmpInst; 9984 return true; 9985 } 9986 9987 // Handle encoding choice for the shift-immediate instructions. 9988 case ARM::t2LSLri: 9989 case ARM::t2LSRri: 9990 case ARM::t2ASRri: 9991 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 9992 isARMLowRegister(Inst.getOperand(1).getReg()) && 9993 Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) && 9994 !HasWideQualifier) { 9995 unsigned NewOpc; 9996 switch (Inst.getOpcode()) { 9997 default: llvm_unreachable("unexpected opcode"); 9998 case ARM::t2LSLri: NewOpc = ARM::tLSLri; break; 9999 case ARM::t2LSRri: NewOpc = ARM::tLSRri; break; 10000 case ARM::t2ASRri: NewOpc = ARM::tASRri; break; 10001 } 10002 // The Thumb1 operands aren't in the same order. Awesome, eh? 10003 MCInst TmpInst; 10004 TmpInst.setOpcode(NewOpc); 10005 TmpInst.addOperand(Inst.getOperand(0)); 10006 TmpInst.addOperand(Inst.getOperand(5)); 10007 TmpInst.addOperand(Inst.getOperand(1)); 10008 TmpInst.addOperand(Inst.getOperand(2)); 10009 TmpInst.addOperand(Inst.getOperand(3)); 10010 TmpInst.addOperand(Inst.getOperand(4)); 10011 Inst = TmpInst; 10012 return true; 10013 } 10014 return false; 10015 10016 // Handle the Thumb2 mode MOV complex aliases. 10017 case ARM::t2MOVsr: 10018 case ARM::t2MOVSsr: { 10019 // Which instruction to expand to depends on the CCOut operand and 10020 // whether we're in an IT block if the register operands are low 10021 // registers. 10022 bool isNarrow = false; 10023 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 10024 isARMLowRegister(Inst.getOperand(1).getReg()) && 10025 isARMLowRegister(Inst.getOperand(2).getReg()) && 10026 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && 10027 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr) && 10028 !HasWideQualifier) 10029 isNarrow = true; 10030 MCInst TmpInst; 10031 unsigned newOpc; 10032 switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) { 10033 default: llvm_unreachable("unexpected opcode!"); 10034 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break; 10035 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break; 10036 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break; 10037 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break; 10038 } 10039 TmpInst.setOpcode(newOpc); 10040 TmpInst.addOperand(Inst.getOperand(0)); // Rd 10041 if (isNarrow) 10042 TmpInst.addOperand(MCOperand::createReg( 10043 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0)); 10044 TmpInst.addOperand(Inst.getOperand(1)); // Rn 10045 TmpInst.addOperand(Inst.getOperand(2)); // Rm 10046 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 10047 TmpInst.addOperand(Inst.getOperand(5)); 10048 if (!isNarrow) 10049 TmpInst.addOperand(MCOperand::createReg( 10050 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0)); 10051 Inst = TmpInst; 10052 return true; 10053 } 10054 case ARM::t2MOVsi: 10055 case ARM::t2MOVSsi: { 10056 // Which instruction to expand to depends on the CCOut operand and 10057 // whether we're in an IT block if the register operands are low 10058 // registers. 10059 bool isNarrow = false; 10060 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 10061 isARMLowRegister(Inst.getOperand(1).getReg()) && 10062 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi) && 10063 !HasWideQualifier) 10064 isNarrow = true; 10065 MCInst TmpInst; 10066 unsigned newOpc; 10067 unsigned Shift = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm()); 10068 unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()); 10069 bool isMov = false; 10070 // MOV rd, rm, LSL #0 is actually a MOV instruction 10071 if (Shift == ARM_AM::lsl && Amount == 0) { 10072 isMov = true; 10073 // The 16-bit encoding of MOV rd, rm, LSL #N is explicitly encoding T2 of 10074 // MOV (register) in the ARMv8-A and ARMv8-M manuals, and immediate 0 is 10075 // unpredictable in an IT block so the 32-bit encoding T3 has to be used 10076 // instead. 10077 if (inITBlock()) { 10078 isNarrow = false; 10079 } 10080 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr; 10081 } else { 10082 switch(Shift) { 10083 default: llvm_unreachable("unexpected opcode!"); 10084 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break; 10085 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break; 10086 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break; 10087 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break; 10088 case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break; 10089 } 10090 } 10091 if (Amount == 32) Amount = 0; 10092 TmpInst.setOpcode(newOpc); 10093 TmpInst.addOperand(Inst.getOperand(0)); // Rd 10094 if (isNarrow && !isMov) 10095 TmpInst.addOperand(MCOperand::createReg( 10096 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0)); 10097 TmpInst.addOperand(Inst.getOperand(1)); // Rn 10098 if (newOpc != ARM::t2RRX && !isMov) 10099 TmpInst.addOperand(MCOperand::createImm(Amount)); 10100 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 10101 TmpInst.addOperand(Inst.getOperand(4)); 10102 if (!isNarrow) 10103 TmpInst.addOperand(MCOperand::createReg( 10104 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0)); 10105 Inst = TmpInst; 10106 return true; 10107 } 10108 // Handle the ARM mode MOV complex aliases. 10109 case ARM::ASRr: 10110 case ARM::LSRr: 10111 case ARM::LSLr: 10112 case ARM::RORr: { 10113 ARM_AM::ShiftOpc ShiftTy; 10114 switch(Inst.getOpcode()) { 10115 default: llvm_unreachable("unexpected opcode!"); 10116 case ARM::ASRr: ShiftTy = ARM_AM::asr; break; 10117 case ARM::LSRr: ShiftTy = ARM_AM::lsr; break; 10118 case ARM::LSLr: ShiftTy = ARM_AM::lsl; break; 10119 case ARM::RORr: ShiftTy = ARM_AM::ror; break; 10120 } 10121 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0); 10122 MCInst TmpInst; 10123 TmpInst.setOpcode(ARM::MOVsr); 10124 TmpInst.addOperand(Inst.getOperand(0)); // Rd 10125 TmpInst.addOperand(Inst.getOperand(1)); // Rn 10126 TmpInst.addOperand(Inst.getOperand(2)); // Rm 10127 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty 10128 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 10129 TmpInst.addOperand(Inst.getOperand(4)); 10130 TmpInst.addOperand(Inst.getOperand(5)); // cc_out 10131 Inst = TmpInst; 10132 return true; 10133 } 10134 case ARM::ASRi: 10135 case ARM::LSRi: 10136 case ARM::LSLi: 10137 case ARM::RORi: { 10138 ARM_AM::ShiftOpc ShiftTy; 10139 switch(Inst.getOpcode()) { 10140 default: llvm_unreachable("unexpected opcode!"); 10141 case ARM::ASRi: ShiftTy = ARM_AM::asr; break; 10142 case ARM::LSRi: ShiftTy = ARM_AM::lsr; break; 10143 case ARM::LSLi: ShiftTy = ARM_AM::lsl; break; 10144 case ARM::RORi: ShiftTy = ARM_AM::ror; break; 10145 } 10146 // A shift by zero is a plain MOVr, not a MOVsi. 10147 unsigned Amt = Inst.getOperand(2).getImm(); 10148 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi; 10149 // A shift by 32 should be encoded as 0 when permitted 10150 if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr)) 10151 Amt = 0; 10152 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt); 10153 MCInst TmpInst; 10154 TmpInst.setOpcode(Opc); 10155 TmpInst.addOperand(Inst.getOperand(0)); // Rd 10156 TmpInst.addOperand(Inst.getOperand(1)); // Rn 10157 if (Opc == ARM::MOVsi) 10158 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty 10159 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 10160 TmpInst.addOperand(Inst.getOperand(4)); 10161 TmpInst.addOperand(Inst.getOperand(5)); // cc_out 10162 Inst = TmpInst; 10163 return true; 10164 } 10165 case ARM::RRXi: { 10166 unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0); 10167 MCInst TmpInst; 10168 TmpInst.setOpcode(ARM::MOVsi); 10169 TmpInst.addOperand(Inst.getOperand(0)); // Rd 10170 TmpInst.addOperand(Inst.getOperand(1)); // Rn 10171 TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty 10172 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 10173 TmpInst.addOperand(Inst.getOperand(3)); 10174 TmpInst.addOperand(Inst.getOperand(4)); // cc_out 10175 Inst = TmpInst; 10176 return true; 10177 } 10178 case ARM::t2LDMIA_UPD: { 10179 // If this is a load of a single register, then we should use 10180 // a post-indexed LDR instruction instead, per the ARM ARM. 10181 if (Inst.getNumOperands() != 5) 10182 return false; 10183 MCInst TmpInst; 10184 TmpInst.setOpcode(ARM::t2LDR_POST); 10185 TmpInst.addOperand(Inst.getOperand(4)); // Rt 10186 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 10187 TmpInst.addOperand(Inst.getOperand(1)); // Rn 10188 TmpInst.addOperand(MCOperand::createImm(4)); 10189 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 10190 TmpInst.addOperand(Inst.getOperand(3)); 10191 Inst = TmpInst; 10192 return true; 10193 } 10194 case ARM::t2STMDB_UPD: { 10195 // If this is a store of a single register, then we should use 10196 // a pre-indexed STR instruction instead, per the ARM ARM. 10197 if (Inst.getNumOperands() != 5) 10198 return false; 10199 MCInst TmpInst; 10200 TmpInst.setOpcode(ARM::t2STR_PRE); 10201 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 10202 TmpInst.addOperand(Inst.getOperand(4)); // Rt 10203 TmpInst.addOperand(Inst.getOperand(1)); // Rn 10204 TmpInst.addOperand(MCOperand::createImm(-4)); 10205 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 10206 TmpInst.addOperand(Inst.getOperand(3)); 10207 Inst = TmpInst; 10208 return true; 10209 } 10210 case ARM::LDMIA_UPD: 10211 // If this is a load of a single register via a 'pop', then we should use 10212 // a post-indexed LDR instruction instead, per the ARM ARM. 10213 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "pop" && 10214 Inst.getNumOperands() == 5) { 10215 MCInst TmpInst; 10216 TmpInst.setOpcode(ARM::LDR_POST_IMM); 10217 TmpInst.addOperand(Inst.getOperand(4)); // Rt 10218 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 10219 TmpInst.addOperand(Inst.getOperand(1)); // Rn 10220 TmpInst.addOperand(MCOperand::createReg(0)); // am2offset 10221 TmpInst.addOperand(MCOperand::createImm(4)); 10222 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 10223 TmpInst.addOperand(Inst.getOperand(3)); 10224 Inst = TmpInst; 10225 return true; 10226 } 10227 break; 10228 case ARM::STMDB_UPD: 10229 // If this is a store of a single register via a 'push', then we should use 10230 // a pre-indexed STR instruction instead, per the ARM ARM. 10231 if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "push" && 10232 Inst.getNumOperands() == 5) { 10233 MCInst TmpInst; 10234 TmpInst.setOpcode(ARM::STR_PRE_IMM); 10235 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 10236 TmpInst.addOperand(Inst.getOperand(4)); // Rt 10237 TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 10238 TmpInst.addOperand(MCOperand::createImm(-4)); 10239 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 10240 TmpInst.addOperand(Inst.getOperand(3)); 10241 Inst = TmpInst; 10242 } 10243 break; 10244 case ARM::t2ADDri12: 10245 case ARM::t2SUBri12: 10246 case ARM::t2ADDspImm12: 10247 case ARM::t2SUBspImm12: { 10248 // If the immediate fits for encoding T3 and the generic 10249 // mnemonic was used, encoding T3 is preferred. 10250 const StringRef Token = static_cast<ARMOperand &>(*Operands[0]).getToken(); 10251 if ((Token != "add" && Token != "sub") || 10252 ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 10253 break; 10254 switch (Inst.getOpcode()) { 10255 case ARM::t2ADDri12: 10256 Inst.setOpcode(ARM::t2ADDri); 10257 break; 10258 case ARM::t2SUBri12: 10259 Inst.setOpcode(ARM::t2SUBri); 10260 break; 10261 case ARM::t2ADDspImm12: 10262 Inst.setOpcode(ARM::t2ADDspImm); 10263 break; 10264 case ARM::t2SUBspImm12: 10265 Inst.setOpcode(ARM::t2SUBspImm); 10266 break; 10267 } 10268 10269 Inst.addOperand(MCOperand::createReg(0)); // cc_out 10270 return true; 10271 } 10272 case ARM::tADDi8: 10273 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 10274 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 10275 // to encoding T2 if <Rd> is specified and encoding T2 is preferred 10276 // to encoding T1 if <Rd> is omitted." 10277 if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 10278 Inst.setOpcode(ARM::tADDi3); 10279 return true; 10280 } 10281 break; 10282 case ARM::tSUBi8: 10283 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 10284 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 10285 // to encoding T2 if <Rd> is specified and encoding T2 is preferred 10286 // to encoding T1 if <Rd> is omitted." 10287 if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 10288 Inst.setOpcode(ARM::tSUBi3); 10289 return true; 10290 } 10291 break; 10292 case ARM::t2ADDri: 10293 case ARM::t2SUBri: { 10294 // If the destination and first source operand are the same, and 10295 // the flags are compatible with the current IT status, use encoding T2 10296 // instead of T3. For compatibility with the system 'as'. Make sure the 10297 // wide encoding wasn't explicit. 10298 if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() || 10299 !isARMLowRegister(Inst.getOperand(0).getReg()) || 10300 (Inst.getOperand(2).isImm() && 10301 (unsigned)Inst.getOperand(2).getImm() > 255) || 10302 Inst.getOperand(5).getReg() != (inITBlock() ? 0 : ARM::CPSR) || 10303 HasWideQualifier) 10304 break; 10305 MCInst TmpInst; 10306 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ? 10307 ARM::tADDi8 : ARM::tSUBi8); 10308 TmpInst.addOperand(Inst.getOperand(0)); 10309 TmpInst.addOperand(Inst.getOperand(5)); 10310 TmpInst.addOperand(Inst.getOperand(0)); 10311 TmpInst.addOperand(Inst.getOperand(2)); 10312 TmpInst.addOperand(Inst.getOperand(3)); 10313 TmpInst.addOperand(Inst.getOperand(4)); 10314 Inst = TmpInst; 10315 return true; 10316 } 10317 case ARM::t2ADDspImm: 10318 case ARM::t2SUBspImm: { 10319 // Prefer T1 encoding if possible 10320 if (Inst.getOperand(5).getReg() != 0 || HasWideQualifier) 10321 break; 10322 unsigned V = Inst.getOperand(2).getImm(); 10323 if (V & 3 || V > ((1 << 7) - 1) << 2) 10324 break; 10325 MCInst TmpInst; 10326 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDspImm ? ARM::tADDspi 10327 : ARM::tSUBspi); 10328 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // destination reg 10329 TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // source reg 10330 TmpInst.addOperand(MCOperand::createImm(V / 4)); // immediate 10331 TmpInst.addOperand(Inst.getOperand(3)); // pred 10332 TmpInst.addOperand(Inst.getOperand(4)); 10333 Inst = TmpInst; 10334 return true; 10335 } 10336 case ARM::t2ADDrr: { 10337 // If the destination and first source operand are the same, and 10338 // there's no setting of the flags, use encoding T2 instead of T3. 10339 // Note that this is only for ADD, not SUB. This mirrors the system 10340 // 'as' behaviour. Also take advantage of ADD being commutative. 10341 // Make sure the wide encoding wasn't explicit. 10342 bool Swap = false; 10343 auto DestReg = Inst.getOperand(0).getReg(); 10344 bool Transform = DestReg == Inst.getOperand(1).getReg(); 10345 if (!Transform && DestReg == Inst.getOperand(2).getReg()) { 10346 Transform = true; 10347 Swap = true; 10348 } 10349 if (!Transform || 10350 Inst.getOperand(5).getReg() != 0 || 10351 HasWideQualifier) 10352 break; 10353 MCInst TmpInst; 10354 TmpInst.setOpcode(ARM::tADDhirr); 10355 TmpInst.addOperand(Inst.getOperand(0)); 10356 TmpInst.addOperand(Inst.getOperand(0)); 10357 TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2)); 10358 TmpInst.addOperand(Inst.getOperand(3)); 10359 TmpInst.addOperand(Inst.getOperand(4)); 10360 Inst = TmpInst; 10361 return true; 10362 } 10363 case ARM::tADDrSP: 10364 // If the non-SP source operand and the destination operand are not the 10365 // same, we need to use the 32-bit encoding if it's available. 10366 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) { 10367 Inst.setOpcode(ARM::t2ADDrr); 10368 Inst.addOperand(MCOperand::createReg(0)); // cc_out 10369 return true; 10370 } 10371 break; 10372 case ARM::tB: 10373 // A Thumb conditional branch outside of an IT block is a tBcc. 10374 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) { 10375 Inst.setOpcode(ARM::tBcc); 10376 return true; 10377 } 10378 break; 10379 case ARM::t2B: 10380 // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 10381 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){ 10382 Inst.setOpcode(ARM::t2Bcc); 10383 return true; 10384 } 10385 break; 10386 case ARM::t2Bcc: 10387 // If the conditional is AL or we're in an IT block, we really want t2B. 10388 if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) { 10389 Inst.setOpcode(ARM::t2B); 10390 return true; 10391 } 10392 break; 10393 case ARM::tBcc: 10394 // If the conditional is AL, we really want tB. 10395 if (Inst.getOperand(1).getImm() == ARMCC::AL) { 10396 Inst.setOpcode(ARM::tB); 10397 return true; 10398 } 10399 break; 10400 case ARM::tLDMIA: { 10401 // If the register list contains any high registers, or if the writeback 10402 // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 10403 // instead if we're in Thumb2. Otherwise, this should have generated 10404 // an error in validateInstruction(). 10405 unsigned Rn = Inst.getOperand(0).getReg(); 10406 bool hasWritebackToken = 10407 (static_cast<ARMOperand &>(*Operands[3]).isToken() && 10408 static_cast<ARMOperand &>(*Operands[3]).getToken() == "!"); 10409 bool listContainsBase; 10410 if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 10411 (!listContainsBase && !hasWritebackToken) || 10412 (listContainsBase && hasWritebackToken)) { 10413 // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 10414 assert(isThumbTwo()); 10415 Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 10416 // If we're switching to the updating version, we need to insert 10417 // the writeback tied operand. 10418 if (hasWritebackToken) 10419 Inst.insert(Inst.begin(), 10420 MCOperand::createReg(Inst.getOperand(0).getReg())); 10421 return true; 10422 } 10423 break; 10424 } 10425 case ARM::tSTMIA_UPD: { 10426 // If the register list contains any high registers, we need to use 10427 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 10428 // should have generated an error in validateInstruction(). 10429 unsigned Rn = Inst.getOperand(0).getReg(); 10430 bool listContainsBase; 10431 if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 10432 // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 10433 assert(isThumbTwo()); 10434 Inst.setOpcode(ARM::t2STMIA_UPD); 10435 return true; 10436 } 10437 break; 10438 } 10439 case ARM::tPOP: { 10440 bool listContainsBase; 10441 // If the register list contains any high registers, we need to use 10442 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 10443 // should have generated an error in validateInstruction(). 10444 if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase)) 10445 return false; 10446 assert(isThumbTwo()); 10447 Inst.setOpcode(ARM::t2LDMIA_UPD); 10448 // Add the base register and writeback operands. 10449 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP)); 10450 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP)); 10451 return true; 10452 } 10453 case ARM::tPUSH: { 10454 bool listContainsBase; 10455 if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase)) 10456 return false; 10457 assert(isThumbTwo()); 10458 Inst.setOpcode(ARM::t2STMDB_UPD); 10459 // Add the base register and writeback operands. 10460 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP)); 10461 Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP)); 10462 return true; 10463 } 10464 case ARM::t2MOVi: 10465 // If we can use the 16-bit encoding and the user didn't explicitly 10466 // request the 32-bit variant, transform it here. 10467 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 10468 (Inst.getOperand(1).isImm() && 10469 (unsigned)Inst.getOperand(1).getImm() <= 255) && 10470 Inst.getOperand(4).getReg() == (inITBlock() ? 0 : ARM::CPSR) && 10471 !HasWideQualifier) { 10472 // The operands aren't in the same order for tMOVi8... 10473 MCInst TmpInst; 10474 TmpInst.setOpcode(ARM::tMOVi8); 10475 TmpInst.addOperand(Inst.getOperand(0)); 10476 TmpInst.addOperand(Inst.getOperand(4)); 10477 TmpInst.addOperand(Inst.getOperand(1)); 10478 TmpInst.addOperand(Inst.getOperand(2)); 10479 TmpInst.addOperand(Inst.getOperand(3)); 10480 Inst = TmpInst; 10481 return true; 10482 } 10483 break; 10484 10485 case ARM::t2MOVr: 10486 // If we can use the 16-bit encoding and the user didn't explicitly 10487 // request the 32-bit variant, transform it here. 10488 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 10489 isARMLowRegister(Inst.getOperand(1).getReg()) && 10490 Inst.getOperand(2).getImm() == ARMCC::AL && 10491 Inst.getOperand(4).getReg() == ARM::CPSR && 10492 !HasWideQualifier) { 10493 // The operands aren't the same for tMOV[S]r... (no cc_out) 10494 MCInst TmpInst; 10495 unsigned Op = Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr; 10496 TmpInst.setOpcode(Op); 10497 TmpInst.addOperand(Inst.getOperand(0)); 10498 TmpInst.addOperand(Inst.getOperand(1)); 10499 if (Op == ARM::tMOVr) { 10500 TmpInst.addOperand(Inst.getOperand(2)); 10501 TmpInst.addOperand(Inst.getOperand(3)); 10502 } 10503 Inst = TmpInst; 10504 return true; 10505 } 10506 break; 10507 10508 case ARM::t2SXTH: 10509 case ARM::t2SXTB: 10510 case ARM::t2UXTH: 10511 case ARM::t2UXTB: 10512 // If we can use the 16-bit encoding and the user didn't explicitly 10513 // request the 32-bit variant, transform it here. 10514 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 10515 isARMLowRegister(Inst.getOperand(1).getReg()) && 10516 Inst.getOperand(2).getImm() == 0 && 10517 !HasWideQualifier) { 10518 unsigned NewOpc; 10519 switch (Inst.getOpcode()) { 10520 default: llvm_unreachable("Illegal opcode!"); 10521 case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 10522 case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 10523 case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 10524 case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 10525 } 10526 // The operands aren't the same for thumb1 (no rotate operand). 10527 MCInst TmpInst; 10528 TmpInst.setOpcode(NewOpc); 10529 TmpInst.addOperand(Inst.getOperand(0)); 10530 TmpInst.addOperand(Inst.getOperand(1)); 10531 TmpInst.addOperand(Inst.getOperand(3)); 10532 TmpInst.addOperand(Inst.getOperand(4)); 10533 Inst = TmpInst; 10534 return true; 10535 } 10536 break; 10537 10538 case ARM::MOVsi: { 10539 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm()); 10540 // rrx shifts and asr/lsr of #32 is encoded as 0 10541 if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr) 10542 return false; 10543 if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) { 10544 // Shifting by zero is accepted as a vanilla 'MOVr' 10545 MCInst TmpInst; 10546 TmpInst.setOpcode(ARM::MOVr); 10547 TmpInst.addOperand(Inst.getOperand(0)); 10548 TmpInst.addOperand(Inst.getOperand(1)); 10549 TmpInst.addOperand(Inst.getOperand(3)); 10550 TmpInst.addOperand(Inst.getOperand(4)); 10551 TmpInst.addOperand(Inst.getOperand(5)); 10552 Inst = TmpInst; 10553 return true; 10554 } 10555 return false; 10556 } 10557 case ARM::ANDrsi: 10558 case ARM::ORRrsi: 10559 case ARM::EORrsi: 10560 case ARM::BICrsi: 10561 case ARM::SUBrsi: 10562 case ARM::ADDrsi: { 10563 unsigned newOpc; 10564 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm()); 10565 if (SOpc == ARM_AM::rrx) return false; 10566 switch (Inst.getOpcode()) { 10567 default: llvm_unreachable("unexpected opcode!"); 10568 case ARM::ANDrsi: newOpc = ARM::ANDrr; break; 10569 case ARM::ORRrsi: newOpc = ARM::ORRrr; break; 10570 case ARM::EORrsi: newOpc = ARM::EORrr; break; 10571 case ARM::BICrsi: newOpc = ARM::BICrr; break; 10572 case ARM::SUBrsi: newOpc = ARM::SUBrr; break; 10573 case ARM::ADDrsi: newOpc = ARM::ADDrr; break; 10574 } 10575 // If the shift is by zero, use the non-shifted instruction definition. 10576 // The exception is for right shifts, where 0 == 32 10577 if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 && 10578 !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) { 10579 MCInst TmpInst; 10580 TmpInst.setOpcode(newOpc); 10581 TmpInst.addOperand(Inst.getOperand(0)); 10582 TmpInst.addOperand(Inst.getOperand(1)); 10583 TmpInst.addOperand(Inst.getOperand(2)); 10584 TmpInst.addOperand(Inst.getOperand(4)); 10585 TmpInst.addOperand(Inst.getOperand(5)); 10586 TmpInst.addOperand(Inst.getOperand(6)); 10587 Inst = TmpInst; 10588 return true; 10589 } 10590 return false; 10591 } 10592 case ARM::ITasm: 10593 case ARM::t2IT: { 10594 // Set up the IT block state according to the IT instruction we just 10595 // matched. 10596 assert(!inITBlock() && "nested IT blocks?!"); 10597 startExplicitITBlock(ARMCC::CondCodes(Inst.getOperand(0).getImm()), 10598 Inst.getOperand(1).getImm()); 10599 break; 10600 } 10601 case ARM::t2LSLrr: 10602 case ARM::t2LSRrr: 10603 case ARM::t2ASRrr: 10604 case ARM::t2SBCrr: 10605 case ARM::t2RORrr: 10606 case ARM::t2BICrr: 10607 // Assemblers should use the narrow encodings of these instructions when permissible. 10608 if ((isARMLowRegister(Inst.getOperand(1).getReg()) && 10609 isARMLowRegister(Inst.getOperand(2).getReg())) && 10610 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && 10611 Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) && 10612 !HasWideQualifier) { 10613 unsigned NewOpc; 10614 switch (Inst.getOpcode()) { 10615 default: llvm_unreachable("unexpected opcode"); 10616 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break; 10617 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break; 10618 case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break; 10619 case ARM::t2SBCrr: NewOpc = ARM::tSBC; break; 10620 case ARM::t2RORrr: NewOpc = ARM::tROR; break; 10621 case ARM::t2BICrr: NewOpc = ARM::tBIC; break; 10622 } 10623 MCInst TmpInst; 10624 TmpInst.setOpcode(NewOpc); 10625 TmpInst.addOperand(Inst.getOperand(0)); 10626 TmpInst.addOperand(Inst.getOperand(5)); 10627 TmpInst.addOperand(Inst.getOperand(1)); 10628 TmpInst.addOperand(Inst.getOperand(2)); 10629 TmpInst.addOperand(Inst.getOperand(3)); 10630 TmpInst.addOperand(Inst.getOperand(4)); 10631 Inst = TmpInst; 10632 return true; 10633 } 10634 return false; 10635 10636 case ARM::t2ANDrr: 10637 case ARM::t2EORrr: 10638 case ARM::t2ADCrr: 10639 case ARM::t2ORRrr: 10640 // Assemblers should use the narrow encodings of these instructions when permissible. 10641 // These instructions are special in that they are commutable, so shorter encodings 10642 // are available more often. 10643 if ((isARMLowRegister(Inst.getOperand(1).getReg()) && 10644 isARMLowRegister(Inst.getOperand(2).getReg())) && 10645 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() || 10646 Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) && 10647 Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) && 10648 !HasWideQualifier) { 10649 unsigned NewOpc; 10650 switch (Inst.getOpcode()) { 10651 default: llvm_unreachable("unexpected opcode"); 10652 case ARM::t2ADCrr: NewOpc = ARM::tADC; break; 10653 case ARM::t2ANDrr: NewOpc = ARM::tAND; break; 10654 case ARM::t2EORrr: NewOpc = ARM::tEOR; break; 10655 case ARM::t2ORRrr: NewOpc = ARM::tORR; break; 10656 } 10657 MCInst TmpInst; 10658 TmpInst.setOpcode(NewOpc); 10659 TmpInst.addOperand(Inst.getOperand(0)); 10660 TmpInst.addOperand(Inst.getOperand(5)); 10661 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) { 10662 TmpInst.addOperand(Inst.getOperand(1)); 10663 TmpInst.addOperand(Inst.getOperand(2)); 10664 } else { 10665 TmpInst.addOperand(Inst.getOperand(2)); 10666 TmpInst.addOperand(Inst.getOperand(1)); 10667 } 10668 TmpInst.addOperand(Inst.getOperand(3)); 10669 TmpInst.addOperand(Inst.getOperand(4)); 10670 Inst = TmpInst; 10671 return true; 10672 } 10673 return false; 10674 case ARM::MVE_VPST: 10675 case ARM::MVE_VPTv16i8: 10676 case ARM::MVE_VPTv8i16: 10677 case ARM::MVE_VPTv4i32: 10678 case ARM::MVE_VPTv16u8: 10679 case ARM::MVE_VPTv8u16: 10680 case ARM::MVE_VPTv4u32: 10681 case ARM::MVE_VPTv16s8: 10682 case ARM::MVE_VPTv8s16: 10683 case ARM::MVE_VPTv4s32: 10684 case ARM::MVE_VPTv4f32: 10685 case ARM::MVE_VPTv8f16: 10686 case ARM::MVE_VPTv16i8r: 10687 case ARM::MVE_VPTv8i16r: 10688 case ARM::MVE_VPTv4i32r: 10689 case ARM::MVE_VPTv16u8r: 10690 case ARM::MVE_VPTv8u16r: 10691 case ARM::MVE_VPTv4u32r: 10692 case ARM::MVE_VPTv16s8r: 10693 case ARM::MVE_VPTv8s16r: 10694 case ARM::MVE_VPTv4s32r: 10695 case ARM::MVE_VPTv4f32r: 10696 case ARM::MVE_VPTv8f16r: { 10697 assert(!inVPTBlock() && "Nested VPT blocks are not allowed"); 10698 MCOperand &MO = Inst.getOperand(0); 10699 VPTState.Mask = MO.getImm(); 10700 VPTState.CurPosition = 0; 10701 break; 10702 } 10703 } 10704 return false; 10705 } 10706 10707 unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 10708 // 16-bit thumb arithmetic instructions either require or preclude the 'S' 10709 // suffix depending on whether they're in an IT block or not. 10710 unsigned Opc = Inst.getOpcode(); 10711 const MCInstrDesc &MCID = MII.get(Opc); 10712 if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 10713 assert(MCID.hasOptionalDef() && 10714 "optionally flag setting instruction missing optional def operand"); 10715 assert(MCID.NumOperands == Inst.getNumOperands() && 10716 "operand count mismatch!"); 10717 // Find the optional-def operand (cc_out). 10718 unsigned OpNo; 10719 for (OpNo = 0; 10720 !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 10721 ++OpNo) 10722 ; 10723 // If we're parsing Thumb1, reject it completely. 10724 if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 10725 return Match_RequiresFlagSetting; 10726 // If we're parsing Thumb2, which form is legal depends on whether we're 10727 // in an IT block. 10728 if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 10729 !inITBlock()) 10730 return Match_RequiresITBlock; 10731 if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 10732 inITBlock()) 10733 return Match_RequiresNotITBlock; 10734 // LSL with zero immediate is not allowed in an IT block 10735 if (Opc == ARM::tLSLri && Inst.getOperand(3).getImm() == 0 && inITBlock()) 10736 return Match_RequiresNotITBlock; 10737 } else if (isThumbOne()) { 10738 // Some high-register supporting Thumb1 encodings only allow both registers 10739 // to be from r0-r7 when in Thumb2. 10740 if (Opc == ARM::tADDhirr && !hasV6MOps() && 10741 isARMLowRegister(Inst.getOperand(1).getReg()) && 10742 isARMLowRegister(Inst.getOperand(2).getReg())) 10743 return Match_RequiresThumb2; 10744 // Others only require ARMv6 or later. 10745 else if (Opc == ARM::tMOVr && !hasV6Ops() && 10746 isARMLowRegister(Inst.getOperand(0).getReg()) && 10747 isARMLowRegister(Inst.getOperand(1).getReg())) 10748 return Match_RequiresV6; 10749 } 10750 10751 // Before ARMv8 the rules for when SP is allowed in t2MOVr are more complex 10752 // than the loop below can handle, so it uses the GPRnopc register class and 10753 // we do SP handling here. 10754 if (Opc == ARM::t2MOVr && !hasV8Ops()) 10755 { 10756 // SP as both source and destination is not allowed 10757 if (Inst.getOperand(0).getReg() == ARM::SP && 10758 Inst.getOperand(1).getReg() == ARM::SP) 10759 return Match_RequiresV8; 10760 // When flags-setting SP as either source or destination is not allowed 10761 if (Inst.getOperand(4).getReg() == ARM::CPSR && 10762 (Inst.getOperand(0).getReg() == ARM::SP || 10763 Inst.getOperand(1).getReg() == ARM::SP)) 10764 return Match_RequiresV8; 10765 } 10766 10767 switch (Inst.getOpcode()) { 10768 case ARM::VMRS: 10769 case ARM::VMSR: 10770 case ARM::VMRS_FPCXTS: 10771 case ARM::VMRS_FPCXTNS: 10772 case ARM::VMSR_FPCXTS: 10773 case ARM::VMSR_FPCXTNS: 10774 case ARM::VMRS_FPSCR_NZCVQC: 10775 case ARM::VMSR_FPSCR_NZCVQC: 10776 case ARM::FMSTAT: 10777 case ARM::VMRS_VPR: 10778 case ARM::VMRS_P0: 10779 case ARM::VMSR_VPR: 10780 case ARM::VMSR_P0: 10781 // Use of SP for VMRS/VMSR is only allowed in ARM mode with the exception of 10782 // ARMv8-A. 10783 if (Inst.getOperand(0).isReg() && Inst.getOperand(0).getReg() == ARM::SP && 10784 (isThumb() && !hasV8Ops())) 10785 return Match_InvalidOperand; 10786 break; 10787 case ARM::t2TBB: 10788 case ARM::t2TBH: 10789 // Rn = sp is only allowed with ARMv8-A 10790 if (!hasV8Ops() && (Inst.getOperand(0).getReg() == ARM::SP)) 10791 return Match_RequiresV8; 10792 break; 10793 default: 10794 break; 10795 } 10796 10797 for (unsigned I = 0; I < MCID.NumOperands; ++I) 10798 if (MCID.OpInfo[I].RegClass == ARM::rGPRRegClassID) { 10799 // rGPRRegClass excludes PC, and also excluded SP before ARMv8 10800 const auto &Op = Inst.getOperand(I); 10801 if (!Op.isReg()) { 10802 // This can happen in awkward cases with tied operands, e.g. a 10803 // writeback load/store with a complex addressing mode in 10804 // which there's an output operand corresponding to the 10805 // updated written-back base register: the Tablegen-generated 10806 // AsmMatcher will have written a placeholder operand to that 10807 // slot in the form of an immediate 0, because it can't 10808 // generate the register part of the complex addressing-mode 10809 // operand ahead of time. 10810 continue; 10811 } 10812 10813 unsigned Reg = Op.getReg(); 10814 if ((Reg == ARM::SP) && !hasV8Ops()) 10815 return Match_RequiresV8; 10816 else if (Reg == ARM::PC) 10817 return Match_InvalidOperand; 10818 } 10819 10820 return Match_Success; 10821 } 10822 10823 namespace llvm { 10824 10825 template <> inline bool IsCPSRDead<MCInst>(const MCInst *Instr) { 10826 return true; // In an assembly source, no need to second-guess 10827 } 10828 10829 } // end namespace llvm 10830 10831 // Returns true if Inst is unpredictable if it is in and IT block, but is not 10832 // the last instruction in the block. 10833 bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const { 10834 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 10835 10836 // All branch & call instructions terminate IT blocks with the exception of 10837 // SVC. 10838 if (MCID.isTerminator() || (MCID.isCall() && Inst.getOpcode() != ARM::tSVC) || 10839 MCID.isReturn() || MCID.isBranch() || MCID.isIndirectBranch()) 10840 return true; 10841 10842 // Any arithmetic instruction which writes to the PC also terminates the IT 10843 // block. 10844 if (MCID.hasDefOfPhysReg(Inst, ARM::PC, *MRI)) 10845 return true; 10846 10847 return false; 10848 } 10849 10850 unsigned ARMAsmParser::MatchInstruction(OperandVector &Operands, MCInst &Inst, 10851 SmallVectorImpl<NearMissInfo> &NearMisses, 10852 bool MatchingInlineAsm, 10853 bool &EmitInITBlock, 10854 MCStreamer &Out) { 10855 // If we can't use an implicit IT block here, just match as normal. 10856 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb()) 10857 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm); 10858 10859 // Try to match the instruction in an extension of the current IT block (if 10860 // there is one). 10861 if (inImplicitITBlock()) { 10862 extendImplicitITBlock(ITState.Cond); 10863 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) == 10864 Match_Success) { 10865 // The match succeded, but we still have to check that the instruction is 10866 // valid in this implicit IT block. 10867 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 10868 if (MCID.isPredicable()) { 10869 ARMCC::CondCodes InstCond = 10870 (ARMCC::CondCodes)Inst.getOperand(MCID.findFirstPredOperandIdx()) 10871 .getImm(); 10872 ARMCC::CondCodes ITCond = currentITCond(); 10873 if (InstCond == ITCond) { 10874 EmitInITBlock = true; 10875 return Match_Success; 10876 } else if (InstCond == ARMCC::getOppositeCondition(ITCond)) { 10877 invertCurrentITCondition(); 10878 EmitInITBlock = true; 10879 return Match_Success; 10880 } 10881 } 10882 } 10883 rewindImplicitITPosition(); 10884 } 10885 10886 // Finish the current IT block, and try to match outside any IT block. 10887 flushPendingInstructions(Out); 10888 unsigned PlainMatchResult = 10889 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm); 10890 if (PlainMatchResult == Match_Success) { 10891 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 10892 if (MCID.isPredicable()) { 10893 ARMCC::CondCodes InstCond = 10894 (ARMCC::CondCodes)Inst.getOperand(MCID.findFirstPredOperandIdx()) 10895 .getImm(); 10896 // Some forms of the branch instruction have their own condition code 10897 // fields, so can be conditionally executed without an IT block. 10898 if (Inst.getOpcode() == ARM::tBcc || Inst.getOpcode() == ARM::t2Bcc) { 10899 EmitInITBlock = false; 10900 return Match_Success; 10901 } 10902 if (InstCond == ARMCC::AL) { 10903 EmitInITBlock = false; 10904 return Match_Success; 10905 } 10906 } else { 10907 EmitInITBlock = false; 10908 return Match_Success; 10909 } 10910 } 10911 10912 // Try to match in a new IT block. The matcher doesn't check the actual 10913 // condition, so we create an IT block with a dummy condition, and fix it up 10914 // once we know the actual condition. 10915 startImplicitITBlock(); 10916 if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) == 10917 Match_Success) { 10918 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 10919 if (MCID.isPredicable()) { 10920 ITState.Cond = 10921 (ARMCC::CondCodes)Inst.getOperand(MCID.findFirstPredOperandIdx()) 10922 .getImm(); 10923 EmitInITBlock = true; 10924 return Match_Success; 10925 } 10926 } 10927 discardImplicitITBlock(); 10928 10929 // If none of these succeed, return the error we got when trying to match 10930 // outside any IT blocks. 10931 EmitInITBlock = false; 10932 return PlainMatchResult; 10933 } 10934 10935 static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, 10936 unsigned VariantID = 0); 10937 10938 static const char *getSubtargetFeatureName(uint64_t Val); 10939 bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 10940 OperandVector &Operands, 10941 MCStreamer &Out, uint64_t &ErrorInfo, 10942 bool MatchingInlineAsm) { 10943 MCInst Inst; 10944 unsigned MatchResult; 10945 bool PendConditionalInstruction = false; 10946 10947 SmallVector<NearMissInfo, 4> NearMisses; 10948 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm, 10949 PendConditionalInstruction, Out); 10950 10951 switch (MatchResult) { 10952 case Match_Success: 10953 LLVM_DEBUG(dbgs() << "Parsed as: "; 10954 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode())); 10955 dbgs() << "\n"); 10956 10957 // Context sensitive operand constraints aren't handled by the matcher, 10958 // so check them here. 10959 if (validateInstruction(Inst, Operands)) { 10960 // Still progress the IT block, otherwise one wrong condition causes 10961 // nasty cascading errors. 10962 forwardITPosition(); 10963 forwardVPTPosition(); 10964 return true; 10965 } 10966 10967 { // processInstruction() updates inITBlock state, we need to save it away 10968 bool wasInITBlock = inITBlock(); 10969 10970 // Some instructions need post-processing to, for example, tweak which 10971 // encoding is selected. Loop on it while changes happen so the 10972 // individual transformations can chain off each other. E.g., 10973 // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8) 10974 while (processInstruction(Inst, Operands, Out)) 10975 LLVM_DEBUG(dbgs() << "Changed to: "; 10976 Inst.dump_pretty(dbgs(), MII.getName(Inst.getOpcode())); 10977 dbgs() << "\n"); 10978 10979 // Only after the instruction is fully processed, we can validate it 10980 if (wasInITBlock && hasV8Ops() && isThumb() && 10981 !isV8EligibleForIT(&Inst) && !getTargetOptions().MCNoDeprecatedWarn) { 10982 Warning(IDLoc, "deprecated instruction in IT block"); 10983 } 10984 } 10985 10986 // Only move forward at the very end so that everything in validate 10987 // and process gets a consistent answer about whether we're in an IT 10988 // block. 10989 forwardITPosition(); 10990 forwardVPTPosition(); 10991 10992 // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and 10993 // doesn't actually encode. 10994 if (Inst.getOpcode() == ARM::ITasm) 10995 return false; 10996 10997 Inst.setLoc(IDLoc); 10998 if (PendConditionalInstruction) { 10999 PendingConditionalInsts.push_back(Inst); 11000 if (isITBlockFull() || isITBlockTerminator(Inst)) 11001 flushPendingInstructions(Out); 11002 } else { 11003 Out.emitInstruction(Inst, getSTI()); 11004 } 11005 return false; 11006 case Match_NearMisses: 11007 ReportNearMisses(NearMisses, IDLoc, Operands); 11008 return true; 11009 case Match_MnemonicFail: { 11010 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 11011 std::string Suggestion = ARMMnemonicSpellCheck( 11012 ((ARMOperand &)*Operands[0]).getToken(), FBS); 11013 return Error(IDLoc, "invalid instruction" + Suggestion, 11014 ((ARMOperand &)*Operands[0]).getLocRange()); 11015 } 11016 } 11017 11018 llvm_unreachable("Implement any new match types added!"); 11019 } 11020 11021 /// parseDirective parses the arm specific directives 11022 bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 11023 const MCContext::Environment Format = getContext().getObjectFileType(); 11024 bool IsMachO = Format == MCContext::IsMachO; 11025 bool IsCOFF = Format == MCContext::IsCOFF; 11026 11027 std::string IDVal = DirectiveID.getIdentifier().lower(); 11028 if (IDVal == ".word") 11029 parseLiteralValues(4, DirectiveID.getLoc()); 11030 else if (IDVal == ".short" || IDVal == ".hword") 11031 parseLiteralValues(2, DirectiveID.getLoc()); 11032 else if (IDVal == ".thumb") 11033 parseDirectiveThumb(DirectiveID.getLoc()); 11034 else if (IDVal == ".arm") 11035 parseDirectiveARM(DirectiveID.getLoc()); 11036 else if (IDVal == ".thumb_func") 11037 parseDirectiveThumbFunc(DirectiveID.getLoc()); 11038 else if (IDVal == ".code") 11039 parseDirectiveCode(DirectiveID.getLoc()); 11040 else if (IDVal == ".syntax") 11041 parseDirectiveSyntax(DirectiveID.getLoc()); 11042 else if (IDVal == ".unreq") 11043 parseDirectiveUnreq(DirectiveID.getLoc()); 11044 else if (IDVal == ".fnend") 11045 parseDirectiveFnEnd(DirectiveID.getLoc()); 11046 else if (IDVal == ".cantunwind") 11047 parseDirectiveCantUnwind(DirectiveID.getLoc()); 11048 else if (IDVal == ".personality") 11049 parseDirectivePersonality(DirectiveID.getLoc()); 11050 else if (IDVal == ".handlerdata") 11051 parseDirectiveHandlerData(DirectiveID.getLoc()); 11052 else if (IDVal == ".setfp") 11053 parseDirectiveSetFP(DirectiveID.getLoc()); 11054 else if (IDVal == ".pad") 11055 parseDirectivePad(DirectiveID.getLoc()); 11056 else if (IDVal == ".save") 11057 parseDirectiveRegSave(DirectiveID.getLoc(), false); 11058 else if (IDVal == ".vsave") 11059 parseDirectiveRegSave(DirectiveID.getLoc(), true); 11060 else if (IDVal == ".ltorg" || IDVal == ".pool") 11061 parseDirectiveLtorg(DirectiveID.getLoc()); 11062 else if (IDVal == ".even") 11063 parseDirectiveEven(DirectiveID.getLoc()); 11064 else if (IDVal == ".personalityindex") 11065 parseDirectivePersonalityIndex(DirectiveID.getLoc()); 11066 else if (IDVal == ".unwind_raw") 11067 parseDirectiveUnwindRaw(DirectiveID.getLoc()); 11068 else if (IDVal == ".movsp") 11069 parseDirectiveMovSP(DirectiveID.getLoc()); 11070 else if (IDVal == ".arch_extension") 11071 parseDirectiveArchExtension(DirectiveID.getLoc()); 11072 else if (IDVal == ".align") 11073 return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure. 11074 else if (IDVal == ".thumb_set") 11075 parseDirectiveThumbSet(DirectiveID.getLoc()); 11076 else if (IDVal == ".inst") 11077 parseDirectiveInst(DirectiveID.getLoc()); 11078 else if (IDVal == ".inst.n") 11079 parseDirectiveInst(DirectiveID.getLoc(), 'n'); 11080 else if (IDVal == ".inst.w") 11081 parseDirectiveInst(DirectiveID.getLoc(), 'w'); 11082 else if (!IsMachO && !IsCOFF) { 11083 if (IDVal == ".arch") 11084 parseDirectiveArch(DirectiveID.getLoc()); 11085 else if (IDVal == ".cpu") 11086 parseDirectiveCPU(DirectiveID.getLoc()); 11087 else if (IDVal == ".eabi_attribute") 11088 parseDirectiveEabiAttr(DirectiveID.getLoc()); 11089 else if (IDVal == ".fpu") 11090 parseDirectiveFPU(DirectiveID.getLoc()); 11091 else if (IDVal == ".fnstart") 11092 parseDirectiveFnStart(DirectiveID.getLoc()); 11093 else if (IDVal == ".object_arch") 11094 parseDirectiveObjectArch(DirectiveID.getLoc()); 11095 else if (IDVal == ".tlsdescseq") 11096 parseDirectiveTLSDescSeq(DirectiveID.getLoc()); 11097 else 11098 return true; 11099 } else 11100 return true; 11101 return false; 11102 } 11103 11104 /// parseLiteralValues 11105 /// ::= .hword expression [, expression]* 11106 /// ::= .short expression [, expression]* 11107 /// ::= .word expression [, expression]* 11108 bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) { 11109 auto parseOne = [&]() -> bool { 11110 const MCExpr *Value; 11111 if (getParser().parseExpression(Value)) 11112 return true; 11113 getParser().getStreamer().emitValue(Value, Size, L); 11114 return false; 11115 }; 11116 return (parseMany(parseOne)); 11117 } 11118 11119 /// parseDirectiveThumb 11120 /// ::= .thumb 11121 bool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 11122 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive") || 11123 check(!hasThumb(), L, "target does not support Thumb mode")) 11124 return true; 11125 11126 if (!isThumb()) 11127 SwitchMode(); 11128 11129 getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); 11130 return false; 11131 } 11132 11133 /// parseDirectiveARM 11134 /// ::= .arm 11135 bool ARMAsmParser::parseDirectiveARM(SMLoc L) { 11136 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive") || 11137 check(!hasARM(), L, "target does not support ARM mode")) 11138 return true; 11139 11140 if (isThumb()) 11141 SwitchMode(); 11142 getParser().getStreamer().emitAssemblerFlag(MCAF_Code32); 11143 return false; 11144 } 11145 11146 void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol) { 11147 // We need to flush the current implicit IT block on a label, because it is 11148 // not legal to branch into an IT block. 11149 flushPendingInstructions(getStreamer()); 11150 } 11151 11152 void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) { 11153 if (NextSymbolIsThumb) { 11154 getParser().getStreamer().emitThumbFunc(Symbol); 11155 NextSymbolIsThumb = false; 11156 } 11157 } 11158 11159 /// parseDirectiveThumbFunc 11160 /// ::= .thumbfunc symbol_name 11161 bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 11162 MCAsmParser &Parser = getParser(); 11163 const auto Format = getContext().getObjectFileType(); 11164 bool IsMachO = Format == MCContext::IsMachO; 11165 11166 // Darwin asm has (optionally) function name after .thumb_func direction 11167 // ELF doesn't 11168 11169 if (IsMachO) { 11170 if (Parser.getTok().is(AsmToken::Identifier) || 11171 Parser.getTok().is(AsmToken::String)) { 11172 MCSymbol *Func = getParser().getContext().getOrCreateSymbol( 11173 Parser.getTok().getIdentifier()); 11174 getParser().getStreamer().emitThumbFunc(Func); 11175 Parser.Lex(); 11176 if (parseToken(AsmToken::EndOfStatement, 11177 "unexpected token in '.thumb_func' directive")) 11178 return true; 11179 return false; 11180 } 11181 } 11182 11183 if (parseToken(AsmToken::EndOfStatement, 11184 "unexpected token in '.thumb_func' directive")) 11185 return true; 11186 11187 // .thumb_func implies .thumb 11188 if (!isThumb()) 11189 SwitchMode(); 11190 11191 getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); 11192 11193 NextSymbolIsThumb = true; 11194 return false; 11195 } 11196 11197 /// parseDirectiveSyntax 11198 /// ::= .syntax unified | divided 11199 bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 11200 MCAsmParser &Parser = getParser(); 11201 const AsmToken &Tok = Parser.getTok(); 11202 if (Tok.isNot(AsmToken::Identifier)) { 11203 Error(L, "unexpected token in .syntax directive"); 11204 return false; 11205 } 11206 11207 StringRef Mode = Tok.getString(); 11208 Parser.Lex(); 11209 if (check(Mode == "divided" || Mode == "DIVIDED", L, 11210 "'.syntax divided' arm assembly not supported") || 11211 check(Mode != "unified" && Mode != "UNIFIED", L, 11212 "unrecognized syntax mode in .syntax directive") || 11213 parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 11214 return true; 11215 11216 // TODO tell the MC streamer the mode 11217 // getParser().getStreamer().Emit???(); 11218 return false; 11219 } 11220 11221 /// parseDirectiveCode 11222 /// ::= .code 16 | 32 11223 bool ARMAsmParser::parseDirectiveCode(SMLoc L) { 11224 MCAsmParser &Parser = getParser(); 11225 const AsmToken &Tok = Parser.getTok(); 11226 if (Tok.isNot(AsmToken::Integer)) 11227 return Error(L, "unexpected token in .code directive"); 11228 int64_t Val = Parser.getTok().getIntVal(); 11229 if (Val != 16 && Val != 32) { 11230 Error(L, "invalid operand to .code directive"); 11231 return false; 11232 } 11233 Parser.Lex(); 11234 11235 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 11236 return true; 11237 11238 if (Val == 16) { 11239 if (!hasThumb()) 11240 return Error(L, "target does not support Thumb mode"); 11241 11242 if (!isThumb()) 11243 SwitchMode(); 11244 getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); 11245 } else { 11246 if (!hasARM()) 11247 return Error(L, "target does not support ARM mode"); 11248 11249 if (isThumb()) 11250 SwitchMode(); 11251 getParser().getStreamer().emitAssemblerFlag(MCAF_Code32); 11252 } 11253 11254 return false; 11255 } 11256 11257 /// parseDirectiveReq 11258 /// ::= name .req registername 11259 bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { 11260 MCAsmParser &Parser = getParser(); 11261 Parser.Lex(); // Eat the '.req' token. 11262 unsigned Reg; 11263 SMLoc SRegLoc, ERegLoc; 11264 if (check(ParseRegister(Reg, SRegLoc, ERegLoc), SRegLoc, 11265 "register name expected") || 11266 parseToken(AsmToken::EndOfStatement, 11267 "unexpected input in .req directive.")) 11268 return true; 11269 11270 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg) 11271 return Error(SRegLoc, 11272 "redefinition of '" + Name + "' does not match original."); 11273 11274 return false; 11275 } 11276 11277 /// parseDirectiveUneq 11278 /// ::= .unreq registername 11279 bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) { 11280 MCAsmParser &Parser = getParser(); 11281 if (Parser.getTok().isNot(AsmToken::Identifier)) 11282 return Error(L, "unexpected input in .unreq directive."); 11283 RegisterReqs.erase(Parser.getTok().getIdentifier().lower()); 11284 Parser.Lex(); // Eat the identifier. 11285 if (parseToken(AsmToken::EndOfStatement, 11286 "unexpected input in '.unreq' directive")) 11287 return true; 11288 return false; 11289 } 11290 11291 // After changing arch/CPU, try to put the ARM/Thumb mode back to what it was 11292 // before, if supported by the new target, or emit mapping symbols for the mode 11293 // switch. 11294 void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) { 11295 if (WasThumb != isThumb()) { 11296 if (WasThumb && hasThumb()) { 11297 // Stay in Thumb mode 11298 SwitchMode(); 11299 } else if (!WasThumb && hasARM()) { 11300 // Stay in ARM mode 11301 SwitchMode(); 11302 } else { 11303 // Mode switch forced, because the new arch doesn't support the old mode. 11304 getParser().getStreamer().emitAssemblerFlag(isThumb() ? MCAF_Code16 11305 : MCAF_Code32); 11306 // Warn about the implcit mode switch. GAS does not switch modes here, 11307 // but instead stays in the old mode, reporting an error on any following 11308 // instructions as the mode does not exist on the target. 11309 Warning(Loc, Twine("new target does not support ") + 11310 (WasThumb ? "thumb" : "arm") + " mode, switching to " + 11311 (!WasThumb ? "thumb" : "arm") + " mode"); 11312 } 11313 } 11314 } 11315 11316 /// parseDirectiveArch 11317 /// ::= .arch token 11318 bool ARMAsmParser::parseDirectiveArch(SMLoc L) { 11319 StringRef Arch = getParser().parseStringToEndOfStatement().trim(); 11320 ARM::ArchKind ID = ARM::parseArch(Arch); 11321 11322 if (ID == ARM::ArchKind::INVALID) 11323 return Error(L, "Unknown arch name"); 11324 11325 bool WasThumb = isThumb(); 11326 Triple T; 11327 MCSubtargetInfo &STI = copySTI(); 11328 STI.setDefaultFeatures("", /*TuneCPU*/ "", 11329 ("+" + ARM::getArchName(ID)).str()); 11330 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 11331 FixModeAfterArchChange(WasThumb, L); 11332 11333 getTargetStreamer().emitArch(ID); 11334 return false; 11335 } 11336 11337 /// parseDirectiveEabiAttr 11338 /// ::= .eabi_attribute int, int [, "str"] 11339 /// ::= .eabi_attribute Tag_name, int [, "str"] 11340 bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) { 11341 MCAsmParser &Parser = getParser(); 11342 int64_t Tag; 11343 SMLoc TagLoc; 11344 TagLoc = Parser.getTok().getLoc(); 11345 if (Parser.getTok().is(AsmToken::Identifier)) { 11346 StringRef Name = Parser.getTok().getIdentifier(); 11347 Optional<unsigned> Ret = ELFAttrs::attrTypeFromString( 11348 Name, ARMBuildAttrs::getARMAttributeTags()); 11349 if (!Ret.hasValue()) { 11350 Error(TagLoc, "attribute name not recognised: " + Name); 11351 return false; 11352 } 11353 Tag = Ret.getValue(); 11354 Parser.Lex(); 11355 } else { 11356 const MCExpr *AttrExpr; 11357 11358 TagLoc = Parser.getTok().getLoc(); 11359 if (Parser.parseExpression(AttrExpr)) 11360 return true; 11361 11362 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 11363 if (check(!CE, TagLoc, "expected numeric constant")) 11364 return true; 11365 11366 Tag = CE->getValue(); 11367 } 11368 11369 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 11370 return true; 11371 11372 StringRef StringValue = ""; 11373 bool IsStringValue = false; 11374 11375 int64_t IntegerValue = 0; 11376 bool IsIntegerValue = false; 11377 11378 if (Tag == ARMBuildAttrs::CPU_raw_name || Tag == ARMBuildAttrs::CPU_name) 11379 IsStringValue = true; 11380 else if (Tag == ARMBuildAttrs::compatibility) { 11381 IsStringValue = true; 11382 IsIntegerValue = true; 11383 } else if (Tag < 32 || Tag % 2 == 0) 11384 IsIntegerValue = true; 11385 else if (Tag % 2 == 1) 11386 IsStringValue = true; 11387 else 11388 llvm_unreachable("invalid tag type"); 11389 11390 if (IsIntegerValue) { 11391 const MCExpr *ValueExpr; 11392 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 11393 if (Parser.parseExpression(ValueExpr)) 11394 return true; 11395 11396 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 11397 if (!CE) 11398 return Error(ValueExprLoc, "expected numeric constant"); 11399 IntegerValue = CE->getValue(); 11400 } 11401 11402 if (Tag == ARMBuildAttrs::compatibility) { 11403 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 11404 return true; 11405 } 11406 11407 if (IsStringValue) { 11408 if (Parser.getTok().isNot(AsmToken::String)) 11409 return Error(Parser.getTok().getLoc(), "bad string constant"); 11410 11411 StringValue = Parser.getTok().getStringContents(); 11412 Parser.Lex(); 11413 } 11414 11415 if (Parser.parseToken(AsmToken::EndOfStatement, 11416 "unexpected token in '.eabi_attribute' directive")) 11417 return true; 11418 11419 if (IsIntegerValue && IsStringValue) { 11420 assert(Tag == ARMBuildAttrs::compatibility); 11421 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue); 11422 } else if (IsIntegerValue) 11423 getTargetStreamer().emitAttribute(Tag, IntegerValue); 11424 else if (IsStringValue) 11425 getTargetStreamer().emitTextAttribute(Tag, StringValue); 11426 return false; 11427 } 11428 11429 /// parseDirectiveCPU 11430 /// ::= .cpu str 11431 bool ARMAsmParser::parseDirectiveCPU(SMLoc L) { 11432 StringRef CPU = getParser().parseStringToEndOfStatement().trim(); 11433 getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU); 11434 11435 // FIXME: This is using table-gen data, but should be moved to 11436 // ARMTargetParser once that is table-gen'd. 11437 if (!getSTI().isCPUStringValid(CPU)) 11438 return Error(L, "Unknown CPU name"); 11439 11440 bool WasThumb = isThumb(); 11441 MCSubtargetInfo &STI = copySTI(); 11442 STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, ""); 11443 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 11444 FixModeAfterArchChange(WasThumb, L); 11445 11446 return false; 11447 } 11448 11449 /// parseDirectiveFPU 11450 /// ::= .fpu str 11451 bool ARMAsmParser::parseDirectiveFPU(SMLoc L) { 11452 SMLoc FPUNameLoc = getTok().getLoc(); 11453 StringRef FPU = getParser().parseStringToEndOfStatement().trim(); 11454 11455 unsigned ID = ARM::parseFPU(FPU); 11456 std::vector<StringRef> Features; 11457 if (!ARM::getFPUFeatures(ID, Features)) 11458 return Error(FPUNameLoc, "Unknown FPU name"); 11459 11460 MCSubtargetInfo &STI = copySTI(); 11461 for (auto Feature : Features) 11462 STI.ApplyFeatureFlag(Feature); 11463 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 11464 11465 getTargetStreamer().emitFPU(ID); 11466 return false; 11467 } 11468 11469 /// parseDirectiveFnStart 11470 /// ::= .fnstart 11471 bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) { 11472 if (parseToken(AsmToken::EndOfStatement, 11473 "unexpected token in '.fnstart' directive")) 11474 return true; 11475 11476 if (UC.hasFnStart()) { 11477 Error(L, ".fnstart starts before the end of previous one"); 11478 UC.emitFnStartLocNotes(); 11479 return true; 11480 } 11481 11482 // Reset the unwind directives parser state 11483 UC.reset(); 11484 11485 getTargetStreamer().emitFnStart(); 11486 11487 UC.recordFnStart(L); 11488 return false; 11489 } 11490 11491 /// parseDirectiveFnEnd 11492 /// ::= .fnend 11493 bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) { 11494 if (parseToken(AsmToken::EndOfStatement, 11495 "unexpected token in '.fnend' directive")) 11496 return true; 11497 // Check the ordering of unwind directives 11498 if (!UC.hasFnStart()) 11499 return Error(L, ".fnstart must precede .fnend directive"); 11500 11501 // Reset the unwind directives parser state 11502 getTargetStreamer().emitFnEnd(); 11503 11504 UC.reset(); 11505 return false; 11506 } 11507 11508 /// parseDirectiveCantUnwind 11509 /// ::= .cantunwind 11510 bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) { 11511 if (parseToken(AsmToken::EndOfStatement, 11512 "unexpected token in '.cantunwind' directive")) 11513 return true; 11514 11515 UC.recordCantUnwind(L); 11516 // Check the ordering of unwind directives 11517 if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive")) 11518 return true; 11519 11520 if (UC.hasHandlerData()) { 11521 Error(L, ".cantunwind can't be used with .handlerdata directive"); 11522 UC.emitHandlerDataLocNotes(); 11523 return true; 11524 } 11525 if (UC.hasPersonality()) { 11526 Error(L, ".cantunwind can't be used with .personality directive"); 11527 UC.emitPersonalityLocNotes(); 11528 return true; 11529 } 11530 11531 getTargetStreamer().emitCantUnwind(); 11532 return false; 11533 } 11534 11535 /// parseDirectivePersonality 11536 /// ::= .personality name 11537 bool ARMAsmParser::parseDirectivePersonality(SMLoc L) { 11538 MCAsmParser &Parser = getParser(); 11539 bool HasExistingPersonality = UC.hasPersonality(); 11540 11541 // Parse the name of the personality routine 11542 if (Parser.getTok().isNot(AsmToken::Identifier)) 11543 return Error(L, "unexpected input in .personality directive."); 11544 StringRef Name(Parser.getTok().getIdentifier()); 11545 Parser.Lex(); 11546 11547 if (parseToken(AsmToken::EndOfStatement, 11548 "unexpected token in '.personality' directive")) 11549 return true; 11550 11551 UC.recordPersonality(L); 11552 11553 // Check the ordering of unwind directives 11554 if (!UC.hasFnStart()) 11555 return Error(L, ".fnstart must precede .personality directive"); 11556 if (UC.cantUnwind()) { 11557 Error(L, ".personality can't be used with .cantunwind directive"); 11558 UC.emitCantUnwindLocNotes(); 11559 return true; 11560 } 11561 if (UC.hasHandlerData()) { 11562 Error(L, ".personality must precede .handlerdata directive"); 11563 UC.emitHandlerDataLocNotes(); 11564 return true; 11565 } 11566 if (HasExistingPersonality) { 11567 Error(L, "multiple personality directives"); 11568 UC.emitPersonalityLocNotes(); 11569 return true; 11570 } 11571 11572 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name); 11573 getTargetStreamer().emitPersonality(PR); 11574 return false; 11575 } 11576 11577 /// parseDirectiveHandlerData 11578 /// ::= .handlerdata 11579 bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) { 11580 if (parseToken(AsmToken::EndOfStatement, 11581 "unexpected token in '.handlerdata' directive")) 11582 return true; 11583 11584 UC.recordHandlerData(L); 11585 // Check the ordering of unwind directives 11586 if (!UC.hasFnStart()) 11587 return Error(L, ".fnstart must precede .personality directive"); 11588 if (UC.cantUnwind()) { 11589 Error(L, ".handlerdata can't be used with .cantunwind directive"); 11590 UC.emitCantUnwindLocNotes(); 11591 return true; 11592 } 11593 11594 getTargetStreamer().emitHandlerData(); 11595 return false; 11596 } 11597 11598 /// parseDirectiveSetFP 11599 /// ::= .setfp fpreg, spreg [, offset] 11600 bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) { 11601 MCAsmParser &Parser = getParser(); 11602 // Check the ordering of unwind directives 11603 if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") || 11604 check(UC.hasHandlerData(), L, 11605 ".setfp must precede .handlerdata directive")) 11606 return true; 11607 11608 // Parse fpreg 11609 SMLoc FPRegLoc = Parser.getTok().getLoc(); 11610 int FPReg = tryParseRegister(); 11611 11612 if (check(FPReg == -1, FPRegLoc, "frame pointer register expected") || 11613 Parser.parseToken(AsmToken::Comma, "comma expected")) 11614 return true; 11615 11616 // Parse spreg 11617 SMLoc SPRegLoc = Parser.getTok().getLoc(); 11618 int SPReg = tryParseRegister(); 11619 if (check(SPReg == -1, SPRegLoc, "stack pointer register expected") || 11620 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc, 11621 "register should be either $sp or the latest fp register")) 11622 return true; 11623 11624 // Update the frame pointer register 11625 UC.saveFPReg(FPReg); 11626 11627 // Parse offset 11628 int64_t Offset = 0; 11629 if (Parser.parseOptionalToken(AsmToken::Comma)) { 11630 if (Parser.getTok().isNot(AsmToken::Hash) && 11631 Parser.getTok().isNot(AsmToken::Dollar)) 11632 return Error(Parser.getTok().getLoc(), "'#' expected"); 11633 Parser.Lex(); // skip hash token. 11634 11635 const MCExpr *OffsetExpr; 11636 SMLoc ExLoc = Parser.getTok().getLoc(); 11637 SMLoc EndLoc; 11638 if (getParser().parseExpression(OffsetExpr, EndLoc)) 11639 return Error(ExLoc, "malformed setfp offset"); 11640 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr); 11641 if (check(!CE, ExLoc, "setfp offset must be an immediate")) 11642 return true; 11643 Offset = CE->getValue(); 11644 } 11645 11646 if (Parser.parseToken(AsmToken::EndOfStatement)) 11647 return true; 11648 11649 getTargetStreamer().emitSetFP(static_cast<unsigned>(FPReg), 11650 static_cast<unsigned>(SPReg), Offset); 11651 return false; 11652 } 11653 11654 /// parseDirective 11655 /// ::= .pad offset 11656 bool ARMAsmParser::parseDirectivePad(SMLoc L) { 11657 MCAsmParser &Parser = getParser(); 11658 // Check the ordering of unwind directives 11659 if (!UC.hasFnStart()) 11660 return Error(L, ".fnstart must precede .pad directive"); 11661 if (UC.hasHandlerData()) 11662 return Error(L, ".pad must precede .handlerdata directive"); 11663 11664 // Parse the offset 11665 if (Parser.getTok().isNot(AsmToken::Hash) && 11666 Parser.getTok().isNot(AsmToken::Dollar)) 11667 return Error(Parser.getTok().getLoc(), "'#' expected"); 11668 Parser.Lex(); // skip hash token. 11669 11670 const MCExpr *OffsetExpr; 11671 SMLoc ExLoc = Parser.getTok().getLoc(); 11672 SMLoc EndLoc; 11673 if (getParser().parseExpression(OffsetExpr, EndLoc)) 11674 return Error(ExLoc, "malformed pad offset"); 11675 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr); 11676 if (!CE) 11677 return Error(ExLoc, "pad offset must be an immediate"); 11678 11679 if (parseToken(AsmToken::EndOfStatement, 11680 "unexpected token in '.pad' directive")) 11681 return true; 11682 11683 getTargetStreamer().emitPad(CE->getValue()); 11684 return false; 11685 } 11686 11687 /// parseDirectiveRegSave 11688 /// ::= .save { registers } 11689 /// ::= .vsave { registers } 11690 bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) { 11691 // Check the ordering of unwind directives 11692 if (!UC.hasFnStart()) 11693 return Error(L, ".fnstart must precede .save or .vsave directives"); 11694 if (UC.hasHandlerData()) 11695 return Error(L, ".save or .vsave must precede .handlerdata directive"); 11696 11697 // RAII object to make sure parsed operands are deleted. 11698 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 11699 11700 // Parse the register list 11701 if (parseRegisterList(Operands, true, true) || 11702 parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 11703 return true; 11704 ARMOperand &Op = (ARMOperand &)*Operands[0]; 11705 if (!IsVector && !Op.isRegList()) 11706 return Error(L, ".save expects GPR registers"); 11707 if (IsVector && !Op.isDPRRegList()) 11708 return Error(L, ".vsave expects DPR registers"); 11709 11710 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector); 11711 return false; 11712 } 11713 11714 /// parseDirectiveInst 11715 /// ::= .inst opcode [, ...] 11716 /// ::= .inst.n opcode [, ...] 11717 /// ::= .inst.w opcode [, ...] 11718 bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) { 11719 int Width = 4; 11720 11721 if (isThumb()) { 11722 switch (Suffix) { 11723 case 'n': 11724 Width = 2; 11725 break; 11726 case 'w': 11727 break; 11728 default: 11729 Width = 0; 11730 break; 11731 } 11732 } else { 11733 if (Suffix) 11734 return Error(Loc, "width suffixes are invalid in ARM mode"); 11735 } 11736 11737 auto parseOne = [&]() -> bool { 11738 const MCExpr *Expr; 11739 if (getParser().parseExpression(Expr)) 11740 return true; 11741 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr); 11742 if (!Value) { 11743 return Error(Loc, "expected constant expression"); 11744 } 11745 11746 char CurSuffix = Suffix; 11747 switch (Width) { 11748 case 2: 11749 if (Value->getValue() > 0xffff) 11750 return Error(Loc, "inst.n operand is too big, use inst.w instead"); 11751 break; 11752 case 4: 11753 if (Value->getValue() > 0xffffffff) 11754 return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") + 11755 " operand is too big"); 11756 break; 11757 case 0: 11758 // Thumb mode, no width indicated. Guess from the opcode, if possible. 11759 if (Value->getValue() < 0xe800) 11760 CurSuffix = 'n'; 11761 else if (Value->getValue() >= 0xe8000000) 11762 CurSuffix = 'w'; 11763 else 11764 return Error(Loc, "cannot determine Thumb instruction size, " 11765 "use inst.n/inst.w instead"); 11766 break; 11767 default: 11768 llvm_unreachable("only supported widths are 2 and 4"); 11769 } 11770 11771 getTargetStreamer().emitInst(Value->getValue(), CurSuffix); 11772 return false; 11773 }; 11774 11775 if (parseOptionalToken(AsmToken::EndOfStatement)) 11776 return Error(Loc, "expected expression following directive"); 11777 if (parseMany(parseOne)) 11778 return true; 11779 return false; 11780 } 11781 11782 /// parseDirectiveLtorg 11783 /// ::= .ltorg | .pool 11784 bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) { 11785 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 11786 return true; 11787 getTargetStreamer().emitCurrentConstantPool(); 11788 return false; 11789 } 11790 11791 bool ARMAsmParser::parseDirectiveEven(SMLoc L) { 11792 const MCSection *Section = getStreamer().getCurrentSectionOnly(); 11793 11794 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive")) 11795 return true; 11796 11797 if (!Section) { 11798 getStreamer().initSections(false, getSTI()); 11799 Section = getStreamer().getCurrentSectionOnly(); 11800 } 11801 11802 assert(Section && "must have section to emit alignment"); 11803 if (Section->UseCodeAlign()) 11804 getStreamer().emitCodeAlignment(2, &getSTI()); 11805 else 11806 getStreamer().emitValueToAlignment(2); 11807 11808 return false; 11809 } 11810 11811 /// parseDirectivePersonalityIndex 11812 /// ::= .personalityindex index 11813 bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) { 11814 MCAsmParser &Parser = getParser(); 11815 bool HasExistingPersonality = UC.hasPersonality(); 11816 11817 const MCExpr *IndexExpression; 11818 SMLoc IndexLoc = Parser.getTok().getLoc(); 11819 if (Parser.parseExpression(IndexExpression) || 11820 parseToken(AsmToken::EndOfStatement, 11821 "unexpected token in '.personalityindex' directive")) { 11822 return true; 11823 } 11824 11825 UC.recordPersonalityIndex(L); 11826 11827 if (!UC.hasFnStart()) { 11828 return Error(L, ".fnstart must precede .personalityindex directive"); 11829 } 11830 if (UC.cantUnwind()) { 11831 Error(L, ".personalityindex cannot be used with .cantunwind"); 11832 UC.emitCantUnwindLocNotes(); 11833 return true; 11834 } 11835 if (UC.hasHandlerData()) { 11836 Error(L, ".personalityindex must precede .handlerdata directive"); 11837 UC.emitHandlerDataLocNotes(); 11838 return true; 11839 } 11840 if (HasExistingPersonality) { 11841 Error(L, "multiple personality directives"); 11842 UC.emitPersonalityLocNotes(); 11843 return true; 11844 } 11845 11846 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression); 11847 if (!CE) 11848 return Error(IndexLoc, "index must be a constant number"); 11849 if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX) 11850 return Error(IndexLoc, 11851 "personality routine index should be in range [0-3]"); 11852 11853 getTargetStreamer().emitPersonalityIndex(CE->getValue()); 11854 return false; 11855 } 11856 11857 /// parseDirectiveUnwindRaw 11858 /// ::= .unwind_raw offset, opcode [, opcode...] 11859 bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) { 11860 MCAsmParser &Parser = getParser(); 11861 int64_t StackOffset; 11862 const MCExpr *OffsetExpr; 11863 SMLoc OffsetLoc = getLexer().getLoc(); 11864 11865 if (!UC.hasFnStart()) 11866 return Error(L, ".fnstart must precede .unwind_raw directives"); 11867 if (getParser().parseExpression(OffsetExpr)) 11868 return Error(OffsetLoc, "expected expression"); 11869 11870 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr); 11871 if (!CE) 11872 return Error(OffsetLoc, "offset must be a constant"); 11873 11874 StackOffset = CE->getValue(); 11875 11876 if (Parser.parseToken(AsmToken::Comma, "expected comma")) 11877 return true; 11878 11879 SmallVector<uint8_t, 16> Opcodes; 11880 11881 auto parseOne = [&]() -> bool { 11882 const MCExpr *OE = nullptr; 11883 SMLoc OpcodeLoc = getLexer().getLoc(); 11884 if (check(getLexer().is(AsmToken::EndOfStatement) || 11885 Parser.parseExpression(OE), 11886 OpcodeLoc, "expected opcode expression")) 11887 return true; 11888 const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE); 11889 if (!OC) 11890 return Error(OpcodeLoc, "opcode value must be a constant"); 11891 const int64_t Opcode = OC->getValue(); 11892 if (Opcode & ~0xff) 11893 return Error(OpcodeLoc, "invalid opcode"); 11894 Opcodes.push_back(uint8_t(Opcode)); 11895 return false; 11896 }; 11897 11898 // Must have at least 1 element 11899 SMLoc OpcodeLoc = getLexer().getLoc(); 11900 if (parseOptionalToken(AsmToken::EndOfStatement)) 11901 return Error(OpcodeLoc, "expected opcode expression"); 11902 if (parseMany(parseOne)) 11903 return true; 11904 11905 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes); 11906 return false; 11907 } 11908 11909 /// parseDirectiveTLSDescSeq 11910 /// ::= .tlsdescseq tls-variable 11911 bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) { 11912 MCAsmParser &Parser = getParser(); 11913 11914 if (getLexer().isNot(AsmToken::Identifier)) 11915 return TokError("expected variable after '.tlsdescseq' directive"); 11916 11917 const MCSymbolRefExpr *SRE = 11918 MCSymbolRefExpr::create(Parser.getTok().getIdentifier(), 11919 MCSymbolRefExpr::VK_ARM_TLSDESCSEQ, getContext()); 11920 Lex(); 11921 11922 if (parseToken(AsmToken::EndOfStatement, 11923 "unexpected token in '.tlsdescseq' directive")) 11924 return true; 11925 11926 getTargetStreamer().AnnotateTLSDescriptorSequence(SRE); 11927 return false; 11928 } 11929 11930 /// parseDirectiveMovSP 11931 /// ::= .movsp reg [, #offset] 11932 bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) { 11933 MCAsmParser &Parser = getParser(); 11934 if (!UC.hasFnStart()) 11935 return Error(L, ".fnstart must precede .movsp directives"); 11936 if (UC.getFPReg() != ARM::SP) 11937 return Error(L, "unexpected .movsp directive"); 11938 11939 SMLoc SPRegLoc = Parser.getTok().getLoc(); 11940 int SPReg = tryParseRegister(); 11941 if (SPReg == -1) 11942 return Error(SPRegLoc, "register expected"); 11943 if (SPReg == ARM::SP || SPReg == ARM::PC) 11944 return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive"); 11945 11946 int64_t Offset = 0; 11947 if (Parser.parseOptionalToken(AsmToken::Comma)) { 11948 if (Parser.parseToken(AsmToken::Hash, "expected #constant")) 11949 return true; 11950 11951 const MCExpr *OffsetExpr; 11952 SMLoc OffsetLoc = Parser.getTok().getLoc(); 11953 11954 if (Parser.parseExpression(OffsetExpr)) 11955 return Error(OffsetLoc, "malformed offset expression"); 11956 11957 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr); 11958 if (!CE) 11959 return Error(OffsetLoc, "offset must be an immediate constant"); 11960 11961 Offset = CE->getValue(); 11962 } 11963 11964 if (parseToken(AsmToken::EndOfStatement, 11965 "unexpected token in '.movsp' directive")) 11966 return true; 11967 11968 getTargetStreamer().emitMovSP(SPReg, Offset); 11969 UC.saveFPReg(SPReg); 11970 11971 return false; 11972 } 11973 11974 /// parseDirectiveObjectArch 11975 /// ::= .object_arch name 11976 bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) { 11977 MCAsmParser &Parser = getParser(); 11978 if (getLexer().isNot(AsmToken::Identifier)) 11979 return Error(getLexer().getLoc(), "unexpected token"); 11980 11981 StringRef Arch = Parser.getTok().getString(); 11982 SMLoc ArchLoc = Parser.getTok().getLoc(); 11983 Lex(); 11984 11985 ARM::ArchKind ID = ARM::parseArch(Arch); 11986 11987 if (ID == ARM::ArchKind::INVALID) 11988 return Error(ArchLoc, "unknown architecture '" + Arch + "'"); 11989 if (parseToken(AsmToken::EndOfStatement)) 11990 return true; 11991 11992 getTargetStreamer().emitObjectArch(ID); 11993 return false; 11994 } 11995 11996 /// parseDirectiveAlign 11997 /// ::= .align 11998 bool ARMAsmParser::parseDirectiveAlign(SMLoc L) { 11999 // NOTE: if this is not the end of the statement, fall back to the target 12000 // agnostic handling for this directive which will correctly handle this. 12001 if (parseOptionalToken(AsmToken::EndOfStatement)) { 12002 // '.align' is target specifically handled to mean 2**2 byte alignment. 12003 const MCSection *Section = getStreamer().getCurrentSectionOnly(); 12004 assert(Section && "must have section to emit alignment"); 12005 if (Section->UseCodeAlign()) 12006 getStreamer().emitCodeAlignment(4, &getSTI(), 0); 12007 else 12008 getStreamer().emitValueToAlignment(4, 0, 1, 0); 12009 return false; 12010 } 12011 return true; 12012 } 12013 12014 /// parseDirectiveThumbSet 12015 /// ::= .thumb_set name, value 12016 bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) { 12017 MCAsmParser &Parser = getParser(); 12018 12019 StringRef Name; 12020 if (check(Parser.parseIdentifier(Name), 12021 "expected identifier after '.thumb_set'") || 12022 parseToken(AsmToken::Comma, "expected comma after name '" + Name + "'")) 12023 return true; 12024 12025 MCSymbol *Sym; 12026 const MCExpr *Value; 12027 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true, 12028 Parser, Sym, Value)) 12029 return true; 12030 12031 getTargetStreamer().emitThumbSet(Sym, Value); 12032 return false; 12033 } 12034 12035 /// Force static initialization. 12036 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMAsmParser() { 12037 RegisterMCAsmParser<ARMAsmParser> X(getTheARMLETarget()); 12038 RegisterMCAsmParser<ARMAsmParser> Y(getTheARMBETarget()); 12039 RegisterMCAsmParser<ARMAsmParser> A(getTheThumbLETarget()); 12040 RegisterMCAsmParser<ARMAsmParser> B(getTheThumbBETarget()); 12041 } 12042 12043 #define GET_REGISTER_MATCHER 12044 #define GET_SUBTARGET_FEATURE_NAME 12045 #define GET_MATCHER_IMPLEMENTATION 12046 #define GET_MNEMONIC_SPELL_CHECKER 12047 #include "ARMGenAsmMatcher.inc" 12048 12049 // Some diagnostics need to vary with subtarget features, so they are handled 12050 // here. For example, the DPR class has either 16 or 32 registers, depending 12051 // on the FPU available. 12052 const char * 12053 ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) { 12054 switch (MatchError) { 12055 // rGPR contains sp starting with ARMv8. 12056 case Match_rGPR: 12057 return hasV8Ops() ? "operand must be a register in range [r0, r14]" 12058 : "operand must be a register in range [r0, r12] or r14"; 12059 // DPR contains 16 registers for some FPUs, and 32 for others. 12060 case Match_DPR: 12061 return hasD32() ? "operand must be a register in range [d0, d31]" 12062 : "operand must be a register in range [d0, d15]"; 12063 case Match_DPR_RegList: 12064 return hasD32() ? "operand must be a list of registers in range [d0, d31]" 12065 : "operand must be a list of registers in range [d0, d15]"; 12066 12067 // For all other diags, use the static string from tablegen. 12068 default: 12069 return getMatchKindDiag(MatchError); 12070 } 12071 } 12072 12073 // Process the list of near-misses, throwing away ones we don't want to report 12074 // to the user, and converting the rest to a source location and string that 12075 // should be reported. 12076 void 12077 ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn, 12078 SmallVectorImpl<NearMissMessage> &NearMissesOut, 12079 SMLoc IDLoc, OperandVector &Operands) { 12080 // TODO: If operand didn't match, sub in a dummy one and run target 12081 // predicate, so that we can avoid reporting near-misses that are invalid? 12082 // TODO: Many operand types dont have SuperClasses set, so we report 12083 // redundant ones. 12084 // TODO: Some operands are superclasses of registers (e.g. 12085 // MCK_RegShiftedImm), we don't have any way to represent that currently. 12086 // TODO: This is not all ARM-specific, can some of it be factored out? 12087 12088 // Record some information about near-misses that we have already seen, so 12089 // that we can avoid reporting redundant ones. For example, if there are 12090 // variants of an instruction that take 8- and 16-bit immediates, we want 12091 // to only report the widest one. 12092 std::multimap<unsigned, unsigned> OperandMissesSeen; 12093 SmallSet<FeatureBitset, 4> FeatureMissesSeen; 12094 bool ReportedTooFewOperands = false; 12095 12096 // Process the near-misses in reverse order, so that we see more general ones 12097 // first, and so can avoid emitting more specific ones. 12098 for (NearMissInfo &I : reverse(NearMissesIn)) { 12099 switch (I.getKind()) { 12100 case NearMissInfo::NearMissOperand: { 12101 SMLoc OperandLoc = 12102 ((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc(); 12103 const char *OperandDiag = 12104 getCustomOperandDiag((ARMMatchResultTy)I.getOperandError()); 12105 12106 // If we have already emitted a message for a superclass, don't also report 12107 // the sub-class. We consider all operand classes that we don't have a 12108 // specialised diagnostic for to be equal for the propose of this check, 12109 // so that we don't report the generic error multiple times on the same 12110 // operand. 12111 unsigned DupCheckMatchClass = OperandDiag ? I.getOperandClass() : ~0U; 12112 auto PrevReports = OperandMissesSeen.equal_range(I.getOperandIndex()); 12113 if (std::any_of(PrevReports.first, PrevReports.second, 12114 [DupCheckMatchClass]( 12115 const std::pair<unsigned, unsigned> Pair) { 12116 if (DupCheckMatchClass == ~0U || Pair.second == ~0U) 12117 return Pair.second == DupCheckMatchClass; 12118 else 12119 return isSubclass((MatchClassKind)DupCheckMatchClass, 12120 (MatchClassKind)Pair.second); 12121 })) 12122 break; 12123 OperandMissesSeen.insert( 12124 std::make_pair(I.getOperandIndex(), DupCheckMatchClass)); 12125 12126 NearMissMessage Message; 12127 Message.Loc = OperandLoc; 12128 if (OperandDiag) { 12129 Message.Message = OperandDiag; 12130 } else if (I.getOperandClass() == InvalidMatchClass) { 12131 Message.Message = "too many operands for instruction"; 12132 } else { 12133 Message.Message = "invalid operand for instruction"; 12134 LLVM_DEBUG( 12135 dbgs() << "Missing diagnostic string for operand class " 12136 << getMatchClassName((MatchClassKind)I.getOperandClass()) 12137 << I.getOperandClass() << ", error " << I.getOperandError() 12138 << ", opcode " << MII.getName(I.getOpcode()) << "\n"); 12139 } 12140 NearMissesOut.emplace_back(Message); 12141 break; 12142 } 12143 case NearMissInfo::NearMissFeature: { 12144 const FeatureBitset &MissingFeatures = I.getFeatures(); 12145 // Don't report the same set of features twice. 12146 if (FeatureMissesSeen.count(MissingFeatures)) 12147 break; 12148 FeatureMissesSeen.insert(MissingFeatures); 12149 12150 // Special case: don't report a feature set which includes arm-mode for 12151 // targets that don't have ARM mode. 12152 if (MissingFeatures.test(Feature_IsARMBit) && !hasARM()) 12153 break; 12154 // Don't report any near-misses that both require switching instruction 12155 // set, and adding other subtarget features. 12156 if (isThumb() && MissingFeatures.test(Feature_IsARMBit) && 12157 MissingFeatures.count() > 1) 12158 break; 12159 if (!isThumb() && MissingFeatures.test(Feature_IsThumbBit) && 12160 MissingFeatures.count() > 1) 12161 break; 12162 if (!isThumb() && MissingFeatures.test(Feature_IsThumb2Bit) && 12163 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit, 12164 Feature_IsThumbBit})).any()) 12165 break; 12166 if (isMClass() && MissingFeatures.test(Feature_HasNEONBit)) 12167 break; 12168 12169 NearMissMessage Message; 12170 Message.Loc = IDLoc; 12171 raw_svector_ostream OS(Message.Message); 12172 12173 OS << "instruction requires:"; 12174 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) 12175 if (MissingFeatures.test(i)) 12176 OS << ' ' << getSubtargetFeatureName(i); 12177 12178 NearMissesOut.emplace_back(Message); 12179 12180 break; 12181 } 12182 case NearMissInfo::NearMissPredicate: { 12183 NearMissMessage Message; 12184 Message.Loc = IDLoc; 12185 switch (I.getPredicateError()) { 12186 case Match_RequiresNotITBlock: 12187 Message.Message = "flag setting instruction only valid outside IT block"; 12188 break; 12189 case Match_RequiresITBlock: 12190 Message.Message = "instruction only valid inside IT block"; 12191 break; 12192 case Match_RequiresV6: 12193 Message.Message = "instruction variant requires ARMv6 or later"; 12194 break; 12195 case Match_RequiresThumb2: 12196 Message.Message = "instruction variant requires Thumb2"; 12197 break; 12198 case Match_RequiresV8: 12199 Message.Message = "instruction variant requires ARMv8 or later"; 12200 break; 12201 case Match_RequiresFlagSetting: 12202 Message.Message = "no flag-preserving variant of this instruction available"; 12203 break; 12204 case Match_InvalidOperand: 12205 Message.Message = "invalid operand for instruction"; 12206 break; 12207 default: 12208 llvm_unreachable("Unhandled target predicate error"); 12209 break; 12210 } 12211 NearMissesOut.emplace_back(Message); 12212 break; 12213 } 12214 case NearMissInfo::NearMissTooFewOperands: { 12215 if (!ReportedTooFewOperands) { 12216 SMLoc EndLoc = ((ARMOperand &)*Operands.back()).getEndLoc(); 12217 NearMissesOut.emplace_back(NearMissMessage{ 12218 EndLoc, StringRef("too few operands for instruction")}); 12219 ReportedTooFewOperands = true; 12220 } 12221 break; 12222 } 12223 case NearMissInfo::NoNearMiss: 12224 // This should never leave the matcher. 12225 llvm_unreachable("not a near-miss"); 12226 break; 12227 } 12228 } 12229 } 12230 12231 void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, 12232 SMLoc IDLoc, OperandVector &Operands) { 12233 SmallVector<NearMissMessage, 4> Messages; 12234 FilterNearMisses(NearMisses, Messages, IDLoc, Operands); 12235 12236 if (Messages.size() == 0) { 12237 // No near-misses were found, so the best we can do is "invalid 12238 // instruction". 12239 Error(IDLoc, "invalid instruction"); 12240 } else if (Messages.size() == 1) { 12241 // One near miss was found, report it as the sole error. 12242 Error(Messages[0].Loc, Messages[0].Message); 12243 } else { 12244 // More than one near miss, so report a generic "invalid instruction" 12245 // error, followed by notes for each of the near-misses. 12246 Error(IDLoc, "invalid instruction, any one of the following would fix this:"); 12247 for (auto &M : Messages) { 12248 Note(M.Loc, M.Message); 12249 } 12250 } 12251 } 12252 12253 bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) { 12254 // FIXME: This structure should be moved inside ARMTargetParser 12255 // when we start to table-generate them, and we can use the ARM 12256 // flags below, that were generated by table-gen. 12257 static const struct { 12258 const uint64_t Kind; 12259 const FeatureBitset ArchCheck; 12260 const FeatureBitset Features; 12261 } Extensions[] = { 12262 {ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}}, 12263 {ARM::AEK_AES, 12264 {Feature_HasV8Bit}, 12265 {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}}, 12266 {ARM::AEK_SHA2, 12267 {Feature_HasV8Bit}, 12268 {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}}, 12269 {ARM::AEK_CRYPTO, 12270 {Feature_HasV8Bit}, 12271 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}}, 12272 {ARM::AEK_FP, 12273 {Feature_HasV8Bit}, 12274 {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}}, 12275 {(ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM), 12276 {Feature_HasV7Bit, Feature_IsNotMClassBit}, 12277 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}}, 12278 {ARM::AEK_MP, 12279 {Feature_HasV7Bit, Feature_IsNotMClassBit}, 12280 {ARM::FeatureMP}}, 12281 {ARM::AEK_SIMD, 12282 {Feature_HasV8Bit}, 12283 {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}}, 12284 {ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}}, 12285 // FIXME: Only available in A-class, isel not predicated 12286 {ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}}, 12287 {ARM::AEK_FP16, 12288 {Feature_HasV8_2aBit}, 12289 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}}, 12290 {ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}}, 12291 {ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}}, 12292 {ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI}}, 12293 // FIXME: Unsupported extensions. 12294 {ARM::AEK_OS, {}, {}}, 12295 {ARM::AEK_IWMMXT, {}, {}}, 12296 {ARM::AEK_IWMMXT2, {}, {}}, 12297 {ARM::AEK_MAVERICK, {}, {}}, 12298 {ARM::AEK_XSCALE, {}, {}}, 12299 }; 12300 bool EnableFeature = true; 12301 if (Name.startswith_insensitive("no")) { 12302 EnableFeature = false; 12303 Name = Name.substr(2); 12304 } 12305 uint64_t FeatureKind = ARM::parseArchExt(Name); 12306 if (FeatureKind == ARM::AEK_INVALID) 12307 return Error(ExtLoc, "unknown architectural extension: " + Name); 12308 12309 for (const auto &Extension : Extensions) { 12310 if (Extension.Kind != FeatureKind) 12311 continue; 12312 12313 if (Extension.Features.none()) 12314 return Error(ExtLoc, "unsupported architectural extension: " + Name); 12315 12316 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck) 12317 return Error(ExtLoc, "architectural extension '" + Name + 12318 "' is not " 12319 "allowed for the current base architecture"); 12320 12321 MCSubtargetInfo &STI = copySTI(); 12322 if (EnableFeature) { 12323 STI.SetFeatureBitsTransitively(Extension.Features); 12324 } else { 12325 STI.ClearFeatureBitsTransitively(Extension.Features); 12326 } 12327 FeatureBitset Features = ComputeAvailableFeatures(STI.getFeatureBits()); 12328 setAvailableFeatures(Features); 12329 return true; 12330 } 12331 return false; 12332 } 12333 12334 /// parseDirectiveArchExtension 12335 /// ::= .arch_extension [no]feature 12336 bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) { 12337 12338 MCAsmParser &Parser = getParser(); 12339 12340 if (getLexer().isNot(AsmToken::Identifier)) 12341 return Error(getLexer().getLoc(), "expected architecture extension name"); 12342 12343 StringRef Name = Parser.getTok().getString(); 12344 SMLoc ExtLoc = Parser.getTok().getLoc(); 12345 Lex(); 12346 12347 if (parseToken(AsmToken::EndOfStatement, 12348 "unexpected token in '.arch_extension' directive")) 12349 return true; 12350 12351 if (Name == "nocrypto") { 12352 enableArchExtFeature("nosha2", ExtLoc); 12353 enableArchExtFeature("noaes", ExtLoc); 12354 } 12355 12356 if (enableArchExtFeature(Name, ExtLoc)) 12357 return false; 12358 12359 return Error(ExtLoc, "unknown architectural extension: " + Name); 12360 } 12361 12362 // Define this matcher function after the auto-generated include so we 12363 // have the match class enum definitions. 12364 unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 12365 unsigned Kind) { 12366 ARMOperand &Op = static_cast<ARMOperand &>(AsmOp); 12367 // If the kind is a token for a literal immediate, check if our asm 12368 // operand matches. This is for InstAliases which have a fixed-value 12369 // immediate in the syntax. 12370 switch (Kind) { 12371 default: break; 12372 case MCK__HASH_0: 12373 if (Op.isImm()) 12374 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm())) 12375 if (CE->getValue() == 0) 12376 return Match_Success; 12377 break; 12378 case MCK__HASH_8: 12379 if (Op.isImm()) 12380 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm())) 12381 if (CE->getValue() == 8) 12382 return Match_Success; 12383 break; 12384 case MCK__HASH_16: 12385 if (Op.isImm()) 12386 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm())) 12387 if (CE->getValue() == 16) 12388 return Match_Success; 12389 break; 12390 case MCK_ModImm: 12391 if (Op.isImm()) { 12392 const MCExpr *SOExpr = Op.getImm(); 12393 int64_t Value; 12394 if (!SOExpr->evaluateAsAbsolute(Value)) 12395 return Match_Success; 12396 assert((Value >= std::numeric_limits<int32_t>::min() && 12397 Value <= std::numeric_limits<uint32_t>::max()) && 12398 "expression value must be representable in 32 bits"); 12399 } 12400 break; 12401 case MCK_rGPR: 12402 if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP) 12403 return Match_Success; 12404 return Match_rGPR; 12405 case MCK_GPRPair: 12406 if (Op.isReg() && 12407 MRI->getRegClass(ARM::GPRRegClassID).contains(Op.getReg())) 12408 return Match_Success; 12409 break; 12410 } 12411 return Match_InvalidOperand; 12412 } 12413 12414 bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic, 12415 StringRef ExtraToken) { 12416 if (!hasMVE()) 12417 return false; 12418 12419 return Mnemonic.startswith("vabav") || Mnemonic.startswith("vaddv") || 12420 Mnemonic.startswith("vaddlv") || Mnemonic.startswith("vminnmv") || 12421 Mnemonic.startswith("vminnmav") || Mnemonic.startswith("vminv") || 12422 Mnemonic.startswith("vminav") || Mnemonic.startswith("vmaxnmv") || 12423 Mnemonic.startswith("vmaxnmav") || Mnemonic.startswith("vmaxv") || 12424 Mnemonic.startswith("vmaxav") || Mnemonic.startswith("vmladav") || 12425 Mnemonic.startswith("vrmlaldavh") || Mnemonic.startswith("vrmlalvh") || 12426 Mnemonic.startswith("vmlsdav") || Mnemonic.startswith("vmlav") || 12427 Mnemonic.startswith("vmlaldav") || Mnemonic.startswith("vmlalv") || 12428 Mnemonic.startswith("vmaxnm") || Mnemonic.startswith("vminnm") || 12429 Mnemonic.startswith("vmax") || Mnemonic.startswith("vmin") || 12430 Mnemonic.startswith("vshlc") || Mnemonic.startswith("vmovlt") || 12431 Mnemonic.startswith("vmovlb") || Mnemonic.startswith("vshll") || 12432 Mnemonic.startswith("vrshrn") || Mnemonic.startswith("vshrn") || 12433 Mnemonic.startswith("vqrshrun") || Mnemonic.startswith("vqshrun") || 12434 Mnemonic.startswith("vqrshrn") || Mnemonic.startswith("vqshrn") || 12435 Mnemonic.startswith("vbic") || Mnemonic.startswith("vrev64") || 12436 Mnemonic.startswith("vrev32") || Mnemonic.startswith("vrev16") || 12437 Mnemonic.startswith("vmvn") || Mnemonic.startswith("veor") || 12438 Mnemonic.startswith("vorn") || Mnemonic.startswith("vorr") || 12439 Mnemonic.startswith("vand") || Mnemonic.startswith("vmul") || 12440 Mnemonic.startswith("vqrdmulh") || Mnemonic.startswith("vqdmulh") || 12441 Mnemonic.startswith("vsub") || Mnemonic.startswith("vadd") || 12442 Mnemonic.startswith("vqsub") || Mnemonic.startswith("vqadd") || 12443 Mnemonic.startswith("vabd") || Mnemonic.startswith("vrhadd") || 12444 Mnemonic.startswith("vhsub") || Mnemonic.startswith("vhadd") || 12445 Mnemonic.startswith("vdup") || Mnemonic.startswith("vcls") || 12446 Mnemonic.startswith("vclz") || Mnemonic.startswith("vneg") || 12447 Mnemonic.startswith("vabs") || Mnemonic.startswith("vqneg") || 12448 Mnemonic.startswith("vqabs") || 12449 (Mnemonic.startswith("vrint") && Mnemonic != "vrintr") || 12450 Mnemonic.startswith("vcmla") || Mnemonic.startswith("vfma") || 12451 Mnemonic.startswith("vfms") || Mnemonic.startswith("vcadd") || 12452 Mnemonic.startswith("vadd") || Mnemonic.startswith("vsub") || 12453 Mnemonic.startswith("vshl") || Mnemonic.startswith("vqshl") || 12454 Mnemonic.startswith("vqrshl") || Mnemonic.startswith("vrshl") || 12455 Mnemonic.startswith("vsri") || Mnemonic.startswith("vsli") || 12456 Mnemonic.startswith("vrshr") || Mnemonic.startswith("vshr") || 12457 Mnemonic.startswith("vpsel") || Mnemonic.startswith("vcmp") || 12458 Mnemonic.startswith("vqdmladh") || Mnemonic.startswith("vqrdmladh") || 12459 Mnemonic.startswith("vqdmlsdh") || Mnemonic.startswith("vqrdmlsdh") || 12460 Mnemonic.startswith("vcmul") || Mnemonic.startswith("vrmulh") || 12461 Mnemonic.startswith("vqmovn") || Mnemonic.startswith("vqmovun") || 12462 Mnemonic.startswith("vmovnt") || Mnemonic.startswith("vmovnb") || 12463 Mnemonic.startswith("vmaxa") || Mnemonic.startswith("vmaxnma") || 12464 Mnemonic.startswith("vhcadd") || Mnemonic.startswith("vadc") || 12465 Mnemonic.startswith("vsbc") || Mnemonic.startswith("vrshr") || 12466 Mnemonic.startswith("vshr") || Mnemonic.startswith("vstrb") || 12467 Mnemonic.startswith("vldrb") || 12468 (Mnemonic.startswith("vstrh") && Mnemonic != "vstrhi") || 12469 (Mnemonic.startswith("vldrh") && Mnemonic != "vldrhi") || 12470 Mnemonic.startswith("vstrw") || Mnemonic.startswith("vldrw") || 12471 Mnemonic.startswith("vldrd") || Mnemonic.startswith("vstrd") || 12472 Mnemonic.startswith("vqdmull") || Mnemonic.startswith("vbrsr") || 12473 Mnemonic.startswith("vfmas") || Mnemonic.startswith("vmlas") || 12474 Mnemonic.startswith("vmla") || Mnemonic.startswith("vqdmlash") || 12475 Mnemonic.startswith("vqdmlah") || Mnemonic.startswith("vqrdmlash") || 12476 Mnemonic.startswith("vqrdmlah") || Mnemonic.startswith("viwdup") || 12477 Mnemonic.startswith("vdwdup") || Mnemonic.startswith("vidup") || 12478 Mnemonic.startswith("vddup") || Mnemonic.startswith("vctp") || 12479 Mnemonic.startswith("vpnot") || Mnemonic.startswith("vbic") || 12480 Mnemonic.startswith("vrmlsldavh") || Mnemonic.startswith("vmlsldav") || 12481 Mnemonic.startswith("vcvt") || 12482 MS.isVPTPredicableCDEInstr(Mnemonic) || 12483 (Mnemonic.startswith("vmov") && 12484 !(ExtraToken == ".f16" || ExtraToken == ".32" || 12485 ExtraToken == ".16" || ExtraToken == ".8")); 12486 } 12487