1 //===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "ARMFeatures.h" 11 #include "MCTargetDesc/ARMAddressingModes.h" 12 #include "MCTargetDesc/ARMBaseInfo.h" 13 #include "MCTargetDesc/ARMMCExpr.h" 14 #include "llvm/ADT/STLExtras.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringExtras.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/MC/MCAsmInfo.h" 21 #include "llvm/MC/MCAssembler.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 24 #include "llvm/MC/MCELFStreamer.h" 25 #include "llvm/MC/MCExpr.h" 26 #include "llvm/MC/MCInst.h" 27 #include "llvm/MC/MCInstrDesc.h" 28 #include "llvm/MC/MCInstrInfo.h" 29 #include "llvm/MC/MCObjectFileInfo.h" 30 #include "llvm/MC/MCParser/MCAsmLexer.h" 31 #include "llvm/MC/MCParser/MCAsmParser.h" 32 #include "llvm/MC/MCParser/MCAsmParserUtils.h" 33 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 34 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 35 #include "llvm/MC/MCRegisterInfo.h" 36 #include "llvm/MC/MCSection.h" 37 #include "llvm/MC/MCStreamer.h" 38 #include "llvm/MC/MCSubtargetInfo.h" 39 #include "llvm/MC/MCSymbol.h" 40 #include "llvm/Support/ARMBuildAttributes.h" 41 #include "llvm/Support/ARMEHABI.h" 42 #include "llvm/Support/COFF.h" 43 #include "llvm/Support/Debug.h" 44 #include "llvm/Support/ELF.h" 45 #include "llvm/Support/MathExtras.h" 46 #include "llvm/Support/SourceMgr.h" 47 #include "llvm/Support/TargetParser.h" 48 #include "llvm/Support/TargetRegistry.h" 49 #include "llvm/Support/raw_ostream.h" 50 51 using namespace llvm; 52 53 namespace { 54 55 class ARMOperand; 56 57 enum VectorLaneTy { NoLanes, AllLanes, IndexedLane }; 58 59 class UnwindContext { 60 MCAsmParser &Parser; 61 62 typedef SmallVector<SMLoc, 4> Locs; 63 64 Locs FnStartLocs; 65 Locs CantUnwindLocs; 66 Locs PersonalityLocs; 67 Locs PersonalityIndexLocs; 68 Locs HandlerDataLocs; 69 int FPReg; 70 71 public: 72 UnwindContext(MCAsmParser &P) : Parser(P), FPReg(ARM::SP) {} 73 74 bool hasFnStart() const { return !FnStartLocs.empty(); } 75 bool cantUnwind() const { return !CantUnwindLocs.empty(); } 76 bool hasHandlerData() const { return !HandlerDataLocs.empty(); } 77 bool hasPersonality() const { 78 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty()); 79 } 80 81 void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); } 82 void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); } 83 void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); } 84 void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); } 85 void recordPersonalityIndex(SMLoc L) { PersonalityIndexLocs.push_back(L); } 86 87 void saveFPReg(int Reg) { FPReg = Reg; } 88 int getFPReg() const { return FPReg; } 89 90 void emitFnStartLocNotes() const { 91 for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end(); 92 FI != FE; ++FI) 93 Parser.Note(*FI, ".fnstart was specified here"); 94 } 95 void emitCantUnwindLocNotes() const { 96 for (Locs::const_iterator UI = CantUnwindLocs.begin(), 97 UE = CantUnwindLocs.end(); UI != UE; ++UI) 98 Parser.Note(*UI, ".cantunwind was specified here"); 99 } 100 void emitHandlerDataLocNotes() const { 101 for (Locs::const_iterator HI = HandlerDataLocs.begin(), 102 HE = HandlerDataLocs.end(); HI != HE; ++HI) 103 Parser.Note(*HI, ".handlerdata was specified here"); 104 } 105 void emitPersonalityLocNotes() const { 106 for (Locs::const_iterator PI = PersonalityLocs.begin(), 107 PE = PersonalityLocs.end(), 108 PII = PersonalityIndexLocs.begin(), 109 PIE = PersonalityIndexLocs.end(); 110 PI != PE || PII != PIE;) { 111 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer())) 112 Parser.Note(*PI++, ".personality was specified here"); 113 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer())) 114 Parser.Note(*PII++, ".personalityindex was specified here"); 115 else 116 llvm_unreachable(".personality and .personalityindex cannot be " 117 "at the same location"); 118 } 119 } 120 121 void reset() { 122 FnStartLocs = Locs(); 123 CantUnwindLocs = Locs(); 124 PersonalityLocs = Locs(); 125 HandlerDataLocs = Locs(); 126 PersonalityIndexLocs = Locs(); 127 FPReg = ARM::SP; 128 } 129 }; 130 131 class ARMAsmParser : public MCTargetAsmParser { 132 const MCInstrInfo &MII; 133 const MCRegisterInfo *MRI; 134 UnwindContext UC; 135 136 ARMTargetStreamer &getTargetStreamer() { 137 assert(getParser().getStreamer().getTargetStreamer() && 138 "do not have a target streamer"); 139 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 140 return static_cast<ARMTargetStreamer &>(TS); 141 } 142 143 // Map of register aliases registers via the .req directive. 144 StringMap<unsigned> RegisterReqs; 145 146 bool NextSymbolIsThumb; 147 148 struct { 149 ARMCC::CondCodes Cond; // Condition for IT block. 150 unsigned Mask:4; // Condition mask for instructions. 151 // Starting at first 1 (from lsb). 152 // '1' condition as indicated in IT. 153 // '0' inverse of condition (else). 154 // Count of instructions in IT block is 155 // 4 - trailingzeroes(mask) 156 157 bool FirstCond; // Explicit flag for when we're parsing the 158 // First instruction in the IT block. It's 159 // implied in the mask, so needs special 160 // handling. 161 162 unsigned CurPosition; // Current position in parsing of IT 163 // block. In range [0,3]. Initialized 164 // according to count of instructions in block. 165 // ~0U if no active IT block. 166 } ITState; 167 bool inITBlock() { return ITState.CurPosition != ~0U; } 168 bool lastInITBlock() { 169 return ITState.CurPosition == 4 - countTrailingZeros(ITState.Mask); 170 } 171 void forwardITPosition() { 172 if (!inITBlock()) return; 173 // Move to the next instruction in the IT block, if there is one. If not, 174 // mark the block as done. 175 unsigned TZ = countTrailingZeros(ITState.Mask); 176 if (++ITState.CurPosition == 5 - TZ) 177 ITState.CurPosition = ~0U; // Done with the IT block after this. 178 } 179 180 void Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = None) { 181 return getParser().Note(L, Msg, Ranges); 182 } 183 bool Warning(SMLoc L, const Twine &Msg, 184 ArrayRef<SMRange> Ranges = None) { 185 return getParser().Warning(L, Msg, Ranges); 186 } 187 bool Error(SMLoc L, const Twine &Msg, 188 ArrayRef<SMRange> Ranges = None) { 189 return getParser().Error(L, Msg, Ranges); 190 } 191 192 bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands, 193 unsigned ListNo, bool IsARPop = false); 194 bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands, 195 unsigned ListNo); 196 197 int tryParseRegister(); 198 bool tryParseRegisterWithWriteBack(OperandVector &); 199 int tryParseShiftRegister(OperandVector &); 200 bool parseRegisterList(OperandVector &); 201 bool parseMemory(OperandVector &); 202 bool parseOperand(OperandVector &, StringRef Mnemonic); 203 bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 204 bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 205 unsigned &ShiftAmount); 206 bool parseLiteralValues(unsigned Size, SMLoc L); 207 bool parseDirectiveThumb(SMLoc L); 208 bool parseDirectiveARM(SMLoc L); 209 bool parseDirectiveThumbFunc(SMLoc L); 210 bool parseDirectiveCode(SMLoc L); 211 bool parseDirectiveSyntax(SMLoc L); 212 bool parseDirectiveReq(StringRef Name, SMLoc L); 213 bool parseDirectiveUnreq(SMLoc L); 214 bool parseDirectiveArch(SMLoc L); 215 bool parseDirectiveEabiAttr(SMLoc L); 216 bool parseDirectiveCPU(SMLoc L); 217 bool parseDirectiveFPU(SMLoc L); 218 bool parseDirectiveFnStart(SMLoc L); 219 bool parseDirectiveFnEnd(SMLoc L); 220 bool parseDirectiveCantUnwind(SMLoc L); 221 bool parseDirectivePersonality(SMLoc L); 222 bool parseDirectiveHandlerData(SMLoc L); 223 bool parseDirectiveSetFP(SMLoc L); 224 bool parseDirectivePad(SMLoc L); 225 bool parseDirectiveRegSave(SMLoc L, bool IsVector); 226 bool parseDirectiveInst(SMLoc L, char Suffix = '\0'); 227 bool parseDirectiveLtorg(SMLoc L); 228 bool parseDirectiveEven(SMLoc L); 229 bool parseDirectivePersonalityIndex(SMLoc L); 230 bool parseDirectiveUnwindRaw(SMLoc L); 231 bool parseDirectiveTLSDescSeq(SMLoc L); 232 bool parseDirectiveMovSP(SMLoc L); 233 bool parseDirectiveObjectArch(SMLoc L); 234 bool parseDirectiveArchExtension(SMLoc L); 235 bool parseDirectiveAlign(SMLoc L); 236 bool parseDirectiveThumbSet(SMLoc L); 237 238 StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 239 bool &CarrySetting, unsigned &ProcessorIMod, 240 StringRef &ITMask); 241 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst, 242 bool &CanAcceptCarrySet, 243 bool &CanAcceptPredicationCode); 244 245 void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting, 246 OperandVector &Operands); 247 bool isThumb() const { 248 // FIXME: Can tablegen auto-generate this? 249 return getSTI().getFeatureBits()[ARM::ModeThumb]; 250 } 251 bool isThumbOne() const { 252 return isThumb() && !getSTI().getFeatureBits()[ARM::FeatureThumb2]; 253 } 254 bool isThumbTwo() const { 255 return isThumb() && getSTI().getFeatureBits()[ARM::FeatureThumb2]; 256 } 257 bool hasThumb() const { 258 return getSTI().getFeatureBits()[ARM::HasV4TOps]; 259 } 260 bool hasThumb2() const { 261 return getSTI().getFeatureBits()[ARM::FeatureThumb2]; 262 } 263 bool hasV6Ops() const { 264 return getSTI().getFeatureBits()[ARM::HasV6Ops]; 265 } 266 bool hasV6T2Ops() const { 267 return getSTI().getFeatureBits()[ARM::HasV6T2Ops]; 268 } 269 bool hasV6MOps() const { 270 return getSTI().getFeatureBits()[ARM::HasV6MOps]; 271 } 272 bool hasV7Ops() const { 273 return getSTI().getFeatureBits()[ARM::HasV7Ops]; 274 } 275 bool hasV8Ops() const { 276 return getSTI().getFeatureBits()[ARM::HasV8Ops]; 277 } 278 bool hasV8MBaseline() const { 279 return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps]; 280 } 281 bool hasV8MMainline() const { 282 return getSTI().getFeatureBits()[ARM::HasV8MMainlineOps]; 283 } 284 bool has8MSecExt() const { 285 return getSTI().getFeatureBits()[ARM::Feature8MSecExt]; 286 } 287 bool hasARM() const { 288 return !getSTI().getFeatureBits()[ARM::FeatureNoARM]; 289 } 290 bool hasDSP() const { 291 return getSTI().getFeatureBits()[ARM::FeatureDSP]; 292 } 293 bool hasD16() const { 294 return getSTI().getFeatureBits()[ARM::FeatureD16]; 295 } 296 bool hasV8_1aOps() const { 297 return getSTI().getFeatureBits()[ARM::HasV8_1aOps]; 298 } 299 bool hasRAS() const { 300 return getSTI().getFeatureBits()[ARM::FeatureRAS]; 301 } 302 303 void SwitchMode() { 304 MCSubtargetInfo &STI = copySTI(); 305 uint64_t FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 306 setAvailableFeatures(FB); 307 } 308 void FixModeAfterArchChange(bool WasThumb, SMLoc Loc); 309 bool isMClass() const { 310 return getSTI().getFeatureBits()[ARM::FeatureMClass]; 311 } 312 313 /// @name Auto-generated Match Functions 314 /// { 315 316 #define GET_ASSEMBLER_HEADER 317 #include "ARMGenAsmMatcher.inc" 318 319 /// } 320 321 OperandMatchResultTy parseITCondCode(OperandVector &); 322 OperandMatchResultTy parseCoprocNumOperand(OperandVector &); 323 OperandMatchResultTy parseCoprocRegOperand(OperandVector &); 324 OperandMatchResultTy parseCoprocOptionOperand(OperandVector &); 325 OperandMatchResultTy parseMemBarrierOptOperand(OperandVector &); 326 OperandMatchResultTy parseInstSyncBarrierOptOperand(OperandVector &); 327 OperandMatchResultTy parseProcIFlagsOperand(OperandVector &); 328 OperandMatchResultTy parseMSRMaskOperand(OperandVector &); 329 OperandMatchResultTy parseBankedRegOperand(OperandVector &); 330 OperandMatchResultTy parsePKHImm(OperandVector &O, StringRef Op, int Low, 331 int High); 332 OperandMatchResultTy parsePKHLSLImm(OperandVector &O) { 333 return parsePKHImm(O, "lsl", 0, 31); 334 } 335 OperandMatchResultTy parsePKHASRImm(OperandVector &O) { 336 return parsePKHImm(O, "asr", 1, 32); 337 } 338 OperandMatchResultTy parseSetEndImm(OperandVector &); 339 OperandMatchResultTy parseShifterImm(OperandVector &); 340 OperandMatchResultTy parseRotImm(OperandVector &); 341 OperandMatchResultTy parseModImm(OperandVector &); 342 OperandMatchResultTy parseBitfield(OperandVector &); 343 OperandMatchResultTy parsePostIdxReg(OperandVector &); 344 OperandMatchResultTy parseAM3Offset(OperandVector &); 345 OperandMatchResultTy parseFPImm(OperandVector &); 346 OperandMatchResultTy parseVectorList(OperandVector &); 347 OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, 348 SMLoc &EndLoc); 349 350 // Asm Match Converter Methods 351 void cvtThumbMultiply(MCInst &Inst, const OperandVector &); 352 void cvtThumbBranches(MCInst &Inst, const OperandVector &); 353 354 bool validateInstruction(MCInst &Inst, const OperandVector &Ops); 355 bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out); 356 bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands); 357 bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands); 358 359 public: 360 enum ARMMatchResultTy { 361 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 362 Match_RequiresNotITBlock, 363 Match_RequiresV6, 364 Match_RequiresThumb2, 365 Match_RequiresV8, 366 #define GET_OPERAND_DIAGNOSTIC_TYPES 367 #include "ARMGenAsmMatcher.inc" 368 369 }; 370 371 ARMAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 372 const MCInstrInfo &MII, const MCTargetOptions &Options) 373 : MCTargetAsmParser(Options, STI), MII(MII), UC(Parser) { 374 MCAsmParserExtension::Initialize(Parser); 375 376 // Cache the MCRegisterInfo. 377 MRI = getContext().getRegisterInfo(); 378 379 // Initialize the set of available features. 380 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 381 382 // Not in an ITBlock to start with. 383 ITState.CurPosition = ~0U; 384 385 NextSymbolIsThumb = false; 386 } 387 388 // Implementation of the MCTargetAsmParser interface: 389 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 390 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 391 SMLoc NameLoc, OperandVector &Operands) override; 392 bool ParseDirective(AsmToken DirectiveID) override; 393 394 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 395 unsigned Kind) override; 396 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 397 398 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 399 OperandVector &Operands, MCStreamer &Out, 400 uint64_t &ErrorInfo, 401 bool MatchingInlineAsm) override; 402 void onLabelParsed(MCSymbol *Symbol) override; 403 }; 404 } // end anonymous namespace 405 406 namespace { 407 408 /// ARMOperand - Instances of this class represent a parsed ARM machine 409 /// operand. 410 class ARMOperand : public MCParsedAsmOperand { 411 enum KindTy { 412 k_CondCode, 413 k_CCOut, 414 k_ITCondMask, 415 k_CoprocNum, 416 k_CoprocReg, 417 k_CoprocOption, 418 k_Immediate, 419 k_MemBarrierOpt, 420 k_InstSyncBarrierOpt, 421 k_Memory, 422 k_PostIndexRegister, 423 k_MSRMask, 424 k_BankedReg, 425 k_ProcIFlags, 426 k_VectorIndex, 427 k_Register, 428 k_RegisterList, 429 k_DPRRegisterList, 430 k_SPRRegisterList, 431 k_VectorList, 432 k_VectorListAllLanes, 433 k_VectorListIndexed, 434 k_ShiftedRegister, 435 k_ShiftedImmediate, 436 k_ShifterImmediate, 437 k_RotateImmediate, 438 k_ModifiedImmediate, 439 k_ConstantPoolImmediate, 440 k_BitfieldDescriptor, 441 k_Token, 442 } Kind; 443 444 SMLoc StartLoc, EndLoc, AlignmentLoc; 445 SmallVector<unsigned, 8> Registers; 446 447 struct CCOp { 448 ARMCC::CondCodes Val; 449 }; 450 451 struct CopOp { 452 unsigned Val; 453 }; 454 455 struct CoprocOptionOp { 456 unsigned Val; 457 }; 458 459 struct ITMaskOp { 460 unsigned Mask:4; 461 }; 462 463 struct MBOptOp { 464 ARM_MB::MemBOpt Val; 465 }; 466 467 struct ISBOptOp { 468 ARM_ISB::InstSyncBOpt Val; 469 }; 470 471 struct IFlagsOp { 472 ARM_PROC::IFlags Val; 473 }; 474 475 struct MMaskOp { 476 unsigned Val; 477 }; 478 479 struct BankedRegOp { 480 unsigned Val; 481 }; 482 483 struct TokOp { 484 const char *Data; 485 unsigned Length; 486 }; 487 488 struct RegOp { 489 unsigned RegNum; 490 }; 491 492 // A vector register list is a sequential list of 1 to 4 registers. 493 struct VectorListOp { 494 unsigned RegNum; 495 unsigned Count; 496 unsigned LaneIndex; 497 bool isDoubleSpaced; 498 }; 499 500 struct VectorIndexOp { 501 unsigned Val; 502 }; 503 504 struct ImmOp { 505 const MCExpr *Val; 506 }; 507 508 /// Combined record for all forms of ARM address expressions. 509 struct MemoryOp { 510 unsigned BaseRegNum; 511 // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 512 // was specified. 513 const MCConstantExpr *OffsetImm; // Offset immediate value 514 unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 515 ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 516 unsigned ShiftImm; // shift for OffsetReg. 517 unsigned Alignment; // 0 = no alignment specified 518 // n = alignment in bytes (2, 4, 8, 16, or 32) 519 unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 520 }; 521 522 struct PostIdxRegOp { 523 unsigned RegNum; 524 bool isAdd; 525 ARM_AM::ShiftOpc ShiftTy; 526 unsigned ShiftImm; 527 }; 528 529 struct ShifterImmOp { 530 bool isASR; 531 unsigned Imm; 532 }; 533 534 struct RegShiftedRegOp { 535 ARM_AM::ShiftOpc ShiftTy; 536 unsigned SrcReg; 537 unsigned ShiftReg; 538 unsigned ShiftImm; 539 }; 540 541 struct RegShiftedImmOp { 542 ARM_AM::ShiftOpc ShiftTy; 543 unsigned SrcReg; 544 unsigned ShiftImm; 545 }; 546 547 struct RotImmOp { 548 unsigned Imm; 549 }; 550 551 struct ModImmOp { 552 unsigned Bits; 553 unsigned Rot; 554 }; 555 556 struct BitfieldOp { 557 unsigned LSB; 558 unsigned Width; 559 }; 560 561 union { 562 struct CCOp CC; 563 struct CopOp Cop; 564 struct CoprocOptionOp CoprocOption; 565 struct MBOptOp MBOpt; 566 struct ISBOptOp ISBOpt; 567 struct ITMaskOp ITMask; 568 struct IFlagsOp IFlags; 569 struct MMaskOp MMask; 570 struct BankedRegOp BankedReg; 571 struct TokOp Tok; 572 struct RegOp Reg; 573 struct VectorListOp VectorList; 574 struct VectorIndexOp VectorIndex; 575 struct ImmOp Imm; 576 struct MemoryOp Memory; 577 struct PostIdxRegOp PostIdxReg; 578 struct ShifterImmOp ShifterImm; 579 struct RegShiftedRegOp RegShiftedReg; 580 struct RegShiftedImmOp RegShiftedImm; 581 struct RotImmOp RotImm; 582 struct ModImmOp ModImm; 583 struct BitfieldOp Bitfield; 584 }; 585 586 public: 587 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 588 589 /// getStartLoc - Get the location of the first token of this operand. 590 SMLoc getStartLoc() const override { return StartLoc; } 591 /// getEndLoc - Get the location of the last token of this operand. 592 SMLoc getEndLoc() const override { return EndLoc; } 593 /// getLocRange - Get the range between the first and last token of this 594 /// operand. 595 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 596 597 /// getAlignmentLoc - Get the location of the Alignment token of this operand. 598 SMLoc getAlignmentLoc() const { 599 assert(Kind == k_Memory && "Invalid access!"); 600 return AlignmentLoc; 601 } 602 603 ARMCC::CondCodes getCondCode() const { 604 assert(Kind == k_CondCode && "Invalid access!"); 605 return CC.Val; 606 } 607 608 unsigned getCoproc() const { 609 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 610 return Cop.Val; 611 } 612 613 StringRef getToken() const { 614 assert(Kind == k_Token && "Invalid access!"); 615 return StringRef(Tok.Data, Tok.Length); 616 } 617 618 unsigned getReg() const override { 619 assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 620 return Reg.RegNum; 621 } 622 623 const SmallVectorImpl<unsigned> &getRegList() const { 624 assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 625 Kind == k_SPRRegisterList) && "Invalid access!"); 626 return Registers; 627 } 628 629 const MCExpr *getImm() const { 630 assert(isImm() && "Invalid access!"); 631 return Imm.Val; 632 } 633 634 const MCExpr *getConstantPoolImm() const { 635 assert(isConstantPoolImm() && "Invalid access!"); 636 return Imm.Val; 637 } 638 639 unsigned getVectorIndex() const { 640 assert(Kind == k_VectorIndex && "Invalid access!"); 641 return VectorIndex.Val; 642 } 643 644 ARM_MB::MemBOpt getMemBarrierOpt() const { 645 assert(Kind == k_MemBarrierOpt && "Invalid access!"); 646 return MBOpt.Val; 647 } 648 649 ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const { 650 assert(Kind == k_InstSyncBarrierOpt && "Invalid access!"); 651 return ISBOpt.Val; 652 } 653 654 ARM_PROC::IFlags getProcIFlags() const { 655 assert(Kind == k_ProcIFlags && "Invalid access!"); 656 return IFlags.Val; 657 } 658 659 unsigned getMSRMask() const { 660 assert(Kind == k_MSRMask && "Invalid access!"); 661 return MMask.Val; 662 } 663 664 unsigned getBankedReg() const { 665 assert(Kind == k_BankedReg && "Invalid access!"); 666 return BankedReg.Val; 667 } 668 669 bool isCoprocNum() const { return Kind == k_CoprocNum; } 670 bool isCoprocReg() const { return Kind == k_CoprocReg; } 671 bool isCoprocOption() const { return Kind == k_CoprocOption; } 672 bool isCondCode() const { return Kind == k_CondCode; } 673 bool isCCOut() const { return Kind == k_CCOut; } 674 bool isITMask() const { return Kind == k_ITCondMask; } 675 bool isITCondCode() const { return Kind == k_CondCode; } 676 bool isImm() const override { 677 return Kind == k_Immediate; 678 } 679 680 bool isARMBranchTarget() const { 681 if (!isImm()) return false; 682 683 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) 684 return CE->getValue() % 4 == 0; 685 return true; 686 } 687 688 689 bool isThumbBranchTarget() const { 690 if (!isImm()) return false; 691 692 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) 693 return CE->getValue() % 2 == 0; 694 return true; 695 } 696 697 // checks whether this operand is an unsigned offset which fits is a field 698 // of specified width and scaled by a specific number of bits 699 template<unsigned width, unsigned scale> 700 bool isUnsignedOffset() const { 701 if (!isImm()) return false; 702 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 703 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 704 int64_t Val = CE->getValue(); 705 int64_t Align = 1LL << scale; 706 int64_t Max = Align * ((1LL << width) - 1); 707 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max); 708 } 709 return false; 710 } 711 // checks whether this operand is an signed offset which fits is a field 712 // of specified width and scaled by a specific number of bits 713 template<unsigned width, unsigned scale> 714 bool isSignedOffset() const { 715 if (!isImm()) return false; 716 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 717 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 718 int64_t Val = CE->getValue(); 719 int64_t Align = 1LL << scale; 720 int64_t Max = Align * ((1LL << (width-1)) - 1); 721 int64_t Min = -Align * (1LL << (width-1)); 722 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max); 723 } 724 return false; 725 } 726 727 // checks whether this operand is a memory operand computed as an offset 728 // applied to PC. the offset may have 8 bits of magnitude and is represented 729 // with two bits of shift. textually it may be either [pc, #imm], #imm or 730 // relocable expression... 731 bool isThumbMemPC() const { 732 int64_t Val = 0; 733 if (isImm()) { 734 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 735 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val); 736 if (!CE) return false; 737 Val = CE->getValue(); 738 } 739 else if (isMem()) { 740 if(!Memory.OffsetImm || Memory.OffsetRegNum) return false; 741 if(Memory.BaseRegNum != ARM::PC) return false; 742 Val = Memory.OffsetImm->getValue(); 743 } 744 else return false; 745 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020); 746 } 747 bool isFPImm() const { 748 if (!isImm()) return false; 749 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 750 if (!CE) return false; 751 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue())); 752 return Val != -1; 753 } 754 bool isFBits16() const { 755 if (!isImm()) return false; 756 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 757 if (!CE) return false; 758 int64_t Value = CE->getValue(); 759 return Value >= 0 && Value <= 16; 760 } 761 bool isFBits32() const { 762 if (!isImm()) return false; 763 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 764 if (!CE) return false; 765 int64_t Value = CE->getValue(); 766 return Value >= 1 && Value <= 32; 767 } 768 bool isImm8s4() const { 769 if (!isImm()) return false; 770 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 771 if (!CE) return false; 772 int64_t Value = CE->getValue(); 773 return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 774 } 775 bool isImm0_1020s4() const { 776 if (!isImm()) return false; 777 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 778 if (!CE) return false; 779 int64_t Value = CE->getValue(); 780 return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 781 } 782 bool isImm0_508s4() const { 783 if (!isImm()) return false; 784 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 785 if (!CE) return false; 786 int64_t Value = CE->getValue(); 787 return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 788 } 789 bool isImm0_508s4Neg() const { 790 if (!isImm()) return false; 791 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 792 if (!CE) return false; 793 int64_t Value = -CE->getValue(); 794 // explicitly exclude zero. we want that to use the normal 0_508 version. 795 return ((Value & 3) == 0) && Value > 0 && Value <= 508; 796 } 797 bool isImm0_239() const { 798 if (!isImm()) return false; 799 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 800 if (!CE) return false; 801 int64_t Value = CE->getValue(); 802 return Value >= 0 && Value < 240; 803 } 804 bool isImm0_255() const { 805 if (!isImm()) return false; 806 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 807 if (!CE) return false; 808 int64_t Value = CE->getValue(); 809 return Value >= 0 && Value < 256; 810 } 811 bool isImm0_4095() const { 812 if (!isImm()) return false; 813 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 814 if (!CE) return false; 815 int64_t Value = CE->getValue(); 816 return Value >= 0 && Value < 4096; 817 } 818 bool isImm0_4095Neg() const { 819 if (!isImm()) return false; 820 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 821 if (!CE) return false; 822 int64_t Value = -CE->getValue(); 823 return Value > 0 && Value < 4096; 824 } 825 bool isImm0_1() const { 826 if (!isImm()) return false; 827 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 828 if (!CE) return false; 829 int64_t Value = CE->getValue(); 830 return Value >= 0 && Value < 2; 831 } 832 bool isImm0_3() const { 833 if (!isImm()) return false; 834 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 835 if (!CE) return false; 836 int64_t Value = CE->getValue(); 837 return Value >= 0 && Value < 4; 838 } 839 bool isImm0_7() const { 840 if (!isImm()) return false; 841 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 842 if (!CE) return false; 843 int64_t Value = CE->getValue(); 844 return Value >= 0 && Value < 8; 845 } 846 bool isImm0_15() const { 847 if (!isImm()) return false; 848 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 849 if (!CE) return false; 850 int64_t Value = CE->getValue(); 851 return Value >= 0 && Value < 16; 852 } 853 bool isImm0_31() const { 854 if (!isImm()) return false; 855 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 856 if (!CE) return false; 857 int64_t Value = CE->getValue(); 858 return Value >= 0 && Value < 32; 859 } 860 bool isImm0_63() const { 861 if (!isImm()) return false; 862 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 863 if (!CE) return false; 864 int64_t Value = CE->getValue(); 865 return Value >= 0 && Value < 64; 866 } 867 bool isImm8() const { 868 if (!isImm()) return false; 869 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 870 if (!CE) return false; 871 int64_t Value = CE->getValue(); 872 return Value == 8; 873 } 874 bool isImm16() const { 875 if (!isImm()) return false; 876 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 877 if (!CE) return false; 878 int64_t Value = CE->getValue(); 879 return Value == 16; 880 } 881 bool isImm32() const { 882 if (!isImm()) return false; 883 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 884 if (!CE) return false; 885 int64_t Value = CE->getValue(); 886 return Value == 32; 887 } 888 bool isShrImm8() const { 889 if (!isImm()) return false; 890 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 891 if (!CE) return false; 892 int64_t Value = CE->getValue(); 893 return Value > 0 && Value <= 8; 894 } 895 bool isShrImm16() const { 896 if (!isImm()) return false; 897 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 898 if (!CE) return false; 899 int64_t Value = CE->getValue(); 900 return Value > 0 && Value <= 16; 901 } 902 bool isShrImm32() const { 903 if (!isImm()) return false; 904 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 905 if (!CE) return false; 906 int64_t Value = CE->getValue(); 907 return Value > 0 && Value <= 32; 908 } 909 bool isShrImm64() const { 910 if (!isImm()) return false; 911 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 912 if (!CE) return false; 913 int64_t Value = CE->getValue(); 914 return Value > 0 && Value <= 64; 915 } 916 bool isImm1_7() const { 917 if (!isImm()) return false; 918 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 919 if (!CE) return false; 920 int64_t Value = CE->getValue(); 921 return Value > 0 && Value < 8; 922 } 923 bool isImm1_15() const { 924 if (!isImm()) return false; 925 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 926 if (!CE) return false; 927 int64_t Value = CE->getValue(); 928 return Value > 0 && Value < 16; 929 } 930 bool isImm1_31() const { 931 if (!isImm()) return false; 932 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 933 if (!CE) return false; 934 int64_t Value = CE->getValue(); 935 return Value > 0 && Value < 32; 936 } 937 bool isImm1_16() const { 938 if (!isImm()) return false; 939 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 940 if (!CE) return false; 941 int64_t Value = CE->getValue(); 942 return Value > 0 && Value < 17; 943 } 944 bool isImm1_32() const { 945 if (!isImm()) return false; 946 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 947 if (!CE) return false; 948 int64_t Value = CE->getValue(); 949 return Value > 0 && Value < 33; 950 } 951 bool isImm0_32() const { 952 if (!isImm()) return false; 953 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 954 if (!CE) return false; 955 int64_t Value = CE->getValue(); 956 return Value >= 0 && Value < 33; 957 } 958 bool isImm0_65535() const { 959 if (!isImm()) return false; 960 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 961 if (!CE) return false; 962 int64_t Value = CE->getValue(); 963 return Value >= 0 && Value < 65536; 964 } 965 bool isImm256_65535Expr() const { 966 if (!isImm()) return false; 967 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 968 // If it's not a constant expression, it'll generate a fixup and be 969 // handled later. 970 if (!CE) return true; 971 int64_t Value = CE->getValue(); 972 return Value >= 256 && Value < 65536; 973 } 974 bool isImm0_65535Expr() const { 975 if (!isImm()) return false; 976 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 977 // If it's not a constant expression, it'll generate a fixup and be 978 // handled later. 979 if (!CE) return true; 980 int64_t Value = CE->getValue(); 981 return Value >= 0 && Value < 65536; 982 } 983 bool isImm24bit() const { 984 if (!isImm()) return false; 985 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 986 if (!CE) return false; 987 int64_t Value = CE->getValue(); 988 return Value >= 0 && Value <= 0xffffff; 989 } 990 bool isImmThumbSR() const { 991 if (!isImm()) return false; 992 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 993 if (!CE) return false; 994 int64_t Value = CE->getValue(); 995 return Value > 0 && Value < 33; 996 } 997 bool isPKHLSLImm() const { 998 if (!isImm()) return false; 999 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1000 if (!CE) return false; 1001 int64_t Value = CE->getValue(); 1002 return Value >= 0 && Value < 32; 1003 } 1004 bool isPKHASRImm() const { 1005 if (!isImm()) return false; 1006 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1007 if (!CE) return false; 1008 int64_t Value = CE->getValue(); 1009 return Value > 0 && Value <= 32; 1010 } 1011 bool isAdrLabel() const { 1012 // If we have an immediate that's not a constant, treat it as a label 1013 // reference needing a fixup. 1014 if (isImm() && !isa<MCConstantExpr>(getImm())) 1015 return true; 1016 1017 // If it is a constant, it must fit into a modified immediate encoding. 1018 if (!isImm()) return false; 1019 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1020 if (!CE) return false; 1021 int64_t Value = CE->getValue(); 1022 return (ARM_AM::getSOImmVal(Value) != -1 || 1023 ARM_AM::getSOImmVal(-Value) != -1); 1024 } 1025 bool isT2SOImm() const { 1026 if (!isImm()) return false; 1027 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1028 if (!CE) return false; 1029 int64_t Value = CE->getValue(); 1030 return ARM_AM::getT2SOImmVal(Value) != -1; 1031 } 1032 bool isT2SOImmNot() const { 1033 if (!isImm()) return false; 1034 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1035 if (!CE) return false; 1036 int64_t Value = CE->getValue(); 1037 return ARM_AM::getT2SOImmVal(Value) == -1 && 1038 ARM_AM::getT2SOImmVal(~Value) != -1; 1039 } 1040 bool isT2SOImmNeg() const { 1041 if (!isImm()) return false; 1042 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1043 if (!CE) return false; 1044 int64_t Value = CE->getValue(); 1045 // Only use this when not representable as a plain so_imm. 1046 return ARM_AM::getT2SOImmVal(Value) == -1 && 1047 ARM_AM::getT2SOImmVal(-Value) != -1; 1048 } 1049 bool isSetEndImm() const { 1050 if (!isImm()) return false; 1051 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1052 if (!CE) return false; 1053 int64_t Value = CE->getValue(); 1054 return Value == 1 || Value == 0; 1055 } 1056 bool isReg() const override { return Kind == k_Register; } 1057 bool isRegList() const { return Kind == k_RegisterList; } 1058 bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 1059 bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 1060 bool isToken() const override { return Kind == k_Token; } 1061 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 1062 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; } 1063 bool isMem() const override { return Kind == k_Memory; } 1064 bool isShifterImm() const { return Kind == k_ShifterImmediate; } 1065 bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 1066 bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 1067 bool isRotImm() const { return Kind == k_RotateImmediate; } 1068 bool isModImm() const { return Kind == k_ModifiedImmediate; } 1069 bool isModImmNot() const { 1070 if (!isImm()) return false; 1071 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1072 if (!CE) return false; 1073 int64_t Value = CE->getValue(); 1074 return ARM_AM::getSOImmVal(~Value) != -1; 1075 } 1076 bool isModImmNeg() const { 1077 if (!isImm()) return false; 1078 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1079 if (!CE) return false; 1080 int64_t Value = CE->getValue(); 1081 return ARM_AM::getSOImmVal(Value) == -1 && 1082 ARM_AM::getSOImmVal(-Value) != -1; 1083 } 1084 bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; } 1085 bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 1086 bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 1087 bool isPostIdxReg() const { 1088 return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift; 1089 } 1090 bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const { 1091 if (!isMem()) 1092 return false; 1093 // No offset of any kind. 1094 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr && 1095 (alignOK || Memory.Alignment == Alignment); 1096 } 1097 bool isMemPCRelImm12() const { 1098 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1099 return false; 1100 // Base register must be PC. 1101 if (Memory.BaseRegNum != ARM::PC) 1102 return false; 1103 // Immediate offset in range [-4095, 4095]. 1104 if (!Memory.OffsetImm) return true; 1105 int64_t Val = Memory.OffsetImm->getValue(); 1106 return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 1107 } 1108 bool isAlignedMemory() const { 1109 return isMemNoOffset(true); 1110 } 1111 bool isAlignedMemoryNone() const { 1112 return isMemNoOffset(false, 0); 1113 } 1114 bool isDupAlignedMemoryNone() const { 1115 return isMemNoOffset(false, 0); 1116 } 1117 bool isAlignedMemory16() const { 1118 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2. 1119 return true; 1120 return isMemNoOffset(false, 0); 1121 } 1122 bool isDupAlignedMemory16() const { 1123 if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2. 1124 return true; 1125 return isMemNoOffset(false, 0); 1126 } 1127 bool isAlignedMemory32() const { 1128 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4. 1129 return true; 1130 return isMemNoOffset(false, 0); 1131 } 1132 bool isDupAlignedMemory32() const { 1133 if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4. 1134 return true; 1135 return isMemNoOffset(false, 0); 1136 } 1137 bool isAlignedMemory64() const { 1138 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1139 return true; 1140 return isMemNoOffset(false, 0); 1141 } 1142 bool isDupAlignedMemory64() const { 1143 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1144 return true; 1145 return isMemNoOffset(false, 0); 1146 } 1147 bool isAlignedMemory64or128() const { 1148 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1149 return true; 1150 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16. 1151 return true; 1152 return isMemNoOffset(false, 0); 1153 } 1154 bool isDupAlignedMemory64or128() const { 1155 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1156 return true; 1157 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16. 1158 return true; 1159 return isMemNoOffset(false, 0); 1160 } 1161 bool isAlignedMemory64or128or256() const { 1162 if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8. 1163 return true; 1164 if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16. 1165 return true; 1166 if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32. 1167 return true; 1168 return isMemNoOffset(false, 0); 1169 } 1170 bool isAddrMode2() const { 1171 if (!isMem() || Memory.Alignment != 0) return false; 1172 // Check for register offset. 1173 if (Memory.OffsetRegNum) return true; 1174 // Immediate offset in range [-4095, 4095]. 1175 if (!Memory.OffsetImm) return true; 1176 int64_t Val = Memory.OffsetImm->getValue(); 1177 return Val > -4096 && Val < 4096; 1178 } 1179 bool isAM2OffsetImm() const { 1180 if (!isImm()) return false; 1181 // Immediate offset in range [-4095, 4095]. 1182 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1183 if (!CE) return false; 1184 int64_t Val = CE->getValue(); 1185 return (Val == INT32_MIN) || (Val > -4096 && Val < 4096); 1186 } 1187 bool isAddrMode3() const { 1188 // If we have an immediate that's not a constant, treat it as a label 1189 // reference needing a fixup. If it is a constant, it's something else 1190 // and we reject it. 1191 if (isImm() && !isa<MCConstantExpr>(getImm())) 1192 return true; 1193 if (!isMem() || Memory.Alignment != 0) return false; 1194 // No shifts are legal for AM3. 1195 if (Memory.ShiftType != ARM_AM::no_shift) return false; 1196 // Check for register offset. 1197 if (Memory.OffsetRegNum) return true; 1198 // Immediate offset in range [-255, 255]. 1199 if (!Memory.OffsetImm) return true; 1200 int64_t Val = Memory.OffsetImm->getValue(); 1201 // The #-0 offset is encoded as INT32_MIN, and we have to check 1202 // for this too. 1203 return (Val > -256 && Val < 256) || Val == INT32_MIN; 1204 } 1205 bool isAM3Offset() const { 1206 if (Kind != k_Immediate && Kind != k_PostIndexRegister) 1207 return false; 1208 if (Kind == k_PostIndexRegister) 1209 return PostIdxReg.ShiftTy == ARM_AM::no_shift; 1210 // Immediate offset in range [-255, 255]. 1211 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1212 if (!CE) return false; 1213 int64_t Val = CE->getValue(); 1214 // Special case, #-0 is INT32_MIN. 1215 return (Val > -256 && Val < 256) || Val == INT32_MIN; 1216 } 1217 bool isAddrMode5() const { 1218 // If we have an immediate that's not a constant, treat it as a label 1219 // reference needing a fixup. If it is a constant, it's something else 1220 // and we reject it. 1221 if (isImm() && !isa<MCConstantExpr>(getImm())) 1222 return true; 1223 if (!isMem() || Memory.Alignment != 0) return false; 1224 // Check for register offset. 1225 if (Memory.OffsetRegNum) return false; 1226 // Immediate offset in range [-1020, 1020] and a multiple of 4. 1227 if (!Memory.OffsetImm) return true; 1228 int64_t Val = Memory.OffsetImm->getValue(); 1229 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 1230 Val == INT32_MIN; 1231 } 1232 bool isAddrMode5FP16() const { 1233 // If we have an immediate that's not a constant, treat it as a label 1234 // reference needing a fixup. If it is a constant, it's something else 1235 // and we reject it. 1236 if (isImm() && !isa<MCConstantExpr>(getImm())) 1237 return true; 1238 if (!isMem() || Memory.Alignment != 0) return false; 1239 // Check for register offset. 1240 if (Memory.OffsetRegNum) return false; 1241 // Immediate offset in range [-510, 510] and a multiple of 2. 1242 if (!Memory.OffsetImm) return true; 1243 int64_t Val = Memory.OffsetImm->getValue(); 1244 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) || Val == INT32_MIN; 1245 } 1246 bool isMemTBB() const { 1247 if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative || 1248 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 1249 return false; 1250 return true; 1251 } 1252 bool isMemTBH() const { 1253 if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative || 1254 Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 1255 Memory.Alignment != 0 ) 1256 return false; 1257 return true; 1258 } 1259 bool isMemRegOffset() const { 1260 if (!isMem() || !Memory.OffsetRegNum || Memory.Alignment != 0) 1261 return false; 1262 return true; 1263 } 1264 bool isT2MemRegOffset() const { 1265 if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative || 1266 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC) 1267 return false; 1268 // Only lsl #{0, 1, 2, 3} allowed. 1269 if (Memory.ShiftType == ARM_AM::no_shift) 1270 return true; 1271 if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 1272 return false; 1273 return true; 1274 } 1275 bool isMemThumbRR() const { 1276 // Thumb reg+reg addressing is simple. Just two registers, a base and 1277 // an offset. No shifts, negations or any other complicating factors. 1278 if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative || 1279 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 1280 return false; 1281 return isARMLowRegister(Memory.BaseRegNum) && 1282 (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 1283 } 1284 bool isMemThumbRIs4() const { 1285 if (!isMem() || Memory.OffsetRegNum != 0 || 1286 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1287 return false; 1288 // Immediate offset, multiple of 4 in range [0, 124]. 1289 if (!Memory.OffsetImm) return true; 1290 int64_t Val = Memory.OffsetImm->getValue(); 1291 return Val >= 0 && Val <= 124 && (Val % 4) == 0; 1292 } 1293 bool isMemThumbRIs2() const { 1294 if (!isMem() || Memory.OffsetRegNum != 0 || 1295 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1296 return false; 1297 // Immediate offset, multiple of 4 in range [0, 62]. 1298 if (!Memory.OffsetImm) return true; 1299 int64_t Val = Memory.OffsetImm->getValue(); 1300 return Val >= 0 && Val <= 62 && (Val % 2) == 0; 1301 } 1302 bool isMemThumbRIs1() const { 1303 if (!isMem() || Memory.OffsetRegNum != 0 || 1304 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1305 return false; 1306 // Immediate offset in range [0, 31]. 1307 if (!Memory.OffsetImm) return true; 1308 int64_t Val = Memory.OffsetImm->getValue(); 1309 return Val >= 0 && Val <= 31; 1310 } 1311 bool isMemThumbSPI() const { 1312 if (!isMem() || Memory.OffsetRegNum != 0 || 1313 Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 1314 return false; 1315 // Immediate offset, multiple of 4 in range [0, 1020]. 1316 if (!Memory.OffsetImm) return true; 1317 int64_t Val = Memory.OffsetImm->getValue(); 1318 return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 1319 } 1320 bool isMemImm8s4Offset() const { 1321 // If we have an immediate that's not a constant, treat it as a label 1322 // reference needing a fixup. If it is a constant, it's something else 1323 // and we reject it. 1324 if (isImm() && !isa<MCConstantExpr>(getImm())) 1325 return true; 1326 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1327 return false; 1328 // Immediate offset a multiple of 4 in range [-1020, 1020]. 1329 if (!Memory.OffsetImm) return true; 1330 int64_t Val = Memory.OffsetImm->getValue(); 1331 // Special case, #-0 is INT32_MIN. 1332 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) || Val == INT32_MIN; 1333 } 1334 bool isMemImm0_1020s4Offset() const { 1335 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1336 return false; 1337 // Immediate offset a multiple of 4 in range [0, 1020]. 1338 if (!Memory.OffsetImm) return true; 1339 int64_t Val = Memory.OffsetImm->getValue(); 1340 return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 1341 } 1342 bool isMemImm8Offset() const { 1343 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1344 return false; 1345 // Base reg of PC isn't allowed for these encodings. 1346 if (Memory.BaseRegNum == ARM::PC) return false; 1347 // Immediate offset in range [-255, 255]. 1348 if (!Memory.OffsetImm) return true; 1349 int64_t Val = Memory.OffsetImm->getValue(); 1350 return (Val == INT32_MIN) || (Val > -256 && Val < 256); 1351 } 1352 bool isMemPosImm8Offset() const { 1353 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1354 return false; 1355 // Immediate offset in range [0, 255]. 1356 if (!Memory.OffsetImm) return true; 1357 int64_t Val = Memory.OffsetImm->getValue(); 1358 return Val >= 0 && Val < 256; 1359 } 1360 bool isMemNegImm8Offset() const { 1361 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1362 return false; 1363 // Base reg of PC isn't allowed for these encodings. 1364 if (Memory.BaseRegNum == ARM::PC) return false; 1365 // Immediate offset in range [-255, -1]. 1366 if (!Memory.OffsetImm) return false; 1367 int64_t Val = Memory.OffsetImm->getValue(); 1368 return (Val == INT32_MIN) || (Val > -256 && Val < 0); 1369 } 1370 bool isMemUImm12Offset() const { 1371 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1372 return false; 1373 // Immediate offset in range [0, 4095]. 1374 if (!Memory.OffsetImm) return true; 1375 int64_t Val = Memory.OffsetImm->getValue(); 1376 return (Val >= 0 && Val < 4096); 1377 } 1378 bool isMemImm12Offset() const { 1379 // If we have an immediate that's not a constant, treat it as a label 1380 // reference needing a fixup. If it is a constant, it's something else 1381 // and we reject it. 1382 1383 if (isImm() && !isa<MCConstantExpr>(getImm())) 1384 return true; 1385 1386 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1387 return false; 1388 // Immediate offset in range [-4095, 4095]. 1389 if (!Memory.OffsetImm) return true; 1390 int64_t Val = Memory.OffsetImm->getValue(); 1391 return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 1392 } 1393 bool isConstPoolAsmImm() const { 1394 // Delay processing of Constant Pool Immediate, this will turn into 1395 // a constant. Match no other operand 1396 return (isConstantPoolImm()); 1397 } 1398 bool isPostIdxImm8() const { 1399 if (!isImm()) return false; 1400 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1401 if (!CE) return false; 1402 int64_t Val = CE->getValue(); 1403 return (Val > -256 && Val < 256) || (Val == INT32_MIN); 1404 } 1405 bool isPostIdxImm8s4() const { 1406 if (!isImm()) return false; 1407 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1408 if (!CE) return false; 1409 int64_t Val = CE->getValue(); 1410 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 1411 (Val == INT32_MIN); 1412 } 1413 1414 bool isMSRMask() const { return Kind == k_MSRMask; } 1415 bool isBankedReg() const { return Kind == k_BankedReg; } 1416 bool isProcIFlags() const { return Kind == k_ProcIFlags; } 1417 1418 // NEON operands. 1419 bool isSingleSpacedVectorList() const { 1420 return Kind == k_VectorList && !VectorList.isDoubleSpaced; 1421 } 1422 bool isDoubleSpacedVectorList() const { 1423 return Kind == k_VectorList && VectorList.isDoubleSpaced; 1424 } 1425 bool isVecListOneD() const { 1426 if (!isSingleSpacedVectorList()) return false; 1427 return VectorList.Count == 1; 1428 } 1429 1430 bool isVecListDPair() const { 1431 if (!isSingleSpacedVectorList()) return false; 1432 return (ARMMCRegisterClasses[ARM::DPairRegClassID] 1433 .contains(VectorList.RegNum)); 1434 } 1435 1436 bool isVecListThreeD() const { 1437 if (!isSingleSpacedVectorList()) return false; 1438 return VectorList.Count == 3; 1439 } 1440 1441 bool isVecListFourD() const { 1442 if (!isSingleSpacedVectorList()) return false; 1443 return VectorList.Count == 4; 1444 } 1445 1446 bool isVecListDPairSpaced() const { 1447 if (Kind != k_VectorList) return false; 1448 if (isSingleSpacedVectorList()) return false; 1449 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID] 1450 .contains(VectorList.RegNum)); 1451 } 1452 1453 bool isVecListThreeQ() const { 1454 if (!isDoubleSpacedVectorList()) return false; 1455 return VectorList.Count == 3; 1456 } 1457 1458 bool isVecListFourQ() const { 1459 if (!isDoubleSpacedVectorList()) return false; 1460 return VectorList.Count == 4; 1461 } 1462 1463 bool isSingleSpacedVectorAllLanes() const { 1464 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced; 1465 } 1466 bool isDoubleSpacedVectorAllLanes() const { 1467 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced; 1468 } 1469 bool isVecListOneDAllLanes() const { 1470 if (!isSingleSpacedVectorAllLanes()) return false; 1471 return VectorList.Count == 1; 1472 } 1473 1474 bool isVecListDPairAllLanes() const { 1475 if (!isSingleSpacedVectorAllLanes()) return false; 1476 return (ARMMCRegisterClasses[ARM::DPairRegClassID] 1477 .contains(VectorList.RegNum)); 1478 } 1479 1480 bool isVecListDPairSpacedAllLanes() const { 1481 if (!isDoubleSpacedVectorAllLanes()) return false; 1482 return VectorList.Count == 2; 1483 } 1484 1485 bool isVecListThreeDAllLanes() const { 1486 if (!isSingleSpacedVectorAllLanes()) return false; 1487 return VectorList.Count == 3; 1488 } 1489 1490 bool isVecListThreeQAllLanes() const { 1491 if (!isDoubleSpacedVectorAllLanes()) return false; 1492 return VectorList.Count == 3; 1493 } 1494 1495 bool isVecListFourDAllLanes() const { 1496 if (!isSingleSpacedVectorAllLanes()) return false; 1497 return VectorList.Count == 4; 1498 } 1499 1500 bool isVecListFourQAllLanes() const { 1501 if (!isDoubleSpacedVectorAllLanes()) return false; 1502 return VectorList.Count == 4; 1503 } 1504 1505 bool isSingleSpacedVectorIndexed() const { 1506 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced; 1507 } 1508 bool isDoubleSpacedVectorIndexed() const { 1509 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced; 1510 } 1511 bool isVecListOneDByteIndexed() const { 1512 if (!isSingleSpacedVectorIndexed()) return false; 1513 return VectorList.Count == 1 && VectorList.LaneIndex <= 7; 1514 } 1515 1516 bool isVecListOneDHWordIndexed() const { 1517 if (!isSingleSpacedVectorIndexed()) return false; 1518 return VectorList.Count == 1 && VectorList.LaneIndex <= 3; 1519 } 1520 1521 bool isVecListOneDWordIndexed() const { 1522 if (!isSingleSpacedVectorIndexed()) return false; 1523 return VectorList.Count == 1 && VectorList.LaneIndex <= 1; 1524 } 1525 1526 bool isVecListTwoDByteIndexed() const { 1527 if (!isSingleSpacedVectorIndexed()) return false; 1528 return VectorList.Count == 2 && VectorList.LaneIndex <= 7; 1529 } 1530 1531 bool isVecListTwoDHWordIndexed() const { 1532 if (!isSingleSpacedVectorIndexed()) return false; 1533 return VectorList.Count == 2 && VectorList.LaneIndex <= 3; 1534 } 1535 1536 bool isVecListTwoQWordIndexed() const { 1537 if (!isDoubleSpacedVectorIndexed()) return false; 1538 return VectorList.Count == 2 && VectorList.LaneIndex <= 1; 1539 } 1540 1541 bool isVecListTwoQHWordIndexed() const { 1542 if (!isDoubleSpacedVectorIndexed()) return false; 1543 return VectorList.Count == 2 && VectorList.LaneIndex <= 3; 1544 } 1545 1546 bool isVecListTwoDWordIndexed() const { 1547 if (!isSingleSpacedVectorIndexed()) return false; 1548 return VectorList.Count == 2 && VectorList.LaneIndex <= 1; 1549 } 1550 1551 bool isVecListThreeDByteIndexed() const { 1552 if (!isSingleSpacedVectorIndexed()) return false; 1553 return VectorList.Count == 3 && VectorList.LaneIndex <= 7; 1554 } 1555 1556 bool isVecListThreeDHWordIndexed() const { 1557 if (!isSingleSpacedVectorIndexed()) return false; 1558 return VectorList.Count == 3 && VectorList.LaneIndex <= 3; 1559 } 1560 1561 bool isVecListThreeQWordIndexed() const { 1562 if (!isDoubleSpacedVectorIndexed()) return false; 1563 return VectorList.Count == 3 && VectorList.LaneIndex <= 1; 1564 } 1565 1566 bool isVecListThreeQHWordIndexed() const { 1567 if (!isDoubleSpacedVectorIndexed()) return false; 1568 return VectorList.Count == 3 && VectorList.LaneIndex <= 3; 1569 } 1570 1571 bool isVecListThreeDWordIndexed() const { 1572 if (!isSingleSpacedVectorIndexed()) return false; 1573 return VectorList.Count == 3 && VectorList.LaneIndex <= 1; 1574 } 1575 1576 bool isVecListFourDByteIndexed() const { 1577 if (!isSingleSpacedVectorIndexed()) return false; 1578 return VectorList.Count == 4 && VectorList.LaneIndex <= 7; 1579 } 1580 1581 bool isVecListFourDHWordIndexed() const { 1582 if (!isSingleSpacedVectorIndexed()) return false; 1583 return VectorList.Count == 4 && VectorList.LaneIndex <= 3; 1584 } 1585 1586 bool isVecListFourQWordIndexed() const { 1587 if (!isDoubleSpacedVectorIndexed()) return false; 1588 return VectorList.Count == 4 && VectorList.LaneIndex <= 1; 1589 } 1590 1591 bool isVecListFourQHWordIndexed() const { 1592 if (!isDoubleSpacedVectorIndexed()) return false; 1593 return VectorList.Count == 4 && VectorList.LaneIndex <= 3; 1594 } 1595 1596 bool isVecListFourDWordIndexed() const { 1597 if (!isSingleSpacedVectorIndexed()) return false; 1598 return VectorList.Count == 4 && VectorList.LaneIndex <= 1; 1599 } 1600 1601 bool isVectorIndex8() const { 1602 if (Kind != k_VectorIndex) return false; 1603 return VectorIndex.Val < 8; 1604 } 1605 bool isVectorIndex16() const { 1606 if (Kind != k_VectorIndex) return false; 1607 return VectorIndex.Val < 4; 1608 } 1609 bool isVectorIndex32() const { 1610 if (Kind != k_VectorIndex) return false; 1611 return VectorIndex.Val < 2; 1612 } 1613 1614 bool isNEONi8splat() const { 1615 if (!isImm()) return false; 1616 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1617 // Must be a constant. 1618 if (!CE) return false; 1619 int64_t Value = CE->getValue(); 1620 // i8 value splatted across 8 bytes. The immediate is just the 8 byte 1621 // value. 1622 return Value >= 0 && Value < 256; 1623 } 1624 1625 bool isNEONi16splat() const { 1626 if (isNEONByteReplicate(2)) 1627 return false; // Leave that for bytes replication and forbid by default. 1628 if (!isImm()) 1629 return false; 1630 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1631 // Must be a constant. 1632 if (!CE) return false; 1633 unsigned Value = CE->getValue(); 1634 return ARM_AM::isNEONi16splat(Value); 1635 } 1636 1637 bool isNEONi16splatNot() const { 1638 if (!isImm()) 1639 return false; 1640 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1641 // Must be a constant. 1642 if (!CE) return false; 1643 unsigned Value = CE->getValue(); 1644 return ARM_AM::isNEONi16splat(~Value & 0xffff); 1645 } 1646 1647 bool isNEONi32splat() const { 1648 if (isNEONByteReplicate(4)) 1649 return false; // Leave that for bytes replication and forbid by default. 1650 if (!isImm()) 1651 return false; 1652 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1653 // Must be a constant. 1654 if (!CE) return false; 1655 unsigned Value = CE->getValue(); 1656 return ARM_AM::isNEONi32splat(Value); 1657 } 1658 1659 bool isNEONi32splatNot() const { 1660 if (!isImm()) 1661 return false; 1662 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1663 // Must be a constant. 1664 if (!CE) return false; 1665 unsigned Value = CE->getValue(); 1666 return ARM_AM::isNEONi32splat(~Value); 1667 } 1668 1669 bool isNEONByteReplicate(unsigned NumBytes) const { 1670 if (!isImm()) 1671 return false; 1672 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1673 // Must be a constant. 1674 if (!CE) 1675 return false; 1676 int64_t Value = CE->getValue(); 1677 if (!Value) 1678 return false; // Don't bother with zero. 1679 1680 unsigned char B = Value & 0xff; 1681 for (unsigned i = 1; i < NumBytes; ++i) { 1682 Value >>= 8; 1683 if ((Value & 0xff) != B) 1684 return false; 1685 } 1686 return true; 1687 } 1688 bool isNEONi16ByteReplicate() const { return isNEONByteReplicate(2); } 1689 bool isNEONi32ByteReplicate() const { return isNEONByteReplicate(4); } 1690 bool isNEONi32vmov() const { 1691 if (isNEONByteReplicate(4)) 1692 return false; // Let it to be classified as byte-replicate case. 1693 if (!isImm()) 1694 return false; 1695 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1696 // Must be a constant. 1697 if (!CE) 1698 return false; 1699 int64_t Value = CE->getValue(); 1700 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 1701 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 1702 // FIXME: This is probably wrong and a copy and paste from previous example 1703 return (Value >= 0 && Value < 256) || 1704 (Value >= 0x0100 && Value <= 0xff00) || 1705 (Value >= 0x010000 && Value <= 0xff0000) || 1706 (Value >= 0x01000000 && Value <= 0xff000000) || 1707 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 1708 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 1709 } 1710 bool isNEONi32vmovNeg() const { 1711 if (!isImm()) return false; 1712 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1713 // Must be a constant. 1714 if (!CE) return false; 1715 int64_t Value = ~CE->getValue(); 1716 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 1717 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 1718 // FIXME: This is probably wrong and a copy and paste from previous example 1719 return (Value >= 0 && Value < 256) || 1720 (Value >= 0x0100 && Value <= 0xff00) || 1721 (Value >= 0x010000 && Value <= 0xff0000) || 1722 (Value >= 0x01000000 && Value <= 0xff000000) || 1723 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 1724 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 1725 } 1726 1727 bool isNEONi64splat() const { 1728 if (!isImm()) return false; 1729 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1730 // Must be a constant. 1731 if (!CE) return false; 1732 uint64_t Value = CE->getValue(); 1733 // i64 value with each byte being either 0 or 0xff. 1734 for (unsigned i = 0; i < 8; ++i, Value >>= 8) 1735 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 1736 return true; 1737 } 1738 1739 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 1740 // Add as immediates when possible. Null MCExpr = 0. 1741 if (!Expr) 1742 Inst.addOperand(MCOperand::createImm(0)); 1743 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 1744 Inst.addOperand(MCOperand::createImm(CE->getValue())); 1745 else 1746 Inst.addOperand(MCOperand::createExpr(Expr)); 1747 } 1748 1749 void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const { 1750 assert(N == 1 && "Invalid number of operands!"); 1751 addExpr(Inst, getImm()); 1752 } 1753 1754 void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const { 1755 assert(N == 1 && "Invalid number of operands!"); 1756 addExpr(Inst, getImm()); 1757 } 1758 1759 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1760 assert(N == 2 && "Invalid number of operands!"); 1761 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode()))); 1762 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 1763 Inst.addOperand(MCOperand::createReg(RegNum)); 1764 } 1765 1766 void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 1767 assert(N == 1 && "Invalid number of operands!"); 1768 Inst.addOperand(MCOperand::createImm(getCoproc())); 1769 } 1770 1771 void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 1772 assert(N == 1 && "Invalid number of operands!"); 1773 Inst.addOperand(MCOperand::createImm(getCoproc())); 1774 } 1775 1776 void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 1777 assert(N == 1 && "Invalid number of operands!"); 1778 Inst.addOperand(MCOperand::createImm(CoprocOption.Val)); 1779 } 1780 1781 void addITMaskOperands(MCInst &Inst, unsigned N) const { 1782 assert(N == 1 && "Invalid number of operands!"); 1783 Inst.addOperand(MCOperand::createImm(ITMask.Mask)); 1784 } 1785 1786 void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 1787 assert(N == 1 && "Invalid number of operands!"); 1788 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode()))); 1789 } 1790 1791 void addCCOutOperands(MCInst &Inst, unsigned N) const { 1792 assert(N == 1 && "Invalid number of operands!"); 1793 Inst.addOperand(MCOperand::createReg(getReg())); 1794 } 1795 1796 void addRegOperands(MCInst &Inst, unsigned N) const { 1797 assert(N == 1 && "Invalid number of operands!"); 1798 Inst.addOperand(MCOperand::createReg(getReg())); 1799 } 1800 1801 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 1802 assert(N == 3 && "Invalid number of operands!"); 1803 assert(isRegShiftedReg() && 1804 "addRegShiftedRegOperands() on non-RegShiftedReg!"); 1805 Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg)); 1806 Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg)); 1807 Inst.addOperand(MCOperand::createImm( 1808 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 1809 } 1810 1811 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 1812 assert(N == 2 && "Invalid number of operands!"); 1813 assert(isRegShiftedImm() && 1814 "addRegShiftedImmOperands() on non-RegShiftedImm!"); 1815 Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg)); 1816 // Shift of #32 is encoded as 0 where permitted 1817 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm); 1818 Inst.addOperand(MCOperand::createImm( 1819 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm))); 1820 } 1821 1822 void addShifterImmOperands(MCInst &Inst, unsigned N) const { 1823 assert(N == 1 && "Invalid number of operands!"); 1824 Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) | 1825 ShifterImm.Imm)); 1826 } 1827 1828 void addRegListOperands(MCInst &Inst, unsigned N) const { 1829 assert(N == 1 && "Invalid number of operands!"); 1830 const SmallVectorImpl<unsigned> &RegList = getRegList(); 1831 for (SmallVectorImpl<unsigned>::const_iterator 1832 I = RegList.begin(), E = RegList.end(); I != E; ++I) 1833 Inst.addOperand(MCOperand::createReg(*I)); 1834 } 1835 1836 void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 1837 addRegListOperands(Inst, N); 1838 } 1839 1840 void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 1841 addRegListOperands(Inst, N); 1842 } 1843 1844 void addRotImmOperands(MCInst &Inst, unsigned N) const { 1845 assert(N == 1 && "Invalid number of operands!"); 1846 // Encoded as val>>3. The printer handles display as 8, 16, 24. 1847 Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3)); 1848 } 1849 1850 void addModImmOperands(MCInst &Inst, unsigned N) const { 1851 assert(N == 1 && "Invalid number of operands!"); 1852 1853 // Support for fixups (MCFixup) 1854 if (isImm()) 1855 return addImmOperands(Inst, N); 1856 1857 Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7))); 1858 } 1859 1860 void addModImmNotOperands(MCInst &Inst, unsigned N) const { 1861 assert(N == 1 && "Invalid number of operands!"); 1862 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1863 uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue()); 1864 Inst.addOperand(MCOperand::createImm(Enc)); 1865 } 1866 1867 void addModImmNegOperands(MCInst &Inst, unsigned N) const { 1868 assert(N == 1 && "Invalid number of operands!"); 1869 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1870 uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue()); 1871 Inst.addOperand(MCOperand::createImm(Enc)); 1872 } 1873 1874 void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1875 assert(N == 1 && "Invalid number of operands!"); 1876 // Munge the lsb/width into a bitfield mask. 1877 unsigned lsb = Bitfield.LSB; 1878 unsigned width = Bitfield.Width; 1879 // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1880 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1881 (32 - (lsb + width))); 1882 Inst.addOperand(MCOperand::createImm(Mask)); 1883 } 1884 1885 void addImmOperands(MCInst &Inst, unsigned N) const { 1886 assert(N == 1 && "Invalid number of operands!"); 1887 addExpr(Inst, getImm()); 1888 } 1889 1890 void addFBits16Operands(MCInst &Inst, unsigned N) const { 1891 assert(N == 1 && "Invalid number of operands!"); 1892 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1893 Inst.addOperand(MCOperand::createImm(16 - CE->getValue())); 1894 } 1895 1896 void addFBits32Operands(MCInst &Inst, unsigned N) const { 1897 assert(N == 1 && "Invalid number of operands!"); 1898 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1899 Inst.addOperand(MCOperand::createImm(32 - CE->getValue())); 1900 } 1901 1902 void addFPImmOperands(MCInst &Inst, unsigned N) const { 1903 assert(N == 1 && "Invalid number of operands!"); 1904 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1905 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue())); 1906 Inst.addOperand(MCOperand::createImm(Val)); 1907 } 1908 1909 void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1910 assert(N == 1 && "Invalid number of operands!"); 1911 // FIXME: We really want to scale the value here, but the LDRD/STRD 1912 // instruction don't encode operands that way yet. 1913 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1914 Inst.addOperand(MCOperand::createImm(CE->getValue())); 1915 } 1916 1917 void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 1918 assert(N == 1 && "Invalid number of operands!"); 1919 // The immediate is scaled by four in the encoding and is stored 1920 // in the MCInst as such. Lop off the low two bits here. 1921 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1922 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4)); 1923 } 1924 1925 void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const { 1926 assert(N == 1 && "Invalid number of operands!"); 1927 // The immediate is scaled by four in the encoding and is stored 1928 // in the MCInst as such. Lop off the low two bits here. 1929 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1930 Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4))); 1931 } 1932 1933 void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 1934 assert(N == 1 && "Invalid number of operands!"); 1935 // The immediate is scaled by four in the encoding and is stored 1936 // in the MCInst as such. Lop off the low two bits here. 1937 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1938 Inst.addOperand(MCOperand::createImm(CE->getValue() / 4)); 1939 } 1940 1941 void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1942 assert(N == 1 && "Invalid number of operands!"); 1943 // The constant encodes as the immediate-1, and we store in the instruction 1944 // the bits as encoded, so subtract off one here. 1945 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1946 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1)); 1947 } 1948 1949 void addImm1_32Operands(MCInst &Inst, unsigned N) const { 1950 assert(N == 1 && "Invalid number of operands!"); 1951 // The constant encodes as the immediate-1, and we store in the instruction 1952 // the bits as encoded, so subtract off one here. 1953 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1954 Inst.addOperand(MCOperand::createImm(CE->getValue() - 1)); 1955 } 1956 1957 void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 1958 assert(N == 1 && "Invalid number of operands!"); 1959 // The constant encodes as the immediate, except for 32, which encodes as 1960 // zero. 1961 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1962 unsigned Imm = CE->getValue(); 1963 Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm))); 1964 } 1965 1966 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1967 assert(N == 1 && "Invalid number of operands!"); 1968 // An ASR value of 32 encodes as 0, so that's how we want to add it to 1969 // the instruction as well. 1970 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1971 int Val = CE->getValue(); 1972 Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val)); 1973 } 1974 1975 void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const { 1976 assert(N == 1 && "Invalid number of operands!"); 1977 // The operand is actually a t2_so_imm, but we have its bitwise 1978 // negation in the assembly source, so twiddle it here. 1979 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1980 Inst.addOperand(MCOperand::createImm(~CE->getValue())); 1981 } 1982 1983 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const { 1984 assert(N == 1 && "Invalid number of operands!"); 1985 // The operand is actually a t2_so_imm, but we have its 1986 // negation in the assembly source, so twiddle it here. 1987 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1988 Inst.addOperand(MCOperand::createImm(-CE->getValue())); 1989 } 1990 1991 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const { 1992 assert(N == 1 && "Invalid number of operands!"); 1993 // The operand is actually an imm0_4095, but we have its 1994 // negation in the assembly source, so twiddle it here. 1995 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1996 Inst.addOperand(MCOperand::createImm(-CE->getValue())); 1997 } 1998 1999 void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const { 2000 if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) { 2001 Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2)); 2002 return; 2003 } 2004 2005 const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val); 2006 assert(SR && "Unknown value type!"); 2007 Inst.addOperand(MCOperand::createExpr(SR)); 2008 } 2009 2010 void addThumbMemPCOperands(MCInst &Inst, unsigned N) const { 2011 assert(N == 1 && "Invalid number of operands!"); 2012 if (isImm()) { 2013 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2014 if (CE) { 2015 Inst.addOperand(MCOperand::createImm(CE->getValue())); 2016 return; 2017 } 2018 2019 const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val); 2020 2021 assert(SR && "Unknown value type!"); 2022 Inst.addOperand(MCOperand::createExpr(SR)); 2023 return; 2024 } 2025 2026 assert(isMem() && "Unknown value type!"); 2027 assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!"); 2028 Inst.addOperand(MCOperand::createImm(Memory.OffsetImm->getValue())); 2029 } 2030 2031 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 2032 assert(N == 1 && "Invalid number of operands!"); 2033 Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt()))); 2034 } 2035 2036 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const { 2037 assert(N == 1 && "Invalid number of operands!"); 2038 Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt()))); 2039 } 2040 2041 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 2042 assert(N == 1 && "Invalid number of operands!"); 2043 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2044 } 2045 2046 void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const { 2047 assert(N == 1 && "Invalid number of operands!"); 2048 int32_t Imm = Memory.OffsetImm->getValue(); 2049 Inst.addOperand(MCOperand::createImm(Imm)); 2050 } 2051 2052 void addAdrLabelOperands(MCInst &Inst, unsigned N) const { 2053 assert(N == 1 && "Invalid number of operands!"); 2054 assert(isImm() && "Not an immediate!"); 2055 2056 // If we have an immediate that's not a constant, treat it as a label 2057 // reference needing a fixup. 2058 if (!isa<MCConstantExpr>(getImm())) { 2059 Inst.addOperand(MCOperand::createExpr(getImm())); 2060 return; 2061 } 2062 2063 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2064 int Val = CE->getValue(); 2065 Inst.addOperand(MCOperand::createImm(Val)); 2066 } 2067 2068 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 2069 assert(N == 2 && "Invalid number of operands!"); 2070 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2071 Inst.addOperand(MCOperand::createImm(Memory.Alignment)); 2072 } 2073 2074 void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const { 2075 addAlignedMemoryOperands(Inst, N); 2076 } 2077 2078 void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const { 2079 addAlignedMemoryOperands(Inst, N); 2080 } 2081 2082 void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const { 2083 addAlignedMemoryOperands(Inst, N); 2084 } 2085 2086 void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const { 2087 addAlignedMemoryOperands(Inst, N); 2088 } 2089 2090 void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const { 2091 addAlignedMemoryOperands(Inst, N); 2092 } 2093 2094 void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const { 2095 addAlignedMemoryOperands(Inst, N); 2096 } 2097 2098 void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const { 2099 addAlignedMemoryOperands(Inst, N); 2100 } 2101 2102 void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const { 2103 addAlignedMemoryOperands(Inst, N); 2104 } 2105 2106 void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const { 2107 addAlignedMemoryOperands(Inst, N); 2108 } 2109 2110 void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const { 2111 addAlignedMemoryOperands(Inst, N); 2112 } 2113 2114 void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const { 2115 addAlignedMemoryOperands(Inst, N); 2116 } 2117 2118 void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 2119 assert(N == 3 && "Invalid number of operands!"); 2120 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2121 if (!Memory.OffsetRegNum) { 2122 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2123 // Special case for #-0 2124 if (Val == INT32_MIN) Val = 0; 2125 if (Val < 0) Val = -Val; 2126 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 2127 } else { 2128 // For register offset, we encode the shift type and negation flag 2129 // here. 2130 Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 2131 Memory.ShiftImm, Memory.ShiftType); 2132 } 2133 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2134 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 2135 Inst.addOperand(MCOperand::createImm(Val)); 2136 } 2137 2138 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 2139 assert(N == 2 && "Invalid number of operands!"); 2140 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2141 assert(CE && "non-constant AM2OffsetImm operand!"); 2142 int32_t Val = CE->getValue(); 2143 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2144 // Special case for #-0 2145 if (Val == INT32_MIN) Val = 0; 2146 if (Val < 0) Val = -Val; 2147 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 2148 Inst.addOperand(MCOperand::createReg(0)); 2149 Inst.addOperand(MCOperand::createImm(Val)); 2150 } 2151 2152 void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 2153 assert(N == 3 && "Invalid number of operands!"); 2154 // If we have an immediate that's not a constant, treat it as a label 2155 // reference needing a fixup. If it is a constant, it's something else 2156 // and we reject it. 2157 if (isImm()) { 2158 Inst.addOperand(MCOperand::createExpr(getImm())); 2159 Inst.addOperand(MCOperand::createReg(0)); 2160 Inst.addOperand(MCOperand::createImm(0)); 2161 return; 2162 } 2163 2164 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2165 if (!Memory.OffsetRegNum) { 2166 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2167 // Special case for #-0 2168 if (Val == INT32_MIN) Val = 0; 2169 if (Val < 0) Val = -Val; 2170 Val = ARM_AM::getAM3Opc(AddSub, Val); 2171 } else { 2172 // For register offset, we encode the shift type and negation flag 2173 // here. 2174 Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 2175 } 2176 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2177 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 2178 Inst.addOperand(MCOperand::createImm(Val)); 2179 } 2180 2181 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 2182 assert(N == 2 && "Invalid number of operands!"); 2183 if (Kind == k_PostIndexRegister) { 2184 int32_t Val = 2185 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 2186 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum)); 2187 Inst.addOperand(MCOperand::createImm(Val)); 2188 return; 2189 } 2190 2191 // Constant offset. 2192 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 2193 int32_t Val = CE->getValue(); 2194 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2195 // Special case for #-0 2196 if (Val == INT32_MIN) Val = 0; 2197 if (Val < 0) Val = -Val; 2198 Val = ARM_AM::getAM3Opc(AddSub, Val); 2199 Inst.addOperand(MCOperand::createReg(0)); 2200 Inst.addOperand(MCOperand::createImm(Val)); 2201 } 2202 2203 void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 2204 assert(N == 2 && "Invalid number of operands!"); 2205 // If we have an immediate that's not a constant, treat it as a label 2206 // reference needing a fixup. If it is a constant, it's something else 2207 // and we reject it. 2208 if (isImm()) { 2209 Inst.addOperand(MCOperand::createExpr(getImm())); 2210 Inst.addOperand(MCOperand::createImm(0)); 2211 return; 2212 } 2213 2214 // The lower two bits are always zero and as such are not encoded. 2215 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 2216 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2217 // Special case for #-0 2218 if (Val == INT32_MIN) Val = 0; 2219 if (Val < 0) Val = -Val; 2220 Val = ARM_AM::getAM5Opc(AddSub, Val); 2221 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2222 Inst.addOperand(MCOperand::createImm(Val)); 2223 } 2224 2225 void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const { 2226 assert(N == 2 && "Invalid number of operands!"); 2227 // If we have an immediate that's not a constant, treat it as a label 2228 // reference needing a fixup. If it is a constant, it's something else 2229 // and we reject it. 2230 if (isImm()) { 2231 Inst.addOperand(MCOperand::createExpr(getImm())); 2232 Inst.addOperand(MCOperand::createImm(0)); 2233 return; 2234 } 2235 2236 // The lower bit is always zero and as such is not encoded. 2237 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 2 : 0; 2238 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2239 // Special case for #-0 2240 if (Val == INT32_MIN) Val = 0; 2241 if (Val < 0) Val = -Val; 2242 Val = ARM_AM::getAM5FP16Opc(AddSub, Val); 2243 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2244 Inst.addOperand(MCOperand::createImm(Val)); 2245 } 2246 2247 void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 2248 assert(N == 2 && "Invalid number of operands!"); 2249 // If we have an immediate that's not a constant, treat it as a label 2250 // reference needing a fixup. If it is a constant, it's something else 2251 // and we reject it. 2252 if (isImm()) { 2253 Inst.addOperand(MCOperand::createExpr(getImm())); 2254 Inst.addOperand(MCOperand::createImm(0)); 2255 return; 2256 } 2257 2258 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2259 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2260 Inst.addOperand(MCOperand::createImm(Val)); 2261 } 2262 2263 void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 2264 assert(N == 2 && "Invalid number of operands!"); 2265 // The lower two bits are always zero and as such are not encoded. 2266 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 2267 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2268 Inst.addOperand(MCOperand::createImm(Val)); 2269 } 2270 2271 void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 2272 assert(N == 2 && "Invalid number of operands!"); 2273 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2274 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2275 Inst.addOperand(MCOperand::createImm(Val)); 2276 } 2277 2278 void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 2279 addMemImm8OffsetOperands(Inst, N); 2280 } 2281 2282 void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 2283 addMemImm8OffsetOperands(Inst, N); 2284 } 2285 2286 void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 2287 assert(N == 2 && "Invalid number of operands!"); 2288 // If this is an immediate, it's a label reference. 2289 if (isImm()) { 2290 addExpr(Inst, getImm()); 2291 Inst.addOperand(MCOperand::createImm(0)); 2292 return; 2293 } 2294 2295 // Otherwise, it's a normal memory reg+offset. 2296 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2297 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2298 Inst.addOperand(MCOperand::createImm(Val)); 2299 } 2300 2301 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 2302 assert(N == 2 && "Invalid number of operands!"); 2303 // If this is an immediate, it's a label reference. 2304 if (isImm()) { 2305 addExpr(Inst, getImm()); 2306 Inst.addOperand(MCOperand::createImm(0)); 2307 return; 2308 } 2309 2310 // Otherwise, it's a normal memory reg+offset. 2311 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2312 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2313 Inst.addOperand(MCOperand::createImm(Val)); 2314 } 2315 2316 void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const { 2317 assert(N == 1 && "Invalid number of operands!"); 2318 // This is container for the immediate that we will create the constant 2319 // pool from 2320 addExpr(Inst, getConstantPoolImm()); 2321 return; 2322 } 2323 2324 void addMemTBBOperands(MCInst &Inst, unsigned N) const { 2325 assert(N == 2 && "Invalid number of operands!"); 2326 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2327 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 2328 } 2329 2330 void addMemTBHOperands(MCInst &Inst, unsigned N) const { 2331 assert(N == 2 && "Invalid number of operands!"); 2332 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2333 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 2334 } 2335 2336 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 2337 assert(N == 3 && "Invalid number of operands!"); 2338 unsigned Val = 2339 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 2340 Memory.ShiftImm, Memory.ShiftType); 2341 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2342 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 2343 Inst.addOperand(MCOperand::createImm(Val)); 2344 } 2345 2346 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 2347 assert(N == 3 && "Invalid number of operands!"); 2348 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2349 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 2350 Inst.addOperand(MCOperand::createImm(Memory.ShiftImm)); 2351 } 2352 2353 void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 2354 assert(N == 2 && "Invalid number of operands!"); 2355 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2356 Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum)); 2357 } 2358 2359 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 2360 assert(N == 2 && "Invalid number of operands!"); 2361 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 2362 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2363 Inst.addOperand(MCOperand::createImm(Val)); 2364 } 2365 2366 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 2367 assert(N == 2 && "Invalid number of operands!"); 2368 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 2369 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2370 Inst.addOperand(MCOperand::createImm(Val)); 2371 } 2372 2373 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 2374 assert(N == 2 && "Invalid number of operands!"); 2375 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 2376 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2377 Inst.addOperand(MCOperand::createImm(Val)); 2378 } 2379 2380 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 2381 assert(N == 2 && "Invalid number of operands!"); 2382 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 2383 Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum)); 2384 Inst.addOperand(MCOperand::createImm(Val)); 2385 } 2386 2387 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 2388 assert(N == 1 && "Invalid number of operands!"); 2389 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2390 assert(CE && "non-constant post-idx-imm8 operand!"); 2391 int Imm = CE->getValue(); 2392 bool isAdd = Imm >= 0; 2393 if (Imm == INT32_MIN) Imm = 0; 2394 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 2395 Inst.addOperand(MCOperand::createImm(Imm)); 2396 } 2397 2398 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 2399 assert(N == 1 && "Invalid number of operands!"); 2400 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2401 assert(CE && "non-constant post-idx-imm8s4 operand!"); 2402 int Imm = CE->getValue(); 2403 bool isAdd = Imm >= 0; 2404 if (Imm == INT32_MIN) Imm = 0; 2405 // Immediate is scaled by 4. 2406 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 2407 Inst.addOperand(MCOperand::createImm(Imm)); 2408 } 2409 2410 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 2411 assert(N == 2 && "Invalid number of operands!"); 2412 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum)); 2413 Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd)); 2414 } 2415 2416 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 2417 assert(N == 2 && "Invalid number of operands!"); 2418 Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum)); 2419 // The sign, shift type, and shift amount are encoded in a single operand 2420 // using the AM2 encoding helpers. 2421 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 2422 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 2423 PostIdxReg.ShiftTy); 2424 Inst.addOperand(MCOperand::createImm(Imm)); 2425 } 2426 2427 void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 2428 assert(N == 1 && "Invalid number of operands!"); 2429 Inst.addOperand(MCOperand::createImm(unsigned(getMSRMask()))); 2430 } 2431 2432 void addBankedRegOperands(MCInst &Inst, unsigned N) const { 2433 assert(N == 1 && "Invalid number of operands!"); 2434 Inst.addOperand(MCOperand::createImm(unsigned(getBankedReg()))); 2435 } 2436 2437 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 2438 assert(N == 1 && "Invalid number of operands!"); 2439 Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags()))); 2440 } 2441 2442 void addVecListOperands(MCInst &Inst, unsigned N) const { 2443 assert(N == 1 && "Invalid number of operands!"); 2444 Inst.addOperand(MCOperand::createReg(VectorList.RegNum)); 2445 } 2446 2447 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const { 2448 assert(N == 2 && "Invalid number of operands!"); 2449 Inst.addOperand(MCOperand::createReg(VectorList.RegNum)); 2450 Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex)); 2451 } 2452 2453 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 2454 assert(N == 1 && "Invalid number of operands!"); 2455 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 2456 } 2457 2458 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 2459 assert(N == 1 && "Invalid number of operands!"); 2460 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 2461 } 2462 2463 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 2464 assert(N == 1 && "Invalid number of operands!"); 2465 Inst.addOperand(MCOperand::createImm(getVectorIndex())); 2466 } 2467 2468 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 2469 assert(N == 1 && "Invalid number of operands!"); 2470 // The immediate encodes the type of constant as well as the value. 2471 // Mask in that this is an i8 splat. 2472 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2473 Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00)); 2474 } 2475 2476 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 2477 assert(N == 1 && "Invalid number of operands!"); 2478 // The immediate encodes the type of constant as well as the value. 2479 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2480 unsigned Value = CE->getValue(); 2481 Value = ARM_AM::encodeNEONi16splat(Value); 2482 Inst.addOperand(MCOperand::createImm(Value)); 2483 } 2484 2485 void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const { 2486 assert(N == 1 && "Invalid number of operands!"); 2487 // The immediate encodes the type of constant as well as the value. 2488 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2489 unsigned Value = CE->getValue(); 2490 Value = ARM_AM::encodeNEONi16splat(~Value & 0xffff); 2491 Inst.addOperand(MCOperand::createImm(Value)); 2492 } 2493 2494 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 2495 assert(N == 1 && "Invalid number of operands!"); 2496 // The immediate encodes the type of constant as well as the value. 2497 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2498 unsigned Value = CE->getValue(); 2499 Value = ARM_AM::encodeNEONi32splat(Value); 2500 Inst.addOperand(MCOperand::createImm(Value)); 2501 } 2502 2503 void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const { 2504 assert(N == 1 && "Invalid number of operands!"); 2505 // The immediate encodes the type of constant as well as the value. 2506 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2507 unsigned Value = CE->getValue(); 2508 Value = ARM_AM::encodeNEONi32splat(~Value); 2509 Inst.addOperand(MCOperand::createImm(Value)); 2510 } 2511 2512 void addNEONinvByteReplicateOperands(MCInst &Inst, unsigned N) const { 2513 assert(N == 1 && "Invalid number of operands!"); 2514 // The immediate encodes the type of constant as well as the value. 2515 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2516 unsigned Value = CE->getValue(); 2517 assert((Inst.getOpcode() == ARM::VMOVv8i8 || 2518 Inst.getOpcode() == ARM::VMOVv16i8) && 2519 "All vmvn instructions that wants to replicate non-zero byte " 2520 "always must be replaced with VMOVv8i8 or VMOVv16i8."); 2521 unsigned B = ((~Value) & 0xff); 2522 B |= 0xe00; // cmode = 0b1110 2523 Inst.addOperand(MCOperand::createImm(B)); 2524 } 2525 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 2526 assert(N == 1 && "Invalid number of operands!"); 2527 // The immediate encodes the type of constant as well as the value. 2528 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2529 unsigned Value = CE->getValue(); 2530 if (Value >= 256 && Value <= 0xffff) 2531 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 2532 else if (Value > 0xffff && Value <= 0xffffff) 2533 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 2534 else if (Value > 0xffffff) 2535 Value = (Value >> 24) | 0x600; 2536 Inst.addOperand(MCOperand::createImm(Value)); 2537 } 2538 2539 void addNEONvmovByteReplicateOperands(MCInst &Inst, unsigned N) const { 2540 assert(N == 1 && "Invalid number of operands!"); 2541 // The immediate encodes the type of constant as well as the value. 2542 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2543 unsigned Value = CE->getValue(); 2544 assert((Inst.getOpcode() == ARM::VMOVv8i8 || 2545 Inst.getOpcode() == ARM::VMOVv16i8) && 2546 "All instructions that wants to replicate non-zero byte " 2547 "always must be replaced with VMOVv8i8 or VMOVv16i8."); 2548 unsigned B = Value & 0xff; 2549 B |= 0xe00; // cmode = 0b1110 2550 Inst.addOperand(MCOperand::createImm(B)); 2551 } 2552 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const { 2553 assert(N == 1 && "Invalid number of operands!"); 2554 // The immediate encodes the type of constant as well as the value. 2555 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2556 unsigned Value = ~CE->getValue(); 2557 if (Value >= 256 && Value <= 0xffff) 2558 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 2559 else if (Value > 0xffff && Value <= 0xffffff) 2560 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 2561 else if (Value > 0xffffff) 2562 Value = (Value >> 24) | 0x600; 2563 Inst.addOperand(MCOperand::createImm(Value)); 2564 } 2565 2566 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 2567 assert(N == 1 && "Invalid number of operands!"); 2568 // The immediate encodes the type of constant as well as the value. 2569 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2570 uint64_t Value = CE->getValue(); 2571 unsigned Imm = 0; 2572 for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 2573 Imm |= (Value & 1) << i; 2574 } 2575 Inst.addOperand(MCOperand::createImm(Imm | 0x1e00)); 2576 } 2577 2578 void print(raw_ostream &OS) const override; 2579 2580 static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S) { 2581 auto Op = make_unique<ARMOperand>(k_ITCondMask); 2582 Op->ITMask.Mask = Mask; 2583 Op->StartLoc = S; 2584 Op->EndLoc = S; 2585 return Op; 2586 } 2587 2588 static std::unique_ptr<ARMOperand> CreateCondCode(ARMCC::CondCodes CC, 2589 SMLoc S) { 2590 auto Op = make_unique<ARMOperand>(k_CondCode); 2591 Op->CC.Val = CC; 2592 Op->StartLoc = S; 2593 Op->EndLoc = S; 2594 return Op; 2595 } 2596 2597 static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S) { 2598 auto Op = make_unique<ARMOperand>(k_CoprocNum); 2599 Op->Cop.Val = CopVal; 2600 Op->StartLoc = S; 2601 Op->EndLoc = S; 2602 return Op; 2603 } 2604 2605 static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S) { 2606 auto Op = make_unique<ARMOperand>(k_CoprocReg); 2607 Op->Cop.Val = CopVal; 2608 Op->StartLoc = S; 2609 Op->EndLoc = S; 2610 return Op; 2611 } 2612 2613 static std::unique_ptr<ARMOperand> CreateCoprocOption(unsigned Val, SMLoc S, 2614 SMLoc E) { 2615 auto Op = make_unique<ARMOperand>(k_CoprocOption); 2616 Op->Cop.Val = Val; 2617 Op->StartLoc = S; 2618 Op->EndLoc = E; 2619 return Op; 2620 } 2621 2622 static std::unique_ptr<ARMOperand> CreateCCOut(unsigned RegNum, SMLoc S) { 2623 auto Op = make_unique<ARMOperand>(k_CCOut); 2624 Op->Reg.RegNum = RegNum; 2625 Op->StartLoc = S; 2626 Op->EndLoc = S; 2627 return Op; 2628 } 2629 2630 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S) { 2631 auto Op = make_unique<ARMOperand>(k_Token); 2632 Op->Tok.Data = Str.data(); 2633 Op->Tok.Length = Str.size(); 2634 Op->StartLoc = S; 2635 Op->EndLoc = S; 2636 return Op; 2637 } 2638 2639 static std::unique_ptr<ARMOperand> CreateReg(unsigned RegNum, SMLoc S, 2640 SMLoc E) { 2641 auto Op = make_unique<ARMOperand>(k_Register); 2642 Op->Reg.RegNum = RegNum; 2643 Op->StartLoc = S; 2644 Op->EndLoc = E; 2645 return Op; 2646 } 2647 2648 static std::unique_ptr<ARMOperand> 2649 CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, unsigned SrcReg, 2650 unsigned ShiftReg, unsigned ShiftImm, SMLoc S, 2651 SMLoc E) { 2652 auto Op = make_unique<ARMOperand>(k_ShiftedRegister); 2653 Op->RegShiftedReg.ShiftTy = ShTy; 2654 Op->RegShiftedReg.SrcReg = SrcReg; 2655 Op->RegShiftedReg.ShiftReg = ShiftReg; 2656 Op->RegShiftedReg.ShiftImm = ShiftImm; 2657 Op->StartLoc = S; 2658 Op->EndLoc = E; 2659 return Op; 2660 } 2661 2662 static std::unique_ptr<ARMOperand> 2663 CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, unsigned SrcReg, 2664 unsigned ShiftImm, SMLoc S, SMLoc E) { 2665 auto Op = make_unique<ARMOperand>(k_ShiftedImmediate); 2666 Op->RegShiftedImm.ShiftTy = ShTy; 2667 Op->RegShiftedImm.SrcReg = SrcReg; 2668 Op->RegShiftedImm.ShiftImm = ShiftImm; 2669 Op->StartLoc = S; 2670 Op->EndLoc = E; 2671 return Op; 2672 } 2673 2674 static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm, 2675 SMLoc S, SMLoc E) { 2676 auto Op = make_unique<ARMOperand>(k_ShifterImmediate); 2677 Op->ShifterImm.isASR = isASR; 2678 Op->ShifterImm.Imm = Imm; 2679 Op->StartLoc = S; 2680 Op->EndLoc = E; 2681 return Op; 2682 } 2683 2684 static std::unique_ptr<ARMOperand> CreateRotImm(unsigned Imm, SMLoc S, 2685 SMLoc E) { 2686 auto Op = make_unique<ARMOperand>(k_RotateImmediate); 2687 Op->RotImm.Imm = Imm; 2688 Op->StartLoc = S; 2689 Op->EndLoc = E; 2690 return Op; 2691 } 2692 2693 static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot, 2694 SMLoc S, SMLoc E) { 2695 auto Op = make_unique<ARMOperand>(k_ModifiedImmediate); 2696 Op->ModImm.Bits = Bits; 2697 Op->ModImm.Rot = Rot; 2698 Op->StartLoc = S; 2699 Op->EndLoc = E; 2700 return Op; 2701 } 2702 2703 static std::unique_ptr<ARMOperand> 2704 CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E) { 2705 auto Op = make_unique<ARMOperand>(k_ConstantPoolImmediate); 2706 Op->Imm.Val = Val; 2707 Op->StartLoc = S; 2708 Op->EndLoc = E; 2709 return Op; 2710 } 2711 2712 static std::unique_ptr<ARMOperand> 2713 CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) { 2714 auto Op = make_unique<ARMOperand>(k_BitfieldDescriptor); 2715 Op->Bitfield.LSB = LSB; 2716 Op->Bitfield.Width = Width; 2717 Op->StartLoc = S; 2718 Op->EndLoc = E; 2719 return Op; 2720 } 2721 2722 static std::unique_ptr<ARMOperand> 2723 CreateRegList(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs, 2724 SMLoc StartLoc, SMLoc EndLoc) { 2725 assert (Regs.size() > 0 && "RegList contains no registers?"); 2726 KindTy Kind = k_RegisterList; 2727 2728 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().second)) 2729 Kind = k_DPRRegisterList; 2730 else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 2731 contains(Regs.front().second)) 2732 Kind = k_SPRRegisterList; 2733 2734 // Sort based on the register encoding values. 2735 array_pod_sort(Regs.begin(), Regs.end()); 2736 2737 auto Op = make_unique<ARMOperand>(Kind); 2738 for (SmallVectorImpl<std::pair<unsigned, unsigned> >::const_iterator 2739 I = Regs.begin(), E = Regs.end(); I != E; ++I) 2740 Op->Registers.push_back(I->second); 2741 Op->StartLoc = StartLoc; 2742 Op->EndLoc = EndLoc; 2743 return Op; 2744 } 2745 2746 static std::unique_ptr<ARMOperand> CreateVectorList(unsigned RegNum, 2747 unsigned Count, 2748 bool isDoubleSpaced, 2749 SMLoc S, SMLoc E) { 2750 auto Op = make_unique<ARMOperand>(k_VectorList); 2751 Op->VectorList.RegNum = RegNum; 2752 Op->VectorList.Count = Count; 2753 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 2754 Op->StartLoc = S; 2755 Op->EndLoc = E; 2756 return Op; 2757 } 2758 2759 static std::unique_ptr<ARMOperand> 2760 CreateVectorListAllLanes(unsigned RegNum, unsigned Count, bool isDoubleSpaced, 2761 SMLoc S, SMLoc E) { 2762 auto Op = make_unique<ARMOperand>(k_VectorListAllLanes); 2763 Op->VectorList.RegNum = RegNum; 2764 Op->VectorList.Count = Count; 2765 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 2766 Op->StartLoc = S; 2767 Op->EndLoc = E; 2768 return Op; 2769 } 2770 2771 static std::unique_ptr<ARMOperand> 2772 CreateVectorListIndexed(unsigned RegNum, unsigned Count, unsigned Index, 2773 bool isDoubleSpaced, SMLoc S, SMLoc E) { 2774 auto Op = make_unique<ARMOperand>(k_VectorListIndexed); 2775 Op->VectorList.RegNum = RegNum; 2776 Op->VectorList.Count = Count; 2777 Op->VectorList.LaneIndex = Index; 2778 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 2779 Op->StartLoc = S; 2780 Op->EndLoc = E; 2781 return Op; 2782 } 2783 2784 static std::unique_ptr<ARMOperand> 2785 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) { 2786 auto Op = make_unique<ARMOperand>(k_VectorIndex); 2787 Op->VectorIndex.Val = Idx; 2788 Op->StartLoc = S; 2789 Op->EndLoc = E; 2790 return Op; 2791 } 2792 2793 static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S, 2794 SMLoc E) { 2795 auto Op = make_unique<ARMOperand>(k_Immediate); 2796 Op->Imm.Val = Val; 2797 Op->StartLoc = S; 2798 Op->EndLoc = E; 2799 return Op; 2800 } 2801 2802 static std::unique_ptr<ARMOperand> 2803 CreateMem(unsigned BaseRegNum, const MCConstantExpr *OffsetImm, 2804 unsigned OffsetRegNum, ARM_AM::ShiftOpc ShiftType, 2805 unsigned ShiftImm, unsigned Alignment, bool isNegative, SMLoc S, 2806 SMLoc E, SMLoc AlignmentLoc = SMLoc()) { 2807 auto Op = make_unique<ARMOperand>(k_Memory); 2808 Op->Memory.BaseRegNum = BaseRegNum; 2809 Op->Memory.OffsetImm = OffsetImm; 2810 Op->Memory.OffsetRegNum = OffsetRegNum; 2811 Op->Memory.ShiftType = ShiftType; 2812 Op->Memory.ShiftImm = ShiftImm; 2813 Op->Memory.Alignment = Alignment; 2814 Op->Memory.isNegative = isNegative; 2815 Op->StartLoc = S; 2816 Op->EndLoc = E; 2817 Op->AlignmentLoc = AlignmentLoc; 2818 return Op; 2819 } 2820 2821 static std::unique_ptr<ARMOperand> 2822 CreatePostIdxReg(unsigned RegNum, bool isAdd, ARM_AM::ShiftOpc ShiftTy, 2823 unsigned ShiftImm, SMLoc S, SMLoc E) { 2824 auto Op = make_unique<ARMOperand>(k_PostIndexRegister); 2825 Op->PostIdxReg.RegNum = RegNum; 2826 Op->PostIdxReg.isAdd = isAdd; 2827 Op->PostIdxReg.ShiftTy = ShiftTy; 2828 Op->PostIdxReg.ShiftImm = ShiftImm; 2829 Op->StartLoc = S; 2830 Op->EndLoc = E; 2831 return Op; 2832 } 2833 2834 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, 2835 SMLoc S) { 2836 auto Op = make_unique<ARMOperand>(k_MemBarrierOpt); 2837 Op->MBOpt.Val = Opt; 2838 Op->StartLoc = S; 2839 Op->EndLoc = S; 2840 return Op; 2841 } 2842 2843 static std::unique_ptr<ARMOperand> 2844 CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S) { 2845 auto Op = make_unique<ARMOperand>(k_InstSyncBarrierOpt); 2846 Op->ISBOpt.Val = Opt; 2847 Op->StartLoc = S; 2848 Op->EndLoc = S; 2849 return Op; 2850 } 2851 2852 static std::unique_ptr<ARMOperand> CreateProcIFlags(ARM_PROC::IFlags IFlags, 2853 SMLoc S) { 2854 auto Op = make_unique<ARMOperand>(k_ProcIFlags); 2855 Op->IFlags.Val = IFlags; 2856 Op->StartLoc = S; 2857 Op->EndLoc = S; 2858 return Op; 2859 } 2860 2861 static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S) { 2862 auto Op = make_unique<ARMOperand>(k_MSRMask); 2863 Op->MMask.Val = MMask; 2864 Op->StartLoc = S; 2865 Op->EndLoc = S; 2866 return Op; 2867 } 2868 2869 static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S) { 2870 auto Op = make_unique<ARMOperand>(k_BankedReg); 2871 Op->BankedReg.Val = Reg; 2872 Op->StartLoc = S; 2873 Op->EndLoc = S; 2874 return Op; 2875 } 2876 }; 2877 2878 } // end anonymous namespace. 2879 2880 void ARMOperand::print(raw_ostream &OS) const { 2881 switch (Kind) { 2882 case k_CondCode: 2883 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 2884 break; 2885 case k_CCOut: 2886 OS << "<ccout " << getReg() << ">"; 2887 break; 2888 case k_ITCondMask: { 2889 static const char *const MaskStr[] = { 2890 "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)", 2891 "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)" 2892 }; 2893 assert((ITMask.Mask & 0xf) == ITMask.Mask); 2894 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 2895 break; 2896 } 2897 case k_CoprocNum: 2898 OS << "<coprocessor number: " << getCoproc() << ">"; 2899 break; 2900 case k_CoprocReg: 2901 OS << "<coprocessor register: " << getCoproc() << ">"; 2902 break; 2903 case k_CoprocOption: 2904 OS << "<coprocessor option: " << CoprocOption.Val << ">"; 2905 break; 2906 case k_MSRMask: 2907 OS << "<mask: " << getMSRMask() << ">"; 2908 break; 2909 case k_BankedReg: 2910 OS << "<banked reg: " << getBankedReg() << ">"; 2911 break; 2912 case k_Immediate: 2913 OS << *getImm(); 2914 break; 2915 case k_MemBarrierOpt: 2916 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">"; 2917 break; 2918 case k_InstSyncBarrierOpt: 2919 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">"; 2920 break; 2921 case k_Memory: 2922 OS << "<memory " 2923 << " base:" << Memory.BaseRegNum; 2924 OS << ">"; 2925 break; 2926 case k_PostIndexRegister: 2927 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 2928 << PostIdxReg.RegNum; 2929 if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 2930 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 2931 << PostIdxReg.ShiftImm; 2932 OS << ">"; 2933 break; 2934 case k_ProcIFlags: { 2935 OS << "<ARM_PROC::"; 2936 unsigned IFlags = getProcIFlags(); 2937 for (int i=2; i >= 0; --i) 2938 if (IFlags & (1 << i)) 2939 OS << ARM_PROC::IFlagsToString(1 << i); 2940 OS << ">"; 2941 break; 2942 } 2943 case k_Register: 2944 OS << "<register " << getReg() << ">"; 2945 break; 2946 case k_ShifterImmediate: 2947 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 2948 << " #" << ShifterImm.Imm << ">"; 2949 break; 2950 case k_ShiftedRegister: 2951 OS << "<so_reg_reg " 2952 << RegShiftedReg.SrcReg << " " 2953 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) 2954 << " " << RegShiftedReg.ShiftReg << ">"; 2955 break; 2956 case k_ShiftedImmediate: 2957 OS << "<so_reg_imm " 2958 << RegShiftedImm.SrcReg << " " 2959 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) 2960 << " #" << RegShiftedImm.ShiftImm << ">"; 2961 break; 2962 case k_RotateImmediate: 2963 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 2964 break; 2965 case k_ModifiedImmediate: 2966 OS << "<mod_imm #" << ModImm.Bits << ", #" 2967 << ModImm.Rot << ")>"; 2968 break; 2969 case k_ConstantPoolImmediate: 2970 OS << "<constant_pool_imm #" << *getConstantPoolImm(); 2971 break; 2972 case k_BitfieldDescriptor: 2973 OS << "<bitfield " << "lsb: " << Bitfield.LSB 2974 << ", width: " << Bitfield.Width << ">"; 2975 break; 2976 case k_RegisterList: 2977 case k_DPRRegisterList: 2978 case k_SPRRegisterList: { 2979 OS << "<register_list "; 2980 2981 const SmallVectorImpl<unsigned> &RegList = getRegList(); 2982 for (SmallVectorImpl<unsigned>::const_iterator 2983 I = RegList.begin(), E = RegList.end(); I != E; ) { 2984 OS << *I; 2985 if (++I < E) OS << ", "; 2986 } 2987 2988 OS << ">"; 2989 break; 2990 } 2991 case k_VectorList: 2992 OS << "<vector_list " << VectorList.Count << " * " 2993 << VectorList.RegNum << ">"; 2994 break; 2995 case k_VectorListAllLanes: 2996 OS << "<vector_list(all lanes) " << VectorList.Count << " * " 2997 << VectorList.RegNum << ">"; 2998 break; 2999 case k_VectorListIndexed: 3000 OS << "<vector_list(lane " << VectorList.LaneIndex << ") " 3001 << VectorList.Count << " * " << VectorList.RegNum << ">"; 3002 break; 3003 case k_Token: 3004 OS << "'" << getToken() << "'"; 3005 break; 3006 case k_VectorIndex: 3007 OS << "<vectorindex " << getVectorIndex() << ">"; 3008 break; 3009 } 3010 } 3011 3012 /// @name Auto-generated Match Functions 3013 /// { 3014 3015 static unsigned MatchRegisterName(StringRef Name); 3016 3017 /// } 3018 3019 bool ARMAsmParser::ParseRegister(unsigned &RegNo, 3020 SMLoc &StartLoc, SMLoc &EndLoc) { 3021 const AsmToken &Tok = getParser().getTok(); 3022 StartLoc = Tok.getLoc(); 3023 EndLoc = Tok.getEndLoc(); 3024 RegNo = tryParseRegister(); 3025 3026 return (RegNo == (unsigned)-1); 3027 } 3028 3029 /// Try to parse a register name. The token must be an Identifier when called, 3030 /// and if it is a register name the token is eaten and the register number is 3031 /// returned. Otherwise return -1. 3032 /// 3033 int ARMAsmParser::tryParseRegister() { 3034 MCAsmParser &Parser = getParser(); 3035 const AsmToken &Tok = Parser.getTok(); 3036 if (Tok.isNot(AsmToken::Identifier)) return -1; 3037 3038 std::string lowerCase = Tok.getString().lower(); 3039 unsigned RegNum = MatchRegisterName(lowerCase); 3040 if (!RegNum) { 3041 RegNum = StringSwitch<unsigned>(lowerCase) 3042 .Case("r13", ARM::SP) 3043 .Case("r14", ARM::LR) 3044 .Case("r15", ARM::PC) 3045 .Case("ip", ARM::R12) 3046 // Additional register name aliases for 'gas' compatibility. 3047 .Case("a1", ARM::R0) 3048 .Case("a2", ARM::R1) 3049 .Case("a3", ARM::R2) 3050 .Case("a4", ARM::R3) 3051 .Case("v1", ARM::R4) 3052 .Case("v2", ARM::R5) 3053 .Case("v3", ARM::R6) 3054 .Case("v4", ARM::R7) 3055 .Case("v5", ARM::R8) 3056 .Case("v6", ARM::R9) 3057 .Case("v7", ARM::R10) 3058 .Case("v8", ARM::R11) 3059 .Case("sb", ARM::R9) 3060 .Case("sl", ARM::R10) 3061 .Case("fp", ARM::R11) 3062 .Default(0); 3063 } 3064 if (!RegNum) { 3065 // Check for aliases registered via .req. Canonicalize to lower case. 3066 // That's more consistent since register names are case insensitive, and 3067 // it's how the original entry was passed in from MC/MCParser/AsmParser. 3068 StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase); 3069 // If no match, return failure. 3070 if (Entry == RegisterReqs.end()) 3071 return -1; 3072 Parser.Lex(); // Eat identifier token. 3073 return Entry->getValue(); 3074 } 3075 3076 // Some FPUs only have 16 D registers, so D16-D31 are invalid 3077 if (hasD16() && RegNum >= ARM::D16 && RegNum <= ARM::D31) 3078 return -1; 3079 3080 Parser.Lex(); // Eat identifier token. 3081 3082 return RegNum; 3083 } 3084 3085 // Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 3086 // If a recoverable error occurs, return 1. If an irrecoverable error 3087 // occurs, return -1. An irrecoverable error is one where tokens have been 3088 // consumed in the process of trying to parse the shifter (i.e., when it is 3089 // indeed a shifter operand, but malformed). 3090 int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) { 3091 MCAsmParser &Parser = getParser(); 3092 SMLoc S = Parser.getTok().getLoc(); 3093 const AsmToken &Tok = Parser.getTok(); 3094 if (Tok.isNot(AsmToken::Identifier)) 3095 return -1; 3096 3097 std::string lowerCase = Tok.getString().lower(); 3098 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 3099 .Case("asl", ARM_AM::lsl) 3100 .Case("lsl", ARM_AM::lsl) 3101 .Case("lsr", ARM_AM::lsr) 3102 .Case("asr", ARM_AM::asr) 3103 .Case("ror", ARM_AM::ror) 3104 .Case("rrx", ARM_AM::rrx) 3105 .Default(ARM_AM::no_shift); 3106 3107 if (ShiftTy == ARM_AM::no_shift) 3108 return 1; 3109 3110 Parser.Lex(); // Eat the operator. 3111 3112 // The source register for the shift has already been added to the 3113 // operand list, so we need to pop it off and combine it into the shifted 3114 // register operand instead. 3115 std::unique_ptr<ARMOperand> PrevOp( 3116 (ARMOperand *)Operands.pop_back_val().release()); 3117 if (!PrevOp->isReg()) 3118 return Error(PrevOp->getStartLoc(), "shift must be of a register"); 3119 int SrcReg = PrevOp->getReg(); 3120 3121 SMLoc EndLoc; 3122 int64_t Imm = 0; 3123 int ShiftReg = 0; 3124 if (ShiftTy == ARM_AM::rrx) { 3125 // RRX Doesn't have an explicit shift amount. The encoder expects 3126 // the shift register to be the same as the source register. Seems odd, 3127 // but OK. 3128 ShiftReg = SrcReg; 3129 } else { 3130 // Figure out if this is shifted by a constant or a register (for non-RRX). 3131 if (Parser.getTok().is(AsmToken::Hash) || 3132 Parser.getTok().is(AsmToken::Dollar)) { 3133 Parser.Lex(); // Eat hash. 3134 SMLoc ImmLoc = Parser.getTok().getLoc(); 3135 const MCExpr *ShiftExpr = nullptr; 3136 if (getParser().parseExpression(ShiftExpr, EndLoc)) { 3137 Error(ImmLoc, "invalid immediate shift value"); 3138 return -1; 3139 } 3140 // The expression must be evaluatable as an immediate. 3141 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 3142 if (!CE) { 3143 Error(ImmLoc, "invalid immediate shift value"); 3144 return -1; 3145 } 3146 // Range check the immediate. 3147 // lsl, ror: 0 <= imm <= 31 3148 // lsr, asr: 0 <= imm <= 32 3149 Imm = CE->getValue(); 3150 if (Imm < 0 || 3151 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 3152 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 3153 Error(ImmLoc, "immediate shift value out of range"); 3154 return -1; 3155 } 3156 // shift by zero is a nop. Always send it through as lsl. 3157 // ('as' compatibility) 3158 if (Imm == 0) 3159 ShiftTy = ARM_AM::lsl; 3160 } else if (Parser.getTok().is(AsmToken::Identifier)) { 3161 SMLoc L = Parser.getTok().getLoc(); 3162 EndLoc = Parser.getTok().getEndLoc(); 3163 ShiftReg = tryParseRegister(); 3164 if (ShiftReg == -1) { 3165 Error(L, "expected immediate or register in shift operand"); 3166 return -1; 3167 } 3168 } else { 3169 Error(Parser.getTok().getLoc(), 3170 "expected immediate or register in shift operand"); 3171 return -1; 3172 } 3173 } 3174 3175 if (ShiftReg && ShiftTy != ARM_AM::rrx) 3176 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 3177 ShiftReg, Imm, 3178 S, EndLoc)); 3179 else 3180 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 3181 S, EndLoc)); 3182 3183 return 0; 3184 } 3185 3186 3187 /// Try to parse a register name. The token must be an Identifier when called. 3188 /// If it's a register, an AsmOperand is created. Another AsmOperand is created 3189 /// if there is a "writeback". 'true' if it's not a register. 3190 /// 3191 /// TODO this is likely to change to allow different register types and or to 3192 /// parse for a specific register type. 3193 bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) { 3194 MCAsmParser &Parser = getParser(); 3195 const AsmToken &RegTok = Parser.getTok(); 3196 int RegNo = tryParseRegister(); 3197 if (RegNo == -1) 3198 return true; 3199 3200 Operands.push_back(ARMOperand::CreateReg(RegNo, RegTok.getLoc(), 3201 RegTok.getEndLoc())); 3202 3203 const AsmToken &ExclaimTok = Parser.getTok(); 3204 if (ExclaimTok.is(AsmToken::Exclaim)) { 3205 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 3206 ExclaimTok.getLoc())); 3207 Parser.Lex(); // Eat exclaim token 3208 return false; 3209 } 3210 3211 // Also check for an index operand. This is only legal for vector registers, 3212 // but that'll get caught OK in operand matching, so we don't need to 3213 // explicitly filter everything else out here. 3214 if (Parser.getTok().is(AsmToken::LBrac)) { 3215 SMLoc SIdx = Parser.getTok().getLoc(); 3216 Parser.Lex(); // Eat left bracket token. 3217 3218 const MCExpr *ImmVal; 3219 if (getParser().parseExpression(ImmVal)) 3220 return true; 3221 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 3222 if (!MCE) 3223 return TokError("immediate value expected for vector index"); 3224 3225 if (Parser.getTok().isNot(AsmToken::RBrac)) 3226 return Error(Parser.getTok().getLoc(), "']' expected"); 3227 3228 SMLoc E = Parser.getTok().getEndLoc(); 3229 Parser.Lex(); // Eat right bracket token. 3230 3231 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 3232 SIdx, E, 3233 getContext())); 3234 } 3235 3236 return false; 3237 } 3238 3239 /// MatchCoprocessorOperandName - Try to parse an coprocessor related 3240 /// instruction with a symbolic operand name. 3241 /// We accept "crN" syntax for GAS compatibility. 3242 /// <operand-name> ::= <prefix><number> 3243 /// If CoprocOp is 'c', then: 3244 /// <prefix> ::= c | cr 3245 /// If CoprocOp is 'p', then : 3246 /// <prefix> ::= p 3247 /// <number> ::= integer in range [0, 15] 3248 static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 3249 // Use the same layout as the tablegen'erated register name matcher. Ugly, 3250 // but efficient. 3251 if (Name.size() < 2 || Name[0] != CoprocOp) 3252 return -1; 3253 Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front(); 3254 3255 switch (Name.size()) { 3256 default: return -1; 3257 case 1: 3258 switch (Name[0]) { 3259 default: return -1; 3260 case '0': return 0; 3261 case '1': return 1; 3262 case '2': return 2; 3263 case '3': return 3; 3264 case '4': return 4; 3265 case '5': return 5; 3266 case '6': return 6; 3267 case '7': return 7; 3268 case '8': return 8; 3269 case '9': return 9; 3270 } 3271 case 2: 3272 if (Name[0] != '1') 3273 return -1; 3274 switch (Name[1]) { 3275 default: return -1; 3276 // CP10 and CP11 are VFP/NEON and so vector instructions should be used. 3277 // However, old cores (v5/v6) did use them in that way. 3278 case '0': return 10; 3279 case '1': return 11; 3280 case '2': return 12; 3281 case '3': return 13; 3282 case '4': return 14; 3283 case '5': return 15; 3284 } 3285 } 3286 } 3287 3288 /// parseITCondCode - Try to parse a condition code for an IT instruction. 3289 ARMAsmParser::OperandMatchResultTy 3290 ARMAsmParser::parseITCondCode(OperandVector &Operands) { 3291 MCAsmParser &Parser = getParser(); 3292 SMLoc S = Parser.getTok().getLoc(); 3293 const AsmToken &Tok = Parser.getTok(); 3294 if (!Tok.is(AsmToken::Identifier)) 3295 return MatchOperand_NoMatch; 3296 unsigned CC = StringSwitch<unsigned>(Tok.getString().lower()) 3297 .Case("eq", ARMCC::EQ) 3298 .Case("ne", ARMCC::NE) 3299 .Case("hs", ARMCC::HS) 3300 .Case("cs", ARMCC::HS) 3301 .Case("lo", ARMCC::LO) 3302 .Case("cc", ARMCC::LO) 3303 .Case("mi", ARMCC::MI) 3304 .Case("pl", ARMCC::PL) 3305 .Case("vs", ARMCC::VS) 3306 .Case("vc", ARMCC::VC) 3307 .Case("hi", ARMCC::HI) 3308 .Case("ls", ARMCC::LS) 3309 .Case("ge", ARMCC::GE) 3310 .Case("lt", ARMCC::LT) 3311 .Case("gt", ARMCC::GT) 3312 .Case("le", ARMCC::LE) 3313 .Case("al", ARMCC::AL) 3314 .Default(~0U); 3315 if (CC == ~0U) 3316 return MatchOperand_NoMatch; 3317 Parser.Lex(); // Eat the token. 3318 3319 Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 3320 3321 return MatchOperand_Success; 3322 } 3323 3324 /// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 3325 /// token must be an Identifier when called, and if it is a coprocessor 3326 /// number, the token is eaten and the operand is added to the operand list. 3327 ARMAsmParser::OperandMatchResultTy 3328 ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) { 3329 MCAsmParser &Parser = getParser(); 3330 SMLoc S = Parser.getTok().getLoc(); 3331 const AsmToken &Tok = Parser.getTok(); 3332 if (Tok.isNot(AsmToken::Identifier)) 3333 return MatchOperand_NoMatch; 3334 3335 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 3336 if (Num == -1) 3337 return MatchOperand_NoMatch; 3338 // ARMv7 and v8 don't allow cp10/cp11 due to VFP/NEON specific instructions 3339 if ((hasV7Ops() || hasV8Ops()) && (Num == 10 || Num == 11)) 3340 return MatchOperand_NoMatch; 3341 3342 Parser.Lex(); // Eat identifier token. 3343 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 3344 return MatchOperand_Success; 3345 } 3346 3347 /// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 3348 /// token must be an Identifier when called, and if it is a coprocessor 3349 /// number, the token is eaten and the operand is added to the operand list. 3350 ARMAsmParser::OperandMatchResultTy 3351 ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) { 3352 MCAsmParser &Parser = getParser(); 3353 SMLoc S = Parser.getTok().getLoc(); 3354 const AsmToken &Tok = Parser.getTok(); 3355 if (Tok.isNot(AsmToken::Identifier)) 3356 return MatchOperand_NoMatch; 3357 3358 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 3359 if (Reg == -1) 3360 return MatchOperand_NoMatch; 3361 3362 Parser.Lex(); // Eat identifier token. 3363 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 3364 return MatchOperand_Success; 3365 } 3366 3367 /// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 3368 /// coproc_option : '{' imm0_255 '}' 3369 ARMAsmParser::OperandMatchResultTy 3370 ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) { 3371 MCAsmParser &Parser = getParser(); 3372 SMLoc S = Parser.getTok().getLoc(); 3373 3374 // If this isn't a '{', this isn't a coprocessor immediate operand. 3375 if (Parser.getTok().isNot(AsmToken::LCurly)) 3376 return MatchOperand_NoMatch; 3377 Parser.Lex(); // Eat the '{' 3378 3379 const MCExpr *Expr; 3380 SMLoc Loc = Parser.getTok().getLoc(); 3381 if (getParser().parseExpression(Expr)) { 3382 Error(Loc, "illegal expression"); 3383 return MatchOperand_ParseFail; 3384 } 3385 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 3386 if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 3387 Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 3388 return MatchOperand_ParseFail; 3389 } 3390 int Val = CE->getValue(); 3391 3392 // Check for and consume the closing '}' 3393 if (Parser.getTok().isNot(AsmToken::RCurly)) 3394 return MatchOperand_ParseFail; 3395 SMLoc E = Parser.getTok().getEndLoc(); 3396 Parser.Lex(); // Eat the '}' 3397 3398 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 3399 return MatchOperand_Success; 3400 } 3401 3402 // For register list parsing, we need to map from raw GPR register numbering 3403 // to the enumeration values. The enumeration values aren't sorted by 3404 // register number due to our using "sp", "lr" and "pc" as canonical names. 3405 static unsigned getNextRegister(unsigned Reg) { 3406 // If this is a GPR, we need to do it manually, otherwise we can rely 3407 // on the sort ordering of the enumeration since the other reg-classes 3408 // are sane. 3409 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 3410 return Reg + 1; 3411 switch(Reg) { 3412 default: llvm_unreachable("Invalid GPR number!"); 3413 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 3414 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 3415 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 3416 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 3417 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 3418 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 3419 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 3420 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 3421 } 3422 } 3423 3424 // Return the low-subreg of a given Q register. 3425 static unsigned getDRegFromQReg(unsigned QReg) { 3426 switch (QReg) { 3427 default: llvm_unreachable("expected a Q register!"); 3428 case ARM::Q0: return ARM::D0; 3429 case ARM::Q1: return ARM::D2; 3430 case ARM::Q2: return ARM::D4; 3431 case ARM::Q3: return ARM::D6; 3432 case ARM::Q4: return ARM::D8; 3433 case ARM::Q5: return ARM::D10; 3434 case ARM::Q6: return ARM::D12; 3435 case ARM::Q7: return ARM::D14; 3436 case ARM::Q8: return ARM::D16; 3437 case ARM::Q9: return ARM::D18; 3438 case ARM::Q10: return ARM::D20; 3439 case ARM::Q11: return ARM::D22; 3440 case ARM::Q12: return ARM::D24; 3441 case ARM::Q13: return ARM::D26; 3442 case ARM::Q14: return ARM::D28; 3443 case ARM::Q15: return ARM::D30; 3444 } 3445 } 3446 3447 /// Parse a register list. 3448 bool ARMAsmParser::parseRegisterList(OperandVector &Operands) { 3449 MCAsmParser &Parser = getParser(); 3450 assert(Parser.getTok().is(AsmToken::LCurly) && 3451 "Token is not a Left Curly Brace"); 3452 SMLoc S = Parser.getTok().getLoc(); 3453 Parser.Lex(); // Eat '{' token. 3454 SMLoc RegLoc = Parser.getTok().getLoc(); 3455 3456 // Check the first register in the list to see what register class 3457 // this is a list of. 3458 int Reg = tryParseRegister(); 3459 if (Reg == -1) 3460 return Error(RegLoc, "register expected"); 3461 3462 // The reglist instructions have at most 16 registers, so reserve 3463 // space for that many. 3464 int EReg = 0; 3465 SmallVector<std::pair<unsigned, unsigned>, 16> Registers; 3466 3467 // Allow Q regs and just interpret them as the two D sub-registers. 3468 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3469 Reg = getDRegFromQReg(Reg); 3470 EReg = MRI->getEncodingValue(Reg); 3471 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3472 ++Reg; 3473 } 3474 const MCRegisterClass *RC; 3475 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 3476 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 3477 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 3478 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 3479 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 3480 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 3481 else 3482 return Error(RegLoc, "invalid register in register list"); 3483 3484 // Store the register. 3485 EReg = MRI->getEncodingValue(Reg); 3486 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3487 3488 // This starts immediately after the first register token in the list, 3489 // so we can see either a comma or a minus (range separator) as a legal 3490 // next token. 3491 while (Parser.getTok().is(AsmToken::Comma) || 3492 Parser.getTok().is(AsmToken::Minus)) { 3493 if (Parser.getTok().is(AsmToken::Minus)) { 3494 Parser.Lex(); // Eat the minus. 3495 SMLoc AfterMinusLoc = Parser.getTok().getLoc(); 3496 int EndReg = tryParseRegister(); 3497 if (EndReg == -1) 3498 return Error(AfterMinusLoc, "register expected"); 3499 // Allow Q regs and just interpret them as the two D sub-registers. 3500 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 3501 EndReg = getDRegFromQReg(EndReg) + 1; 3502 // If the register is the same as the start reg, there's nothing 3503 // more to do. 3504 if (Reg == EndReg) 3505 continue; 3506 // The register must be in the same register class as the first. 3507 if (!RC->contains(EndReg)) 3508 return Error(AfterMinusLoc, "invalid register in register list"); 3509 // Ranges must go from low to high. 3510 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg)) 3511 return Error(AfterMinusLoc, "bad range in register list"); 3512 3513 // Add all the registers in the range to the register list. 3514 while (Reg != EndReg) { 3515 Reg = getNextRegister(Reg); 3516 EReg = MRI->getEncodingValue(Reg); 3517 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3518 } 3519 continue; 3520 } 3521 Parser.Lex(); // Eat the comma. 3522 RegLoc = Parser.getTok().getLoc(); 3523 int OldReg = Reg; 3524 const AsmToken RegTok = Parser.getTok(); 3525 Reg = tryParseRegister(); 3526 if (Reg == -1) 3527 return Error(RegLoc, "register expected"); 3528 // Allow Q regs and just interpret them as the two D sub-registers. 3529 bool isQReg = false; 3530 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3531 Reg = getDRegFromQReg(Reg); 3532 isQReg = true; 3533 } 3534 // The register must be in the same register class as the first. 3535 if (!RC->contains(Reg)) 3536 return Error(RegLoc, "invalid register in register list"); 3537 // List must be monotonically increasing. 3538 if (MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) { 3539 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 3540 Warning(RegLoc, "register list not in ascending order"); 3541 else 3542 return Error(RegLoc, "register list not in ascending order"); 3543 } 3544 if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) { 3545 Warning(RegLoc, "duplicated register (" + RegTok.getString() + 3546 ") in register list"); 3547 continue; 3548 } 3549 // VFP register lists must also be contiguous. 3550 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 3551 Reg != OldReg + 1) 3552 return Error(RegLoc, "non-contiguous register range"); 3553 EReg = MRI->getEncodingValue(Reg); 3554 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3555 if (isQReg) { 3556 EReg = MRI->getEncodingValue(++Reg); 3557 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3558 } 3559 } 3560 3561 if (Parser.getTok().isNot(AsmToken::RCurly)) 3562 return Error(Parser.getTok().getLoc(), "'}' expected"); 3563 SMLoc E = Parser.getTok().getEndLoc(); 3564 Parser.Lex(); // Eat '}' token. 3565 3566 // Push the register list operand. 3567 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 3568 3569 // The ARM system instruction variants for LDM/STM have a '^' token here. 3570 if (Parser.getTok().is(AsmToken::Caret)) { 3571 Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc())); 3572 Parser.Lex(); // Eat '^' token. 3573 } 3574 3575 return false; 3576 } 3577 3578 // Helper function to parse the lane index for vector lists. 3579 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3580 parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, SMLoc &EndLoc) { 3581 MCAsmParser &Parser = getParser(); 3582 Index = 0; // Always return a defined index value. 3583 if (Parser.getTok().is(AsmToken::LBrac)) { 3584 Parser.Lex(); // Eat the '['. 3585 if (Parser.getTok().is(AsmToken::RBrac)) { 3586 // "Dn[]" is the 'all lanes' syntax. 3587 LaneKind = AllLanes; 3588 EndLoc = Parser.getTok().getEndLoc(); 3589 Parser.Lex(); // Eat the ']'. 3590 return MatchOperand_Success; 3591 } 3592 3593 // There's an optional '#' token here. Normally there wouldn't be, but 3594 // inline assemble puts one in, and it's friendly to accept that. 3595 if (Parser.getTok().is(AsmToken::Hash)) 3596 Parser.Lex(); // Eat '#' or '$'. 3597 3598 const MCExpr *LaneIndex; 3599 SMLoc Loc = Parser.getTok().getLoc(); 3600 if (getParser().parseExpression(LaneIndex)) { 3601 Error(Loc, "illegal expression"); 3602 return MatchOperand_ParseFail; 3603 } 3604 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex); 3605 if (!CE) { 3606 Error(Loc, "lane index must be empty or an integer"); 3607 return MatchOperand_ParseFail; 3608 } 3609 if (Parser.getTok().isNot(AsmToken::RBrac)) { 3610 Error(Parser.getTok().getLoc(), "']' expected"); 3611 return MatchOperand_ParseFail; 3612 } 3613 EndLoc = Parser.getTok().getEndLoc(); 3614 Parser.Lex(); // Eat the ']'. 3615 int64_t Val = CE->getValue(); 3616 3617 // FIXME: Make this range check context sensitive for .8, .16, .32. 3618 if (Val < 0 || Val > 7) { 3619 Error(Parser.getTok().getLoc(), "lane index out of range"); 3620 return MatchOperand_ParseFail; 3621 } 3622 Index = Val; 3623 LaneKind = IndexedLane; 3624 return MatchOperand_Success; 3625 } 3626 LaneKind = NoLanes; 3627 return MatchOperand_Success; 3628 } 3629 3630 // parse a vector register list 3631 ARMAsmParser::OperandMatchResultTy 3632 ARMAsmParser::parseVectorList(OperandVector &Operands) { 3633 MCAsmParser &Parser = getParser(); 3634 VectorLaneTy LaneKind; 3635 unsigned LaneIndex; 3636 SMLoc S = Parser.getTok().getLoc(); 3637 // As an extension (to match gas), support a plain D register or Q register 3638 // (without encosing curly braces) as a single or double entry list, 3639 // respectively. 3640 if (Parser.getTok().is(AsmToken::Identifier)) { 3641 SMLoc E = Parser.getTok().getEndLoc(); 3642 int Reg = tryParseRegister(); 3643 if (Reg == -1) 3644 return MatchOperand_NoMatch; 3645 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) { 3646 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E); 3647 if (Res != MatchOperand_Success) 3648 return Res; 3649 switch (LaneKind) { 3650 case NoLanes: 3651 Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E)); 3652 break; 3653 case AllLanes: 3654 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false, 3655 S, E)); 3656 break; 3657 case IndexedLane: 3658 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1, 3659 LaneIndex, 3660 false, S, E)); 3661 break; 3662 } 3663 return MatchOperand_Success; 3664 } 3665 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3666 Reg = getDRegFromQReg(Reg); 3667 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E); 3668 if (Res != MatchOperand_Success) 3669 return Res; 3670 switch (LaneKind) { 3671 case NoLanes: 3672 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0, 3673 &ARMMCRegisterClasses[ARM::DPairRegClassID]); 3674 Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E)); 3675 break; 3676 case AllLanes: 3677 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0, 3678 &ARMMCRegisterClasses[ARM::DPairRegClassID]); 3679 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false, 3680 S, E)); 3681 break; 3682 case IndexedLane: 3683 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2, 3684 LaneIndex, 3685 false, S, E)); 3686 break; 3687 } 3688 return MatchOperand_Success; 3689 } 3690 Error(S, "vector register expected"); 3691 return MatchOperand_ParseFail; 3692 } 3693 3694 if (Parser.getTok().isNot(AsmToken::LCurly)) 3695 return MatchOperand_NoMatch; 3696 3697 Parser.Lex(); // Eat '{' token. 3698 SMLoc RegLoc = Parser.getTok().getLoc(); 3699 3700 int Reg = tryParseRegister(); 3701 if (Reg == -1) { 3702 Error(RegLoc, "register expected"); 3703 return MatchOperand_ParseFail; 3704 } 3705 unsigned Count = 1; 3706 int Spacing = 0; 3707 unsigned FirstReg = Reg; 3708 // The list is of D registers, but we also allow Q regs and just interpret 3709 // them as the two D sub-registers. 3710 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3711 FirstReg = Reg = getDRegFromQReg(Reg); 3712 Spacing = 1; // double-spacing requires explicit D registers, otherwise 3713 // it's ambiguous with four-register single spaced. 3714 ++Reg; 3715 ++Count; 3716 } 3717 3718 SMLoc E; 3719 if (parseVectorLane(LaneKind, LaneIndex, E) != MatchOperand_Success) 3720 return MatchOperand_ParseFail; 3721 3722 while (Parser.getTok().is(AsmToken::Comma) || 3723 Parser.getTok().is(AsmToken::Minus)) { 3724 if (Parser.getTok().is(AsmToken::Minus)) { 3725 if (!Spacing) 3726 Spacing = 1; // Register range implies a single spaced list. 3727 else if (Spacing == 2) { 3728 Error(Parser.getTok().getLoc(), 3729 "sequential registers in double spaced list"); 3730 return MatchOperand_ParseFail; 3731 } 3732 Parser.Lex(); // Eat the minus. 3733 SMLoc AfterMinusLoc = Parser.getTok().getLoc(); 3734 int EndReg = tryParseRegister(); 3735 if (EndReg == -1) { 3736 Error(AfterMinusLoc, "register expected"); 3737 return MatchOperand_ParseFail; 3738 } 3739 // Allow Q regs and just interpret them as the two D sub-registers. 3740 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 3741 EndReg = getDRegFromQReg(EndReg) + 1; 3742 // If the register is the same as the start reg, there's nothing 3743 // more to do. 3744 if (Reg == EndReg) 3745 continue; 3746 // The register must be in the same register class as the first. 3747 if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) { 3748 Error(AfterMinusLoc, "invalid register in register list"); 3749 return MatchOperand_ParseFail; 3750 } 3751 // Ranges must go from low to high. 3752 if (Reg > EndReg) { 3753 Error(AfterMinusLoc, "bad range in register list"); 3754 return MatchOperand_ParseFail; 3755 } 3756 // Parse the lane specifier if present. 3757 VectorLaneTy NextLaneKind; 3758 unsigned NextLaneIndex; 3759 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != 3760 MatchOperand_Success) 3761 return MatchOperand_ParseFail; 3762 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 3763 Error(AfterMinusLoc, "mismatched lane index in register list"); 3764 return MatchOperand_ParseFail; 3765 } 3766 3767 // Add all the registers in the range to the register list. 3768 Count += EndReg - Reg; 3769 Reg = EndReg; 3770 continue; 3771 } 3772 Parser.Lex(); // Eat the comma. 3773 RegLoc = Parser.getTok().getLoc(); 3774 int OldReg = Reg; 3775 Reg = tryParseRegister(); 3776 if (Reg == -1) { 3777 Error(RegLoc, "register expected"); 3778 return MatchOperand_ParseFail; 3779 } 3780 // vector register lists must be contiguous. 3781 // It's OK to use the enumeration values directly here rather, as the 3782 // VFP register classes have the enum sorted properly. 3783 // 3784 // The list is of D registers, but we also allow Q regs and just interpret 3785 // them as the two D sub-registers. 3786 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3787 if (!Spacing) 3788 Spacing = 1; // Register range implies a single spaced list. 3789 else if (Spacing == 2) { 3790 Error(RegLoc, 3791 "invalid register in double-spaced list (must be 'D' register')"); 3792 return MatchOperand_ParseFail; 3793 } 3794 Reg = getDRegFromQReg(Reg); 3795 if (Reg != OldReg + 1) { 3796 Error(RegLoc, "non-contiguous register range"); 3797 return MatchOperand_ParseFail; 3798 } 3799 ++Reg; 3800 Count += 2; 3801 // Parse the lane specifier if present. 3802 VectorLaneTy NextLaneKind; 3803 unsigned NextLaneIndex; 3804 SMLoc LaneLoc = Parser.getTok().getLoc(); 3805 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != 3806 MatchOperand_Success) 3807 return MatchOperand_ParseFail; 3808 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 3809 Error(LaneLoc, "mismatched lane index in register list"); 3810 return MatchOperand_ParseFail; 3811 } 3812 continue; 3813 } 3814 // Normal D register.