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 "ARMFPUName.h" 11 #include "ARMFeatures.h" 12 #include "MCTargetDesc/ARMAddressingModes.h" 13 #include "MCTargetDesc/ARMArchName.h" 14 #include "MCTargetDesc/ARMBaseInfo.h" 15 #include "MCTargetDesc/ARMMCExpr.h" 16 #include "llvm/ADT/BitVector.h" 17 #include "llvm/ADT/MapVector.h" 18 #include "llvm/ADT/OwningPtr.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/StringExtras.h" 22 #include "llvm/ADT/StringSwitch.h" 23 #include "llvm/ADT/Twine.h" 24 #include "llvm/MC/MCAsmInfo.h" 25 #include "llvm/MC/MCAssembler.h" 26 #include "llvm/MC/MCContext.h" 27 #include "llvm/MC/MCDisassembler.h" 28 #include "llvm/MC/MCELFStreamer.h" 29 #include "llvm/MC/MCExpr.h" 30 #include "llvm/MC/MCInst.h" 31 #include "llvm/MC/MCInstrDesc.h" 32 #include "llvm/MC/MCInstrInfo.h" 33 #include "llvm/MC/MCParser/MCAsmLexer.h" 34 #include "llvm/MC/MCParser/MCAsmParser.h" 35 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 36 #include "llvm/MC/MCRegisterInfo.h" 37 #include "llvm/MC/MCSection.h" 38 #include "llvm/MC/MCStreamer.h" 39 #include "llvm/MC/MCSubtargetInfo.h" 40 #include "llvm/MC/MCSymbol.h" 41 #include "llvm/MC/MCTargetAsmParser.h" 42 #include "llvm/Support/ARMBuildAttributes.h" 43 #include "llvm/Support/ARMEHABI.h" 44 #include "llvm/Support/Debug.h" 45 #include "llvm/Support/ELF.h" 46 #include "llvm/Support/MathExtras.h" 47 #include "llvm/Support/SourceMgr.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 MCSubtargetInfo &STI; 133 MCAsmParser &Parser; 134 const MCInstrInfo &MII; 135 const MCRegisterInfo *MRI; 136 UnwindContext UC; 137 138 ARMTargetStreamer &getTargetStreamer() { 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 void forwardITPosition() { 169 if (!inITBlock()) return; 170 // Move to the next instruction in the IT block, if there is one. If not, 171 // mark the block as done. 172 unsigned TZ = countTrailingZeros(ITState.Mask); 173 if (++ITState.CurPosition == 5 - TZ) 174 ITState.CurPosition = ~0U; // Done with the IT block after this. 175 } 176 177 178 MCAsmParser &getParser() const { return Parser; } 179 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 180 181 void Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = None) { 182 return Parser.Note(L, Msg, Ranges); 183 } 184 bool Warning(SMLoc L, const Twine &Msg, 185 ArrayRef<SMRange> Ranges = None) { 186 return Parser.Warning(L, Msg, Ranges); 187 } 188 bool Error(SMLoc L, const Twine &Msg, 189 ArrayRef<SMRange> Ranges = None) { 190 return Parser.Error(L, Msg, Ranges); 191 } 192 193 int tryParseRegister(); 194 bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 195 int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 196 bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 197 bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 198 bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 199 bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 200 bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 201 unsigned &ShiftAmount); 202 bool parseDirectiveWord(unsigned Size, SMLoc L); 203 bool parseDirectiveThumb(SMLoc L); 204 bool parseDirectiveARM(SMLoc L); 205 bool parseDirectiveThumbFunc(SMLoc L); 206 bool parseDirectiveCode(SMLoc L); 207 bool parseDirectiveSyntax(SMLoc L); 208 bool parseDirectiveReq(StringRef Name, SMLoc L); 209 bool parseDirectiveUnreq(SMLoc L); 210 bool parseDirectiveArch(SMLoc L); 211 bool parseDirectiveEabiAttr(SMLoc L); 212 bool parseDirectiveCPU(SMLoc L); 213 bool parseDirectiveFPU(SMLoc L); 214 bool parseDirectiveFnStart(SMLoc L); 215 bool parseDirectiveFnEnd(SMLoc L); 216 bool parseDirectiveCantUnwind(SMLoc L); 217 bool parseDirectivePersonality(SMLoc L); 218 bool parseDirectiveHandlerData(SMLoc L); 219 bool parseDirectiveSetFP(SMLoc L); 220 bool parseDirectivePad(SMLoc L); 221 bool parseDirectiveRegSave(SMLoc L, bool IsVector); 222 bool parseDirectiveInst(SMLoc L, char Suffix = '\0'); 223 bool parseDirectiveLtorg(SMLoc L); 224 bool parseDirectiveEven(SMLoc L); 225 bool parseDirectivePersonalityIndex(SMLoc L); 226 bool parseDirectiveUnwindRaw(SMLoc L); 227 bool parseDirectiveTLSDescSeq(SMLoc L); 228 bool parseDirectiveMovSP(SMLoc L); 229 bool parseDirectiveObjectArch(SMLoc L); 230 bool parseDirectiveArchExtension(SMLoc L); 231 232 StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 233 bool &CarrySetting, unsigned &ProcessorIMod, 234 StringRef &ITMask); 235 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst, 236 bool &CanAcceptCarrySet, 237 bool &CanAcceptPredicationCode); 238 239 bool isThumb() const { 240 // FIXME: Can tablegen auto-generate this? 241 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 242 } 243 bool isThumbOne() const { 244 return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 245 } 246 bool isThumbTwo() const { 247 return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 248 } 249 bool hasThumb() const { 250 return STI.getFeatureBits() & ARM::HasV4TOps; 251 } 252 bool hasV6Ops() const { 253 return STI.getFeatureBits() & ARM::HasV6Ops; 254 } 255 bool hasV6MOps() const { 256 return STI.getFeatureBits() & ARM::HasV6MOps; 257 } 258 bool hasV7Ops() const { 259 return STI.getFeatureBits() & ARM::HasV7Ops; 260 } 261 bool hasV8Ops() const { 262 return STI.getFeatureBits() & ARM::HasV8Ops; 263 } 264 bool hasARM() const { 265 return !(STI.getFeatureBits() & ARM::FeatureNoARM); 266 } 267 268 void SwitchMode() { 269 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 270 setAvailableFeatures(FB); 271 } 272 bool isMClass() const { 273 return STI.getFeatureBits() & ARM::FeatureMClass; 274 } 275 276 /// @name Auto-generated Match Functions 277 /// { 278 279 #define GET_ASSEMBLER_HEADER 280 #include "ARMGenAsmMatcher.inc" 281 282 /// } 283 284 OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 285 OperandMatchResultTy parseCoprocNumOperand( 286 SmallVectorImpl<MCParsedAsmOperand*>&); 287 OperandMatchResultTy parseCoprocRegOperand( 288 SmallVectorImpl<MCParsedAsmOperand*>&); 289 OperandMatchResultTy parseCoprocOptionOperand( 290 SmallVectorImpl<MCParsedAsmOperand*>&); 291 OperandMatchResultTy parseMemBarrierOptOperand( 292 SmallVectorImpl<MCParsedAsmOperand*>&); 293 OperandMatchResultTy parseInstSyncBarrierOptOperand( 294 SmallVectorImpl<MCParsedAsmOperand*>&); 295 OperandMatchResultTy parseProcIFlagsOperand( 296 SmallVectorImpl<MCParsedAsmOperand*>&); 297 OperandMatchResultTy parseMSRMaskOperand( 298 SmallVectorImpl<MCParsedAsmOperand*>&); 299 OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 300 StringRef Op, int Low, int High); 301 OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 302 return parsePKHImm(O, "lsl", 0, 31); 303 } 304 OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 305 return parsePKHImm(O, "asr", 1, 32); 306 } 307 OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 308 OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 309 OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 310 OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 311 OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 312 OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 313 OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 314 OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&); 315 OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, 316 SMLoc &EndLoc); 317 318 // Asm Match Converter Methods 319 void cvtThumbMultiply(MCInst &Inst, 320 const SmallVectorImpl<MCParsedAsmOperand*> &); 321 void cvtThumbBranches(MCInst &Inst, 322 const SmallVectorImpl<MCParsedAsmOperand*> &); 323 324 bool validateInstruction(MCInst &Inst, 325 const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 326 bool processInstruction(MCInst &Inst, 327 const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 328 bool shouldOmitCCOutOperand(StringRef Mnemonic, 329 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 330 bool shouldOmitPredicateOperand(StringRef Mnemonic, 331 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 332 public: 333 enum ARMMatchResultTy { 334 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 335 Match_RequiresNotITBlock, 336 Match_RequiresV6, 337 Match_RequiresThumb2, 338 #define GET_OPERAND_DIAGNOSTIC_TYPES 339 #include "ARMGenAsmMatcher.inc" 340 341 }; 342 343 ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser, 344 const MCInstrInfo &MII) 345 : MCTargetAsmParser(), STI(_STI), Parser(_Parser), MII(MII), UC(_Parser) { 346 MCAsmParserExtension::Initialize(_Parser); 347 348 // Cache the MCRegisterInfo. 349 MRI = getContext().getRegisterInfo(); 350 351 // Initialize the set of available features. 352 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 353 354 // Not in an ITBlock to start with. 355 ITState.CurPosition = ~0U; 356 357 NextSymbolIsThumb = false; 358 } 359 360 // Implementation of the MCTargetAsmParser interface: 361 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 362 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 363 SMLoc NameLoc, 364 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 365 bool ParseDirective(AsmToken DirectiveID); 366 367 unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, unsigned Kind); 368 unsigned checkTargetMatchPredicate(MCInst &Inst); 369 370 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 371 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 372 MCStreamer &Out, unsigned &ErrorInfo, 373 bool MatchingInlineAsm); 374 void onLabelParsed(MCSymbol *Symbol); 375 }; 376 } // end anonymous namespace 377 378 namespace { 379 380 /// ARMOperand - Instances of this class represent a parsed ARM machine 381 /// operand. 382 class ARMOperand : public MCParsedAsmOperand { 383 enum KindTy { 384 k_CondCode, 385 k_CCOut, 386 k_ITCondMask, 387 k_CoprocNum, 388 k_CoprocReg, 389 k_CoprocOption, 390 k_Immediate, 391 k_MemBarrierOpt, 392 k_InstSyncBarrierOpt, 393 k_Memory, 394 k_PostIndexRegister, 395 k_MSRMask, 396 k_ProcIFlags, 397 k_VectorIndex, 398 k_Register, 399 k_RegisterList, 400 k_DPRRegisterList, 401 k_SPRRegisterList, 402 k_VectorList, 403 k_VectorListAllLanes, 404 k_VectorListIndexed, 405 k_ShiftedRegister, 406 k_ShiftedImmediate, 407 k_ShifterImmediate, 408 k_RotateImmediate, 409 k_BitfieldDescriptor, 410 k_Token 411 } Kind; 412 413 SMLoc StartLoc, EndLoc; 414 SmallVector<unsigned, 8> Registers; 415 416 struct CCOp { 417 ARMCC::CondCodes Val; 418 }; 419 420 struct CopOp { 421 unsigned Val; 422 }; 423 424 struct CoprocOptionOp { 425 unsigned Val; 426 }; 427 428 struct ITMaskOp { 429 unsigned Mask:4; 430 }; 431 432 struct MBOptOp { 433 ARM_MB::MemBOpt Val; 434 }; 435 436 struct ISBOptOp { 437 ARM_ISB::InstSyncBOpt Val; 438 }; 439 440 struct IFlagsOp { 441 ARM_PROC::IFlags Val; 442 }; 443 444 struct MMaskOp { 445 unsigned Val; 446 }; 447 448 struct TokOp { 449 const char *Data; 450 unsigned Length; 451 }; 452 453 struct RegOp { 454 unsigned RegNum; 455 }; 456 457 // A vector register list is a sequential list of 1 to 4 registers. 458 struct VectorListOp { 459 unsigned RegNum; 460 unsigned Count; 461 unsigned LaneIndex; 462 bool isDoubleSpaced; 463 }; 464 465 struct VectorIndexOp { 466 unsigned Val; 467 }; 468 469 struct ImmOp { 470 const MCExpr *Val; 471 }; 472 473 /// Combined record for all forms of ARM address expressions. 474 struct MemoryOp { 475 unsigned BaseRegNum; 476 // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 477 // was specified. 478 const MCConstantExpr *OffsetImm; // Offset immediate value 479 unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 480 ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 481 unsigned ShiftImm; // shift for OffsetReg. 482 unsigned Alignment; // 0 = no alignment specified 483 // n = alignment in bytes (2, 4, 8, 16, or 32) 484 unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 485 }; 486 487 struct PostIdxRegOp { 488 unsigned RegNum; 489 bool isAdd; 490 ARM_AM::ShiftOpc ShiftTy; 491 unsigned ShiftImm; 492 }; 493 494 struct ShifterImmOp { 495 bool isASR; 496 unsigned Imm; 497 }; 498 499 struct RegShiftedRegOp { 500 ARM_AM::ShiftOpc ShiftTy; 501 unsigned SrcReg; 502 unsigned ShiftReg; 503 unsigned ShiftImm; 504 }; 505 506 struct RegShiftedImmOp { 507 ARM_AM::ShiftOpc ShiftTy; 508 unsigned SrcReg; 509 unsigned ShiftImm; 510 }; 511 512 struct RotImmOp { 513 unsigned Imm; 514 }; 515 516 struct BitfieldOp { 517 unsigned LSB; 518 unsigned Width; 519 }; 520 521 union { 522 struct CCOp CC; 523 struct CopOp Cop; 524 struct CoprocOptionOp CoprocOption; 525 struct MBOptOp MBOpt; 526 struct ISBOptOp ISBOpt; 527 struct ITMaskOp ITMask; 528 struct IFlagsOp IFlags; 529 struct MMaskOp MMask; 530 struct TokOp Tok; 531 struct RegOp Reg; 532 struct VectorListOp VectorList; 533 struct VectorIndexOp VectorIndex; 534 struct ImmOp Imm; 535 struct MemoryOp Memory; 536 struct PostIdxRegOp PostIdxReg; 537 struct ShifterImmOp ShifterImm; 538 struct RegShiftedRegOp RegShiftedReg; 539 struct RegShiftedImmOp RegShiftedImm; 540 struct RotImmOp RotImm; 541 struct BitfieldOp Bitfield; 542 }; 543 544 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 545 public: 546 ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 547 Kind = o.Kind; 548 StartLoc = o.StartLoc; 549 EndLoc = o.EndLoc; 550 switch (Kind) { 551 case k_CondCode: 552 CC = o.CC; 553 break; 554 case k_ITCondMask: 555 ITMask = o.ITMask; 556 break; 557 case k_Token: 558 Tok = o.Tok; 559 break; 560 case k_CCOut: 561 case k_Register: 562 Reg = o.Reg; 563 break; 564 case k_RegisterList: 565 case k_DPRRegisterList: 566 case k_SPRRegisterList: 567 Registers = o.Registers; 568 break; 569 case k_VectorList: 570 case k_VectorListAllLanes: 571 case k_VectorListIndexed: 572 VectorList = o.VectorList; 573 break; 574 case k_CoprocNum: 575 case k_CoprocReg: 576 Cop = o.Cop; 577 break; 578 case k_CoprocOption: 579 CoprocOption = o.CoprocOption; 580 break; 581 case k_Immediate: 582 Imm = o.Imm; 583 break; 584 case k_MemBarrierOpt: 585 MBOpt = o.MBOpt; 586 break; 587 case k_InstSyncBarrierOpt: 588 ISBOpt = o.ISBOpt; 589 case k_Memory: 590 Memory = o.Memory; 591 break; 592 case k_PostIndexRegister: 593 PostIdxReg = o.PostIdxReg; 594 break; 595 case k_MSRMask: 596 MMask = o.MMask; 597 break; 598 case k_ProcIFlags: 599 IFlags = o.IFlags; 600 break; 601 case k_ShifterImmediate: 602 ShifterImm = o.ShifterImm; 603 break; 604 case k_ShiftedRegister: 605 RegShiftedReg = o.RegShiftedReg; 606 break; 607 case k_ShiftedImmediate: 608 RegShiftedImm = o.RegShiftedImm; 609 break; 610 case k_RotateImmediate: 611 RotImm = o.RotImm; 612 break; 613 case k_BitfieldDescriptor: 614 Bitfield = o.Bitfield; 615 break; 616 case k_VectorIndex: 617 VectorIndex = o.VectorIndex; 618 break; 619 } 620 } 621 622 /// getStartLoc - Get the location of the first token of this operand. 623 SMLoc getStartLoc() const { return StartLoc; } 624 /// getEndLoc - Get the location of the last token of this operand. 625 SMLoc getEndLoc() const { return EndLoc; } 626 /// getLocRange - Get the range between the first and last token of this 627 /// operand. 628 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 629 630 ARMCC::CondCodes getCondCode() const { 631 assert(Kind == k_CondCode && "Invalid access!"); 632 return CC.Val; 633 } 634 635 unsigned getCoproc() const { 636 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 637 return Cop.Val; 638 } 639 640 StringRef getToken() const { 641 assert(Kind == k_Token && "Invalid access!"); 642 return StringRef(Tok.Data, Tok.Length); 643 } 644 645 unsigned getReg() const { 646 assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 647 return Reg.RegNum; 648 } 649 650 const SmallVectorImpl<unsigned> &getRegList() const { 651 assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 652 Kind == k_SPRRegisterList) && "Invalid access!"); 653 return Registers; 654 } 655 656 const MCExpr *getImm() const { 657 assert(isImm() && "Invalid access!"); 658 return Imm.Val; 659 } 660 661 unsigned getVectorIndex() const { 662 assert(Kind == k_VectorIndex && "Invalid access!"); 663 return VectorIndex.Val; 664 } 665 666 ARM_MB::MemBOpt getMemBarrierOpt() const { 667 assert(Kind == k_MemBarrierOpt && "Invalid access!"); 668 return MBOpt.Val; 669 } 670 671 ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const { 672 assert(Kind == k_InstSyncBarrierOpt && "Invalid access!"); 673 return ISBOpt.Val; 674 } 675 676 ARM_PROC::IFlags getProcIFlags() const { 677 assert(Kind == k_ProcIFlags && "Invalid access!"); 678 return IFlags.Val; 679 } 680 681 unsigned getMSRMask() const { 682 assert(Kind == k_MSRMask && "Invalid access!"); 683 return MMask.Val; 684 } 685 686 bool isCoprocNum() const { return Kind == k_CoprocNum; } 687 bool isCoprocReg() const { return Kind == k_CoprocReg; } 688 bool isCoprocOption() const { return Kind == k_CoprocOption; } 689 bool isCondCode() const { return Kind == k_CondCode; } 690 bool isCCOut() const { return Kind == k_CCOut; } 691 bool isITMask() const { return Kind == k_ITCondMask; } 692 bool isITCondCode() const { return Kind == k_CondCode; } 693 bool isImm() const { return Kind == k_Immediate; } 694 // checks whether this operand is an unsigned offset which fits is a field 695 // of specified width and scaled by a specific number of bits 696 template<unsigned width, unsigned scale> 697 bool isUnsignedOffset() const { 698 if (!isImm()) return false; 699 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 700 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 701 int64_t Val = CE->getValue(); 702 int64_t Align = 1LL << scale; 703 int64_t Max = Align * ((1LL << width) - 1); 704 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max); 705 } 706 return false; 707 } 708 // checks whether this operand is an signed offset which fits is a field 709 // of specified width and scaled by a specific number of bits 710 template<unsigned width, unsigned scale> 711 bool isSignedOffset() const { 712 if (!isImm()) return false; 713 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 714 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) { 715 int64_t Val = CE->getValue(); 716 int64_t Align = 1LL << scale; 717 int64_t Max = Align * ((1LL << (width-1)) - 1); 718 int64_t Min = -Align * (1LL << (width-1)); 719 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max); 720 } 721 return false; 722 } 723 724 // checks whether this operand is a memory operand computed as an offset 725 // applied to PC. the offset may have 8 bits of magnitude and is represented 726 // with two bits of shift. textually it may be either [pc, #imm], #imm or 727 // relocable expression... 728 bool isThumbMemPC() const { 729 int64_t Val = 0; 730 if (isImm()) { 731 if (isa<MCSymbolRefExpr>(Imm.Val)) return true; 732 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val); 733 if (!CE) return false; 734 Val = CE->getValue(); 735 } 736 else if (isMem()) { 737 if(!Memory.OffsetImm || Memory.OffsetRegNum) return false; 738 if(Memory.BaseRegNum != ARM::PC) return false; 739 Val = Memory.OffsetImm->getValue(); 740 } 741 else return false; 742 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020); 743 } 744 bool isFPImm() const { 745 if (!isImm()) return false; 746 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 747 if (!CE) return false; 748 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue())); 749 return Val != -1; 750 } 751 bool isFBits16() const { 752 if (!isImm()) return false; 753 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 754 if (!CE) return false; 755 int64_t Value = CE->getValue(); 756 return Value >= 0 && Value <= 16; 757 } 758 bool isFBits32() const { 759 if (!isImm()) return false; 760 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 761 if (!CE) return false; 762 int64_t Value = CE->getValue(); 763 return Value >= 1 && Value <= 32; 764 } 765 bool isImm8s4() const { 766 if (!isImm()) return false; 767 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 768 if (!CE) return false; 769 int64_t Value = CE->getValue(); 770 return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 771 } 772 bool isImm0_1020s4() const { 773 if (!isImm()) return false; 774 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 775 if (!CE) return false; 776 int64_t Value = CE->getValue(); 777 return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 778 } 779 bool isImm0_508s4() const { 780 if (!isImm()) return false; 781 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 782 if (!CE) return false; 783 int64_t Value = CE->getValue(); 784 return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 785 } 786 bool isImm0_508s4Neg() const { 787 if (!isImm()) return false; 788 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 789 if (!CE) return false; 790 int64_t Value = -CE->getValue(); 791 // explicitly exclude zero. we want that to use the normal 0_508 version. 792 return ((Value & 3) == 0) && Value > 0 && Value <= 508; 793 } 794 bool isImm0_239() const { 795 if (!isImm()) return false; 796 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 797 if (!CE) return false; 798 int64_t Value = CE->getValue(); 799 return Value >= 0 && Value < 240; 800 } 801 bool isImm0_255() const { 802 if (!isImm()) return false; 803 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 804 if (!CE) return false; 805 int64_t Value = CE->getValue(); 806 return Value >= 0 && Value < 256; 807 } 808 bool isImm0_4095() const { 809 if (!isImm()) return false; 810 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 811 if (!CE) return false; 812 int64_t Value = CE->getValue(); 813 return Value >= 0 && Value < 4096; 814 } 815 bool isImm0_4095Neg() const { 816 if (!isImm()) return false; 817 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 818 if (!CE) return false; 819 int64_t Value = -CE->getValue(); 820 return Value > 0 && Value < 4096; 821 } 822 bool isImm0_1() const { 823 if (!isImm()) return false; 824 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 825 if (!CE) return false; 826 int64_t Value = CE->getValue(); 827 return Value >= 0 && Value < 2; 828 } 829 bool isImm0_3() const { 830 if (!isImm()) return false; 831 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 832 if (!CE) return false; 833 int64_t Value = CE->getValue(); 834 return Value >= 0 && Value < 4; 835 } 836 bool isImm0_7() const { 837 if (!isImm()) return false; 838 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 839 if (!CE) return false; 840 int64_t Value = CE->getValue(); 841 return Value >= 0 && Value < 8; 842 } 843 bool isImm0_15() const { 844 if (!isImm()) return false; 845 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 846 if (!CE) return false; 847 int64_t Value = CE->getValue(); 848 return Value >= 0 && Value < 16; 849 } 850 bool isImm0_31() const { 851 if (!isImm()) return false; 852 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 853 if (!CE) return false; 854 int64_t Value = CE->getValue(); 855 return Value >= 0 && Value < 32; 856 } 857 bool isImm0_63() const { 858 if (!isImm()) return false; 859 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 860 if (!CE) return false; 861 int64_t Value = CE->getValue(); 862 return Value >= 0 && Value < 64; 863 } 864 bool isImm8() const { 865 if (!isImm()) return false; 866 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 867 if (!CE) return false; 868 int64_t Value = CE->getValue(); 869 return Value == 8; 870 } 871 bool isImm16() const { 872 if (!isImm()) return false; 873 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 874 if (!CE) return false; 875 int64_t Value = CE->getValue(); 876 return Value == 16; 877 } 878 bool isImm32() const { 879 if (!isImm()) return false; 880 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 881 if (!CE) return false; 882 int64_t Value = CE->getValue(); 883 return Value == 32; 884 } 885 bool isShrImm8() const { 886 if (!isImm()) return false; 887 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 888 if (!CE) return false; 889 int64_t Value = CE->getValue(); 890 return Value > 0 && Value <= 8; 891 } 892 bool isShrImm16() const { 893 if (!isImm()) return false; 894 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 895 if (!CE) return false; 896 int64_t Value = CE->getValue(); 897 return Value > 0 && Value <= 16; 898 } 899 bool isShrImm32() const { 900 if (!isImm()) return false; 901 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 902 if (!CE) return false; 903 int64_t Value = CE->getValue(); 904 return Value > 0 && Value <= 32; 905 } 906 bool isShrImm64() const { 907 if (!isImm()) return false; 908 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 909 if (!CE) return false; 910 int64_t Value = CE->getValue(); 911 return Value > 0 && Value <= 64; 912 } 913 bool isImm1_7() const { 914 if (!isImm()) return false; 915 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 916 if (!CE) return false; 917 int64_t Value = CE->getValue(); 918 return Value > 0 && Value < 8; 919 } 920 bool isImm1_15() const { 921 if (!isImm()) return false; 922 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 923 if (!CE) return false; 924 int64_t Value = CE->getValue(); 925 return Value > 0 && Value < 16; 926 } 927 bool isImm1_31() const { 928 if (!isImm()) return false; 929 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 930 if (!CE) return false; 931 int64_t Value = CE->getValue(); 932 return Value > 0 && Value < 32; 933 } 934 bool isImm1_16() const { 935 if (!isImm()) return false; 936 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 937 if (!CE) return false; 938 int64_t Value = CE->getValue(); 939 return Value > 0 && Value < 17; 940 } 941 bool isImm1_32() const { 942 if (!isImm()) return false; 943 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 944 if (!CE) return false; 945 int64_t Value = CE->getValue(); 946 return Value > 0 && Value < 33; 947 } 948 bool isImm0_32() const { 949 if (!isImm()) return false; 950 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 951 if (!CE) return false; 952 int64_t Value = CE->getValue(); 953 return Value >= 0 && Value < 33; 954 } 955 bool isImm0_65535() const { 956 if (!isImm()) return false; 957 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 958 if (!CE) return false; 959 int64_t Value = CE->getValue(); 960 return Value >= 0 && Value < 65536; 961 } 962 bool isImm256_65535Expr() const { 963 if (!isImm()) return false; 964 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 965 // If it's not a constant expression, it'll generate a fixup and be 966 // handled later. 967 if (!CE) return true; 968 int64_t Value = CE->getValue(); 969 return Value >= 256 && Value < 65536; 970 } 971 bool isImm0_65535Expr() const { 972 if (!isImm()) return false; 973 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 974 // If it's not a constant expression, it'll generate a fixup and be 975 // handled later. 976 if (!CE) return true; 977 int64_t Value = CE->getValue(); 978 return Value >= 0 && Value < 65536; 979 } 980 bool isImm24bit() const { 981 if (!isImm()) return false; 982 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 983 if (!CE) return false; 984 int64_t Value = CE->getValue(); 985 return Value >= 0 && Value <= 0xffffff; 986 } 987 bool isImmThumbSR() const { 988 if (!isImm()) return false; 989 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 990 if (!CE) return false; 991 int64_t Value = CE->getValue(); 992 return Value > 0 && Value < 33; 993 } 994 bool isPKHLSLImm() const { 995 if (!isImm()) return false; 996 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 997 if (!CE) return false; 998 int64_t Value = CE->getValue(); 999 return Value >= 0 && Value < 32; 1000 } 1001 bool isPKHASRImm() const { 1002 if (!isImm()) return false; 1003 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1004 if (!CE) return false; 1005 int64_t Value = CE->getValue(); 1006 return Value > 0 && Value <= 32; 1007 } 1008 bool isAdrLabel() const { 1009 // If we have an immediate that's not a constant, treat it as a label 1010 // reference needing a fixup. If it is a constant, but it can't fit 1011 // into shift immediate encoding, we reject it. 1012 if (isImm() && !isa<MCConstantExpr>(getImm())) return true; 1013 else return (isARMSOImm() || isARMSOImmNeg()); 1014 } 1015 bool isARMSOImm() const { 1016 if (!isImm()) return false; 1017 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1018 if (!CE) return false; 1019 int64_t Value = CE->getValue(); 1020 return ARM_AM::getSOImmVal(Value) != -1; 1021 } 1022 bool isARMSOImmNot() const { 1023 if (!isImm()) return false; 1024 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1025 if (!CE) return false; 1026 int64_t Value = CE->getValue(); 1027 return ARM_AM::getSOImmVal(~Value) != -1; 1028 } 1029 bool isARMSOImmNeg() const { 1030 if (!isImm()) return false; 1031 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1032 if (!CE) return false; 1033 int64_t Value = CE->getValue(); 1034 // Only use this when not representable as a plain so_imm. 1035 return ARM_AM::getSOImmVal(Value) == -1 && 1036 ARM_AM::getSOImmVal(-Value) != -1; 1037 } 1038 bool isT2SOImm() const { 1039 if (!isImm()) return false; 1040 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1041 if (!CE) return false; 1042 int64_t Value = CE->getValue(); 1043 return ARM_AM::getT2SOImmVal(Value) != -1; 1044 } 1045 bool isT2SOImmNot() const { 1046 if (!isImm()) return false; 1047 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1048 if (!CE) return false; 1049 int64_t Value = CE->getValue(); 1050 return ARM_AM::getT2SOImmVal(Value) == -1 && 1051 ARM_AM::getT2SOImmVal(~Value) != -1; 1052 } 1053 bool isT2SOImmNeg() const { 1054 if (!isImm()) return false; 1055 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1056 if (!CE) return false; 1057 int64_t Value = CE->getValue(); 1058 // Only use this when not representable as a plain so_imm. 1059 return ARM_AM::getT2SOImmVal(Value) == -1 && 1060 ARM_AM::getT2SOImmVal(-Value) != -1; 1061 } 1062 bool isSetEndImm() const { 1063 if (!isImm()) return false; 1064 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1065 if (!CE) return false; 1066 int64_t Value = CE->getValue(); 1067 return Value == 1 || Value == 0; 1068 } 1069 bool isReg() const { return Kind == k_Register; } 1070 bool isRegList() const { return Kind == k_RegisterList; } 1071 bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 1072 bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 1073 bool isToken() const { return Kind == k_Token; } 1074 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 1075 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; } 1076 bool isMem() const { return Kind == k_Memory; } 1077 bool isShifterImm() const { return Kind == k_ShifterImmediate; } 1078 bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 1079 bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 1080 bool isRotImm() const { return Kind == k_RotateImmediate; } 1081 bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 1082 bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 1083 bool isPostIdxReg() const { 1084 return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift; 1085 } 1086 bool isMemNoOffset(bool alignOK = false) const { 1087 if (!isMem()) 1088 return false; 1089 // No offset of any kind. 1090 return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 && 1091 (alignOK || Memory.Alignment == 0); 1092 } 1093 bool isMemPCRelImm12() const { 1094 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1095 return false; 1096 // Base register must be PC. 1097 if (Memory.BaseRegNum != ARM::PC) 1098 return false; 1099 // Immediate offset in range [-4095, 4095]. 1100 if (!Memory.OffsetImm) return true; 1101 int64_t Val = Memory.OffsetImm->getValue(); 1102 return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 1103 } 1104 bool isAlignedMemory() const { 1105 return isMemNoOffset(true); 1106 } 1107 bool isAddrMode2() const { 1108 if (!isMem() || Memory.Alignment != 0) return false; 1109 // Check for register offset. 1110 if (Memory.OffsetRegNum) return true; 1111 // Immediate offset in range [-4095, 4095]. 1112 if (!Memory.OffsetImm) return true; 1113 int64_t Val = Memory.OffsetImm->getValue(); 1114 return Val > -4096 && Val < 4096; 1115 } 1116 bool isAM2OffsetImm() const { 1117 if (!isImm()) return false; 1118 // Immediate offset in range [-4095, 4095]. 1119 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1120 if (!CE) return false; 1121 int64_t Val = CE->getValue(); 1122 return (Val == INT32_MIN) || (Val > -4096 && Val < 4096); 1123 } 1124 bool isAddrMode3() const { 1125 // If we have an immediate that's not a constant, treat it as a label 1126 // reference needing a fixup. If it is a constant, it's something else 1127 // and we reject it. 1128 if (isImm() && !isa<MCConstantExpr>(getImm())) 1129 return true; 1130 if (!isMem() || Memory.Alignment != 0) return false; 1131 // No shifts are legal for AM3. 1132 if (Memory.ShiftType != ARM_AM::no_shift) return false; 1133 // Check for register offset. 1134 if (Memory.OffsetRegNum) return true; 1135 // Immediate offset in range [-255, 255]. 1136 if (!Memory.OffsetImm) return true; 1137 int64_t Val = Memory.OffsetImm->getValue(); 1138 // The #-0 offset is encoded as INT32_MIN, and we have to check 1139 // for this too. 1140 return (Val > -256 && Val < 256) || Val == INT32_MIN; 1141 } 1142 bool isAM3Offset() const { 1143 if (Kind != k_Immediate && Kind != k_PostIndexRegister) 1144 return false; 1145 if (Kind == k_PostIndexRegister) 1146 return PostIdxReg.ShiftTy == ARM_AM::no_shift; 1147 // Immediate offset in range [-255, 255]. 1148 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1149 if (!CE) return false; 1150 int64_t Val = CE->getValue(); 1151 // Special case, #-0 is INT32_MIN. 1152 return (Val > -256 && Val < 256) || Val == INT32_MIN; 1153 } 1154 bool isAddrMode5() const { 1155 // If we have an immediate that's not a constant, treat it as a label 1156 // reference needing a fixup. If it is a constant, it's something else 1157 // and we reject it. 1158 if (isImm() && !isa<MCConstantExpr>(getImm())) 1159 return true; 1160 if (!isMem() || Memory.Alignment != 0) return false; 1161 // Check for register offset. 1162 if (Memory.OffsetRegNum) return false; 1163 // Immediate offset in range [-1020, 1020] and a multiple of 4. 1164 if (!Memory.OffsetImm) return true; 1165 int64_t Val = Memory.OffsetImm->getValue(); 1166 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 1167 Val == INT32_MIN; 1168 } 1169 bool isMemTBB() const { 1170 if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative || 1171 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 1172 return false; 1173 return true; 1174 } 1175 bool isMemTBH() const { 1176 if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative || 1177 Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 1178 Memory.Alignment != 0 ) 1179 return false; 1180 return true; 1181 } 1182 bool isMemRegOffset() const { 1183 if (!isMem() || !Memory.OffsetRegNum || Memory.Alignment != 0) 1184 return false; 1185 return true; 1186 } 1187 bool isT2MemRegOffset() const { 1188 if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative || 1189 Memory.Alignment != 0) 1190 return false; 1191 // Only lsl #{0, 1, 2, 3} allowed. 1192 if (Memory.ShiftType == ARM_AM::no_shift) 1193 return true; 1194 if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 1195 return false; 1196 return true; 1197 } 1198 bool isMemThumbRR() const { 1199 // Thumb reg+reg addressing is simple. Just two registers, a base and 1200 // an offset. No shifts, negations or any other complicating factors. 1201 if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative || 1202 Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 1203 return false; 1204 return isARMLowRegister(Memory.BaseRegNum) && 1205 (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 1206 } 1207 bool isMemThumbRIs4() const { 1208 if (!isMem() || Memory.OffsetRegNum != 0 || 1209 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1210 return false; 1211 // Immediate offset, multiple of 4 in range [0, 124]. 1212 if (!Memory.OffsetImm) return true; 1213 int64_t Val = Memory.OffsetImm->getValue(); 1214 return Val >= 0 && Val <= 124 && (Val % 4) == 0; 1215 } 1216 bool isMemThumbRIs2() const { 1217 if (!isMem() || Memory.OffsetRegNum != 0 || 1218 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1219 return false; 1220 // Immediate offset, multiple of 4 in range [0, 62]. 1221 if (!Memory.OffsetImm) return true; 1222 int64_t Val = Memory.OffsetImm->getValue(); 1223 return Val >= 0 && Val <= 62 && (Val % 2) == 0; 1224 } 1225 bool isMemThumbRIs1() const { 1226 if (!isMem() || Memory.OffsetRegNum != 0 || 1227 !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 1228 return false; 1229 // Immediate offset in range [0, 31]. 1230 if (!Memory.OffsetImm) return true; 1231 int64_t Val = Memory.OffsetImm->getValue(); 1232 return Val >= 0 && Val <= 31; 1233 } 1234 bool isMemThumbSPI() const { 1235 if (!isMem() || Memory.OffsetRegNum != 0 || 1236 Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 1237 return false; 1238 // Immediate offset, multiple of 4 in range [0, 1020]. 1239 if (!Memory.OffsetImm) return true; 1240 int64_t Val = Memory.OffsetImm->getValue(); 1241 return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 1242 } 1243 bool isMemImm8s4Offset() const { 1244 // If we have an immediate that's not a constant, treat it as a label 1245 // reference needing a fixup. If it is a constant, it's something else 1246 // and we reject it. 1247 if (isImm() && !isa<MCConstantExpr>(getImm())) 1248 return true; 1249 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1250 return false; 1251 // Immediate offset a multiple of 4 in range [-1020, 1020]. 1252 if (!Memory.OffsetImm) return true; 1253 int64_t Val = Memory.OffsetImm->getValue(); 1254 // Special case, #-0 is INT32_MIN. 1255 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) || Val == INT32_MIN; 1256 } 1257 bool isMemImm0_1020s4Offset() const { 1258 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1259 return false; 1260 // Immediate offset a multiple of 4 in range [0, 1020]. 1261 if (!Memory.OffsetImm) return true; 1262 int64_t Val = Memory.OffsetImm->getValue(); 1263 return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 1264 } 1265 bool isMemImm8Offset() const { 1266 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1267 return false; 1268 // Base reg of PC isn't allowed for these encodings. 1269 if (Memory.BaseRegNum == ARM::PC) return false; 1270 // Immediate offset in range [-255, 255]. 1271 if (!Memory.OffsetImm) return true; 1272 int64_t Val = Memory.OffsetImm->getValue(); 1273 return (Val == INT32_MIN) || (Val > -256 && Val < 256); 1274 } 1275 bool isMemPosImm8Offset() const { 1276 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1277 return false; 1278 // Immediate offset in range [0, 255]. 1279 if (!Memory.OffsetImm) return true; 1280 int64_t Val = Memory.OffsetImm->getValue(); 1281 return Val >= 0 && Val < 256; 1282 } 1283 bool isMemNegImm8Offset() const { 1284 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1285 return false; 1286 // Base reg of PC isn't allowed for these encodings. 1287 if (Memory.BaseRegNum == ARM::PC) return false; 1288 // Immediate offset in range [-255, -1]. 1289 if (!Memory.OffsetImm) return false; 1290 int64_t Val = Memory.OffsetImm->getValue(); 1291 return (Val == INT32_MIN) || (Val > -256 && Val < 0); 1292 } 1293 bool isMemUImm12Offset() const { 1294 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1295 return false; 1296 // Immediate offset in range [0, 4095]. 1297 if (!Memory.OffsetImm) return true; 1298 int64_t Val = Memory.OffsetImm->getValue(); 1299 return (Val >= 0 && Val < 4096); 1300 } 1301 bool isMemImm12Offset() const { 1302 // If we have an immediate that's not a constant, treat it as a label 1303 // reference needing a fixup. If it is a constant, it's something else 1304 // and we reject it. 1305 if (isImm() && !isa<MCConstantExpr>(getImm())) 1306 return true; 1307 1308 if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 1309 return false; 1310 // Immediate offset in range [-4095, 4095]. 1311 if (!Memory.OffsetImm) return true; 1312 int64_t Val = Memory.OffsetImm->getValue(); 1313 return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 1314 } 1315 bool isPostIdxImm8() const { 1316 if (!isImm()) return false; 1317 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1318 if (!CE) return false; 1319 int64_t Val = CE->getValue(); 1320 return (Val > -256 && Val < 256) || (Val == INT32_MIN); 1321 } 1322 bool isPostIdxImm8s4() const { 1323 if (!isImm()) return false; 1324 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1325 if (!CE) return false; 1326 int64_t Val = CE->getValue(); 1327 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 1328 (Val == INT32_MIN); 1329 } 1330 1331 bool isMSRMask() const { return Kind == k_MSRMask; } 1332 bool isProcIFlags() const { return Kind == k_ProcIFlags; } 1333 1334 // NEON operands. 1335 bool isSingleSpacedVectorList() const { 1336 return Kind == k_VectorList && !VectorList.isDoubleSpaced; 1337 } 1338 bool isDoubleSpacedVectorList() const { 1339 return Kind == k_VectorList && VectorList.isDoubleSpaced; 1340 } 1341 bool isVecListOneD() const { 1342 if (!isSingleSpacedVectorList()) return false; 1343 return VectorList.Count == 1; 1344 } 1345 1346 bool isVecListDPair() const { 1347 if (!isSingleSpacedVectorList()) return false; 1348 return (ARMMCRegisterClasses[ARM::DPairRegClassID] 1349 .contains(VectorList.RegNum)); 1350 } 1351 1352 bool isVecListThreeD() const { 1353 if (!isSingleSpacedVectorList()) return false; 1354 return VectorList.Count == 3; 1355 } 1356 1357 bool isVecListFourD() const { 1358 if (!isSingleSpacedVectorList()) return false; 1359 return VectorList.Count == 4; 1360 } 1361 1362 bool isVecListDPairSpaced() const { 1363 if (isSingleSpacedVectorList()) return false; 1364 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID] 1365 .contains(VectorList.RegNum)); 1366 } 1367 1368 bool isVecListThreeQ() const { 1369 if (!isDoubleSpacedVectorList()) return false; 1370 return VectorList.Count == 3; 1371 } 1372 1373 bool isVecListFourQ() const { 1374 if (!isDoubleSpacedVectorList()) return false; 1375 return VectorList.Count == 4; 1376 } 1377 1378 bool isSingleSpacedVectorAllLanes() const { 1379 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced; 1380 } 1381 bool isDoubleSpacedVectorAllLanes() const { 1382 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced; 1383 } 1384 bool isVecListOneDAllLanes() const { 1385 if (!isSingleSpacedVectorAllLanes()) return false; 1386 return VectorList.Count == 1; 1387 } 1388 1389 bool isVecListDPairAllLanes() const { 1390 if (!isSingleSpacedVectorAllLanes()) return false; 1391 return (ARMMCRegisterClasses[ARM::DPairRegClassID] 1392 .contains(VectorList.RegNum)); 1393 } 1394 1395 bool isVecListDPairSpacedAllLanes() const { 1396 if (!isDoubleSpacedVectorAllLanes()) return false; 1397 return VectorList.Count == 2; 1398 } 1399 1400 bool isVecListThreeDAllLanes() const { 1401 if (!isSingleSpacedVectorAllLanes()) return false; 1402 return VectorList.Count == 3; 1403 } 1404 1405 bool isVecListThreeQAllLanes() const { 1406 if (!isDoubleSpacedVectorAllLanes()) return false; 1407 return VectorList.Count == 3; 1408 } 1409 1410 bool isVecListFourDAllLanes() const { 1411 if (!isSingleSpacedVectorAllLanes()) return false; 1412 return VectorList.Count == 4; 1413 } 1414 1415 bool isVecListFourQAllLanes() const { 1416 if (!isDoubleSpacedVectorAllLanes()) return false; 1417 return VectorList.Count == 4; 1418 } 1419 1420 bool isSingleSpacedVectorIndexed() const { 1421 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced; 1422 } 1423 bool isDoubleSpacedVectorIndexed() const { 1424 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced; 1425 } 1426 bool isVecListOneDByteIndexed() const { 1427 if (!isSingleSpacedVectorIndexed()) return false; 1428 return VectorList.Count == 1 && VectorList.LaneIndex <= 7; 1429 } 1430 1431 bool isVecListOneDHWordIndexed() const { 1432 if (!isSingleSpacedVectorIndexed()) return false; 1433 return VectorList.Count == 1 && VectorList.LaneIndex <= 3; 1434 } 1435 1436 bool isVecListOneDWordIndexed() const { 1437 if (!isSingleSpacedVectorIndexed()) return false; 1438 return VectorList.Count == 1 && VectorList.LaneIndex <= 1; 1439 } 1440 1441 bool isVecListTwoDByteIndexed() const { 1442 if (!isSingleSpacedVectorIndexed()) return false; 1443 return VectorList.Count == 2 && VectorList.LaneIndex <= 7; 1444 } 1445 1446 bool isVecListTwoDHWordIndexed() const { 1447 if (!isSingleSpacedVectorIndexed()) return false; 1448 return VectorList.Count == 2 && VectorList.LaneIndex <= 3; 1449 } 1450 1451 bool isVecListTwoQWordIndexed() const { 1452 if (!isDoubleSpacedVectorIndexed()) return false; 1453 return VectorList.Count == 2 && VectorList.LaneIndex <= 1; 1454 } 1455 1456 bool isVecListTwoQHWordIndexed() const { 1457 if (!isDoubleSpacedVectorIndexed()) return false; 1458 return VectorList.Count == 2 && VectorList.LaneIndex <= 3; 1459 } 1460 1461 bool isVecListTwoDWordIndexed() const { 1462 if (!isSingleSpacedVectorIndexed()) return false; 1463 return VectorList.Count == 2 && VectorList.LaneIndex <= 1; 1464 } 1465 1466 bool isVecListThreeDByteIndexed() const { 1467 if (!isSingleSpacedVectorIndexed()) return false; 1468 return VectorList.Count == 3 && VectorList.LaneIndex <= 7; 1469 } 1470 1471 bool isVecListThreeDHWordIndexed() const { 1472 if (!isSingleSpacedVectorIndexed()) return false; 1473 return VectorList.Count == 3 && VectorList.LaneIndex <= 3; 1474 } 1475 1476 bool isVecListThreeQWordIndexed() const { 1477 if (!isDoubleSpacedVectorIndexed()) return false; 1478 return VectorList.Count == 3 && VectorList.LaneIndex <= 1; 1479 } 1480 1481 bool isVecListThreeQHWordIndexed() const { 1482 if (!isDoubleSpacedVectorIndexed()) return false; 1483 return VectorList.Count == 3 && VectorList.LaneIndex <= 3; 1484 } 1485 1486 bool isVecListThreeDWordIndexed() const { 1487 if (!isSingleSpacedVectorIndexed()) return false; 1488 return VectorList.Count == 3 && VectorList.LaneIndex <= 1; 1489 } 1490 1491 bool isVecListFourDByteIndexed() const { 1492 if (!isSingleSpacedVectorIndexed()) return false; 1493 return VectorList.Count == 4 && VectorList.LaneIndex <= 7; 1494 } 1495 1496 bool isVecListFourDHWordIndexed() const { 1497 if (!isSingleSpacedVectorIndexed()) return false; 1498 return VectorList.Count == 4 && VectorList.LaneIndex <= 3; 1499 } 1500 1501 bool isVecListFourQWordIndexed() const { 1502 if (!isDoubleSpacedVectorIndexed()) return false; 1503 return VectorList.Count == 4 && VectorList.LaneIndex <= 1; 1504 } 1505 1506 bool isVecListFourQHWordIndexed() const { 1507 if (!isDoubleSpacedVectorIndexed()) return false; 1508 return VectorList.Count == 4 && VectorList.LaneIndex <= 3; 1509 } 1510 1511 bool isVecListFourDWordIndexed() const { 1512 if (!isSingleSpacedVectorIndexed()) return false; 1513 return VectorList.Count == 4 && VectorList.LaneIndex <= 1; 1514 } 1515 1516 bool isVectorIndex8() const { 1517 if (Kind != k_VectorIndex) return false; 1518 return VectorIndex.Val < 8; 1519 } 1520 bool isVectorIndex16() const { 1521 if (Kind != k_VectorIndex) return false; 1522 return VectorIndex.Val < 4; 1523 } 1524 bool isVectorIndex32() const { 1525 if (Kind != k_VectorIndex) return false; 1526 return VectorIndex.Val < 2; 1527 } 1528 1529 bool isNEONi8splat() const { 1530 if (!isImm()) return false; 1531 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1532 // Must be a constant. 1533 if (!CE) return false; 1534 int64_t Value = CE->getValue(); 1535 // i8 value splatted across 8 bytes. The immediate is just the 8 byte 1536 // value. 1537 return Value >= 0 && Value < 256; 1538 } 1539 1540 bool isNEONi16splat() const { 1541 if (!isImm()) return false; 1542 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1543 // Must be a constant. 1544 if (!CE) return false; 1545 int64_t Value = CE->getValue(); 1546 // i16 value in the range [0,255] or [0x0100, 0xff00] 1547 return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00); 1548 } 1549 1550 bool isNEONi32splat() const { 1551 if (!isImm()) return false; 1552 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1553 // Must be a constant. 1554 if (!CE) return false; 1555 int64_t Value = CE->getValue(); 1556 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X. 1557 return (Value >= 0 && Value < 256) || 1558 (Value >= 0x0100 && Value <= 0xff00) || 1559 (Value >= 0x010000 && Value <= 0xff0000) || 1560 (Value >= 0x01000000 && Value <= 0xff000000); 1561 } 1562 1563 bool isNEONi32vmov() const { 1564 if (!isImm()) return false; 1565 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1566 // Must be a constant. 1567 if (!CE) return false; 1568 int64_t Value = CE->getValue(); 1569 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 1570 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 1571 return (Value >= 0 && Value < 256) || 1572 (Value >= 0x0100 && Value <= 0xff00) || 1573 (Value >= 0x010000 && Value <= 0xff0000) || 1574 (Value >= 0x01000000 && Value <= 0xff000000) || 1575 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 1576 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 1577 } 1578 bool isNEONi32vmovNeg() const { 1579 if (!isImm()) return false; 1580 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1581 // Must be a constant. 1582 if (!CE) return false; 1583 int64_t Value = ~CE->getValue(); 1584 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X, 1585 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted. 1586 return (Value >= 0 && Value < 256) || 1587 (Value >= 0x0100 && Value <= 0xff00) || 1588 (Value >= 0x010000 && Value <= 0xff0000) || 1589 (Value >= 0x01000000 && Value <= 0xff000000) || 1590 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || 1591 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); 1592 } 1593 1594 bool isNEONi64splat() const { 1595 if (!isImm()) return false; 1596 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1597 // Must be a constant. 1598 if (!CE) return false; 1599 uint64_t Value = CE->getValue(); 1600 // i64 value with each byte being either 0 or 0xff. 1601 for (unsigned i = 0; i < 8; ++i) 1602 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false; 1603 return true; 1604 } 1605 1606 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 1607 // Add as immediates when possible. Null MCExpr = 0. 1608 if (Expr == 0) 1609 Inst.addOperand(MCOperand::CreateImm(0)); 1610 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 1611 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1612 else 1613 Inst.addOperand(MCOperand::CreateExpr(Expr)); 1614 } 1615 1616 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 1617 assert(N == 2 && "Invalid number of operands!"); 1618 Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 1619 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 1620 Inst.addOperand(MCOperand::CreateReg(RegNum)); 1621 } 1622 1623 void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 1624 assert(N == 1 && "Invalid number of operands!"); 1625 Inst.addOperand(MCOperand::CreateImm(getCoproc())); 1626 } 1627 1628 void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 1629 assert(N == 1 && "Invalid number of operands!"); 1630 Inst.addOperand(MCOperand::CreateImm(getCoproc())); 1631 } 1632 1633 void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 1634 assert(N == 1 && "Invalid number of operands!"); 1635 Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val)); 1636 } 1637 1638 void addITMaskOperands(MCInst &Inst, unsigned N) const { 1639 assert(N == 1 && "Invalid number of operands!"); 1640 Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 1641 } 1642 1643 void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 1644 assert(N == 1 && "Invalid number of operands!"); 1645 Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 1646 } 1647 1648 void addCCOutOperands(MCInst &Inst, unsigned N) const { 1649 assert(N == 1 && "Invalid number of operands!"); 1650 Inst.addOperand(MCOperand::CreateReg(getReg())); 1651 } 1652 1653 void addRegOperands(MCInst &Inst, unsigned N) const { 1654 assert(N == 1 && "Invalid number of operands!"); 1655 Inst.addOperand(MCOperand::CreateReg(getReg())); 1656 } 1657 1658 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 1659 assert(N == 3 && "Invalid number of operands!"); 1660 assert(isRegShiftedReg() && 1661 "addRegShiftedRegOperands() on non-RegShiftedReg!"); 1662 Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 1663 Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 1664 Inst.addOperand(MCOperand::CreateImm( 1665 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 1666 } 1667 1668 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 1669 assert(N == 2 && "Invalid number of operands!"); 1670 assert(isRegShiftedImm() && 1671 "addRegShiftedImmOperands() on non-RegShiftedImm!"); 1672 Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 1673 // Shift of #32 is encoded as 0 where permitted 1674 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm); 1675 Inst.addOperand(MCOperand::CreateImm( 1676 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm))); 1677 } 1678 1679 void addShifterImmOperands(MCInst &Inst, unsigned N) const { 1680 assert(N == 1 && "Invalid number of operands!"); 1681 Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 1682 ShifterImm.Imm)); 1683 } 1684 1685 void addRegListOperands(MCInst &Inst, unsigned N) const { 1686 assert(N == 1 && "Invalid number of operands!"); 1687 const SmallVectorImpl<unsigned> &RegList = getRegList(); 1688 for (SmallVectorImpl<unsigned>::const_iterator 1689 I = RegList.begin(), E = RegList.end(); I != E; ++I) 1690 Inst.addOperand(MCOperand::CreateReg(*I)); 1691 } 1692 1693 void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 1694 addRegListOperands(Inst, N); 1695 } 1696 1697 void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 1698 addRegListOperands(Inst, N); 1699 } 1700 1701 void addRotImmOperands(MCInst &Inst, unsigned N) const { 1702 assert(N == 1 && "Invalid number of operands!"); 1703 // Encoded as val>>3. The printer handles display as 8, 16, 24. 1704 Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 1705 } 1706 1707 void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1708 assert(N == 1 && "Invalid number of operands!"); 1709 // Munge the lsb/width into a bitfield mask. 1710 unsigned lsb = Bitfield.LSB; 1711 unsigned width = Bitfield.Width; 1712 // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1713 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1714 (32 - (lsb + width))); 1715 Inst.addOperand(MCOperand::CreateImm(Mask)); 1716 } 1717 1718 void addImmOperands(MCInst &Inst, unsigned N) const { 1719 assert(N == 1 && "Invalid number of operands!"); 1720 addExpr(Inst, getImm()); 1721 } 1722 1723 void addFBits16Operands(MCInst &Inst, unsigned N) const { 1724 assert(N == 1 && "Invalid number of operands!"); 1725 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1726 Inst.addOperand(MCOperand::CreateImm(16 - CE->getValue())); 1727 } 1728 1729 void addFBits32Operands(MCInst &Inst, unsigned N) const { 1730 assert(N == 1 && "Invalid number of operands!"); 1731 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1732 Inst.addOperand(MCOperand::CreateImm(32 - CE->getValue())); 1733 } 1734 1735 void addFPImmOperands(MCInst &Inst, unsigned N) const { 1736 assert(N == 1 && "Invalid number of operands!"); 1737 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1738 int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue())); 1739 Inst.addOperand(MCOperand::CreateImm(Val)); 1740 } 1741 1742 void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1743 assert(N == 1 && "Invalid number of operands!"); 1744 // FIXME: We really want to scale the value here, but the LDRD/STRD 1745 // instruction don't encode operands that way yet. 1746 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1747 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1748 } 1749 1750 void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 1751 assert(N == 1 && "Invalid number of operands!"); 1752 // The immediate is scaled by four in the encoding and is stored 1753 // in the MCInst as such. Lop off the low two bits here. 1754 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1755 Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 1756 } 1757 1758 void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const { 1759 assert(N == 1 && "Invalid number of operands!"); 1760 // The immediate is scaled by four in the encoding and is stored 1761 // in the MCInst as such. Lop off the low two bits here. 1762 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1763 Inst.addOperand(MCOperand::CreateImm(-(CE->getValue() / 4))); 1764 } 1765 1766 void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 1767 assert(N == 1 && "Invalid number of operands!"); 1768 // The immediate is scaled by four in the encoding and is stored 1769 // in the MCInst as such. Lop off the low two bits here. 1770 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1771 Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 1772 } 1773 1774 void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1775 assert(N == 1 && "Invalid number of operands!"); 1776 // The constant encodes as the immediate-1, and we store in the instruction 1777 // the bits as encoded, so subtract off one here. 1778 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1779 Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1780 } 1781 1782 void addImm1_32Operands(MCInst &Inst, unsigned N) const { 1783 assert(N == 1 && "Invalid number of operands!"); 1784 // The constant encodes as the immediate-1, and we store in the instruction 1785 // the bits as encoded, so subtract off one here. 1786 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1787 Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1788 } 1789 1790 void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 1791 assert(N == 1 && "Invalid number of operands!"); 1792 // The constant encodes as the immediate, except for 32, which encodes as 1793 // zero. 1794 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1795 unsigned Imm = CE->getValue(); 1796 Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1797 } 1798 1799 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1800 assert(N == 1 && "Invalid number of operands!"); 1801 // An ASR value of 32 encodes as 0, so that's how we want to add it to 1802 // the instruction as well. 1803 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1804 int Val = CE->getValue(); 1805 Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1806 } 1807 1808 void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const { 1809 assert(N == 1 && "Invalid number of operands!"); 1810 // The operand is actually a t2_so_imm, but we have its bitwise 1811 // negation in the assembly source, so twiddle it here. 1812 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1813 Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 1814 } 1815 1816 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const { 1817 assert(N == 1 && "Invalid number of operands!"); 1818 // The operand is actually a t2_so_imm, but we have its 1819 // negation in the assembly source, so twiddle it here. 1820 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1821 Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 1822 } 1823 1824 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const { 1825 assert(N == 1 && "Invalid number of operands!"); 1826 // The operand is actually an imm0_4095, but we have its 1827 // negation in the assembly source, so twiddle it here. 1828 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1829 Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 1830 } 1831 1832 void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const { 1833 if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) { 1834 Inst.addOperand(MCOperand::CreateImm(CE->getValue() >> 2)); 1835 return; 1836 } 1837 1838 const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val); 1839 assert(SR && "Unknown value type!"); 1840 Inst.addOperand(MCOperand::CreateExpr(SR)); 1841 } 1842 1843 void addThumbMemPCOperands(MCInst &Inst, unsigned N) const { 1844 assert(N == 1 && "Invalid number of operands!"); 1845 if (isImm()) { 1846 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1847 if (CE) { 1848 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1849 return; 1850 } 1851 1852 const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val); 1853 assert(SR && "Unknown value type!"); 1854 Inst.addOperand(MCOperand::CreateExpr(SR)); 1855 return; 1856 } 1857 1858 assert(isMem() && "Unknown value type!"); 1859 assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!"); 1860 Inst.addOperand(MCOperand::CreateImm(Memory.OffsetImm->getValue())); 1861 } 1862 1863 void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const { 1864 assert(N == 1 && "Invalid number of operands!"); 1865 // The operand is actually a so_imm, but we have its bitwise 1866 // negation in the assembly source, so twiddle it here. 1867 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1868 Inst.addOperand(MCOperand::CreateImm(~CE->getValue())); 1869 } 1870 1871 void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const { 1872 assert(N == 1 && "Invalid number of operands!"); 1873 // The operand is actually a so_imm, but we have its 1874 // negation in the assembly source, so twiddle it here. 1875 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1876 Inst.addOperand(MCOperand::CreateImm(-CE->getValue())); 1877 } 1878 1879 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1880 assert(N == 1 && "Invalid number of operands!"); 1881 Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1882 } 1883 1884 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const { 1885 assert(N == 1 && "Invalid number of operands!"); 1886 Inst.addOperand(MCOperand::CreateImm(unsigned(getInstSyncBarrierOpt()))); 1887 } 1888 1889 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 1890 assert(N == 1 && "Invalid number of operands!"); 1891 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1892 } 1893 1894 void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const { 1895 assert(N == 1 && "Invalid number of operands!"); 1896 int32_t Imm = Memory.OffsetImm->getValue(); 1897 Inst.addOperand(MCOperand::CreateImm(Imm)); 1898 } 1899 1900 void addAdrLabelOperands(MCInst &Inst, unsigned N) const { 1901 assert(N == 1 && "Invalid number of operands!"); 1902 assert(isImm() && "Not an immediate!"); 1903 1904 // If we have an immediate that's not a constant, treat it as a label 1905 // reference needing a fixup. 1906 if (!isa<MCConstantExpr>(getImm())) { 1907 Inst.addOperand(MCOperand::CreateExpr(getImm())); 1908 return; 1909 } 1910 1911 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1912 int Val = CE->getValue(); 1913 Inst.addOperand(MCOperand::CreateImm(Val)); 1914 } 1915 1916 void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 1917 assert(N == 2 && "Invalid number of operands!"); 1918 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1919 Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 1920 } 1921 1922 void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 1923 assert(N == 3 && "Invalid number of operands!"); 1924 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1925 if (!Memory.OffsetRegNum) { 1926 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1927 // Special case for #-0 1928 if (Val == INT32_MIN) Val = 0; 1929 if (Val < 0) Val = -Val; 1930 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1931 } else { 1932 // For register offset, we encode the shift type and negation flag 1933 // here. 1934 Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1935 Memory.ShiftImm, Memory.ShiftType); 1936 } 1937 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1938 Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1939 Inst.addOperand(MCOperand::CreateImm(Val)); 1940 } 1941 1942 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1943 assert(N == 2 && "Invalid number of operands!"); 1944 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1945 assert(CE && "non-constant AM2OffsetImm operand!"); 1946 int32_t Val = CE->getValue(); 1947 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1948 // Special case for #-0 1949 if (Val == INT32_MIN) Val = 0; 1950 if (Val < 0) Val = -Val; 1951 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1952 Inst.addOperand(MCOperand::CreateReg(0)); 1953 Inst.addOperand(MCOperand::CreateImm(Val)); 1954 } 1955 1956 void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 1957 assert(N == 3 && "Invalid number of operands!"); 1958 // If we have an immediate that's not a constant, treat it as a label 1959 // reference needing a fixup. If it is a constant, it's something else 1960 // and we reject it. 1961 if (isImm()) { 1962 Inst.addOperand(MCOperand::CreateExpr(getImm())); 1963 Inst.addOperand(MCOperand::CreateReg(0)); 1964 Inst.addOperand(MCOperand::CreateImm(0)); 1965 return; 1966 } 1967 1968 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1969 if (!Memory.OffsetRegNum) { 1970 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1971 // Special case for #-0 1972 if (Val == INT32_MIN) Val = 0; 1973 if (Val < 0) Val = -Val; 1974 Val = ARM_AM::getAM3Opc(AddSub, Val); 1975 } else { 1976 // For register offset, we encode the shift type and negation flag 1977 // here. 1978 Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 1979 } 1980 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1981 Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1982 Inst.addOperand(MCOperand::CreateImm(Val)); 1983 } 1984 1985 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 1986 assert(N == 2 && "Invalid number of operands!"); 1987 if (Kind == k_PostIndexRegister) { 1988 int32_t Val = 1989 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 1990 Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1991 Inst.addOperand(MCOperand::CreateImm(Val)); 1992 return; 1993 } 1994 1995 // Constant offset. 1996 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 1997 int32_t Val = CE->getValue(); 1998 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1999 // Special case for #-0 2000 if (Val == INT32_MIN) Val = 0; 2001 if (Val < 0) Val = -Val; 2002 Val = ARM_AM::getAM3Opc(AddSub, Val); 2003 Inst.addOperand(MCOperand::CreateReg(0)); 2004 Inst.addOperand(MCOperand::CreateImm(Val)); 2005 } 2006 2007 void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 2008 assert(N == 2 && "Invalid number of operands!"); 2009 // If we have an immediate that's not a constant, treat it as a label 2010 // reference needing a fixup. If it is a constant, it's something else 2011 // and we reject it. 2012 if (isImm()) { 2013 Inst.addOperand(MCOperand::CreateExpr(getImm())); 2014 Inst.addOperand(MCOperand::CreateImm(0)); 2015 return; 2016 } 2017 2018 // The lower two bits are always zero and as such are not encoded. 2019 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 2020 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 2021 // Special case for #-0 2022 if (Val == INT32_MIN) Val = 0; 2023 if (Val < 0) Val = -Val; 2024 Val = ARM_AM::getAM5Opc(AddSub, Val); 2025 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2026 Inst.addOperand(MCOperand::CreateImm(Val)); 2027 } 2028 2029 void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 2030 assert(N == 2 && "Invalid number of operands!"); 2031 // If we have an immediate that's not a constant, treat it as a label 2032 // reference needing a fixup. If it is a constant, it's something else 2033 // and we reject it. 2034 if (isImm()) { 2035 Inst.addOperand(MCOperand::CreateExpr(getImm())); 2036 Inst.addOperand(MCOperand::CreateImm(0)); 2037 return; 2038 } 2039 2040 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2041 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2042 Inst.addOperand(MCOperand::CreateImm(Val)); 2043 } 2044 2045 void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 2046 assert(N == 2 && "Invalid number of operands!"); 2047 // The lower two bits are always zero and as such are not encoded. 2048 int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 2049 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2050 Inst.addOperand(MCOperand::CreateImm(Val)); 2051 } 2052 2053 void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 2054 assert(N == 2 && "Invalid number of operands!"); 2055 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2056 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2057 Inst.addOperand(MCOperand::CreateImm(Val)); 2058 } 2059 2060 void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 2061 addMemImm8OffsetOperands(Inst, N); 2062 } 2063 2064 void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 2065 addMemImm8OffsetOperands(Inst, N); 2066 } 2067 2068 void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 2069 assert(N == 2 && "Invalid number of operands!"); 2070 // If this is an immediate, it's a label reference. 2071 if (isImm()) { 2072 addExpr(Inst, getImm()); 2073 Inst.addOperand(MCOperand::CreateImm(0)); 2074 return; 2075 } 2076 2077 // Otherwise, it's a normal memory reg+offset. 2078 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2079 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2080 Inst.addOperand(MCOperand::CreateImm(Val)); 2081 } 2082 2083 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 2084 assert(N == 2 && "Invalid number of operands!"); 2085 // If this is an immediate, it's a label reference. 2086 if (isImm()) { 2087 addExpr(Inst, getImm()); 2088 Inst.addOperand(MCOperand::CreateImm(0)); 2089 return; 2090 } 2091 2092 // Otherwise, it's a normal memory reg+offset. 2093 int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 2094 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2095 Inst.addOperand(MCOperand::CreateImm(Val)); 2096 } 2097 2098 void addMemTBBOperands(MCInst &Inst, unsigned N) const { 2099 assert(N == 2 && "Invalid number of operands!"); 2100 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2101 Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 2102 } 2103 2104 void addMemTBHOperands(MCInst &Inst, unsigned N) const { 2105 assert(N == 2 && "Invalid number of operands!"); 2106 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2107 Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 2108 } 2109 2110 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 2111 assert(N == 3 && "Invalid number of operands!"); 2112 unsigned Val = 2113 ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 2114 Memory.ShiftImm, Memory.ShiftType); 2115 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2116 Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 2117 Inst.addOperand(MCOperand::CreateImm(Val)); 2118 } 2119 2120 void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 2121 assert(N == 3 && "Invalid number of operands!"); 2122 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2123 Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 2124 Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 2125 } 2126 2127 void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 2128 assert(N == 2 && "Invalid number of operands!"); 2129 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2130 Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 2131 } 2132 2133 void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 2134 assert(N == 2 && "Invalid number of operands!"); 2135 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 2136 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2137 Inst.addOperand(MCOperand::CreateImm(Val)); 2138 } 2139 2140 void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 2141 assert(N == 2 && "Invalid number of operands!"); 2142 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 2143 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2144 Inst.addOperand(MCOperand::CreateImm(Val)); 2145 } 2146 2147 void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 2148 assert(N == 2 && "Invalid number of operands!"); 2149 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 2150 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2151 Inst.addOperand(MCOperand::CreateImm(Val)); 2152 } 2153 2154 void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 2155 assert(N == 2 && "Invalid number of operands!"); 2156 int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 2157 Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 2158 Inst.addOperand(MCOperand::CreateImm(Val)); 2159 } 2160 2161 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 2162 assert(N == 1 && "Invalid number of operands!"); 2163 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2164 assert(CE && "non-constant post-idx-imm8 operand!"); 2165 int Imm = CE->getValue(); 2166 bool isAdd = Imm >= 0; 2167 if (Imm == INT32_MIN) Imm = 0; 2168 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 2169 Inst.addOperand(MCOperand::CreateImm(Imm)); 2170 } 2171 2172 void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 2173 assert(N == 1 && "Invalid number of operands!"); 2174 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2175 assert(CE && "non-constant post-idx-imm8s4 operand!"); 2176 int Imm = CE->getValue(); 2177 bool isAdd = Imm >= 0; 2178 if (Imm == INT32_MIN) Imm = 0; 2179 // Immediate is scaled by 4. 2180 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 2181 Inst.addOperand(MCOperand::CreateImm(Imm)); 2182 } 2183 2184 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 2185 assert(N == 2 && "Invalid number of operands!"); 2186 Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 2187 Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 2188 } 2189 2190 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 2191 assert(N == 2 && "Invalid number of operands!"); 2192 Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 2193 // The sign, shift type, and shift amount are encoded in a single operand 2194 // using the AM2 encoding helpers. 2195 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 2196 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 2197 PostIdxReg.ShiftTy); 2198 Inst.addOperand(MCOperand::CreateImm(Imm)); 2199 } 2200 2201 void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 2202 assert(N == 1 && "Invalid number of operands!"); 2203 Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 2204 } 2205 2206 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 2207 assert(N == 1 && "Invalid number of operands!"); 2208 Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 2209 } 2210 2211 void addVecListOperands(MCInst &Inst, unsigned N) const { 2212 assert(N == 1 && "Invalid number of operands!"); 2213 Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 2214 } 2215 2216 void addVecListIndexedOperands(MCInst &Inst, unsigned N) const { 2217 assert(N == 2 && "Invalid number of operands!"); 2218 Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); 2219 Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex)); 2220 } 2221 2222 void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 2223 assert(N == 1 && "Invalid number of operands!"); 2224 Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 2225 } 2226 2227 void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 2228 assert(N == 1 && "Invalid number of operands!"); 2229 Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 2230 } 2231 2232 void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 2233 assert(N == 1 && "Invalid number of operands!"); 2234 Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 2235 } 2236 2237 void addNEONi8splatOperands(MCInst &Inst, unsigned N) const { 2238 assert(N == 1 && "Invalid number of operands!"); 2239 // The immediate encodes the type of constant as well as the value. 2240 // Mask in that this is an i8 splat. 2241 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2242 Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00)); 2243 } 2244 2245 void addNEONi16splatOperands(MCInst &Inst, unsigned N) const { 2246 assert(N == 1 && "Invalid number of operands!"); 2247 // The immediate encodes the type of constant as well as the value. 2248 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2249 unsigned Value = CE->getValue(); 2250 if (Value >= 256) 2251 Value = (Value >> 8) | 0xa00; 2252 else 2253 Value |= 0x800; 2254 Inst.addOperand(MCOperand::CreateImm(Value)); 2255 } 2256 2257 void addNEONi32splatOperands(MCInst &Inst, unsigned N) const { 2258 assert(N == 1 && "Invalid number of operands!"); 2259 // The immediate encodes the type of constant as well as the value. 2260 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2261 unsigned Value = CE->getValue(); 2262 if (Value >= 256 && Value <= 0xff00) 2263 Value = (Value >> 8) | 0x200; 2264 else if (Value > 0xffff && Value <= 0xff0000) 2265 Value = (Value >> 16) | 0x400; 2266 else if (Value > 0xffffff) 2267 Value = (Value >> 24) | 0x600; 2268 Inst.addOperand(MCOperand::CreateImm(Value)); 2269 } 2270 2271 void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const { 2272 assert(N == 1 && "Invalid number of operands!"); 2273 // The immediate encodes the type of constant as well as the value. 2274 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2275 unsigned Value = CE->getValue(); 2276 if (Value >= 256 && Value <= 0xffff) 2277 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 2278 else if (Value > 0xffff && Value <= 0xffffff) 2279 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 2280 else if (Value > 0xffffff) 2281 Value = (Value >> 24) | 0x600; 2282 Inst.addOperand(MCOperand::CreateImm(Value)); 2283 } 2284 2285 void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const { 2286 assert(N == 1 && "Invalid number of operands!"); 2287 // The immediate encodes the type of constant as well as the value. 2288 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2289 unsigned Value = ~CE->getValue(); 2290 if (Value >= 256 && Value <= 0xffff) 2291 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); 2292 else if (Value > 0xffff && Value <= 0xffffff) 2293 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); 2294 else if (Value > 0xffffff) 2295 Value = (Value >> 24) | 0x600; 2296 Inst.addOperand(MCOperand::CreateImm(Value)); 2297 } 2298 2299 void addNEONi64splatOperands(MCInst &Inst, unsigned N) const { 2300 assert(N == 1 && "Invalid number of operands!"); 2301 // The immediate encodes the type of constant as well as the value. 2302 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2303 uint64_t Value = CE->getValue(); 2304 unsigned Imm = 0; 2305 for (unsigned i = 0; i < 8; ++i, Value >>= 8) { 2306 Imm |= (Value & 1) << i; 2307 } 2308 Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00)); 2309 } 2310 2311 virtual void print(raw_ostream &OS) const; 2312 2313 static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 2314 ARMOperand *Op = new ARMOperand(k_ITCondMask); 2315 Op->ITMask.Mask = Mask; 2316 Op->StartLoc = S; 2317 Op->EndLoc = S; 2318 return Op; 2319 } 2320 2321 static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 2322 ARMOperand *Op = new ARMOperand(k_CondCode); 2323 Op->CC.Val = CC; 2324 Op->StartLoc = S; 2325 Op->EndLoc = S; 2326 return Op; 2327 } 2328 2329 static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 2330 ARMOperand *Op = new ARMOperand(k_CoprocNum); 2331 Op->Cop.Val = CopVal; 2332 Op->StartLoc = S; 2333 Op->EndLoc = S; 2334 return Op; 2335 } 2336 2337 static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 2338 ARMOperand *Op = new ARMOperand(k_CoprocReg); 2339 Op->Cop.Val = CopVal; 2340 Op->StartLoc = S; 2341 Op->EndLoc = S; 2342 return Op; 2343 } 2344 2345 static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) { 2346 ARMOperand *Op = new ARMOperand(k_CoprocOption); 2347 Op->Cop.Val = Val; 2348 Op->StartLoc = S; 2349 Op->EndLoc = E; 2350 return Op; 2351 } 2352 2353 static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 2354 ARMOperand *Op = new ARMOperand(k_CCOut); 2355 Op->Reg.RegNum = RegNum; 2356 Op->StartLoc = S; 2357 Op->EndLoc = S; 2358 return Op; 2359 } 2360 2361 static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 2362 ARMOperand *Op = new ARMOperand(k_Token); 2363 Op->Tok.Data = Str.data(); 2364 Op->Tok.Length = Str.size(); 2365 Op->StartLoc = S; 2366 Op->EndLoc = S; 2367 return Op; 2368 } 2369 2370 static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 2371 ARMOperand *Op = new ARMOperand(k_Register); 2372 Op->Reg.RegNum = RegNum; 2373 Op->StartLoc = S; 2374 Op->EndLoc = E; 2375 return Op; 2376 } 2377 2378 static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 2379 unsigned SrcReg, 2380 unsigned ShiftReg, 2381 unsigned ShiftImm, 2382 SMLoc S, SMLoc E) { 2383 ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 2384 Op->RegShiftedReg.ShiftTy = ShTy; 2385 Op->RegShiftedReg.SrcReg = SrcReg; 2386 Op->RegShiftedReg.ShiftReg = ShiftReg; 2387 Op->RegShiftedReg.ShiftImm = ShiftImm; 2388 Op->StartLoc = S; 2389 Op->EndLoc = E; 2390 return Op; 2391 } 2392 2393 static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 2394 unsigned SrcReg, 2395 unsigned ShiftImm, 2396 SMLoc S, SMLoc E) { 2397 ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 2398 Op->RegShiftedImm.ShiftTy = ShTy; 2399 Op->RegShiftedImm.SrcReg = SrcReg; 2400 Op->RegShiftedImm.ShiftImm = ShiftImm; 2401 Op->StartLoc = S; 2402 Op->EndLoc = E; 2403 return Op; 2404 } 2405 2406 static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 2407 SMLoc S, SMLoc E) { 2408 ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 2409 Op->ShifterImm.isASR = isASR; 2410 Op->ShifterImm.Imm = Imm; 2411 Op->StartLoc = S; 2412 Op->EndLoc = E; 2413 return Op; 2414 } 2415 2416 static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 2417 ARMOperand *Op = new ARMOperand(k_RotateImmediate); 2418 Op->RotImm.Imm = Imm; 2419 Op->StartLoc = S; 2420 Op->EndLoc = E; 2421 return Op; 2422 } 2423 2424 static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 2425 SMLoc S, SMLoc E) { 2426 ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 2427 Op->Bitfield.LSB = LSB; 2428 Op->Bitfield.Width = Width; 2429 Op->StartLoc = S; 2430 Op->EndLoc = E; 2431 return Op; 2432 } 2433 2434 static ARMOperand * 2435 CreateRegList(SmallVectorImpl<std::pair<unsigned, unsigned> > &Regs, 2436 SMLoc StartLoc, SMLoc EndLoc) { 2437 assert (Regs.size() > 0 && "RegList contains no registers?"); 2438 KindTy Kind = k_RegisterList; 2439 2440 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().second)) 2441 Kind = k_DPRRegisterList; 2442 else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 2443 contains(Regs.front().second)) 2444 Kind = k_SPRRegisterList; 2445 2446 // Sort based on the register encoding values. 2447 array_pod_sort(Regs.begin(), Regs.end()); 2448 2449 ARMOperand *Op = new ARMOperand(Kind); 2450 for (SmallVectorImpl<std::pair<unsigned, unsigned> >::const_iterator 2451 I = Regs.begin(), E = Regs.end(); I != E; ++I) 2452 Op->Registers.push_back(I->second); 2453 Op->StartLoc = StartLoc; 2454 Op->EndLoc = EndLoc; 2455 return Op; 2456 } 2457 2458 static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count, 2459 bool isDoubleSpaced, SMLoc S, SMLoc E) { 2460 ARMOperand *Op = new ARMOperand(k_VectorList); 2461 Op->VectorList.RegNum = RegNum; 2462 Op->VectorList.Count = Count; 2463 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 2464 Op->StartLoc = S; 2465 Op->EndLoc = E; 2466 return Op; 2467 } 2468 2469 static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count, 2470 bool isDoubleSpaced, 2471 SMLoc S, SMLoc E) { 2472 ARMOperand *Op = new ARMOperand(k_VectorListAllLanes); 2473 Op->VectorList.RegNum = RegNum; 2474 Op->VectorList.Count = Count; 2475 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 2476 Op->StartLoc = S; 2477 Op->EndLoc = E; 2478 return Op; 2479 } 2480 2481 static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count, 2482 unsigned Index, 2483 bool isDoubleSpaced, 2484 SMLoc S, SMLoc E) { 2485 ARMOperand *Op = new ARMOperand(k_VectorListIndexed); 2486 Op->VectorList.RegNum = RegNum; 2487 Op->VectorList.Count = Count; 2488 Op->VectorList.LaneIndex = Index; 2489 Op->VectorList.isDoubleSpaced = isDoubleSpaced; 2490 Op->StartLoc = S; 2491 Op->EndLoc = E; 2492 return Op; 2493 } 2494 2495 static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 2496 MCContext &Ctx) { 2497 ARMOperand *Op = new ARMOperand(k_VectorIndex); 2498 Op->VectorIndex.Val = Idx; 2499 Op->StartLoc = S; 2500 Op->EndLoc = E; 2501 return Op; 2502 } 2503 2504 static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 2505 ARMOperand *Op = new ARMOperand(k_Immediate); 2506 Op->Imm.Val = Val; 2507 Op->StartLoc = S; 2508 Op->EndLoc = E; 2509 return Op; 2510 } 2511 2512 static ARMOperand *CreateMem(unsigned BaseRegNum, 2513 const MCConstantExpr *OffsetImm, 2514 unsigned OffsetRegNum, 2515 ARM_AM::ShiftOpc ShiftType, 2516 unsigned ShiftImm, 2517 unsigned Alignment, 2518 bool isNegative, 2519 SMLoc S, SMLoc E) { 2520 ARMOperand *Op = new ARMOperand(k_Memory); 2521 Op->Memory.BaseRegNum = BaseRegNum; 2522 Op->Memory.OffsetImm = OffsetImm; 2523 Op->Memory.OffsetRegNum = OffsetRegNum; 2524 Op->Memory.ShiftType = ShiftType; 2525 Op->Memory.ShiftImm = ShiftImm; 2526 Op->Memory.Alignment = Alignment; 2527 Op->Memory.isNegative = isNegative; 2528 Op->StartLoc = S; 2529 Op->EndLoc = E; 2530 return Op; 2531 } 2532 2533 static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 2534 ARM_AM::ShiftOpc ShiftTy, 2535 unsigned ShiftImm, 2536 SMLoc S, SMLoc E) { 2537 ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 2538 Op->PostIdxReg.RegNum = RegNum; 2539 Op->PostIdxReg.isAdd = isAdd; 2540 Op->PostIdxReg.ShiftTy = ShiftTy; 2541 Op->PostIdxReg.ShiftImm = ShiftImm; 2542 Op->StartLoc = S; 2543 Op->EndLoc = E; 2544 return Op; 2545 } 2546 2547 static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 2548 ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 2549 Op->MBOpt.Val = Opt; 2550 Op->StartLoc = S; 2551 Op->EndLoc = S; 2552 return Op; 2553 } 2554 2555 static ARMOperand *CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, 2556 SMLoc S) { 2557 ARMOperand *Op = new ARMOperand(k_InstSyncBarrierOpt); 2558 Op->ISBOpt.Val = Opt; 2559 Op->StartLoc = S; 2560 Op->EndLoc = S; 2561 return Op; 2562 } 2563 2564 static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 2565 ARMOperand *Op = new ARMOperand(k_ProcIFlags); 2566 Op->IFlags.Val = IFlags; 2567 Op->StartLoc = S; 2568 Op->EndLoc = S; 2569 return Op; 2570 } 2571 2572 static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 2573 ARMOperand *Op = new ARMOperand(k_MSRMask); 2574 Op->MMask.Val = MMask; 2575 Op->StartLoc = S; 2576 Op->EndLoc = S; 2577 return Op; 2578 } 2579 }; 2580 2581 } // end anonymous namespace. 2582 2583 void ARMOperand::print(raw_ostream &OS) const { 2584 switch (Kind) { 2585 case k_CondCode: 2586 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 2587 break; 2588 case k_CCOut: 2589 OS << "<ccout " << getReg() << ">"; 2590 break; 2591 case k_ITCondMask: { 2592 static const char *const MaskStr[] = { 2593 "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)", 2594 "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)" 2595 }; 2596 assert((ITMask.Mask & 0xf) == ITMask.Mask); 2597 OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 2598 break; 2599 } 2600 case k_CoprocNum: 2601 OS << "<coprocessor number: " << getCoproc() << ">"; 2602 break; 2603 case k_CoprocReg: 2604 OS << "<coprocessor register: " << getCoproc() << ">"; 2605 break; 2606 case k_CoprocOption: 2607 OS << "<coprocessor option: " << CoprocOption.Val << ">"; 2608 break; 2609 case k_MSRMask: 2610 OS << "<mask: " << getMSRMask() << ">"; 2611 break; 2612 case k_Immediate: 2613 getImm()->print(OS); 2614 break; 2615 case k_MemBarrierOpt: 2616 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">"; 2617 break; 2618 case k_InstSyncBarrierOpt: 2619 OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">"; 2620 break; 2621 case k_Memory: 2622 OS << "<memory " 2623 << " base:" << Memory.BaseRegNum; 2624 OS << ">"; 2625 break; 2626 case k_PostIndexRegister: 2627 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 2628 << PostIdxReg.RegNum; 2629 if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 2630 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 2631 << PostIdxReg.ShiftImm; 2632 OS << ">"; 2633 break; 2634 case k_ProcIFlags: { 2635 OS << "<ARM_PROC::"; 2636 unsigned IFlags = getProcIFlags(); 2637 for (int i=2; i >= 0; --i) 2638 if (IFlags & (1 << i)) 2639 OS << ARM_PROC::IFlagsToString(1 << i); 2640 OS << ">"; 2641 break; 2642 } 2643 case k_Register: 2644 OS << "<register " << getReg() << ">"; 2645 break; 2646 case k_ShifterImmediate: 2647 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 2648 << " #" << ShifterImm.Imm << ">"; 2649 break; 2650 case k_ShiftedRegister: 2651 OS << "<so_reg_reg " 2652 << RegShiftedReg.SrcReg << " " 2653 << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy) 2654 << " " << RegShiftedReg.ShiftReg << ">"; 2655 break; 2656 case k_ShiftedImmediate: 2657 OS << "<so_reg_imm " 2658 << RegShiftedImm.SrcReg << " " 2659 << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy) 2660 << " #" << RegShiftedImm.ShiftImm << ">"; 2661 break; 2662 case k_RotateImmediate: 2663 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 2664 break; 2665 case k_BitfieldDescriptor: 2666 OS << "<bitfield " << "lsb: " << Bitfield.LSB 2667 << ", width: " << Bitfield.Width << ">"; 2668 break; 2669 case k_RegisterList: 2670 case k_DPRRegisterList: 2671 case k_SPRRegisterList: { 2672 OS << "<register_list "; 2673 2674 const SmallVectorImpl<unsigned> &RegList = getRegList(); 2675 for (SmallVectorImpl<unsigned>::const_iterator 2676 I = RegList.begin(), E = RegList.end(); I != E; ) { 2677 OS << *I; 2678 if (++I < E) OS << ", "; 2679 } 2680 2681 OS << ">"; 2682 break; 2683 } 2684 case k_VectorList: 2685 OS << "<vector_list " << VectorList.Count << " * " 2686 << VectorList.RegNum << ">"; 2687 break; 2688 case k_VectorListAllLanes: 2689 OS << "<vector_list(all lanes) " << VectorList.Count << " * " 2690 << VectorList.RegNum << ">"; 2691 break; 2692 case k_VectorListIndexed: 2693 OS << "<vector_list(lane " << VectorList.LaneIndex << ") " 2694 << VectorList.Count << " * " << VectorList.RegNum << ">"; 2695 break; 2696 case k_Token: 2697 OS << "'" << getToken() << "'"; 2698 break; 2699 case k_VectorIndex: 2700 OS << "<vectorindex " << getVectorIndex() << ">"; 2701 break; 2702 } 2703 } 2704 2705 /// @name Auto-generated Match Functions 2706 /// { 2707 2708 static unsigned MatchRegisterName(StringRef Name); 2709 2710 /// } 2711 2712 bool ARMAsmParser::ParseRegister(unsigned &RegNo, 2713 SMLoc &StartLoc, SMLoc &EndLoc) { 2714 StartLoc = Parser.getTok().getLoc(); 2715 EndLoc = Parser.getTok().getEndLoc(); 2716 RegNo = tryParseRegister(); 2717 2718 return (RegNo == (unsigned)-1); 2719 } 2720 2721 /// Try to parse a register name. The token must be an Identifier when called, 2722 /// and if it is a register name the token is eaten and the register number is 2723 /// returned. Otherwise return -1. 2724 /// 2725 int ARMAsmParser::tryParseRegister() { 2726 const AsmToken &Tok = Parser.getTok(); 2727 if (Tok.isNot(AsmToken::Identifier)) return -1; 2728 2729 std::string lowerCase = Tok.getString().lower(); 2730 unsigned RegNum = MatchRegisterName(lowerCase); 2731 if (!RegNum) { 2732 RegNum = StringSwitch<unsigned>(lowerCase) 2733 .Case("r13", ARM::SP) 2734 .Case("r14", ARM::LR) 2735 .Case("r15", ARM::PC) 2736 .Case("ip", ARM::R12) 2737 // Additional register name aliases for 'gas' compatibility. 2738 .Case("a1", ARM::R0) 2739 .Case("a2", ARM::R1) 2740 .Case("a3", ARM::R2) 2741 .Case("a4", ARM::R3) 2742 .Case("v1", ARM::R4) 2743 .Case("v2", ARM::R5) 2744 .Case("v3", ARM::R6) 2745 .Case("v4", ARM::R7) 2746 .Case("v5", ARM::R8) 2747 .Case("v6", ARM::R9) 2748 .Case("v7", ARM::R10) 2749 .Case("v8", ARM::R11) 2750 .Case("sb", ARM::R9) 2751 .Case("sl", ARM::R10) 2752 .Case("fp", ARM::R11) 2753 .Default(0); 2754 } 2755 if (!RegNum) { 2756 // Check for aliases registered via .req. Canonicalize to lower case. 2757 // That's more consistent since register names are case insensitive, and 2758 // it's how the original entry was passed in from MC/MCParser/AsmParser. 2759 StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase); 2760 // If no match, return failure. 2761 if (Entry == RegisterReqs.end()) 2762 return -1; 2763 Parser.Lex(); // Eat identifier token. 2764 return Entry->getValue(); 2765 } 2766 2767 Parser.Lex(); // Eat identifier token. 2768 2769 return RegNum; 2770 } 2771 2772 // Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 2773 // If a recoverable error occurs, return 1. If an irrecoverable error 2774 // occurs, return -1. An irrecoverable error is one where tokens have been 2775 // consumed in the process of trying to parse the shifter (i.e., when it is 2776 // indeed a shifter operand, but malformed). 2777 int ARMAsmParser::tryParseShiftRegister( 2778 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2779 SMLoc S = Parser.getTok().getLoc(); 2780 const AsmToken &Tok = Parser.getTok(); 2781 if (Tok.isNot(AsmToken::Identifier)) 2782 return -1; 2783 2784 std::string lowerCase = Tok.getString().lower(); 2785 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 2786 .Case("asl", ARM_AM::lsl) 2787 .Case("lsl", ARM_AM::lsl) 2788 .Case("lsr", ARM_AM::lsr) 2789 .Case("asr", ARM_AM::asr) 2790 .Case("ror", ARM_AM::ror) 2791 .Case("rrx", ARM_AM::rrx) 2792 .Default(ARM_AM::no_shift); 2793 2794 if (ShiftTy == ARM_AM::no_shift) 2795 return 1; 2796 2797 Parser.Lex(); // Eat the operator. 2798 2799 // The source register for the shift has already been added to the 2800 // operand list, so we need to pop it off and combine it into the shifted 2801 // register operand instead. 2802 OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 2803 if (!PrevOp->isReg()) 2804 return Error(PrevOp->getStartLoc(), "shift must be of a register"); 2805 int SrcReg = PrevOp->getReg(); 2806 2807 SMLoc EndLoc; 2808 int64_t Imm = 0; 2809 int ShiftReg = 0; 2810 if (ShiftTy == ARM_AM::rrx) { 2811 // RRX Doesn't have an explicit shift amount. The encoder expects 2812 // the shift register to be the same as the source register. Seems odd, 2813 // but OK. 2814 ShiftReg = SrcReg; 2815 } else { 2816 // Figure out if this is shifted by a constant or a register (for non-RRX). 2817 if (Parser.getTok().is(AsmToken::Hash) || 2818 Parser.getTok().is(AsmToken::Dollar)) { 2819 Parser.Lex(); // Eat hash. 2820 SMLoc ImmLoc = Parser.getTok().getLoc(); 2821 const MCExpr *ShiftExpr = 0; 2822 if (getParser().parseExpression(ShiftExpr, EndLoc)) { 2823 Error(ImmLoc, "invalid immediate shift value"); 2824 return -1; 2825 } 2826 // The expression must be evaluatable as an immediate. 2827 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 2828 if (!CE) { 2829 Error(ImmLoc, "invalid immediate shift value"); 2830 return -1; 2831 } 2832 // Range check the immediate. 2833 // lsl, ror: 0 <= imm <= 31 2834 // lsr, asr: 0 <= imm <= 32 2835 Imm = CE->getValue(); 2836 if (Imm < 0 || 2837 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 2838 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 2839 Error(ImmLoc, "immediate shift value out of range"); 2840 return -1; 2841 } 2842 // shift by zero is a nop. Always send it through as lsl. 2843 // ('as' compatibility) 2844 if (Imm == 0) 2845 ShiftTy = ARM_AM::lsl; 2846 } else if (Parser.getTok().is(AsmToken::Identifier)) { 2847 SMLoc L = Parser.getTok().getLoc(); 2848 EndLoc = Parser.getTok().getEndLoc(); 2849 ShiftReg = tryParseRegister(); 2850 if (ShiftReg == -1) { 2851 Error (L, "expected immediate or register in shift operand"); 2852 return -1; 2853 } 2854 } else { 2855 Error (Parser.getTok().getLoc(), 2856 "expected immediate or register in shift operand"); 2857 return -1; 2858 } 2859 } 2860 2861 if (ShiftReg && ShiftTy != ARM_AM::rrx) 2862 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 2863 ShiftReg, Imm, 2864 S, EndLoc)); 2865 else 2866 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 2867 S, EndLoc)); 2868 2869 return 0; 2870 } 2871 2872 2873 /// Try to parse a register name. The token must be an Identifier when called. 2874 /// If it's a register, an AsmOperand is created. Another AsmOperand is created 2875 /// if there is a "writeback". 'true' if it's not a register. 2876 /// 2877 /// TODO this is likely to change to allow different register types and or to 2878 /// parse for a specific register type. 2879 bool ARMAsmParser:: 2880 tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2881 const AsmToken &RegTok = Parser.getTok(); 2882 int RegNo = tryParseRegister(); 2883 if (RegNo == -1) 2884 return true; 2885 2886 Operands.push_back(ARMOperand::CreateReg(RegNo, RegTok.getLoc(), 2887 RegTok.getEndLoc())); 2888 2889 const AsmToken &ExclaimTok = Parser.getTok(); 2890 if (ExclaimTok.is(AsmToken::Exclaim)) { 2891 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 2892 ExclaimTok.getLoc())); 2893 Parser.Lex(); // Eat exclaim token 2894 return false; 2895 } 2896 2897 // Also check for an index operand. This is only legal for vector registers, 2898 // but that'll get caught OK in operand matching, so we don't need to 2899 // explicitly filter everything else out here. 2900 if (Parser.getTok().is(AsmToken::LBrac)) { 2901 SMLoc SIdx = Parser.getTok().getLoc(); 2902 Parser.Lex(); // Eat left bracket token. 2903 2904 const MCExpr *ImmVal; 2905 if (getParser().parseExpression(ImmVal)) 2906 return true; 2907 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 2908 if (!MCE) 2909 return TokError("immediate value expected for vector index"); 2910 2911 if (Parser.getTok().isNot(AsmToken::RBrac)) 2912 return Error(Parser.getTok().getLoc(), "']' expected"); 2913 2914 SMLoc E = Parser.getTok().getEndLoc(); 2915 Parser.Lex(); // Eat right bracket token. 2916 2917 Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 2918 SIdx, E, 2919 getContext())); 2920 } 2921 2922 return false; 2923 } 2924 2925 /// MatchCoprocessorOperandName - Try to parse an coprocessor related 2926 /// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 2927 /// "c5", ... 2928 static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 2929 // Use the same layout as the tablegen'erated register name matcher. Ugly, 2930 // but efficient. 2931 switch (Name.size()) { 2932 default: return -1; 2933 case 2: 2934 if (Name[0] != CoprocOp) 2935 return -1; 2936 switch (Name[1]) { 2937 default: return -1; 2938 case '0': return 0; 2939 case '1': return 1; 2940 case '2': return 2; 2941 case '3': return 3; 2942 case '4': return 4; 2943 case '5': return 5; 2944 case '6': return 6; 2945 case '7': return 7; 2946 case '8': return 8; 2947 case '9': return 9; 2948 } 2949 case 3: 2950 if (Name[0] != CoprocOp || Name[1] != '1') 2951 return -1; 2952 switch (Name[2]) { 2953 default: return -1; 2954 // p10 and p11 are invalid for coproc instructions (reserved for FP/NEON) 2955 case '0': return CoprocOp == 'p'? -1: 10; 2956 case '1': return CoprocOp == 'p'? -1: 11; 2957 case '2': return 12; 2958 case '3': return 13; 2959 case '4': return 14; 2960 case '5': return 15; 2961 } 2962 } 2963 } 2964 2965 /// parseITCondCode - Try to parse a condition code for an IT instruction. 2966 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2967 parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2968 SMLoc S = Parser.getTok().getLoc(); 2969 const AsmToken &Tok = Parser.getTok(); 2970 if (!Tok.is(AsmToken::Identifier)) 2971 return MatchOperand_NoMatch; 2972 unsigned CC = StringSwitch<unsigned>(Tok.getString().lower()) 2973 .Case("eq", ARMCC::EQ) 2974 .Case("ne", ARMCC::NE) 2975 .Case("hs", ARMCC::HS) 2976 .Case("cs", ARMCC::HS) 2977 .Case("lo", ARMCC::LO) 2978 .Case("cc", ARMCC::LO) 2979 .Case("mi", ARMCC::MI) 2980 .Case("pl", ARMCC::PL) 2981 .Case("vs", ARMCC::VS) 2982 .Case("vc", ARMCC::VC) 2983 .Case("hi", ARMCC::HI) 2984 .Case("ls", ARMCC::LS) 2985 .Case("ge", ARMCC::GE) 2986 .Case("lt", ARMCC::LT) 2987 .Case("gt", ARMCC::GT) 2988 .Case("le", ARMCC::LE) 2989 .Case("al", ARMCC::AL) 2990 .Default(~0U); 2991 if (CC == ~0U) 2992 return MatchOperand_NoMatch; 2993 Parser.Lex(); // Eat the token. 2994 2995 Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 2996 2997 return MatchOperand_Success; 2998 } 2999 3000 /// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 3001 /// token must be an Identifier when called, and if it is a coprocessor 3002 /// number, the token is eaten and the operand is added to the operand list. 3003 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3004 parseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3005 SMLoc S = Parser.getTok().getLoc(); 3006 const AsmToken &Tok = Parser.getTok(); 3007 if (Tok.isNot(AsmToken::Identifier)) 3008 return MatchOperand_NoMatch; 3009 3010 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 3011 if (Num == -1) 3012 return MatchOperand_NoMatch; 3013 3014 Parser.Lex(); // Eat identifier token. 3015 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 3016 return MatchOperand_Success; 3017 } 3018 3019 /// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 3020 /// token must be an Identifier when called, and if it is a coprocessor 3021 /// number, the token is eaten and the operand is added to the operand list. 3022 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3023 parseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3024 SMLoc S = Parser.getTok().getLoc(); 3025 const AsmToken &Tok = Parser.getTok(); 3026 if (Tok.isNot(AsmToken::Identifier)) 3027 return MatchOperand_NoMatch; 3028 3029 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 3030 if (Reg == -1) 3031 return MatchOperand_NoMatch; 3032 3033 Parser.Lex(); // Eat identifier token. 3034 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 3035 return MatchOperand_Success; 3036 } 3037 3038 /// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 3039 /// coproc_option : '{' imm0_255 '}' 3040 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3041 parseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3042 SMLoc S = Parser.getTok().getLoc(); 3043 3044 // If this isn't a '{', this isn't a coprocessor immediate operand. 3045 if (Parser.getTok().isNot(AsmToken::LCurly)) 3046 return MatchOperand_NoMatch; 3047 Parser.Lex(); // Eat the '{' 3048 3049 const MCExpr *Expr; 3050 SMLoc Loc = Parser.getTok().getLoc(); 3051 if (getParser().parseExpression(Expr)) { 3052 Error(Loc, "illegal expression"); 3053 return MatchOperand_ParseFail; 3054 } 3055 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 3056 if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 3057 Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 3058 return MatchOperand_ParseFail; 3059 } 3060 int Val = CE->getValue(); 3061 3062 // Check for and consume the closing '}' 3063 if (Parser.getTok().isNot(AsmToken::RCurly)) 3064 return MatchOperand_ParseFail; 3065 SMLoc E = Parser.getTok().getEndLoc(); 3066 Parser.Lex(); // Eat the '}' 3067 3068 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 3069 return MatchOperand_Success; 3070 } 3071 3072 // For register list parsing, we need to map from raw GPR register numbering 3073 // to the enumeration values. The enumeration values aren't sorted by 3074 // register number due to our using "sp", "lr" and "pc" as canonical names. 3075 static unsigned getNextRegister(unsigned Reg) { 3076 // If this is a GPR, we need to do it manually, otherwise we can rely 3077 // on the sort ordering of the enumeration since the other reg-classes 3078 // are sane. 3079 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 3080 return Reg + 1; 3081 switch(Reg) { 3082 default: llvm_unreachable("Invalid GPR number!"); 3083 case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 3084 case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 3085 case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 3086 case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 3087 case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 3088 case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 3089 case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 3090 case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 3091 } 3092 } 3093 3094 // Return the low-subreg of a given Q register. 3095 static unsigned getDRegFromQReg(unsigned QReg) { 3096 switch (QReg) { 3097 default: llvm_unreachable("expected a Q register!"); 3098 case ARM::Q0: return ARM::D0; 3099 case ARM::Q1: return ARM::D2; 3100 case ARM::Q2: return ARM::D4; 3101 case ARM::Q3: return ARM::D6; 3102 case ARM::Q4: return ARM::D8; 3103 case ARM::Q5: return ARM::D10; 3104 case ARM::Q6: return ARM::D12; 3105 case ARM::Q7: return ARM::D14; 3106 case ARM::Q8: return ARM::D16; 3107 case ARM::Q9: return ARM::D18; 3108 case ARM::Q10: return ARM::D20; 3109 case ARM::Q11: return ARM::D22; 3110 case ARM::Q12: return ARM::D24; 3111 case ARM::Q13: return ARM::D26; 3112 case ARM::Q14: return ARM::D28; 3113 case ARM::Q15: return ARM::D30; 3114 } 3115 } 3116 3117 /// Parse a register list. 3118 bool ARMAsmParser:: 3119 parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3120 assert(Parser.getTok().is(AsmToken::LCurly) && 3121 "Token is not a Left Curly Brace"); 3122 SMLoc S = Parser.getTok().getLoc(); 3123 Parser.Lex(); // Eat '{' token. 3124 SMLoc RegLoc = Parser.getTok().getLoc(); 3125 3126 // Check the first register in the list to see what register class 3127 // this is a list of. 3128 int Reg = tryParseRegister(); 3129 if (Reg == -1) 3130 return Error(RegLoc, "register expected"); 3131 3132 // The reglist instructions have at most 16 registers, so reserve 3133 // space for that many. 3134 int EReg = 0; 3135 SmallVector<std::pair<unsigned, unsigned>, 16> Registers; 3136 3137 // Allow Q regs and just interpret them as the two D sub-registers. 3138 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3139 Reg = getDRegFromQReg(Reg); 3140 EReg = MRI->getEncodingValue(Reg); 3141 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3142 ++Reg; 3143 } 3144 const MCRegisterClass *RC; 3145 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 3146 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 3147 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 3148 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 3149 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 3150 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 3151 else 3152 return Error(RegLoc, "invalid register in register list"); 3153 3154 // Store the register. 3155 EReg = MRI->getEncodingValue(Reg); 3156 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3157 3158 // This starts immediately after the first register token in the list, 3159 // so we can see either a comma or a minus (range separator) as a legal 3160 // next token. 3161 while (Parser.getTok().is(AsmToken::Comma) || 3162 Parser.getTok().is(AsmToken::Minus)) { 3163 if (Parser.getTok().is(AsmToken::Minus)) { 3164 Parser.Lex(); // Eat the minus. 3165 SMLoc AfterMinusLoc = Parser.getTok().getLoc(); 3166 int EndReg = tryParseRegister(); 3167 if (EndReg == -1) 3168 return Error(AfterMinusLoc, "register expected"); 3169 // Allow Q regs and just interpret them as the two D sub-registers. 3170 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 3171 EndReg = getDRegFromQReg(EndReg) + 1; 3172 // If the register is the same as the start reg, there's nothing 3173 // more to do. 3174 if (Reg == EndReg) 3175 continue; 3176 // The register must be in the same register class as the first. 3177 if (!RC->contains(EndReg)) 3178 return Error(AfterMinusLoc, "invalid register in register list"); 3179 // Ranges must go from low to high. 3180 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg)) 3181 return Error(AfterMinusLoc, "bad range in register list"); 3182 3183 // Add all the registers in the range to the register list. 3184 while (Reg != EndReg) { 3185 Reg = getNextRegister(Reg); 3186 EReg = MRI->getEncodingValue(Reg); 3187 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3188 } 3189 continue; 3190 } 3191 Parser.Lex(); // Eat the comma. 3192 RegLoc = Parser.getTok().getLoc(); 3193 int OldReg = Reg; 3194 const AsmToken RegTok = Parser.getTok(); 3195 Reg = tryParseRegister(); 3196 if (Reg == -1) 3197 return Error(RegLoc, "register expected"); 3198 // Allow Q regs and just interpret them as the two D sub-registers. 3199 bool isQReg = false; 3200 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3201 Reg = getDRegFromQReg(Reg); 3202 isQReg = true; 3203 } 3204 // The register must be in the same register class as the first. 3205 if (!RC->contains(Reg)) 3206 return Error(RegLoc, "invalid register in register list"); 3207 // List must be monotonically increasing. 3208 if (MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) { 3209 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 3210 Warning(RegLoc, "register list not in ascending order"); 3211 else 3212 return Error(RegLoc, "register list not in ascending order"); 3213 } 3214 if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) { 3215 Warning(RegLoc, "duplicated register (" + RegTok.getString() + 3216 ") in register list"); 3217 continue; 3218 } 3219 // VFP register lists must also be contiguous. 3220 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 3221 Reg != OldReg + 1) 3222 return Error(RegLoc, "non-contiguous register range"); 3223 EReg = MRI->getEncodingValue(Reg); 3224 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3225 if (isQReg) { 3226 EReg = MRI->getEncodingValue(++Reg); 3227 Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg)); 3228 } 3229 } 3230 3231 if (Parser.getTok().isNot(AsmToken::RCurly)) 3232 return Error(Parser.getTok().getLoc(), "'}' expected"); 3233 SMLoc E = Parser.getTok().getEndLoc(); 3234 Parser.Lex(); // Eat '}' token. 3235 3236 // Push the register list operand. 3237 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 3238 3239 // The ARM system instruction variants for LDM/STM have a '^' token here. 3240 if (Parser.getTok().is(AsmToken::Caret)) { 3241 Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc())); 3242 Parser.Lex(); // Eat '^' token. 3243 } 3244 3245 return false; 3246 } 3247 3248 // Helper function to parse the lane index for vector lists. 3249 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3250 parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, SMLoc &EndLoc) { 3251 Index = 0; // Always return a defined index value. 3252 if (Parser.getTok().is(AsmToken::LBrac)) { 3253 Parser.Lex(); // Eat the '['. 3254 if (Parser.getTok().is(AsmToken::RBrac)) { 3255 // "Dn[]" is the 'all lanes' syntax. 3256 LaneKind = AllLanes; 3257 EndLoc = Parser.getTok().getEndLoc(); 3258 Parser.Lex(); // Eat the ']'. 3259 return MatchOperand_Success; 3260 } 3261 3262 // There's an optional '#' token here. Normally there wouldn't be, but 3263 // inline assemble puts one in, and it's friendly to accept that. 3264 if (Parser.getTok().is(AsmToken::Hash)) 3265 Parser.Lex(); // Eat '#' or '$'. 3266 3267 const MCExpr *LaneIndex; 3268 SMLoc Loc = Parser.getTok().getLoc(); 3269 if (getParser().parseExpression(LaneIndex)) { 3270 Error(Loc, "illegal expression"); 3271 return MatchOperand_ParseFail; 3272 } 3273 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex); 3274 if (!CE) { 3275 Error(Loc, "lane index must be empty or an integer"); 3276 return MatchOperand_ParseFail; 3277 } 3278 if (Parser.getTok().isNot(AsmToken::RBrac)) { 3279 Error(Parser.getTok().getLoc(), "']' expected"); 3280 return MatchOperand_ParseFail; 3281 } 3282 EndLoc = Parser.getTok().getEndLoc(); 3283 Parser.Lex(); // Eat the ']'. 3284 int64_t Val = CE->getValue(); 3285 3286 // FIXME: Make this range check context sensitive for .8, .16, .32. 3287 if (Val < 0 || Val > 7) { 3288 Error(Parser.getTok().getLoc(), "lane index out of range"); 3289 return MatchOperand_ParseFail; 3290 } 3291 Index = Val; 3292 LaneKind = IndexedLane; 3293 return MatchOperand_Success; 3294 } 3295 LaneKind = NoLanes; 3296 return MatchOperand_Success; 3297 } 3298 3299 // parse a vector register list 3300 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3301 parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3302 VectorLaneTy LaneKind; 3303 unsigned LaneIndex; 3304 SMLoc S = Parser.getTok().getLoc(); 3305 // As an extension (to match gas), support a plain D register or Q register 3306 // (without encosing curly braces) as a single or double entry list, 3307 // respectively. 3308 if (Parser.getTok().is(AsmToken::Identifier)) { 3309 SMLoc E = Parser.getTok().getEndLoc(); 3310 int Reg = tryParseRegister(); 3311 if (Reg == -1) 3312 return MatchOperand_NoMatch; 3313 if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) { 3314 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E); 3315 if (Res != MatchOperand_Success) 3316 return Res; 3317 switch (LaneKind) { 3318 case NoLanes: 3319 Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E)); 3320 break; 3321 case AllLanes: 3322 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false, 3323 S, E)); 3324 break; 3325 case IndexedLane: 3326 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1, 3327 LaneIndex, 3328 false, S, E)); 3329 break; 3330 } 3331 return MatchOperand_Success; 3332 } 3333 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3334 Reg = getDRegFromQReg(Reg); 3335 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E); 3336 if (Res != MatchOperand_Success) 3337 return Res; 3338 switch (LaneKind) { 3339 case NoLanes: 3340 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0, 3341 &ARMMCRegisterClasses[ARM::DPairRegClassID]); 3342 Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E)); 3343 break; 3344 case AllLanes: 3345 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0, 3346 &ARMMCRegisterClasses[ARM::DPairRegClassID]); 3347 Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false, 3348 S, E)); 3349 break; 3350 case IndexedLane: 3351 Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2, 3352 LaneIndex, 3353 false, S, E)); 3354 break; 3355 } 3356 return MatchOperand_Success; 3357 } 3358 Error(S, "vector register expected"); 3359 return MatchOperand_ParseFail; 3360 } 3361 3362 if (Parser.getTok().isNot(AsmToken::LCurly)) 3363 return MatchOperand_NoMatch; 3364 3365 Parser.Lex(); // Eat '{' token. 3366 SMLoc RegLoc = Parser.getTok().getLoc(); 3367 3368 int Reg = tryParseRegister(); 3369 if (Reg == -1) { 3370 Error(RegLoc, "register expected"); 3371 return MatchOperand_ParseFail; 3372 } 3373 unsigned Count = 1; 3374 int Spacing = 0; 3375 unsigned FirstReg = Reg; 3376 // The list is of D registers, but we also allow Q regs and just interpret 3377 // them as the two D sub-registers. 3378 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3379 FirstReg = Reg = getDRegFromQReg(Reg); 3380 Spacing = 1; // double-spacing requires explicit D registers, otherwise 3381 // it's ambiguous with four-register single spaced. 3382 ++Reg; 3383 ++Count; 3384 } 3385 3386 SMLoc E; 3387 if (parseVectorLane(LaneKind, LaneIndex, E) != MatchOperand_Success) 3388 return MatchOperand_ParseFail; 3389 3390 while (Parser.getTok().is(AsmToken::Comma) || 3391 Parser.getTok().is(AsmToken::Minus)) { 3392 if (Parser.getTok().is(AsmToken::Minus)) { 3393 if (!Spacing) 3394 Spacing = 1; // Register range implies a single spaced list. 3395 else if (Spacing == 2) { 3396 Error(Parser.getTok().getLoc(), 3397 "sequential registers in double spaced list"); 3398 return MatchOperand_ParseFail; 3399 } 3400 Parser.Lex(); // Eat the minus. 3401 SMLoc AfterMinusLoc = Parser.getTok().getLoc(); 3402 int EndReg = tryParseRegister(); 3403 if (EndReg == -1) { 3404 Error(AfterMinusLoc, "register expected"); 3405 return MatchOperand_ParseFail; 3406 } 3407 // Allow Q regs and just interpret them as the two D sub-registers. 3408 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg)) 3409 EndReg = getDRegFromQReg(EndReg) + 1; 3410 // If the register is the same as the start reg, there's nothing 3411 // more to do. 3412 if (Reg == EndReg) 3413 continue; 3414 // The register must be in the same register class as the first. 3415 if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) { 3416 Error(AfterMinusLoc, "invalid register in register list"); 3417 return MatchOperand_ParseFail; 3418 } 3419 // Ranges must go from low to high. 3420 if (Reg > EndReg) { 3421 Error(AfterMinusLoc, "bad range in register list"); 3422 return MatchOperand_ParseFail; 3423 } 3424 // Parse the lane specifier if present. 3425 VectorLaneTy NextLaneKind; 3426 unsigned NextLaneIndex; 3427 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != 3428 MatchOperand_Success) 3429 return MatchOperand_ParseFail; 3430 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 3431 Error(AfterMinusLoc, "mismatched lane index in register list"); 3432 return MatchOperand_ParseFail; 3433 } 3434 3435 // Add all the registers in the range to the register list. 3436 Count += EndReg - Reg; 3437 Reg = EndReg; 3438 continue; 3439 } 3440 Parser.Lex(); // Eat the comma. 3441 RegLoc = Parser.getTok().getLoc(); 3442 int OldReg = Reg; 3443 Reg = tryParseRegister(); 3444 if (Reg == -1) { 3445 Error(RegLoc, "register expected"); 3446 return MatchOperand_ParseFail; 3447 } 3448 // vector register lists must be contiguous. 3449 // It's OK to use the enumeration values directly here rather, as the 3450 // VFP register classes have the enum sorted properly. 3451 // 3452 // The list is of D registers, but we also allow Q regs and just interpret 3453 // them as the two D sub-registers. 3454 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) { 3455 if (!Spacing) 3456 Spacing = 1; // Register range implies a single spaced list. 3457 else if (Spacing == 2) { 3458 Error(RegLoc, 3459 "invalid register in double-spaced list (must be 'D' register')"); 3460 return MatchOperand_ParseFail; 3461 } 3462 Reg = getDRegFromQReg(Reg); 3463 if (Reg != OldReg + 1) { 3464 Error(RegLoc, "non-contiguous register range"); 3465 return MatchOperand_ParseFail; 3466 } 3467 ++Reg; 3468 Count += 2; 3469 // Parse the lane specifier if present. 3470 VectorLaneTy NextLaneKind; 3471 unsigned NextLaneIndex; 3472 SMLoc LaneLoc = Parser.getTok().getLoc(); 3473 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != 3474 MatchOperand_Success) 3475 return MatchOperand_ParseFail; 3476 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 3477 Error(LaneLoc, "mismatched lane index in register list"); 3478 return MatchOperand_ParseFail; 3479 } 3480 continue; 3481 } 3482 // Normal D register. 3483 // Figure out the register spacing (single or double) of the list if 3484 // we don't know it already. 3485 if (!Spacing) 3486 Spacing = 1 + (Reg == OldReg + 2); 3487 3488 // Just check that it's contiguous and keep going. 3489 if (Reg != OldReg + Spacing) { 3490 Error(RegLoc, "non-contiguous register range"); 3491 return MatchOperand_ParseFail; 3492 } 3493 ++Count; 3494 // Parse the lane specifier if present. 3495 VectorLaneTy NextLaneKind; 3496 unsigned NextLaneIndex; 3497 SMLoc EndLoc = Parser.getTok().getLoc(); 3498 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != MatchOperand_Success) 3499 return MatchOperand_ParseFail; 3500 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) { 3501 Error(EndLoc, "mismatched lane index in register list"); 3502 return MatchOperand_ParseFail; 3503 } 3504 } 3505 3506 if (Parser.getTok().isNot(AsmToken::RCurly)) { 3507 Error(Parser.getTok().getLoc(), "'}' expected"); 3508 return MatchOperand_ParseFail; 3509 } 3510 E = Parser.getTok().getEndLoc(); 3511 Parser.Lex(); // Eat '}' token. 3512 3513 switch (LaneKind) { 3514 case NoLanes: 3515 // Two-register operands have been converted to the 3516 // composite register classes. 3517 if (Count == 2) { 3518 const MCRegisterClass *RC = (Spacing == 1) ? 3519 &ARMMCRegisterClasses[ARM::DPairRegClassID] : 3520 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID]; 3521 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC); 3522 } 3523 3524 Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, 3525 (Spacing == 2), S, E)); 3526 break; 3527 case AllLanes: 3528 // Two-register operands have been converted to the 3529 // composite register classes. 3530 if (Count == 2) { 3531 const MCRegisterClass *RC = (Spacing == 1) ? 3532 &ARMMCRegisterClasses[ARM::DPairRegClassID] : 3533 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID]; 3534 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC); 3535 } 3536 Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count, 3537 (Spacing == 2), 3538 S, E)); 3539 break; 3540 case IndexedLane: 3541 Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count, 3542 LaneIndex, 3543 (Spacing == 2), 3544 S, E)); 3545 break; 3546 } 3547 return MatchOperand_Success; 3548 } 3549 3550 /// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 3551 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3552 parseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3553 SMLoc S = Parser.getTok().getLoc(); 3554 const AsmToken &Tok = Parser.getTok(); 3555 unsigned Opt; 3556 3557 if (Tok.is(AsmToken::Identifier)) { 3558 StringRef OptStr = Tok.getString(); 3559 3560 Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()).lower()) 3561 .Case("sy", ARM_MB::SY) 3562 .Case("st", ARM_MB::ST) 3563 .Case("ld", ARM_MB::LD) 3564 .Case("sh", ARM_MB::ISH) 3565 .Case("ish", ARM_MB::ISH) 3566 .Case("shst", ARM_MB::ISHST) 3567 .Case("ishst", ARM_MB::ISHST) 3568 .Case("ishld", ARM_MB::ISHLD) 3569 .Case("nsh", ARM_MB::NSH) 3570 .Case("un", ARM_MB::NSH) 3571 .Case("nshst", ARM_MB::NSHST) 3572 .Case("nshld", ARM_MB::NSHLD) 3573 .Case("unst", ARM_MB::NSHST) 3574 .Case("osh", ARM_MB::OSH) 3575 .Case("oshst", ARM_MB::OSHST) 3576 .Case("oshld", ARM_MB::OSHLD) 3577 .Default(~0U); 3578 3579 // ishld, oshld, nshld and ld are only available from ARMv8. 3580 if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD || 3581 Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD)) 3582 Opt = ~0U; 3583 3584 if (Opt == ~0U) 3585 return MatchOperand_NoMatch; 3586 3587 Parser.Lex(); // Eat identifier token. 3588 } else if (Tok.is(AsmToken::Hash) || 3589 Tok.is(AsmToken::Dollar) || 3590 Tok.is(AsmToken::Integer)) { 3591 if (Parser.getTok().isNot(AsmToken::Integer)) 3592 Parser.Lex(); // Eat '#' or '$'. 3593 SMLoc Loc = Parser.getTok().getLoc(); 3594 3595 const MCExpr *MemBarrierID; 3596 if (getParser().parseExpression(MemBarrierID)) { 3597 Error(Loc, "illegal expression"); 3598 return MatchOperand_ParseFail; 3599 } 3600 3601 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID); 3602 if (!CE) { 3603 Error(Loc, "constant expression expected"); 3604 return MatchOperand_ParseFail; 3605 } 3606 3607 int Val = CE->getValue(); 3608 if (Val & ~0xf) { 3609 Error(Loc, "immediate value out of range"); 3610 return MatchOperand_ParseFail; 3611 } 3612 3613 Opt = ARM_MB::RESERVED_0 + Val; 3614 } else 3615 return MatchOperand_ParseFail; 3616 3617 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 3618 return MatchOperand_Success; 3619 } 3620 3621 /// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options. 3622 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3623 parseInstSyncBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3624 SMLoc S = Parser.getTok().getLoc(); 3625 const AsmToken &Tok = Parser.getTok(); 3626 unsigned Opt; 3627 3628 if (Tok.is(AsmToken::Identifier)) { 3629 StringRef OptStr = Tok.getString(); 3630 3631 if (OptStr.equals_lower("sy")) 3632 Opt = ARM_ISB::SY; 3633 else 3634 return MatchOperand_NoMatch; 3635 3636 Parser.Lex(); // Eat identifier token. 3637 } else if (Tok.is(AsmToken::Hash) || 3638 Tok.is(AsmToken::Dollar) || 3639 Tok.is(AsmToken::Integer)) { 3640 if (Parser.getTok().isNot(AsmToken::Integer)) 3641 Parser.Lex(); // Eat '#' or '$'. 3642 SMLoc Loc = Parser.getTok().getLoc(); 3643 3644 const MCExpr *ISBarrierID; 3645 if (getParser().parseExpression(ISBarrierID)) { 3646 Error(Loc, "illegal expression"); 3647 return MatchOperand_ParseFail; 3648 } 3649 3650 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID); 3651 if (!CE) { 3652 Error(Loc, "constant expression expected"); 3653 return MatchOperand_ParseFail; 3654 } 3655 3656 int Val = CE->getValue(); 3657 if (Val & ~0xf) { 3658 Error(Loc, "immediate value out of range"); 3659 return MatchOperand_ParseFail; 3660 } 3661 3662 Opt = ARM_ISB::RESERVED_0 + Val; 3663 } else 3664 return MatchOperand_ParseFail; 3665 3666 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt( 3667 (ARM_ISB::InstSyncBOpt)Opt, S)); 3668 return MatchOperand_Success; 3669 } 3670 3671 3672 /// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 3673 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3674 parseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3675 SMLoc S = Parser.getTok().getLoc(); 3676 const AsmToken &Tok = Parser.getTok(); 3677 if (!Tok.is(AsmToken::Identifier)) 3678 return MatchOperand_NoMatch; 3679 StringRef IFlagsStr = Tok.getString(); 3680 3681 // An iflags string of "none" is interpreted to mean that none of the AIF 3682 // bits are set. Not a terribly useful instruction, but a valid encoding. 3683 unsigned IFlags = 0; 3684 if (IFlagsStr != "none") { 3685 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 3686 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 3687 .Case("a", ARM_PROC::A) 3688 .Case("i", ARM_PROC::I) 3689 .Case("f", ARM_PROC::F) 3690 .Default(~0U); 3691 3692 // If some specific iflag is already set, it means that some letter is 3693 // present more than once, this is not acceptable. 3694 if (Flag == ~0U || (IFlags & Flag)) 3695 return MatchOperand_NoMatch; 3696 3697 IFlags |= Flag; 3698 } 3699 } 3700 3701 Parser.Lex(); // Eat identifier token. 3702 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 3703 return MatchOperand_Success; 3704 } 3705 3706 /// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 3707 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3708 parseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3709 SMLoc S = Parser.getTok().getLoc(); 3710 const AsmToken &Tok = Parser.getTok(); 3711 if (!Tok.is(AsmToken::Identifier)) 3712 return MatchOperand_NoMatch; 3713 StringRef Mask = Tok.getString(); 3714 3715 if (isMClass()) { 3716 // See ARMv6-M 10.1.1 3717 std::string Name = Mask.lower(); 3718 unsigned FlagsVal = StringSwitch<unsigned>(Name) 3719 // Note: in the documentation: 3720 // ARM deprecates using MSR APSR without a _<bits> qualifier as an alias 3721 // for MSR APSR_nzcvq. 3722 // but we do make it an alias here. This is so to get the "mask encoding" 3723 // bits correct on MSR APSR writes. 3724 // 3725 // FIXME: Note the 0xc00 "mask encoding" bits version of the registers 3726 // should really only be allowed when writing a special register. Note 3727 // they get dropped in the MRS instruction reading a special register as 3728 // the SYSm field is only 8 bits. 3729 // 3730 // FIXME: the _g and _nzcvqg versions are only allowed if the processor 3731 // includes the DSP extension but that is not checked. 3732 .Case("apsr", 0x800) 3733 .Case("apsr_nzcvq", 0x800) 3734 .Case("apsr_g", 0x400) 3735 .Case("apsr_nzcvqg", 0xc00) 3736 .Case("iapsr", 0x801) 3737 .Case("iapsr_nzcvq", 0x801) 3738 .Case("iapsr_g", 0x401) 3739 .Case("iapsr_nzcvqg", 0xc01) 3740 .Case("eapsr", 0x802) 3741 .Case("eapsr_nzcvq", 0x802) 3742 .Case("eapsr_g", 0x402) 3743 .Case("eapsr_nzcvqg", 0xc02) 3744 .Case("xpsr", 0x803) 3745 .Case("xpsr_nzcvq", 0x803) 3746 .Case("xpsr_g", 0x403) 3747 .Case("xpsr_nzcvqg", 0xc03) 3748 .Case("ipsr", 0x805) 3749 .Case("epsr", 0x806) 3750 .Case("iepsr", 0x807) 3751 .Case("msp", 0x808) 3752 .Case("psp", 0x809) 3753 .Case("primask", 0x810) 3754 .Case("basepri", 0x811) 3755 .Case("basepri_max", 0x812) 3756 .Case("faultmask", 0x813) 3757 .Case("control", 0x814) 3758 .Default(~0U); 3759 3760 if (FlagsVal == ~0U) 3761 return MatchOperand_NoMatch; 3762 3763 if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813) 3764 // basepri, basepri_max and faultmask only valid for V7m. 3765 return MatchOperand_NoMatch; 3766 3767 Parser.Lex(); // Eat identifier token. 3768 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 3769 return MatchOperand_Success; 3770 } 3771 3772 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 3773 size_t Start = 0, Next = Mask.find('_'); 3774 StringRef Flags = ""; 3775 std::string SpecReg = Mask.slice(Start, Next).lower(); 3776 if (Next != StringRef::npos) 3777 Flags = Mask.slice(Next+1, Mask.size()); 3778 3779 // FlagsVal contains the complete mask: 3780 // 3-0: Mask 3781 // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 3782 unsigned FlagsVal = 0; 3783 3784 if (SpecReg == "apsr") { 3785 FlagsVal = StringSwitch<unsigned>(Flags) 3786 .Case("nzcvq", 0x8) // same as CPSR_f 3787 .Case("g", 0x4) // same as CPSR_s 3788 .Case("nzcvqg", 0xc) // same as CPSR_fs 3789 .Default(~0U); 3790 3791 if (FlagsVal == ~0U) { 3792 if (!Flags.empty()) 3793 return MatchOperand_NoMatch; 3794 else 3795 FlagsVal = 8; // No flag 3796 } 3797 } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 3798 // cpsr_all is an alias for cpsr_fc, as is plain cpsr. 3799 if (Flags == "all" || Flags == "") 3800 Flags = "fc"; 3801 for (int i = 0, e = Flags.size(); i != e; ++i) { 3802 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 3803 .Case("c", 1) 3804 .Case("x", 2) 3805 .Case("s", 4) 3806 .Case("f", 8) 3807 .Default(~0U); 3808 3809 // If some specific flag is already set, it means that some letter is 3810 // present more than once, this is not acceptable. 3811 if (FlagsVal == ~0U || (FlagsVal & Flag)) 3812 return MatchOperand_NoMatch; 3813 FlagsVal |= Flag; 3814 } 3815 } else // No match for special register. 3816 return MatchOperand_NoMatch; 3817 3818 // Special register without flags is NOT equivalent to "fc" flags. 3819 // NOTE: This is a divergence from gas' behavior. Uncommenting the following 3820 // two lines would enable gas compatibility at the expense of breaking 3821 // round-tripping. 3822 // 3823 // if (!FlagsVal) 3824 // FlagsVal = 0x9; 3825 3826 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 3827 if (SpecReg == "spsr") 3828 FlagsVal |= 16; 3829 3830 Parser.Lex(); // Eat identifier token. 3831 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 3832 return MatchOperand_Success; 3833 } 3834 3835 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3836 parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 3837 int Low, int High) { 3838 const AsmToken &Tok = Parser.getTok(); 3839 if (Tok.isNot(AsmToken::Identifier)) { 3840 Error(Parser.getTok().getLoc(), Op + " operand expected."); 3841 return MatchOperand_ParseFail; 3842 } 3843 StringRef ShiftName = Tok.getString(); 3844 std::string LowerOp = Op.lower(); 3845 std::string UpperOp = Op.upper(); 3846 if (ShiftName != LowerOp && ShiftName != UpperOp) { 3847 Error(Parser.getTok().getLoc(), Op + " operand expected."); 3848 return MatchOperand_ParseFail; 3849 } 3850 Parser.Lex(); // Eat shift type token. 3851 3852 // There must be a '#' and a shift amount. 3853 if (Parser.getTok().isNot(AsmToken::Hash) && 3854 Parser.getTok().isNot(AsmToken::Dollar)) { 3855 Error(Parser.getTok().getLoc(), "'#' expected"); 3856 return MatchOperand_ParseFail; 3857 } 3858 Parser.Lex(); // Eat hash token. 3859 3860 const MCExpr *ShiftAmount; 3861 SMLoc Loc = Parser.getTok().getLoc(); 3862 SMLoc EndLoc; 3863 if (getParser().parseExpression(ShiftAmount, EndLoc)) { 3864 Error(Loc, "illegal expression"); 3865 return MatchOperand_ParseFail; 3866 } 3867 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 3868 if (!CE) { 3869 Error(Loc, "constant expression expected"); 3870 return MatchOperand_ParseFail; 3871 } 3872 int Val = CE->getValue(); 3873 if (Val < Low || Val > High) { 3874 Error(Loc, "immediate value out of range"); 3875 return MatchOperand_ParseFail; 3876 } 3877 3878 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc)); 3879 3880 return MatchOperand_Success; 3881 } 3882 3883 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3884 parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3885 const AsmToken &Tok = Parser.getTok(); 3886 SMLoc S = Tok.getLoc(); 3887 if (Tok.isNot(AsmToken::Identifier)) { 3888 Error(S, "'be' or 'le' operand expected"); 3889 return MatchOperand_ParseFail; 3890 } 3891 int Val = StringSwitch<int>(Tok.getString().lower()) 3892 .Case("be", 1) 3893 .Case("le", 0) 3894 .Default(-1); 3895 Parser.Lex(); // Eat the token. 3896 3897 if (Val == -1) { 3898 Error(S, "'be' or 'le' operand expected"); 3899 return MatchOperand_ParseFail; 3900 } 3901 Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 3902 getContext()), 3903 S, Tok.getEndLoc())); 3904 return MatchOperand_Success; 3905 } 3906 3907 /// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 3908 /// instructions. Legal values are: 3909 /// lsl #n 'n' in [0,31] 3910 /// asr #n 'n' in [1,32] 3911 /// n == 32 encoded as n == 0. 3912 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3913 parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3914 const AsmToken &Tok = Parser.getTok(); 3915 SMLoc S = Tok.getLoc(); 3916 if (Tok.isNot(AsmToken::Identifier)) { 3917 Error(S, "shift operator 'asr' or 'lsl' expected"); 3918 return MatchOperand_ParseFail; 3919 } 3920 StringRef ShiftName = Tok.getString(); 3921 bool isASR; 3922 if (ShiftName == "lsl" || ShiftName == "LSL") 3923 isASR = false; 3924 else if (ShiftName == "asr" || ShiftName == "ASR") 3925 isASR = true; 3926 else { 3927 Error(S, "shift operator 'asr' or 'lsl' expected"); 3928 return MatchOperand_ParseFail; 3929 } 3930 Parser.Lex(); // Eat the operator. 3931 3932 // A '#' and a shift amount. 3933 if (Parser.getTok().isNot(AsmToken::Hash) && 3934 Parser.getTok().isNot(AsmToken::Dollar)) { 3935 Error(Parser.getTok().getLoc(), "'#' expected"); 3936 return MatchOperand_ParseFail; 3937 } 3938 Parser.Lex(); // Eat hash token. 3939 SMLoc ExLoc = Parser.getTok().getLoc(); 3940 3941 const MCExpr *ShiftAmount; 3942 SMLoc EndLoc; 3943 if (getParser().parseExpression(ShiftAmount, EndLoc)) { 3944 Error(ExLoc, "malformed shift expression"); 3945 return MatchOperand_ParseFail; 3946 } 3947 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 3948 if (!CE) { 3949 Error(ExLoc, "shift amount must be an immediate"); 3950 return MatchOperand_ParseFail; 3951 } 3952 3953 int64_t Val = CE->getValue(); 3954 if (isASR) { 3955 // Shift amount must be in [1,32] 3956 if (Val < 1 || Val > 32) { 3957 Error(ExLoc, "'asr' shift amount must be in range [1,32]"); 3958 return MatchOperand_ParseFail; 3959 } 3960 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 3961 if (isThumb() && Val == 32) { 3962 Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode"); 3963 return MatchOperand_ParseFail; 3964 } 3965 if (Val == 32) Val = 0; 3966 } else { 3967 // Shift amount must be in [1,32] 3968 if (Val < 0 || Val > 31) { 3969 Error(ExLoc, "'lsr' shift amount must be in range [0,31]"); 3970 return MatchOperand_ParseFail; 3971 } 3972 } 3973 3974 Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc)); 3975 3976 return MatchOperand_Success; 3977 } 3978 3979 /// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 3980 /// of instructions. Legal values are: 3981 /// ror #n 'n' in {0, 8, 16, 24} 3982 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3983 parseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3984 const AsmToken &Tok = Parser.getTok(); 3985 SMLoc S = Tok.getLoc(); 3986 if (Tok.isNot(AsmToken::Identifier)) 3987 return MatchOperand_NoMatch; 3988 StringRef ShiftName = Tok.getString(); 3989 if (ShiftName != "ror" && ShiftName != "ROR") 3990 return MatchOperand_NoMatch; 3991 Parser.Lex(); // Eat the operator. 3992 3993 // A '#' and a rotate amount. 3994 if (Parser.getTok().isNot(AsmToken::Hash) && 3995 Parser.getTok().isNot(AsmToken::Dollar)) { 3996 Error(Parser.getTok().getLoc(), "'#' expected"); 3997 return MatchOperand_ParseFail; 3998 } 3999 Parser.Lex(); // Eat hash token. 4000 SMLoc ExLoc = Parser.getTok().getLoc(); 4001 4002 const MCExpr *ShiftAmount; 4003 SMLoc EndLoc; 4004 if (getParser().parseExpression(ShiftAmount, EndLoc)) { 4005 Error(ExLoc, "malformed rotate expression"); 4006 return MatchOperand_ParseFail; 4007 } 4008 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 4009 if (!CE) { 4010 Error(ExLoc, "rotate amount must be an immediate"); 4011 return MatchOperand_ParseFail; 4012 } 4013 4014 int64_t Val = CE->getValue(); 4015 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 4016 // normally, zero is represented in asm by omitting the rotate operand 4017 // entirely. 4018 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 4019 Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24"); 4020 return MatchOperand_ParseFail; 4021 } 4022 4023 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc)); 4024 4025 return MatchOperand_Success; 4026 } 4027 4028 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 4029 parseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4030 SMLoc S = Parser.getTok().getLoc(); 4031 // The bitfield descriptor is really two operands, the LSB and the width. 4032 if (Parser.getTok().isNot(AsmToken::Hash) && 4033 Parser.getTok().isNot(AsmToken::Dollar)) { 4034 Error(Parser.getTok().getLoc(), "'#' expected"); 4035 return MatchOperand_ParseFail; 4036 } 4037 Parser.Lex(); // Eat hash token. 4038 4039 const MCExpr *LSBExpr; 4040 SMLoc E = Parser.getTok().getLoc(); 4041 if (getParser().parseExpression(LSBExpr)) { 4042 Error(E, "malformed immediate expression"); 4043 return MatchOperand_ParseFail; 4044 } 4045 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 4046 if (!CE) { 4047 Error(E, "'lsb' operand must be an immediate"); 4048 return MatchOperand_ParseFail; 4049 } 4050 4051 int64_t LSB = CE->getValue(); 4052 // The LSB must be in the range [0,31] 4053 if (LSB < 0 || LSB > 31) { 4054 Error(E, "'lsb' operand must be in the range [0,31]"); 4055 return MatchOperand_ParseFail; 4056 } 4057 E = Parser.getTok().getLoc(); 4058 4059 // Expect another immediate operand. 4060 if (Parser.getTok().isNot(AsmToken::Comma)) { 4061 Error(Parser.getTok().getLoc(), "too few operands"); 4062 return MatchOperand_ParseFail; 4063 } 4064 Parser.Lex(); // Eat hash token. 4065 if (Parser.getTok().isNot(AsmToken::Hash) && 4066 Parser.getTok().isNot(AsmToken::Dollar)) { 4067 Error(Parser.getTok().getLoc(), "'#' expected"); 4068 return MatchOperand_ParseFail; 4069 } 4070 Parser.Lex(); // Eat hash token. 4071 4072 const MCExpr *WidthExpr; 4073 SMLoc EndLoc; 4074 if (getParser().parseExpression(WidthExpr, EndLoc)) { 4075 Error(E, "malformed immediate expression"); 4076 return MatchOperand_ParseFail; 4077 } 4078 CE = dyn_cast<MCConstantExpr>(WidthExpr); 4079 if (!CE) { 4080 Error(E, "'width' operand must be an immediate"); 4081 return MatchOperand_ParseFail; 4082 } 4083 4084 int64_t Width = CE->getValue(); 4085 // The LSB must be in the range [1,32-lsb] 4086 if (Width < 1 || Width > 32 - LSB) { 4087 Error(E, "'width' operand must be in the range [1,32-lsb]"); 4088 return MatchOperand_ParseFail; 4089 } 4090 4091 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc)); 4092 4093 return MatchOperand_Success; 4094 } 4095 4096 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 4097 parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4098 // Check for a post-index addressing register operand. Specifically: 4099 // postidx_reg := '+' register {, shift} 4100 // | '-' register {, shift} 4101 // | register {, shift} 4102 4103 // This method must return MatchOperand_NoMatch without consuming any tokens 4104 // in the case where there is no match, as other alternatives take other 4105 // parse methods. 4106 AsmToken Tok = Parser.getTok(); 4107 SMLoc S = Tok.getLoc(); 4108 bool haveEaten = false; 4109 bool isAdd = true; 4110 if (Tok.is(AsmToken::Plus)) { 4111 Parser.Lex(); // Eat the '+' token. 4112 haveEaten = true; 4113 } else if (Tok.is(AsmToken::Minus)) { 4114 Parser.Lex(); // Eat the '-' token. 4115 isAdd = false; 4116 haveEaten = true; 4117 } 4118 4119 SMLoc E = Parser.getTok().getEndLoc(); 4120 int Reg = tryParseRegister(); 4121 if (Reg == -1) { 4122 if (!haveEaten) 4123 return MatchOperand_NoMatch; 4124 Error(Parser.getTok().getLoc(), "register expected"); 4125 return MatchOperand_ParseFail; 4126 } 4127 4128 ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 4129 unsigned ShiftImm = 0; 4130 if (Parser.getTok().is(AsmToken::Comma)) { 4131 Parser.Lex(); // Eat the ','. 4132 if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 4133 return MatchOperand_ParseFail; 4134 4135 // FIXME: Only approximates end...may include intervening whitespace. 4136 E = Parser.getTok().getLoc(); 4137 } 4138 4139 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 4140 ShiftImm, S, E)); 4141 4142 return MatchOperand_Success; 4143 } 4144 4145 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 4146 parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4147 // Check for a post-index addressing register operand. Specifically: 4148 // am3offset := '+' register 4149 // | '-' register 4150 // | register 4151 // | # imm 4152 // | # + imm 4153 // | # - imm 4154 4155 // This method must return MatchOperand_NoMatch without consuming any tokens 4156 // in the case where there is no match, as other alternatives take other 4157 // parse methods. 4158 AsmToken Tok = Parser.getTok(); 4159 SMLoc S = Tok.getLoc(); 4160 4161 // Do immediates first, as we always parse those if we have a '#'. 4162 if (Parser.getTok().is(AsmToken::Hash) || 4163 Parser.getTok().is(AsmToken::Dollar)) { 4164 Parser.Lex(); // Eat '#' or '$'. 4165 // Explicitly look for a '-', as we need to encode negative zero 4166 // differently. 4167 bool isNegative = Parser.getTok().is(AsmToken::Minus); 4168 const MCExpr *Offset; 4169 SMLoc E; 4170 if (getParser().parseExpression(Offset, E)) 4171 return MatchOperand_ParseFail; 4172 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 4173 if (!CE) { 4174 Error(S, "constant expression expected"); 4175 return MatchOperand_ParseFail; 4176 } 4177 // Negative zero is encoded as the flag value INT32_MIN. 4178 int32_t Val = CE->getValue(); 4179 if (isNegative && Val == 0) 4180 Val = INT32_MIN; 4181 4182 Operands.push_back( 4183 ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 4184 4185 return MatchOperand_Success; 4186 } 4187 4188 4189 bool haveEaten = false; 4190 bool isAdd = true; 4191 if (Tok.is(AsmToken::Plus)) { 4192 Parser.Lex(); // Eat the '+' token. 4193 haveEaten = true; 4194 } else if (Tok.is(AsmToken::Minus)) { 4195 Parser.Lex(); // Eat the '-' token. 4196 isAdd = false; 4197 haveEaten = true; 4198 } 4199 4200 Tok = Parser.getTok(); 4201 int Reg = tryParseRegister(); 4202 if (Reg == -1) { 4203 if (!haveEaten) 4204 return MatchOperand_NoMatch; 4205 Error(Tok.getLoc(), "register expected"); 4206 return MatchOperand_ParseFail; 4207 } 4208 4209 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 4210 0, S, Tok.getEndLoc())); 4211 4212 return MatchOperand_Success; 4213 } 4214 4215 /// Convert parsed operands to MCInst. Needed here because this instruction 4216 /// only has two register operands, but multiplication is commutative so 4217 /// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN". 4218 void ARMAsmParser:: 4219 cvtThumbMultiply(MCInst &Inst, 4220 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4221 ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 4222 ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 4223 // If we have a three-operand form, make sure to set Rn to be the operand 4224 // that isn't the same as Rd. 4225 unsigned RegOp = 4; 4226 if (Operands.size() == 6 && 4227 ((ARMOperand*)Operands[4])->getReg() == 4228 ((ARMOperand*)Operands[3])->getReg()) 4229 RegOp = 5; 4230 ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1); 4231 Inst.addOperand(Inst.getOperand(0)); 4232 ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 4233 } 4234 4235 void ARMAsmParser:: 4236 cvtThumbBranches(MCInst &Inst, 4237 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4238 int CondOp = -1, ImmOp = -1; 4239 switch(Inst.getOpcode()) { 4240 case ARM::tB: 4241 case ARM::tBcc: CondOp = 1; ImmOp = 2; break; 4242 4243 case ARM::t2B: 4244 case ARM::t2Bcc: CondOp = 1; ImmOp = 3; break; 4245 4246 default: llvm_unreachable("Unexpected instruction in cvtThumbBranches"); 4247 } 4248 // first decide whether or not the branch should be conditional 4249 // by looking at it's location relative to an IT block 4250 if(inITBlock()) { 4251 // inside an IT block we cannot have any conditional branches. any 4252 // such instructions needs to be converted to unconditional form 4253 switch(Inst.getOpcode()) { 4254 case ARM::tBcc: Inst.setOpcode(ARM::tB); break; 4255 case ARM::t2Bcc: Inst.setOpcode(ARM::t2B); break; 4256 } 4257 } else { 4258 // outside IT blocks we can only have unconditional branches with AL 4259 // condition code or conditional branches with non-AL condition code 4260 unsigned Cond = static_cast<ARMOperand*>(Operands[CondOp])->getCondCode(); 4261 switch(Inst.getOpcode()) { 4262 case ARM::tB: 4263 case ARM::tBcc: 4264 Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc); 4265 break; 4266 case ARM::t2B: 4267 case ARM::t2Bcc: 4268 Inst.setOpcode(Cond == ARMCC::AL ? ARM::t2B : ARM::t2Bcc); 4269 break; 4270 } 4271 } 4272 4273 // now decide on encoding size based on branch target range 4274 switch(Inst.getOpcode()) { 4275 // classify tB as either t2B or t1B based on range of immediate operand 4276 case ARM::tB: { 4277 ARMOperand* op = static_cast<ARMOperand*>(Operands[ImmOp]); 4278 if(!op->isSignedOffset<11, 1>() && isThumbTwo()) 4279 Inst.setOpcode(ARM::t2B); 4280 break; 4281 } 4282 // classify tBcc as either t2Bcc or t1Bcc based on range of immediate operand 4283 case ARM::tBcc: { 4284 ARMOperand* op = static_cast<ARMOperand*>(Operands[ImmOp]); 4285 if(!op->isSignedOffset<8, 1>() && isThumbTwo()) 4286 Inst.setOpcode(ARM::t2Bcc); 4287 break; 4288 } 4289 } 4290 ((ARMOperand*)Operands[ImmOp])->addImmOperands(Inst, 1); 4291 ((ARMOperand*)Operands[CondOp])->addCondCodeOperands(Inst, 2); 4292 } 4293 4294 /// Parse an ARM memory expression, return false if successful else return true 4295 /// or an error. The first token must be a '[' when called. 4296 bool ARMAsmParser:: 4297 parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4298 SMLoc S, E; 4299 assert(Parser.getTok().is(AsmToken::LBrac) && 4300 "Token is not a Left Bracket"); 4301 S = Parser.getTok().getLoc(); 4302 Parser.Lex(); // Eat left bracket token. 4303 4304 const AsmToken &BaseRegTok = Parser.getTok(); 4305 int BaseRegNum = tryParseRegister(); 4306 if (BaseRegNum == -1) 4307 return Error(BaseRegTok.getLoc(), "register expected"); 4308 4309 // The next token must either be a comma, a colon or a closing bracket. 4310 const AsmToken &Tok = Parser.getTok(); 4311 if (!Tok.is(AsmToken::Colon) && !Tok.is(AsmToken::Comma) && 4312 !Tok.is(AsmToken::RBrac)) 4313 return Error(Tok.getLoc(), "malformed memory operand"); 4314 4315 if (Tok.is(AsmToken::RBrac)) { 4316 E = Tok.getEndLoc(); 4317 Parser.Lex(); // Eat right bracket token. 4318 4319 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 4320 0, 0, false, S, E)); 4321 4322 // If there's a pre-indexing writeback marker, '!', just add it as a token 4323 // operand. It's rather odd, but syntactically valid. 4324 if (Parser.getTok().is(AsmToken::Exclaim)) { 4325 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 4326 Parser.Lex(); // Eat the '!'. 4327 } 4328 4329 return false; 4330 } 4331 4332 assert((Tok.is(AsmToken::Colon) || Tok.is(AsmToken::Comma)) && 4333 "Lost colon or comma in memory operand?!"); 4334 if (Tok.is(AsmToken::Comma)) { 4335 Parser.Lex(); // Eat the comma. 4336 } 4337 4338 // If we have a ':', it's an alignment specifier. 4339 if (Parser.getTok().is(AsmToken::Colon)) { 4340 Parser.Lex(); // Eat the ':'. 4341 E = Parser.getTok().getLoc(); 4342 4343 const MCExpr *Expr; 4344 if (getParser().parseExpression(Expr)) 4345 return true; 4346 4347 // The expression has to be a constant. Memory references with relocations 4348 // don't come through here, as they use the <label> forms of the relevant 4349 // instructions. 4350 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 4351 if (!CE) 4352 return Error (E, "constant expression expected"); 4353 4354 unsigned Align = 0; 4355 switch (CE->getValue()) { 4356 default: 4357 return Error(E, 4358 "alignment specifier must be 16, 32, 64, 128, or 256 bits"); 4359 case 16: Align = 2; break; 4360 case 32: Align = 4; break; 4361 case 64: Align = 8; break; 4362 case 128: Align = 16; break; 4363 case 256: Align = 32; break; 4364 } 4365 4366 // Now we should have the closing ']' 4367 if (Parser.getTok().isNot(AsmToken::RBrac)) 4368 return Error(Parser.getTok().getLoc(), "']' expected"); 4369 E = Parser.getTok().getEndLoc(); 4370 Parser.Lex(); // Eat right bracket token. 4371 4372 // Don't worry about range checking the value here. That's handled by 4373 // the is*() predicates. 4374 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 4375 ARM_AM::no_shift, 0, Align, 4376 false, S, E)); 4377 4378 // If there's a pre-indexing writeback marker, '!', just add it as a token 4379 // operand. 4380 if (Parser.getTok().is(AsmToken::Exclaim)) { 4381 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 4382 Parser.Lex(); // Eat the '!'. 4383 } 4384 4385 return false; 4386 } 4387 4388 // If we have a '#', it's an immediate offset, else assume it's a register 4389 // offset. Be friendly and also accept a plain integer (without a leading 4390 // hash) for gas compatibility. 4391 if (Parser.getTok().is(AsmToken::Hash) || 4392 Parser.getTok().is(AsmToken::Dollar) || 4393 Parser.getTok().is(AsmToken::Integer)) { 4394 if (Parser.getTok().isNot(AsmToken::Integer)) 4395 Parser.Lex(); // Eat '#' or '$'. 4396 E = Parser.getTok().getLoc(); 4397 4398 bool isNegative = getParser().getTok().is(AsmToken::Minus); 4399 const MCExpr *Offset; 4400 if (getParser().parseExpression(Offset)) 4401 return true; 4402 4403 // The expression has to be a constant. Memory references with relocations 4404 // don't come through here, as they use the <label> forms of the relevant 4405 // instructions. 4406 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 4407 if (!CE) 4408 return Error (E, "constant expression expected"); 4409 4410 // If the constant was #-0, represent it as INT32_MIN. 4411 int32_t Val = CE->getValue(); 4412 if (isNegative && Val == 0) 4413 CE = MCConstantExpr::Create(INT32_MIN, getContext()); 4414 4415 // Now we should have the closing ']' 4416 if (Parser.getTok().isNot(AsmToken::RBrac)) 4417 return Error(Parser.getTok().getLoc(), "']' expected"); 4418 E = Parser.getTok().getEndLoc(); 4419 Parser.Lex(); // Eat right bracket token. 4420 4421 // Don't worry about range checking the value here. That's handled by 4422 // the is*() predicates. 4423 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 4424 ARM_AM::no_shift, 0, 0, 4425 false, S, E)); 4426 4427 // If there's a pre-indexing writeback marker, '!', just add it as a token 4428 // operand. 4429 if (Parser.getTok().is(AsmToken::Exclaim)) { 4430 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 4431 Parser.Lex(); // Eat the '!'. 4432 } 4433 4434 return false; 4435 } 4436 4437 // The register offset is optionally preceded by a '+' or '-' 4438 bool isNegative = false; 4439 if (Parser.getTok().is(AsmToken::Minus)) { 4440 isNegative = true; 4441 Parser.Lex(); // Eat the '-'. 4442 } else if (Parser.getTok().is(AsmToken::Plus)) { 4443 // Nothing to do. 4444 Parser.Lex(); // Eat the '+'. 4445 } 4446 4447 E = Parser.getTok().getLoc(); 4448 int OffsetRegNum = tryParseRegister(); 4449 if (OffsetRegNum == -1) 4450 return Error(E, "register expected"); 4451 4452 // If there's a shift operator, handle it. 4453 ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 4454 unsigned ShiftImm = 0; 4455 if (Parser.getTok().is(AsmToken::Comma)) { 4456 Parser.Lex(); // Eat the ','. 4457 if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 4458 return true; 4459 } 4460 4461 // Now we should have the closing ']' 4462 if (Parser.getTok().isNot(AsmToken::RBrac)) 4463 return Error(Parser.getTok().getLoc(), "']' expected"); 4464 E = Parser.getTok().getEndLoc(); 4465 Parser.Lex(); // Eat right bracket token. 4466 4467 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 4468 ShiftType, ShiftImm, 0, isNegative, 4469 S, E)); 4470 4471 // If there's a pre-indexing writeback marker, '!', just add it as a token 4472 // operand. 4473 if (Parser.getTok().is(AsmToken::Exclaim)) { 4474 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 4475 Parser.Lex(); // Eat the '!'. 4476 } 4477 4478 return false; 4479 } 4480 4481 /// parseMemRegOffsetShift - one of these two: 4482 /// ( lsl | lsr | asr | ror ) , # shift_amount 4483 /// rrx 4484 /// return true if it parses a shift otherwise it returns false. 4485 bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 4486 unsigned &Amount) { 4487 SMLoc Loc = Parser.getTok().getLoc(); 4488 const AsmToken &Tok = Parser.getTok(); 4489 if (Tok.isNot(AsmToken::Identifier)) 4490 return true; 4491 StringRef ShiftName = Tok.getString(); 4492 if (ShiftName == "lsl" || ShiftName == "LSL" || 4493 ShiftName == "asl" || ShiftName == "ASL") 4494 St = ARM_AM::lsl; 4495 else if (ShiftName == "lsr" || ShiftName == "LSR") 4496 St = ARM_AM::lsr; 4497 else if (ShiftName == "asr" || ShiftName == "ASR") 4498 St = ARM_AM::asr; 4499 else if (ShiftName == "ror" || ShiftName == "ROR") 4500 St = ARM_AM::ror; 4501 else if (ShiftName == "rrx" || ShiftName == "RRX") 4502 St = ARM_AM::rrx; 4503 else 4504 return Error(Loc, "illegal shift operator"); 4505 Parser.Lex(); // Eat shift type token. 4506 4507 // rrx stands alone. 4508 Amount = 0; 4509 if (St != ARM_AM::rrx) { 4510 Loc = Parser.getTok().getLoc(); 4511 // A '#' and a shift amount. 4512 const AsmToken &HashTok = Parser.getTok(); 4513 if (HashTok.isNot(AsmToken::Hash) && 4514 HashTok.isNot(AsmToken::Dollar)) 4515 return Error(HashTok.getLoc(), "'#' expected"); 4516 Parser.Lex(); // Eat hash token. 4517 4518 const MCExpr *Expr; 4519 if (getParser().parseExpression(Expr)) 4520 return true; 4521 // Range check the immediate. 4522 // lsl, ror: 0 <= imm <= 31 4523 // lsr, asr: 0 <= imm <= 32 4524 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 4525 if (!CE) 4526 return Error(Loc, "shift amount must be an immediate"); 4527 int64_t Imm = CE->getValue(); 4528 if (Imm < 0 || 4529 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 4530 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 4531 return Error(Loc, "immediate shift value out of range"); 4532 // If <ShiftTy> #0, turn it into a no_shift. 4533 if (Imm == 0) 4534 St = ARM_AM::lsl; 4535 // For consistency, treat lsr #32 and asr #32 as having immediate value 0. 4536 if (Imm == 32) 4537 Imm = 0; 4538 Amount = Imm; 4539 } 4540 4541 return false; 4542 } 4543 4544 /// parseFPImm - A floating point immediate expression operand. 4545 ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 4546 parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4547 // Anything that can accept a floating point constant as an operand 4548 // needs to go through here, as the regular parseExpression is 4549 // integer only. 4550 // 4551 // This routine still creates a generic Immediate operand, containing 4552 // a bitcast of the 64-bit floating point value. The various operands 4553 // that accept floats can check whether the value is valid for them 4554 // via the standard is*() predicates. 4555 4556 SMLoc S = Parser.getTok().getLoc(); 4557 4558 if (Parser.getTok().isNot(AsmToken::Hash) && 4559 Parser.getTok().isNot(AsmToken::Dollar)) 4560 return MatchOperand_NoMatch; 4561 4562 // Disambiguate the VMOV forms that can accept an FP immediate. 4563 // vmov.f32 <sreg>, #imm 4564 // vmov.f64 <dreg>, #imm 4565 // vmov.f32 <dreg>, #imm @ vector f32x2 4566 // vmov.f32 <qreg>, #imm @ vector f32x4 4567 // 4568 // There are also the NEON VMOV instructions which expect an 4569 // integer constant. Make sure we don't try to parse an FPImm 4570 // for these: 4571 // vmov.i{8|16|32|64} <dreg|qreg>, #imm 4572 ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]); 4573 bool isVmovf = TyOp->isToken() && (TyOp->getToken() == ".f32" || 4574 TyOp->getToken() == ".f64"); 4575 ARMOperand *Mnemonic = static_cast<ARMOperand*>(Operands[0]); 4576 bool isFconst = Mnemonic->isToken() && (Mnemonic->getToken() == "fconstd" || 4577 Mnemonic->getToken() == "fconsts"); 4578 if (!(isVmovf || isFconst)) 4579 return MatchOperand_NoMatch; 4580 4581 Parser.Lex(); // Eat '#' or '$'. 4582 4583 // Handle negation, as that still comes through as a separate token. 4584 bool isNegative = false; 4585 if (Parser.getTok().is(AsmToken::Minus)) { 4586 isNegative = true; 4587 Parser.Lex(); 4588 } 4589 const AsmToken &Tok = Parser.getTok(); 4590 SMLoc Loc = Tok.getLoc(); 4591 if (Tok.is(AsmToken::Real) && isVmovf) { 4592 APFloat RealVal(APFloat::IEEEsingle, Tok.getString()); 4593 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 4594 // If we had a '-' in front, toggle the sign bit. 4595 IntVal ^= (uint64_t)isNegative << 31; 4596 Parser.Lex(); // Eat the token. 4597 Operands.push_back(ARMOperand::CreateImm( 4598 MCConstantExpr::Create(IntVal, getContext()), 4599 S, Parser.getTok().getLoc())); 4600 return MatchOperand_Success; 4601 } 4602 // Also handle plain integers. Instructions which allow floating point 4603 // immediates also allow a raw encoded 8-bit value. 4604 if (Tok.is(AsmToken::Integer) && isFconst) { 4605 int64_t Val = Tok.getIntVal(); 4606 Parser.Lex(); // Eat the token. 4607 if (Val > 255 || Val < 0) { 4608 Error(Loc, "encoded floating point value out of range"); 4609 return MatchOperand_ParseFail; 4610 } 4611 float RealVal = ARM_AM::getFPImmFloat(Val); 4612 Val = APFloat(RealVal).bitcastToAPInt().getZExtValue(); 4613 4614 Operands.push_back(ARMOperand::CreateImm( 4615 MCConstantExpr::Create(Val, getContext()), S, 4616 Parser.getTok().getLoc())); 4617 return MatchOperand_Success; 4618 } 4619 4620 Error(Loc, "invalid floating point immediate"); 4621 return MatchOperand_ParseFail; 4622 } 4623 4624 /// Parse a arm instruction operand. For now this parses the operand regardless 4625 /// of the mnemonic. 4626 bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4627 StringRef Mnemonic) { 4628 SMLoc S, E; 4629 4630 // Check if the current operand has a custom associated parser, if so, try to 4631 // custom parse the operand, or fallback to the general approach. 4632 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 4633 if (ResTy == MatchOperand_Success) 4634 return false; 4635 // If there wasn't a custom match, try the generic matcher below. Otherwise, 4636 // there was a match, but an error occurred, in which case, just return that 4637 // the operand parsing failed. 4638 if (ResTy == MatchOperand_ParseFail) 4639 return true; 4640 4641 switch (getLexer().getKind()) { 4642 default: 4643 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 4644 return true; 4645 case AsmToken::Identifier: { 4646 // If we've seen a branch mnemonic, the next operand must be a label. This 4647 // is true even if the label is a register name. So "br r1" means branch to 4648 // label "r1". 4649 bool ExpectLabel = Mnemonic == "b" || Mnemonic == "bl"; 4650 if (!ExpectLabel) { 4651 if (!tryParseRegisterWithWriteBack(Operands)) 4652 return false; 4653 int Res = tryParseShiftRegister(Operands); 4654 if (Res == 0) // success 4655 return false; 4656 else if (Res == -1) // irrecoverable error 4657 return true; 4658 // If this is VMRS, check for the apsr_nzcv operand. 4659 if (Mnemonic == "vmrs" && 4660 Parser.getTok().getString().equals_lower("apsr_nzcv")) { 4661 S = Parser.getTok().getLoc(); 4662 Parser.Lex(); 4663 Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S)); 4664 return false; 4665 } 4666 } 4667 4668 // Fall though for the Identifier case that is not a register or a 4669 // special name. 4670 } 4671 case AsmToken::LParen: // parenthesized expressions like (_strcmp-4) 4672 case AsmToken::Integer: // things like 1f and 2b as a branch targets 4673 case AsmToken::String: // quoted label names. 4674 case AsmToken::Dot: { // . as a branch target 4675 // This was not a register so parse other operands that start with an 4676 // identifier (like labels) as expressions and create them as immediates. 4677 const MCExpr *IdVal; 4678 S = Parser.getTok().getLoc(); 4679 if (getParser().parseExpression(IdVal)) 4680 return true; 4681 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4682 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 4683 return false; 4684 } 4685 case AsmToken::LBrac: 4686 return parseMemory(Operands); 4687 case AsmToken::LCurly: 4688 return parseRegisterList(Operands); 4689 case AsmToken::Dollar: 4690 case AsmToken::Hash: { 4691 // #42 -> immediate. 4692 S = Parser.getTok().getLoc(); 4693 Parser.Lex(); 4694 4695 if (Parser.getTok().isNot(AsmToken::Colon)) { 4696 bool isNegative = Parser.getTok().is(AsmToken::Minus); 4697 const MCExpr *ImmVal; 4698 if (getParser().parseExpression(ImmVal)) 4699 return true; 4700 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 4701 if (CE) { 4702 int32_t Val = CE->getValue(); 4703 if (isNegative && Val == 0) 4704 ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 4705 } 4706 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4707 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 4708 4709 // There can be a trailing '!' on operands that we want as a separate 4710 // '!' Token operand. Handle that here. For example, the compatibility 4711 // alias for 'srsdb sp!, #imm' is 'srsdb #imm!'. 4712 if (Parser.getTok().is(AsmToken::Exclaim)) { 4713 Operands.push_back(ARMOperand::CreateToken(Parser.getTok().getString(), 4714 Parser.getTok().getLoc())); 4715 Parser.Lex(); // Eat exclaim token 4716 } 4717 return false; 4718 } 4719 // w/ a ':' after the '#', it's just like a plain ':'. 4720 // FALLTHROUGH 4721 } 4722 case AsmToken::Colon: { 4723 // ":lower16:" and ":upper16:" expression prefixes 4724 // FIXME: Check it's an expression prefix, 4725 // e.g. (FOO - :lower16:BAR) isn't legal. 4726 ARMMCExpr::VariantKind RefKind; 4727 if (parsePrefix(RefKind)) 4728 return true; 4729 4730 const MCExpr *SubExprVal; 4731 if (getParser().parseExpression(SubExprVal)) 4732 return true; 4733 4734 const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 4735 getContext()); 4736 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4737 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 4738 return false; 4739 } 4740 case AsmToken::Equal: { 4741 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val) 4742 return Error(Parser.getTok().getLoc(), "unexpected token in operand"); 4743 4744 Parser.Lex(); // Eat '=' 4745 const MCExpr *SubExprVal; 4746 if (getParser().parseExpression(SubExprVal)) 4747 return true; 4748 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4749 4750 const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal); 4751 Operands.push_back(ARMOperand::CreateImm(CPLoc, S, E)); 4752 return false; 4753 } 4754 } 4755 } 4756 4757 // parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 4758 // :lower16: and :upper16:. 4759 bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 4760 RefKind = ARMMCExpr::VK_ARM_None; 4761 4762 // consume an optional '#' (GNU compatibility) 4763 if (getLexer().is(AsmToken::Hash)) 4764 Parser.Lex(); 4765 4766 // :lower16: and :upper16: modifiers 4767 assert(getLexer().is(AsmToken::Colon) && "expected a :"); 4768 Parser.Lex(); // Eat ':' 4769 4770 if (getLexer().isNot(AsmToken::Identifier)) { 4771 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 4772 return true; 4773 } 4774 4775 StringRef IDVal = Parser.getTok().getIdentifier(); 4776 if (IDVal == "lower16") { 4777 RefKind = ARMMCExpr::VK_ARM_LO16; 4778 } else if (IDVal == "upper16") { 4779 RefKind = ARMMCExpr::VK_ARM_HI16; 4780 } else { 4781 Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 4782 return true; 4783 } 4784 Parser.Lex(); 4785 4786 if (getLexer().isNot(AsmToken::Colon)) { 4787 Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 4788 return true; 4789 } 4790 Parser.Lex(); // Eat the last ':' 4791 return false; 4792 } 4793 4794 /// \brief Given a mnemonic, split out possible predication code and carry 4795 /// setting letters to form a canonical mnemonic and flags. 4796 // 4797 // FIXME: Would be nice to autogen this. 4798 // FIXME: This is a bit of a maze of special cases. 4799 StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 4800 unsigned &PredicationCode, 4801 bool &CarrySetting, 4802 unsigned &ProcessorIMod, 4803 StringRef &ITMask) { 4804 PredicationCode = ARMCC::AL; 4805 CarrySetting = false; 4806 ProcessorIMod = 0; 4807 4808 // Ignore some mnemonics we know aren't predicated forms. 4809 // 4810 // FIXME: Would be nice to autogen this. 4811 if ((Mnemonic == "movs" && isThumb()) || 4812 Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 4813 Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 4814 Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 4815 Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 4816 Mnemonic == "vaclt" || Mnemonic == "vacle" || Mnemonic == "hlt" || 4817 Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 4818 Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 4819 Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" || 4820 Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || 4821 Mnemonic == "vcvta" || Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || 4822 Mnemonic == "vcvtm" || Mnemonic == "vrinta" || Mnemonic == "vrintn" || 4823 Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic.startswith("vsel")) 4824 return Mnemonic; 4825 4826 // First, split out any predication code. Ignore mnemonics we know aren't 4827 // predicated but do have a carry-set and so weren't caught above. 4828 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 4829 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 4830 Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 4831 Mnemonic != "sbcs" && Mnemonic != "rscs") { 4832 unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 4833 .Case("eq", ARMCC::EQ) 4834 .Case("ne", ARMCC::NE) 4835 .Case("hs", ARMCC::HS) 4836 .Case("cs", ARMCC::HS) 4837 .Case("lo", ARMCC::LO) 4838 .Case("cc", ARMCC::LO) 4839 .Case("mi", ARMCC::MI) 4840 .Case("pl", ARMCC::PL) 4841 .Case("vs", ARMCC::VS) 4842 .Case("vc", ARMCC::VC) 4843 .Case("hi", ARMCC::HI) 4844 .Case("ls", ARMCC::LS) 4845 .Case("ge", ARMCC::GE) 4846 .Case("lt", ARMCC::LT) 4847 .Case("gt", ARMCC::GT) 4848 .Case("le", ARMCC::LE) 4849 .Case("al", ARMCC::AL) 4850 .Default(~0U); 4851 if (CC != ~0U) { 4852 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 4853 PredicationCode = CC; 4854 } 4855 } 4856 4857 // Next, determine if we have a carry setting bit. We explicitly ignore all 4858 // the instructions we know end in 's'. 4859 if (Mnemonic.endswith("s") && 4860 !(Mnemonic == "cps" || Mnemonic == "mls" || 4861 Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 4862 Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 4863 Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 4864 Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" || 4865 Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" || 4866 Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" || 4867 Mnemonic == "fmuls" || Mnemonic == "fcmps" || Mnemonic == "fcmpzs" || 4868 Mnemonic == "vfms" || Mnemonic == "vfnms" || Mnemonic == "fconsts" || 4869 (Mnemonic == "movs" && isThumb()))) { 4870 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 4871 CarrySetting = true; 4872 } 4873 4874 // The "cps" instruction can have a interrupt mode operand which is glued into 4875 // the mnemonic. Check if this is the case, split it and parse the imod op 4876 if (Mnemonic.startswith("cps")) { 4877 // Split out any imod code. 4878 unsigned IMod = 4879 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 4880 .Case("ie", ARM_PROC::IE) 4881 .Case("id", ARM_PROC::ID) 4882 .Default(~0U); 4883 if (IMod != ~0U) { 4884 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 4885 ProcessorIMod = IMod; 4886 } 4887 } 4888 4889 // The "it" instruction has the condition mask on the end of the mnemonic. 4890 if (Mnemonic.startswith("it")) { 4891 ITMask = Mnemonic.slice(2, Mnemonic.size()); 4892 Mnemonic = Mnemonic.slice(0, 2); 4893 } 4894 4895 return Mnemonic; 4896 } 4897 4898 /// \brief Given a canonical mnemonic, determine if the instruction ever allows 4899 /// inclusion of carry set or predication code operands. 4900 // 4901 // FIXME: It would be nice to autogen this. 4902 void ARMAsmParser:: 4903 getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst, 4904 bool &CanAcceptCarrySet, bool &CanAcceptPredicationCode) { 4905 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 4906 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 4907 Mnemonic == "add" || Mnemonic == "adc" || 4908 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 4909 Mnemonic == "orr" || Mnemonic == "mvn" || 4910 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 4911 Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 4912 Mnemonic == "vfm" || Mnemonic == "vfnm" || 4913 (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 4914 Mnemonic == "mla" || Mnemonic == "smlal" || 4915 Mnemonic == "umlal" || Mnemonic == "umull"))) { 4916 CanAcceptCarrySet = true; 4917 } else 4918 CanAcceptCarrySet = false; 4919 4920 if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" || 4921 Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" || 4922 Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic.startswith("crc32") || 4923 Mnemonic.startswith("cps") || Mnemonic.startswith("vsel") || 4924 Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" || 4925 Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || 4926 Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" || 4927 Mnemonic == "vrintm" || Mnemonic.startswith("aes") || 4928 Mnemonic.startswith("sha1") || Mnemonic.startswith("sha256") || 4929 (FullInst.startswith("vmull") && FullInst.endswith(".p64"))) { 4930 // These mnemonics are never predicable 4931 CanAcceptPredicationCode = false; 4932 } else if (!isThumb()) { 4933 // Some instructions are only predicable in Thumb mode 4934 CanAcceptPredicationCode 4935 = Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" && 4936 Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" && 4937 Mnemonic != "dmb" && Mnemonic != "dsb" && Mnemonic != "isb" && 4938 Mnemonic != "pld" && Mnemonic != "pli" && Mnemonic != "pldw" && 4939 Mnemonic != "ldc2" && Mnemonic != "ldc2l" && 4940 Mnemonic != "stc2" && Mnemonic != "stc2l" && 4941 !Mnemonic.startswith("rfe") && !Mnemonic.startswith("srs"); 4942 } else if (isThumbOne()) { 4943 if (hasV6MOps()) 4944 CanAcceptPredicationCode = Mnemonic != "movs"; 4945 else 4946 CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs"; 4947 } else 4948 CanAcceptPredicationCode = true; 4949 } 4950 4951 bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 4952 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4953 // FIXME: This is all horribly hacky. We really need a better way to deal 4954 // with optional operands like this in the matcher table. 4955 4956 // The 'mov' mnemonic is special. One variant has a cc_out operand, while 4957 // another does not. Specifically, the MOVW instruction does not. So we 4958 // special case it here and remove the defaulted (non-setting) cc_out 4959 // operand if that's the instruction we're trying to match. 4960 // 4961 // We do this as post-processing of the explicit operands rather than just 4962 // conditionally adding the cc_out in the first place because we need 4963 // to check the type of the parsed immediate operand. 4964 if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 4965 !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 4966 static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 4967 static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 4968 return true; 4969 4970 // Register-register 'add' for thumb does not have a cc_out operand 4971 // when there are only two register operands. 4972 if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 4973 static_cast<ARMOperand*>(Operands[3])->isReg() && 4974 static_cast<ARMOperand*>(Operands[4])->isReg() && 4975 static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 4976 return true; 4977 // Register-register 'add' for thumb does not have a cc_out operand 4978 // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 4979 // have to check the immediate range here since Thumb2 has a variant 4980 // that can handle a different range and has a cc_out operand. 4981 if (((isThumb() && Mnemonic == "add") || 4982 (isThumbTwo() && Mnemonic == "sub")) && 4983 Operands.size() == 6 && 4984 static_cast<ARMOperand*>(Operands[3])->isReg() && 4985 static_cast<ARMOperand*>(Operands[4])->isReg() && 4986 static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 4987 static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 4988 ((Mnemonic == "add" &&static_cast<ARMOperand*>(Operands[5])->isReg()) || 4989 static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 4990 return true; 4991 // For Thumb2, add/sub immediate does not have a cc_out operand for the 4992 // imm0_4095 variant. That's the least-preferred variant when 4993 // selecting via the generic "add" mnemonic, so to know that we 4994 // should remove the cc_out operand, we have to explicitly check that 4995 // it's not one of the other variants. Ugh. 4996 if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 4997 Operands.size() == 6 && 4998 static_cast<ARMOperand*>(Operands[3])->isReg() && 4999 static_cast<ARMOperand*>(Operands[4])->isReg() && 5000 static_cast<ARMOperand*>(Operands[5])->isImm()) { 5001 // Nest conditions rather than one big 'if' statement for readability. 5002 // 5003 // If both registers are low, we're in an IT block, and the immediate is 5004 // in range, we should use encoding T1 instead, which has a cc_out. 5005 if (inITBlock() && 5006 isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 5007 isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 5008 static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 5009 return false; 5010 // Check against T3. If the second register is the PC, this is an 5011 // alternate form of ADR, which uses encoding T4, so check for that too. 5012 if (static_cast<ARMOperand*>(Operands[4])->getReg() != ARM::PC && 5013 static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 5014 return false; 5015 5016 // Otherwise, we use encoding T4, which does not have a cc_out 5017 // operand. 5018 return true; 5019 } 5020 5021 // The thumb2 multiply instruction doesn't have a CCOut register, so 5022 // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 5023 // use the 16-bit encoding or not. 5024 if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 5025 static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 5026 static_cast<ARMOperand*>(Operands[3])->isReg() && 5027 static_cast<ARMOperand*>(Operands[4])->isReg() && 5028 static_cast<ARMOperand*>(Operands[5])->isReg() && 5029 // If the registers aren't low regs, the destination reg isn't the 5030 // same as one of the source regs, or the cc_out operand is zero 5031 // outside of an IT block, we have to use the 32-bit encoding, so 5032 // remove the cc_out operand. 5033 (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 5034 !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 5035 !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) || 5036 !inITBlock() || 5037 (static_cast<ARMOperand*>(Operands[3])->getReg() != 5038 static_cast<ARMOperand*>(Operands[5])->getReg() && 5039 static_cast<ARMOperand*>(Operands[3])->getReg() != 5040 static_cast<ARMOperand*>(Operands[4])->getReg()))) 5041 return true; 5042 5043 // Also check the 'mul' syntax variant that doesn't specify an explicit 5044 // destination register. 5045 if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 && 5046 static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 5047 static_cast<ARMOperand*>(Operands[3])->isReg() && 5048 static_cast<ARMOperand*>(Operands[4])->isReg() && 5049 // If the registers aren't low regs or the cc_out operand is zero 5050 // outside of an IT block, we have to use the 32-bit encoding, so 5051 // remove the cc_out operand. 5052 (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 5053 !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 5054 !inITBlock())) 5055 return true; 5056 5057 5058 5059 // Register-register 'add/sub' for thumb does not have a cc_out operand 5060 // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 5061 // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 5062 // right, this will result in better diagnostics (which operand is off) 5063 // anyway. 5064 if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 5065 (Operands.size() == 5 || Operands.size() == 6) && 5066 static_cast<ARMOperand*>(Operands[3])->isReg() && 5067 static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 5068 static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 5069 (static_cast<ARMOperand*>(Operands[4])->isImm() || 5070 (Operands.size() == 6 && 5071 static_cast<ARMOperand*>(Operands[5])->isImm()))) 5072 return true; 5073 5074 return false; 5075 } 5076 5077 bool ARMAsmParser::shouldOmitPredicateOperand( 5078 StringRef Mnemonic, SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 5079 // VRINT{Z, R, X} have a predicate operand in VFP, but not in NEON 5080 unsigned RegIdx = 3; 5081 if ((Mnemonic == "vrintz" || Mnemonic == "vrintx" || Mnemonic == "vrintr") && 5082 static_cast<ARMOperand *>(Operands[2])->getToken() == ".f32") { 5083 if (static_cast<ARMOperand *>(Operands[3])->isToken() && 5084 static_cast<ARMOperand *>(Operands[3])->getToken() == ".f32") 5085 RegIdx = 4; 5086 5087 if (static_cast<ARMOperand *>(Operands[RegIdx])->isReg() && 5088 (ARMMCRegisterClasses[ARM::DPRRegClassID] 5089 .contains(static_cast<ARMOperand *>(Operands[RegIdx])->getReg()) || 5090 ARMMCRegisterClasses[ARM::QPRRegClassID] 5091 .contains(static_cast<ARMOperand *>(Operands[RegIdx])->getReg()))) 5092 return true; 5093 } 5094 return false; 5095 } 5096 5097 static bool isDataTypeToken(StringRef Tok) { 5098 return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" || 5099 Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" || 5100 Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" || 5101 Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" || 5102 Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" || 5103 Tok == ".f" || Tok == ".d"; 5104 } 5105 5106 // FIXME: This bit should probably be handled via an explicit match class 5107 // in the .td files that matches the suffix instead of having it be 5108 // a literal string token the way it is now. 5109 static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) { 5110 return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm"); 5111 } 5112 static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features, 5113 unsigned VariantID); 5114 5115 static bool RequiresVFPRegListValidation(StringRef Inst, 5116 bool &AcceptSinglePrecisionOnly, 5117 bool &AcceptDoublePrecisionOnly) { 5118 if (Inst.size() < 7) 5119 return false; 5120 5121 if (Inst.startswith("fldm") || Inst.startswith("fstm")) { 5122 StringRef AddressingMode = Inst.substr(4, 2); 5123 if (AddressingMode == "ia" || AddressingMode == "db" || 5124 AddressingMode == "ea" || AddressingMode == "fd") { 5125 AcceptSinglePrecisionOnly = Inst[6] == 's'; 5126 AcceptDoublePrecisionOnly = Inst[6] == 'd' || Inst[6] == 'x'; 5127 return true; 5128 } 5129 } 5130 5131 return false; 5132 } 5133 5134 /// Parse an arm instruction mnemonic followed by its operands. 5135 bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 5136 SMLoc NameLoc, 5137 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 5138 // FIXME: Can this be done via tablegen in some fashion? 5139 bool RequireVFPRegisterListCheck; 5140 bool AcceptSinglePrecisionOnly; 5141 bool AcceptDoublePrecisionOnly; 5142 RequireVFPRegisterListCheck = 5143 RequiresVFPRegListValidation(Name, AcceptSinglePrecisionOnly, 5144 AcceptDoublePrecisionOnly); 5145 5146 // Apply mnemonic aliases before doing anything else, as the destination 5147 // mnemonic may include suffices and we want to handle them normally. 5148 // The generic tblgen'erated code does this later, at the start of 5149 // MatchInstructionImpl(), but that's too late for aliases that include 5150 // any sort of suffix. 5151 unsigned AvailableFeatures = getAvailableFeatures(); 5152 unsigned AssemblerDialect = getParser().getAssemblerDialect(); 5153 applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect); 5154 5155 // First check for the ARM-specific .req directive. 5156 if (Parser.getTok().is(AsmToken::Identifier) && 5157 Parser.getTok().getIdentifier() == ".req") { 5158 parseDirectiveReq(Name, NameLoc); 5159 // We always return 'error' for this, as we're done with this 5160 // statement and don't need to match the 'instruction." 5161 return true; 5162 } 5163 5164 // Create the leading tokens for the mnemonic, split by '.' characters. 5165 size_t Start = 0, Next = Name.find('.'); 5166 StringRef Mnemonic = Name.slice(Start, Next); 5167 5168 // Split out the predication code and carry setting flag from the mnemonic. 5169 unsigned PredicationCode; 5170 unsigned ProcessorIMod; 5171 bool CarrySetting; 5172 StringRef ITMask; 5173 Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 5174 ProcessorIMod, ITMask); 5175 5176 // In Thumb1, only the branch (B) instruction can be predicated. 5177 if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 5178 Parser.eatToEndOfStatement(); 5179 return Error(NameLoc, "conditional execution not supported in Thumb1"); 5180 } 5181 5182 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 5183 5184 // Handle the IT instruction ITMask. Convert it to a bitmask. This 5185 // is the mask as it will be for the IT encoding if the conditional 5186 // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 5187 // where the conditional bit0 is zero, the instruction post-processing 5188 // will adjust the mask accordingly. 5189 if (Mnemonic == "it") { 5190 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 5191 if (ITMask.size() > 3) { 5192 Parser.eatToEndOfStatement(); 5193 return Error(Loc, "too many conditions on IT instruction"); 5194 } 5195 unsigned Mask = 8; 5196 for (unsigned i = ITMask.size(); i != 0; --i) { 5197 char pos = ITMask[i - 1]; 5198 if (pos != 't' && pos != 'e') { 5199 Parser.eatToEndOfStatement(); 5200 return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 5201 } 5202 Mask >>= 1; 5203 if (ITMask[i - 1] == 't') 5204 Mask |= 8; 5205 } 5206 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 5207 } 5208 5209 // FIXME: This is all a pretty gross hack. We should automatically handle 5210 // optional operands like this via tblgen. 5211 5212 // Next, add the CCOut and ConditionCode operands, if needed. 5213 // 5214 // For mnemonics which can ever incorporate a carry setting bit or predication 5215 // code, our matching model involves us always generating CCOut and 5216 // ConditionCode operands to match the mnemonic "as written" and then we let 5217 // the matcher deal with finding the right instruction or generating an 5218 // appropriate error. 5219 bool CanAcceptCarrySet, CanAcceptPredicationCode; 5220 getMnemonicAcceptInfo(Mnemonic, Name, CanAcceptCarrySet, CanAcceptPredicationCode); 5221 5222 // If we had a carry-set on an instruction that can't do that, issue an 5223 // error. 5224 if (!CanAcceptCarrySet && CarrySetting) { 5225 Parser.eatToEndOfStatement(); 5226 return Error(NameLoc, "instruction '" + Mnemonic + 5227 "' can not set flags, but 's' suffix specified"); 5228 } 5229 // If we had a predication code on an instruction that can't do that, issue an 5230 // error. 5231 if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 5232 Parser.eatToEndOfStatement(); 5233 return Error(NameLoc, "instruction '" + Mnemonic + 5234 "' is not predicable, but condition code specified"); 5235 } 5236 5237 // Add the carry setting operand, if necessary. 5238 if (CanAcceptCarrySet) { 5239 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 5240 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 5241 Loc)); 5242 } 5243 5244 // Add the predication code operand, if necessary. 5245 if (CanAcceptPredicationCode) { 5246 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 5247 CarrySetting); 5248 Operands.push_back(ARMOperand::CreateCondCode( 5249 ARMCC::CondCodes(PredicationCode), Loc)); 5250 } 5251 5252 // Add the processor imod operand, if necessary. 5253 if (ProcessorIMod) { 5254 Operands.push_back(ARMOperand::CreateImm( 5255 MCConstantExpr::Create(ProcessorIMod, getContext()), 5256 NameLoc, NameLoc)); 5257 } 5258 5259 // Add the remaining tokens in the mnemonic. 5260 while (Next != StringRef::npos) { 5261 Start = Next; 5262 Next = Name.find('.', Start + 1); 5263 StringRef ExtraToken = Name.slice(Start, Next); 5264 5265 // Some NEON instructions have an optional datatype suffix that is 5266 // completely ignored. Check for that. 5267 if (isDataTypeToken(ExtraToken) && 5268 doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken)) 5269 continue; 5270 5271 // For for ARM mode generate an error if the .n qualifier is used. 5272 if (ExtraToken == ".n" && !isThumb()) { 5273 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 5274 Parser.eatToEndOfStatement(); 5275 return Error(Loc, "instruction with .n (narrow) qualifier not allowed in " 5276 "arm mode"); 5277 } 5278 5279 // The .n qualifier is always discarded as that is what the tables 5280 // and matcher expect. In ARM mode the .w qualifier has no effect, 5281 // so discard it to avoid errors that can be caused by the matcher. 5282 if (ExtraToken != ".n" && (isThumb() || ExtraToken != ".w")) { 5283 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 5284 Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 5285 } 5286 } 5287 5288 // Read the remaining operands. 5289 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5290 // Read the first operand. 5291 if (parseOperand(Operands, Mnemonic)) { 5292 Parser.eatToEndOfStatement(); 5293 return true; 5294 } 5295 5296 while (getLexer().is(AsmToken::Comma)) { 5297 Parser.Lex(); // Eat the comma. 5298 5299 // Parse and remember the operand. 5300 if (parseOperand(Operands, Mnemonic)) { 5301 Parser.eatToEndOfStatement(); 5302 return true; 5303 } 5304 } 5305 } 5306 5307 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5308 SMLoc Loc = getLexer().getLoc(); 5309 Parser.eatToEndOfStatement(); 5310 return Error(Loc, "unexpected token in argument list"); 5311 } 5312 5313 Parser.Lex(); // Consume the EndOfStatement 5314 5315 if (RequireVFPRegisterListCheck) { 5316 ARMOperand *Op = static_cast<ARMOperand*>(Operands.back()); 5317 if (AcceptSinglePrecisionOnly && !Op->isSPRRegList()) 5318 return Error(Op->getStartLoc(), 5319 "VFP/Neon single precision register expected"); 5320 if (AcceptDoublePrecisionOnly && !Op->isDPRRegList()) 5321 return Error(Op->getStartLoc(), 5322 "VFP/Neon double precision register expected"); 5323 } 5324 5325 // Some instructions, mostly Thumb, have forms for the same mnemonic that 5326 // do and don't have a cc_out optional-def operand. With some spot-checks 5327 // of the operand list, we can figure out which variant we're trying to 5328 // parse and adjust accordingly before actually matching. We shouldn't ever 5329 // try to remove a cc_out operand that was explicitly set on the the 5330 // mnemonic, of course (CarrySetting == true). Reason number #317 the 5331 // table driven matcher doesn't fit well with the ARM instruction set. 5332 if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 5333 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 5334 Operands.erase(Operands.begin() + 1); 5335 delete Op; 5336 } 5337 5338 // Some instructions have the same mnemonic, but don't always 5339 // have a predicate. Distinguish them here and delete the 5340 // predicate if needed. 5341 if (shouldOmitPredicateOperand(Mnemonic, Operands)) { 5342 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 5343 Operands.erase(Operands.begin() + 1); 5344 delete Op; 5345 } 5346 5347 // ARM mode 'blx' need special handling, as the register operand version 5348 // is predicable, but the label operand version is not. So, we can't rely 5349 // on the Mnemonic based checking to correctly figure out when to put 5350 // a k_CondCode operand in the list. If we're trying to match the label 5351 // version, remove the k_CondCode operand here. 5352 if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 5353 static_cast<ARMOperand*>(Operands[2])->isImm()) { 5354 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 5355 Operands.erase(Operands.begin() + 1); 5356 delete Op; 5357 } 5358 5359 // Adjust operands of ldrexd/strexd to MCK_GPRPair. 5360 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint, 5361 // a single GPRPair reg operand is used in the .td file to replace the two 5362 // GPRs. However, when parsing from asm, the two GRPs cannot be automatically 5363 // expressed as a GPRPair, so we have to manually merge them. 5364 // FIXME: We would really like to be able to tablegen'erate this. 5365 if (!isThumb() && Operands.size() > 4 && 5366 (Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" || 5367 Mnemonic == "stlexd")) { 5368 bool isLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd"); 5369 unsigned Idx = isLoad ? 2 : 3; 5370 ARMOperand* Op1 = static_cast<ARMOperand*>(Operands[Idx]); 5371 ARMOperand* Op2 = static_cast<ARMOperand*>(Operands[Idx+1]); 5372 5373 const MCRegisterClass& MRC = MRI->getRegClass(ARM::GPRRegClassID); 5374 // Adjust only if Op1 and Op2 are GPRs. 5375 if (Op1->isReg() && Op2->isReg() && MRC.contains(Op1->getReg()) && 5376 MRC.contains(Op2->getReg())) { 5377 unsigned Reg1 = Op1->getReg(); 5378 unsigned Reg2 = Op2->getReg(); 5379 unsigned Rt = MRI->getEncodingValue(Reg1); 5380 unsigned Rt2 = MRI->getEncodingValue(Reg2); 5381 5382 // Rt2 must be Rt + 1 and Rt must be even. 5383 if (Rt + 1 != Rt2 || (Rt & 1)) { 5384 Error(Op2->getStartLoc(), isLoad ? 5385 "destination operands must be sequential" : 5386 "source operands must be sequential"); 5387 return true; 5388 } 5389 unsigned NewReg = MRI->getMatchingSuperReg(Reg1, ARM::gsub_0, 5390 &(MRI->getRegClass(ARM::GPRPairRegClassID))); 5391 Operands.erase(Operands.begin() + Idx, Operands.begin() + Idx + 2); 5392 Operands.insert(Operands.begin() + Idx, ARMOperand::CreateReg( 5393 NewReg, Op1->getStartLoc(), Op2->getEndLoc())); 5394 delete Op1; 5395 delete Op2; 5396 } 5397 } 5398 5399 // GNU Assembler extension (compatibility) 5400 if ((Mnemonic == "ldrd" || Mnemonic == "strd") && !isThumb() && 5401 Operands.size() == 4) { 5402 ARMOperand *Op = static_cast<ARMOperand *>(Operands[2]); 5403 assert(Op->isReg() && "expected register argument"); 5404 assert(MRI->getMatchingSuperReg(Op->getReg(), ARM::gsub_0, 5405 &MRI->getRegClass(ARM::GPRPairRegClassID)) 5406 && "expected register pair"); 5407 Operands.insert(Operands.begin() + 3, 5408 ARMOperand::CreateReg(Op->getReg() + 1, Op->getStartLoc(), 5409 Op->getEndLoc())); 5410 } 5411 5412 // FIXME: As said above, this is all a pretty gross hack. This instruction 5413 // does not fit with other "subs" and tblgen. 5414 // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction 5415 // so the Mnemonic is the original name "subs" and delete the predicate 5416 // operand so it will match the table entry. 5417 if (isThumbTwo() && Mnemonic == "sub" && Operands.size() == 6 && 5418 static_cast<ARMOperand*>(Operands[3])->isReg() && 5419 static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::PC && 5420 static_cast<ARMOperand*>(Operands[4])->isReg() && 5421 static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::LR && 5422 static_cast<ARMOperand*>(Operands[5])->isImm()) { 5423 ARMOperand *Op0 = static_cast<ARMOperand*>(Operands[0]); 5424 Operands.erase(Operands.begin()); 5425 delete Op0; 5426 Operands.insert(Operands.begin(), ARMOperand::CreateToken(Name, NameLoc)); 5427 5428 ARMOperand *Op1 = static_cast<ARMOperand*>(Operands[1]); 5429 Operands.erase(Operands.begin() + 1); 5430 delete Op1; 5431 } 5432 return false; 5433 } 5434 5435 // Validate context-sensitive operand constraints. 5436 5437 // return 'true' if register list contains non-low GPR registers, 5438 // 'false' otherwise. If Reg is in the register list or is HiReg, set 5439 // 'containsReg' to true. 5440 static bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 5441 unsigned HiReg, bool &containsReg) { 5442 containsReg = false; 5443 for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 5444 unsigned OpReg = Inst.getOperand(i).getReg(); 5445 if (OpReg == Reg) 5446 containsReg = true; 5447 // Anything other than a low register isn't legal here. 5448 if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 5449 return true; 5450 } 5451 return false; 5452 } 5453 5454 // Check if the specified regisgter is in the register list of the inst, 5455 // starting at the indicated operand number. 5456 static bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 5457 for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 5458 unsigned OpReg = Inst.getOperand(i).getReg(); 5459 if (OpReg == Reg) 5460 return true; 5461 } 5462 return false; 5463 } 5464 5465 // Return true if instruction has the interesting property of being 5466 // allowed in IT blocks, but not being predicable. 5467 static bool instIsBreakpoint(const MCInst &Inst) { 5468 return Inst.getOpcode() == ARM::tBKPT || 5469 Inst.getOpcode() == ARM::BKPT || 5470 Inst.getOpcode() == ARM::tHLT || 5471 Inst.getOpcode() == ARM::HLT; 5472 5473 } 5474 5475 // FIXME: We would really like to be able to tablegen'erate this. 5476 bool ARMAsmParser:: 5477 validateInstruction(MCInst &Inst, 5478 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 5479 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 5480 SMLoc Loc = Operands[0]->getStartLoc(); 5481 5482 // Check the IT block state first. 5483 // NOTE: BKPT and HLT instructions have the interesting property of being 5484 // allowed in IT blocks, but not being predicable. They just always execute. 5485 if (inITBlock() && !instIsBreakpoint(Inst)) { 5486 unsigned Bit = 1; 5487 if (ITState.FirstCond) 5488 ITState.FirstCond = false; 5489 else 5490 Bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 5491 // The instruction must be predicable. 5492 if (!MCID.isPredicable()) 5493 return Error(Loc, "instructions in IT block must be predicable"); 5494 unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 5495 unsigned ITCond = Bit ? ITState.Cond : 5496 ARMCC::getOppositeCondition(ITState.Cond); 5497 if (Cond != ITCond) { 5498 // Find the condition code Operand to get its SMLoc information. 5499 SMLoc CondLoc; 5500 for (unsigned I = 1; I < Operands.size(); ++I) 5501 if (static_cast<ARMOperand*>(Operands[I])->isCondCode()) 5502 CondLoc = Operands[I]->getStartLoc(); 5503 return Error(CondLoc, "incorrect condition in IT block; got '" + 5504 StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 5505 "', but expected '" + 5506 ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 5507 } 5508 // Check for non-'al' condition codes outside of the IT block. 5509 } else if (isThumbTwo() && MCID.isPredicable() && 5510 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 5511 ARMCC::AL && Inst.getOpcode() != ARM::tBcc && 5512 Inst.getOpcode() != ARM::t2Bcc) 5513 return Error(Loc, "predicated instructions must be in IT block"); 5514 5515 const unsigned Opcode = Inst.getOpcode(); 5516 switch (Opcode) { 5517 case ARM::LDRD: 5518 case ARM::LDRD_PRE: 5519 case ARM::LDRD_POST: { 5520 const unsigned RtReg = Inst.getOperand(0).getReg(); 5521 5522 // Rt can't be R14. 5523 if (RtReg == ARM::LR) 5524 return Error(Operands[3]->getStartLoc(), 5525 "Rt can't be R14"); 5526 5527 const unsigned Rt = MRI->getEncodingValue(RtReg); 5528 // Rt must be even-numbered. 5529 if ((Rt & 1) == 1) 5530 return Error(Operands[3]->getStartLoc(), 5531 "Rt must be even-numbered"); 5532 5533 // Rt2 must be Rt + 1. 5534 const unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 5535 if (Rt2 != Rt + 1) 5536 return Error(Operands[3]->getStartLoc(), 5537 "destination operands must be sequential"); 5538 5539 if (Opcode == ARM::LDRD_PRE || Opcode == ARM::LDRD_POST) { 5540 const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg()); 5541 // For addressing modes with writeback, the base register needs to be 5542 // different from the destination registers. 5543 if (Rn == Rt || Rn == Rt2) 5544 return Error(Operands[3]->getStartLoc(), 5545 "base register needs to be different from destination " 5546 "registers"); 5547 } 5548 5549 return false; 5550 } 5551 case ARM::t2LDRDi8: 5552 case ARM::t2LDRD_PRE: 5553 case ARM::t2LDRD_POST: { 5554 // Rt2 must be different from Rt. 5555 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 5556 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 5557 if (Rt2 == Rt) 5558 return Error(Operands[3]->getStartLoc(), 5559 "destination operands can't be identical"); 5560 return false; 5561 } 5562 case ARM::STRD: { 5563 // Rt2 must be Rt + 1. 5564 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 5565 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 5566 if (Rt2 != Rt + 1) 5567 return Error(Operands[3]->getStartLoc(), 5568 "source operands must be sequential"); 5569 return false; 5570 } 5571 case ARM::STRD_PRE: 5572 case ARM::STRD_POST: { 5573 // Rt2 must be Rt + 1. 5574 unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 5575 unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(2).getReg()); 5576 if (Rt2 != Rt + 1) 5577 return Error(Operands[3]->getStartLoc(), 5578 "source operands must be sequential"); 5579 return false; 5580 } 5581 case ARM::SBFX: 5582 case ARM::UBFX: { 5583 // Width must be in range [1, 32-lsb]. 5584 unsigned LSB = Inst.getOperand(2).getImm(); 5585 unsigned Widthm1 = Inst.getOperand(3).getImm(); 5586 if (Widthm1 >= 32 - LSB) 5587 return Error(Operands[5]->getStartLoc(), 5588 "bitfield width must be in range [1,32-lsb]"); 5589 return false; 5590 } 5591 // Notionally handles ARM::tLDMIA_UPD too. 5592 case ARM::tLDMIA: { 5593 // If we're parsing Thumb2, the .w variant is available and handles 5594 // most cases that are normally illegal for a Thumb1 LDM instruction. 5595 // We'll make the transformation in processInstruction() if necessary. 5596 // 5597 // Thumb LDM instructions are writeback iff the base register is not 5598 // in the register list. 5599 unsigned Rn = Inst.getOperand(0).getReg(); 5600 bool HasWritebackToken = 5601 (static_cast<ARMOperand*>(Operands[3])->isToken() && 5602 static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 5603 bool ListContainsBase; 5604 if (checkLowRegisterList(Inst, 3, Rn, 0, ListContainsBase) && !isThumbTwo()) 5605 return Error(Operands[3 + HasWritebackToken]->getStartLoc(), 5606 "registers must be in range r0-r7"); 5607 // If we should have writeback, then there should be a '!' token. 5608 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo()) 5609 return Error(Operands[2]->getStartLoc(), 5610 "writeback operator '!' expected"); 5611 // If we should not have writeback, there must not be a '!'. This is 5612 // true even for the 32-bit wide encodings. 5613 if (ListContainsBase && HasWritebackToken) 5614 return Error(Operands[3]->getStartLoc(), 5615 "writeback operator '!' not allowed when base register " 5616 "in register list"); 5617 5618 break; 5619 } 5620 case ARM::LDMIA_UPD: 5621 case ARM::LDMDB_UPD: 5622 case ARM::LDMIB_UPD: 5623 case ARM::LDMDA_UPD: 5624 // ARM variants loading and updating the same register are only officially 5625 // UNPREDICTABLE on v7 upwards. Goodness knows what they did before. 5626 if (!hasV7Ops()) 5627 break; 5628 // Fallthrough 5629 case ARM::t2LDMIA_UPD: 5630 case ARM::t2LDMDB_UPD: 5631 case ARM::t2STMIA_UPD: 5632 case ARM::t2STMDB_UPD: { 5633 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 5634 return Error(Operands.back()->getStartLoc(), 5635 "writeback register not allowed in register list"); 5636 break; 5637 } 5638 case ARM::sysLDMIA_UPD: 5639 case ARM::sysLDMDA_UPD: 5640 case ARM::sysLDMDB_UPD: 5641 case ARM::sysLDMIB_UPD: 5642 if (!listContainsReg(Inst, 3, ARM::PC)) 5643 return Error(Operands[4]->getStartLoc(), 5644 "writeback register only allowed on system LDM " 5645 "if PC in register-list"); 5646 break; 5647 case ARM::sysSTMIA_UPD: 5648 case ARM::sysSTMDA_UPD: 5649 case ARM::sysSTMDB_UPD: 5650 case ARM::sysSTMIB_UPD: 5651 return Error(Operands[2]->getStartLoc(), 5652 "system STM cannot have writeback register"); 5653 break; 5654 case ARM::tMUL: { 5655 // The second source operand must be the same register as the destination 5656 // operand. 5657 // 5658 // In this case, we must directly check the parsed operands because the 5659 // cvtThumbMultiply() function is written in such a way that it guarantees 5660 // this first statement is always true for the new Inst. Essentially, the 5661 // destination is unconditionally copied into the second source operand 5662 // without checking to see if it matches what we actually parsed. 5663 if (Operands.size() == 6 && 5664 (((ARMOperand*)Operands[3])->getReg() != 5665 ((ARMOperand*)Operands[5])->getReg()) && 5666 (((ARMOperand*)Operands[3])->getReg() != 5667 ((ARMOperand*)Operands[4])->getReg())) { 5668 return Error(Operands[3]->getStartLoc(), 5669 "destination register must match source register"); 5670 } 5671 break; 5672 } 5673 // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2, 5674 // so only issue a diagnostic for thumb1. The instructions will be 5675 // switched to the t2 encodings in processInstruction() if necessary. 5676 case ARM::tPOP: { 5677 bool ListContainsBase; 5678 if (checkLowRegisterList(Inst, 2, 0, ARM::PC, ListContainsBase) && 5679 !isThumbTwo()) 5680 return Error(Operands[2]->getStartLoc(), 5681 "registers must be in range r0-r7 or pc"); 5682 break; 5683 } 5684 case ARM::tPUSH: { 5685 bool ListContainsBase; 5686 if (checkLowRegisterList(Inst, 2, 0, ARM::LR, ListContainsBase) && 5687 !isThumbTwo()) 5688 return Error(Operands[2]->getStartLoc(), 5689 "registers must be in range r0-r7 or lr"); 5690 break; 5691 } 5692 case ARM::tSTMIA_UPD: { 5693 bool ListContainsBase, InvalidLowList; 5694 InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(), 5695 0, ListContainsBase); 5696 if (InvalidLowList && !isThumbTwo()) 5697 return Error(Operands[4]->getStartLoc(), 5698 "registers must be in range r0-r7"); 5699 5700 // This would be converted to a 32-bit stm, but that's not valid if the 5701 // writeback register is in the list. 5702 if (InvalidLowList && ListContainsBase) 5703 return Error(Operands[4]->getStartLoc(), 5704 "writeback operator '!' not allowed when base register " 5705 "in register list"); 5706 break; 5707 } 5708 case ARM::tADDrSP: { 5709 // If the non-SP source operand and the destination operand are not the 5710 // same, we need thumb2 (for the wide encoding), or we have an error. 5711 if (!isThumbTwo() && 5712 Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) { 5713 return Error(Operands[4]->getStartLoc(), 5714 "source register must be the same as destination"); 5715 } 5716 break; 5717 } 5718 // Final range checking for Thumb unconditional branch instructions. 5719 case ARM::tB: 5720 if (!(static_cast<ARMOperand*>(Operands[2]))->isSignedOffset<11, 1>()) 5721 return Error(Operands[2]->getStartLoc(), "branch target out of range"); 5722 break; 5723 case ARM::t2B: { 5724 int op = (Operands[2]->isImm()) ? 2 : 3; 5725 if (!(static_cast<ARMOperand*>(Operands[op]))->isSignedOffset<24, 1>()) 5726 return Error(Operands[op]->getStartLoc(), "branch target out of range"); 5727 break; 5728 } 5729 // Final range checking for Thumb conditional branch instructions. 5730 case ARM::tBcc: 5731 if (!(static_cast<ARMOperand*>(Operands[2]))->isSignedOffset<8, 1>()) 5732 return Error(Operands[2]->getStartLoc(), "branch target out of range"); 5733 break; 5734 case ARM::t2Bcc: { 5735 int Op = (Operands[2]->isImm()) ? 2 : 3; 5736 if (!(static_cast<ARMOperand*>(Operands[Op]))->isSignedOffset<20, 1>()) 5737 return Error(Operands[Op]->getStartLoc(), "branch target out of range"); 5738 break; 5739 } 5740 } 5741 5742 return false; 5743 } 5744 5745 static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) { 5746 switch(Opc) { 5747 default: llvm_unreachable("unexpected opcode!"); 5748 // VST1LN 5749 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD; 5750 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD; 5751 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD; 5752 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD; 5753 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD; 5754 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD; 5755 case ARM::VST1LNdAsm_8: Spacing = 1; return ARM::VST1LNd8; 5756 case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16; 5757 case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32; 5758 5759 // VST2LN 5760 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD; 5761 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD; 5762 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD; 5763 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD; 5764 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD; 5765 5766 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1; return ARM::VST2LNd8_UPD; 5767 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD; 5768 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD; 5769 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD; 5770 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD; 5771 5772 case ARM::VST2LNdAsm_8: Spacing = 1; return ARM::VST2LNd8; 5773 case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16; 5774 case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32; 5775 case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16; 5776 case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32; 5777 5778 // VST3LN 5779 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD; 5780 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD; 5781 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD; 5782 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD; 5783 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD; 5784 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1; return ARM::VST3LNd8_UPD; 5785 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD; 5786 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD; 5787 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD; 5788 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD; 5789 case ARM::VST3LNdAsm_8: Spacing = 1; return ARM::VST3LNd8; 5790 case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16; 5791 case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32; 5792 case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16; 5793 case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32; 5794 5795 // VST3 5796 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1; return ARM::VST3d8_UPD; 5797 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD; 5798 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD; 5799 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2; return ARM::VST3q8_UPD; 5800 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD; 5801 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD; 5802 case ARM::VST3dWB_register_Asm_8: Spacing = 1; return ARM::VST3d8_UPD; 5803 case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD; 5804 case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD; 5805 case ARM::VST3qWB_register_Asm_8: Spacing = 2; return ARM::VST3q8_UPD; 5806 case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD; 5807 case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD; 5808 case ARM::VST3dAsm_8: Spacing = 1; return ARM::VST3d8; 5809 case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16; 5810 case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32; 5811 case ARM::VST3qAsm_8: Spacing = 2; return ARM::VST3q8; 5812 case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16; 5813 case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32; 5814 5815 // VST4LN 5816 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD; 5817 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD; 5818 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD; 5819 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD; 5820 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD; 5821 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1; return ARM::VST4LNd8_UPD; 5822 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD; 5823 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD; 5824 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD; 5825 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD; 5826 case ARM::VST4LNdAsm_8: Spacing = 1; return ARM::VST4LNd8; 5827 case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16; 5828 case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32; 5829 case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16; 5830 case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32; 5831 5832 // VST4 5833 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1; return ARM::VST4d8_UPD; 5834 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD; 5835 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD; 5836 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2; return ARM::VST4q8_UPD; 5837 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD; 5838 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD; 5839 case ARM::VST4dWB_register_Asm_8: Spacing = 1; return ARM::VST4d8_UPD; 5840 case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD; 5841 case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD; 5842 case ARM::VST4qWB_register_Asm_8: Spacing = 2; return ARM::VST4q8_UPD; 5843 case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD; 5844 case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD; 5845 case ARM::VST4dAsm_8: Spacing = 1; return ARM::VST4d8; 5846 case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16; 5847 case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32; 5848 case ARM::VST4qAsm_8: Spacing = 2; return ARM::VST4q8; 5849 case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16; 5850 case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32; 5851 } 5852 } 5853 5854 static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) { 5855 switch(Opc) { 5856 default: llvm_unreachable("unexpected opcode!"); 5857 // VLD1LN 5858 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD; 5859 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD; 5860 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD; 5861 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD; 5862 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD; 5863 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD; 5864 case ARM::VLD1LNdAsm_8: Spacing = 1; return ARM::VLD1LNd8; 5865 case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16; 5866 case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32; 5867 5868 // VLD2LN 5869 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD; 5870 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD; 5871 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD; 5872 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD; 5873 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD; 5874 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD2LNd8_UPD; 5875 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD; 5876 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD; 5877 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD; 5878 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD; 5879 case ARM::VLD2LNdAsm_8: Spacing = 1; return ARM::VLD2LNd8; 5880 case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16; 5881 case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32; 5882 case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16; 5883 case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32; 5884 5885 // VLD3DUP 5886 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD; 5887 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD; 5888 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD; 5889 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD; 5890 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPq16_UPD; 5891 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD; 5892 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD3DUPd8_UPD; 5893 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD; 5894 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD; 5895 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD; 5896 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD; 5897 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD; 5898 case ARM::VLD3DUPdAsm_8: Spacing = 1; return ARM::VLD3DUPd8; 5899 case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16; 5900 case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32; 5901 case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8; 5902 case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16; 5903 case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32; 5904 5905 // VLD3LN 5906 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD; 5907 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD; 5908 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD; 5909 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD; 5910 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD; 5911 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD3LNd8_UPD; 5912 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD; 5913 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD; 5914 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD; 5915 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD; 5916 case ARM::VLD3LNdAsm_8: Spacing = 1; return ARM::VLD3LNd8; 5917 case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16; 5918 case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32; 5919 case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16; 5920 case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32; 5921 5922 // VLD3 5923 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD; 5924 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD; 5925 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD; 5926 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD; 5927 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD; 5928 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD; 5929 case ARM::VLD3dWB_register_Asm_8: Spacing = 1; return ARM::VLD3d8_UPD; 5930 case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD; 5931 case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD; 5932 case ARM::VLD3qWB_register_Asm_8: Spacing = 2; return ARM::VLD3q8_UPD; 5933 case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD; 5934 case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD; 5935 case ARM::VLD3dAsm_8: Spacing = 1; return ARM::VLD3d8; 5936 case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16; 5937 case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32; 5938 case ARM::VLD3qAsm_8: Spacing = 2; return ARM::VLD3q8; 5939 case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16; 5940 case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32; 5941 5942 // VLD4LN 5943 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD; 5944 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD; 5945 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD; 5946 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNq16_UPD; 5947 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD; 5948 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1; return ARM::VLD4LNd8_UPD; 5949 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD; 5950 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD; 5951 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD; 5952 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD; 5953 case ARM::VLD4LNdAsm_8: Spacing = 1; return ARM::VLD4LNd8; 5954 case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16; 5955 case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32; 5956 case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16; 5957 case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32; 5958 5959 // VLD4DUP 5960 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD; 5961 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD; 5962 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD; 5963 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD; 5964 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD; 5965 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD; 5966 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1; return ARM::VLD4DUPd8_UPD; 5967 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD; 5968 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD; 5969 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD; 5970 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD; 5971 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD; 5972 case ARM::VLD4DUPdAsm_8: Spacing = 1; return ARM::VLD4DUPd8; 5973 case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16; 5974 case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32; 5975 case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8; 5976 case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16; 5977 case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32; 5978 5979 // VLD4 5980 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD; 5981 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD; 5982 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD; 5983 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD; 5984 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD; 5985 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD; 5986 case ARM::VLD4dWB_register_Asm_8: Spacing = 1; return ARM::VLD4d8_UPD; 5987 case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD; 5988 case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD; 5989 case ARM::VLD4qWB_register_Asm_8: Spacing = 2; return ARM::VLD4q8_UPD; 5990 case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD; 5991 case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD; 5992 case ARM::VLD4dAsm_8: Spacing = 1; return ARM::VLD4d8; 5993 case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16; 5994 case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32; 5995 case ARM::VLD4qAsm_8: Spacing = 2; return ARM::VLD4q8; 5996 case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16; 5997 case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32; 5998 } 5999 } 6000 6001 bool ARMAsmParser:: 6002 processInstruction(MCInst &Inst, 6003 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 6004 switch (Inst.getOpcode()) { 6005 // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction. 6006 case ARM::LDRT_POST: 6007 case ARM::LDRBT_POST: { 6008 const unsigned Opcode = 6009 (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM 6010 : ARM::LDRBT_POST_IMM; 6011 MCInst TmpInst; 6012 TmpInst.setOpcode(Opcode); 6013 TmpInst.addOperand(Inst.getOperand(0)); 6014 TmpInst.addOperand(Inst.getOperand(1)); 6015 TmpInst.addOperand(Inst.getOperand(1)); 6016 TmpInst.addOperand(MCOperand::CreateReg(0)); 6017 TmpInst.addOperand(MCOperand::CreateImm(0)); 6018 TmpInst.addOperand(Inst.getOperand(2)); 6019 TmpInst.addOperand(Inst.getOperand(3)); 6020 Inst = TmpInst; 6021 return true; 6022 } 6023 // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction. 6024 case ARM::STRT_POST: 6025 case ARM::STRBT_POST: { 6026 const unsigned Opcode = 6027 (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM 6028 : ARM::STRBT_POST_IMM; 6029 MCInst TmpInst; 6030 TmpInst.setOpcode(Opcode); 6031 TmpInst.addOperand(Inst.getOperand(1)); 6032 TmpInst.addOperand(Inst.getOperand(0)); 6033 TmpInst.addOperand(Inst.getOperand(1)); 6034 TmpInst.addOperand(MCOperand::CreateReg(0)); 6035 TmpInst.addOperand(MCOperand::CreateImm(0)); 6036 TmpInst.addOperand(Inst.getOperand(2)); 6037 TmpInst.addOperand(Inst.getOperand(3)); 6038 Inst = TmpInst; 6039 return true; 6040 } 6041 // Alias for alternate form of 'ADR Rd, #imm' instruction. 6042 case ARM::ADDri: { 6043 if (Inst.getOperand(1).getReg() != ARM::PC || 6044 Inst.getOperand(5).getReg() != 0) 6045 return false; 6046 MCInst TmpInst; 6047 TmpInst.setOpcode(ARM::ADR); 6048 TmpInst.addOperand(Inst.getOperand(0)); 6049 TmpInst.addOperand(Inst.getOperand(2)); 6050 TmpInst.addOperand(Inst.getOperand(3)); 6051 TmpInst.addOperand(Inst.getOperand(4)); 6052 Inst = TmpInst; 6053 return true; 6054 } 6055 // Aliases for alternate PC+imm syntax of LDR instructions. 6056 case ARM::t2LDRpcrel: 6057 // Select the narrow version if the immediate will fit. 6058 if (Inst.getOperand(1).getImm() > 0 && 6059 Inst.getOperand(1).getImm() <= 0xff && 6060 !(static_cast<ARMOperand*>(Operands[2])->isToken() && 6061 static_cast<ARMOperand*>(Operands[2])->getToken() == ".w")) 6062 Inst.setOpcode(ARM::tLDRpci); 6063 else 6064 Inst.setOpcode(ARM::t2LDRpci); 6065 return true; 6066 case ARM::t2LDRBpcrel: 6067 Inst.setOpcode(ARM::t2LDRBpci); 6068 return true; 6069 case ARM::t2LDRHpcrel: 6070 Inst.setOpcode(ARM::t2LDRHpci); 6071 return true; 6072 case ARM::t2LDRSBpcrel: 6073 Inst.setOpcode(ARM::t2LDRSBpci); 6074 return true; 6075 case ARM::t2LDRSHpcrel: 6076 Inst.setOpcode(ARM::t2LDRSHpci); 6077 return true; 6078 // Handle NEON VST complex aliases. 6079 case ARM::VST1LNdWB_register_Asm_8: 6080 case ARM::VST1LNdWB_register_Asm_16: 6081 case ARM::VST1LNdWB_register_Asm_32: { 6082 MCInst TmpInst; 6083 // Shuffle the operands around so the lane index operand is in the 6084 // right place. 6085 unsigned Spacing; 6086 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6087 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6088 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6089 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6090 TmpInst.addOperand(Inst.getOperand(4)); // Rm 6091 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6092 TmpInst.addOperand(Inst.getOperand(1)); // lane 6093 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 6094 TmpInst.addOperand(Inst.getOperand(6)); 6095 Inst = TmpInst; 6096 return true; 6097 } 6098 6099 case ARM::VST2LNdWB_register_Asm_8: 6100 case ARM::VST2LNdWB_register_Asm_16: 6101 case ARM::VST2LNdWB_register_Asm_32: 6102 case ARM::VST2LNqWB_register_Asm_16: 6103 case ARM::VST2LNqWB_register_Asm_32: { 6104 MCInst TmpInst; 6105 // Shuffle the operands around so the lane index operand is in the 6106 // right place. 6107 unsigned Spacing; 6108 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6109 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6110 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6111 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6112 TmpInst.addOperand(Inst.getOperand(4)); // Rm 6113 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6114 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6115 Spacing)); 6116 TmpInst.addOperand(Inst.getOperand(1)); // lane 6117 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 6118 TmpInst.addOperand(Inst.getOperand(6)); 6119 Inst = TmpInst; 6120 return true; 6121 } 6122 6123 case ARM::VST3LNdWB_register_Asm_8: 6124 case ARM::VST3LNdWB_register_Asm_16: 6125 case ARM::VST3LNdWB_register_Asm_32: 6126 case ARM::VST3LNqWB_register_Asm_16: 6127 case ARM::VST3LNqWB_register_Asm_32: { 6128 MCInst TmpInst; 6129 // Shuffle the operands around so the lane index operand is in the 6130 // right place. 6131 unsigned Spacing; 6132 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6133 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6134 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6135 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6136 TmpInst.addOperand(Inst.getOperand(4)); // Rm 6137 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6138 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6139 Spacing)); 6140 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6141 Spacing * 2)); 6142 TmpInst.addOperand(Inst.getOperand(1)); // lane 6143 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 6144 TmpInst.addOperand(Inst.getOperand(6)); 6145 Inst = TmpInst; 6146 return true; 6147 } 6148 6149 case ARM::VST4LNdWB_register_Asm_8: 6150 case ARM::VST4LNdWB_register_Asm_16: 6151 case ARM::VST4LNdWB_register_Asm_32: 6152 case ARM::VST4LNqWB_register_Asm_16: 6153 case ARM::VST4LNqWB_register_Asm_32: { 6154 MCInst TmpInst; 6155 // Shuffle the operands around so the lane index operand is in the 6156 // right place. 6157 unsigned Spacing; 6158 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6159 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6160 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6161 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6162 TmpInst.addOperand(Inst.getOperand(4)); // Rm 6163 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6164 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6165 Spacing)); 6166 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6167 Spacing * 2)); 6168 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6169 Spacing * 3)); 6170 TmpInst.addOperand(Inst.getOperand(1)); // lane 6171 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 6172 TmpInst.addOperand(Inst.getOperand(6)); 6173 Inst = TmpInst; 6174 return true; 6175 } 6176 6177 case ARM::VST1LNdWB_fixed_Asm_8: 6178 case ARM::VST1LNdWB_fixed_Asm_16: 6179 case ARM::VST1LNdWB_fixed_Asm_32: { 6180 MCInst TmpInst; 6181 // Shuffle the operands around so the lane index operand is in the 6182 // right place. 6183 unsigned Spacing; 6184 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6185 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6186 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6187 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6188 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6189 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6190 TmpInst.addOperand(Inst.getOperand(1)); // lane 6191 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6192 TmpInst.addOperand(Inst.getOperand(5)); 6193 Inst = TmpInst; 6194 return true; 6195 } 6196 6197 case ARM::VST2LNdWB_fixed_Asm_8: 6198 case ARM::VST2LNdWB_fixed_Asm_16: 6199 case ARM::VST2LNdWB_fixed_Asm_32: 6200 case ARM::VST2LNqWB_fixed_Asm_16: 6201 case ARM::VST2LNqWB_fixed_Asm_32: { 6202 MCInst TmpInst; 6203 // Shuffle the operands around so the lane index operand is in the 6204 // right place. 6205 unsigned Spacing; 6206 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6207 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6208 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6209 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6210 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6211 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6212 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6213 Spacing)); 6214 TmpInst.addOperand(Inst.getOperand(1)); // lane 6215 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6216 TmpInst.addOperand(Inst.getOperand(5)); 6217 Inst = TmpInst; 6218 return true; 6219 } 6220 6221 case ARM::VST3LNdWB_fixed_Asm_8: 6222 case ARM::VST3LNdWB_fixed_Asm_16: 6223 case ARM::VST3LNdWB_fixed_Asm_32: 6224 case ARM::VST3LNqWB_fixed_Asm_16: 6225 case ARM::VST3LNqWB_fixed_Asm_32: { 6226 MCInst TmpInst; 6227 // Shuffle the operands around so the lane index operand is in the 6228 // right place. 6229 unsigned Spacing; 6230 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6231 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6232 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6233 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6234 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6235 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6236 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6237 Spacing)); 6238 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6239 Spacing * 2)); 6240 TmpInst.addOperand(Inst.getOperand(1)); // lane 6241 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6242 TmpInst.addOperand(Inst.getOperand(5)); 6243 Inst = TmpInst; 6244 return true; 6245 } 6246 6247 case ARM::VST4LNdWB_fixed_Asm_8: 6248 case ARM::VST4LNdWB_fixed_Asm_16: 6249 case ARM::VST4LNdWB_fixed_Asm_32: 6250 case ARM::VST4LNqWB_fixed_Asm_16: 6251 case ARM::VST4LNqWB_fixed_Asm_32: { 6252 MCInst TmpInst; 6253 // Shuffle the operands around so the lane index operand is in the 6254 // right place. 6255 unsigned Spacing; 6256 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6257 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6258 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6259 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6260 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6261 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6262 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6263 Spacing)); 6264 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6265 Spacing * 2)); 6266 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6267 Spacing * 3)); 6268 TmpInst.addOperand(Inst.getOperand(1)); // lane 6269 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6270 TmpInst.addOperand(Inst.getOperand(5)); 6271 Inst = TmpInst; 6272 return true; 6273 } 6274 6275 case ARM::VST1LNdAsm_8: 6276 case ARM::VST1LNdAsm_16: 6277 case ARM::VST1LNdAsm_32: { 6278 MCInst TmpInst; 6279 // Shuffle the operands around so the lane index operand is in the 6280 // right place. 6281 unsigned Spacing; 6282 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6283 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6284 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6285 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6286 TmpInst.addOperand(Inst.getOperand(1)); // lane 6287 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6288 TmpInst.addOperand(Inst.getOperand(5)); 6289 Inst = TmpInst; 6290 return true; 6291 } 6292 6293 case ARM::VST2LNdAsm_8: 6294 case ARM::VST2LNdAsm_16: 6295 case ARM::VST2LNdAsm_32: 6296 case ARM::VST2LNqAsm_16: 6297 case ARM::VST2LNqAsm_32: { 6298 MCInst TmpInst; 6299 // Shuffle the operands around so the lane index operand is in the 6300 // right place. 6301 unsigned Spacing; 6302 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6303 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6304 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6305 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6306 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6307 Spacing)); 6308 TmpInst.addOperand(Inst.getOperand(1)); // lane 6309 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6310 TmpInst.addOperand(Inst.getOperand(5)); 6311 Inst = TmpInst; 6312 return true; 6313 } 6314 6315 case ARM::VST3LNdAsm_8: 6316 case ARM::VST3LNdAsm_16: 6317 case ARM::VST3LNdAsm_32: 6318 case ARM::VST3LNqAsm_16: 6319 case ARM::VST3LNqAsm_32: { 6320 MCInst TmpInst; 6321 // Shuffle the operands around so the lane index operand is in the 6322 // right place. 6323 unsigned Spacing; 6324 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6325 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6326 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6327 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6328 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6329 Spacing)); 6330 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6331 Spacing * 2)); 6332 TmpInst.addOperand(Inst.getOperand(1)); // lane 6333 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6334 TmpInst.addOperand(Inst.getOperand(5)); 6335 Inst = TmpInst; 6336 return true; 6337 } 6338 6339 case ARM::VST4LNdAsm_8: 6340 case ARM::VST4LNdAsm_16: 6341 case ARM::VST4LNdAsm_32: 6342 case ARM::VST4LNqAsm_16: 6343 case ARM::VST4LNqAsm_32: { 6344 MCInst TmpInst; 6345 // Shuffle the operands around so the lane index operand is in the 6346 // right place. 6347 unsigned Spacing; 6348 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 6349 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6350 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6351 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6352 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6353 Spacing)); 6354 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6355 Spacing * 2)); 6356 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6357 Spacing * 3)); 6358 TmpInst.addOperand(Inst.getOperand(1)); // lane 6359 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6360 TmpInst.addOperand(Inst.getOperand(5)); 6361 Inst = TmpInst; 6362 return true; 6363 } 6364 6365 // Handle NEON VLD complex aliases. 6366 case ARM::VLD1LNdWB_register_Asm_8: 6367 case ARM::VLD1LNdWB_register_Asm_16: 6368 case ARM::VLD1LNdWB_register_Asm_32: { 6369 MCInst TmpInst; 6370 // Shuffle the operands around so the lane index operand is in the 6371 // right place. 6372 unsigned Spacing; 6373 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6374 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6375 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6376 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6377 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6378 TmpInst.addOperand(Inst.getOperand(4)); // Rm 6379 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6380 TmpInst.addOperand(Inst.getOperand(1)); // lane 6381 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 6382 TmpInst.addOperand(Inst.getOperand(6)); 6383 Inst = TmpInst; 6384 return true; 6385 } 6386 6387 case ARM::VLD2LNdWB_register_Asm_8: 6388 case ARM::VLD2LNdWB_register_Asm_16: 6389 case ARM::VLD2LNdWB_register_Asm_32: 6390 case ARM::VLD2LNqWB_register_Asm_16: 6391 case ARM::VLD2LNqWB_register_Asm_32: { 6392 MCInst TmpInst; 6393 // Shuffle the operands around so the lane index operand is in the 6394 // right place. 6395 unsigned Spacing; 6396 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6397 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6398 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6399 Spacing)); 6400 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6401 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6402 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6403 TmpInst.addOperand(Inst.getOperand(4)); // Rm 6404 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6405 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6406 Spacing)); 6407 TmpInst.addOperand(Inst.getOperand(1)); // lane 6408 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 6409 TmpInst.addOperand(Inst.getOperand(6)); 6410 Inst = TmpInst; 6411 return true; 6412 } 6413 6414 case ARM::VLD3LNdWB_register_Asm_8: 6415 case ARM::VLD3LNdWB_register_Asm_16: 6416 case ARM::VLD3LNdWB_register_Asm_32: 6417 case ARM::VLD3LNqWB_register_Asm_16: 6418 case ARM::VLD3LNqWB_register_Asm_32: { 6419 MCInst TmpInst; 6420 // Shuffle the operands around so the lane index operand is in the 6421 // right place. 6422 unsigned Spacing; 6423 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6424 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6425 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6426 Spacing)); 6427 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6428 Spacing * 2)); 6429 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6430 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6431 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6432 TmpInst.addOperand(Inst.getOperand(4)); // Rm 6433 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6434 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6435 Spacing)); 6436 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6437 Spacing * 2)); 6438 TmpInst.addOperand(Inst.getOperand(1)); // lane 6439 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 6440 TmpInst.addOperand(Inst.getOperand(6)); 6441 Inst = TmpInst; 6442 return true; 6443 } 6444 6445 case ARM::VLD4LNdWB_register_Asm_8: 6446 case ARM::VLD4LNdWB_register_Asm_16: 6447 case ARM::VLD4LNdWB_register_Asm_32: 6448 case ARM::VLD4LNqWB_register_Asm_16: 6449 case ARM::VLD4LNqWB_register_Asm_32: { 6450 MCInst TmpInst; 6451 // Shuffle the operands around so the lane index operand is in the 6452 // right place. 6453 unsigned Spacing; 6454 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6455 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6456 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6457 Spacing)); 6458 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6459 Spacing * 2)); 6460 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6461 Spacing * 3)); 6462 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6463 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6464 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6465 TmpInst.addOperand(Inst.getOperand(4)); // Rm 6466 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6467 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6468 Spacing)); 6469 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6470 Spacing * 2)); 6471 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6472 Spacing * 3)); 6473 TmpInst.addOperand(Inst.getOperand(1)); // lane 6474 TmpInst.addOperand(Inst.getOperand(5)); // CondCode 6475 TmpInst.addOperand(Inst.getOperand(6)); 6476 Inst = TmpInst; 6477 return true; 6478 } 6479 6480 case ARM::VLD1LNdWB_fixed_Asm_8: 6481 case ARM::VLD1LNdWB_fixed_Asm_16: 6482 case ARM::VLD1LNdWB_fixed_Asm_32: { 6483 MCInst TmpInst; 6484 // Shuffle the operands around so the lane index operand is in the 6485 // right place. 6486 unsigned Spacing; 6487 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6488 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6489 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6490 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6491 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6492 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6493 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6494 TmpInst.addOperand(Inst.getOperand(1)); // lane 6495 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6496 TmpInst.addOperand(Inst.getOperand(5)); 6497 Inst = TmpInst; 6498 return true; 6499 } 6500 6501 case ARM::VLD2LNdWB_fixed_Asm_8: 6502 case ARM::VLD2LNdWB_fixed_Asm_16: 6503 case ARM::VLD2LNdWB_fixed_Asm_32: 6504 case ARM::VLD2LNqWB_fixed_Asm_16: 6505 case ARM::VLD2LNqWB_fixed_Asm_32: { 6506 MCInst TmpInst; 6507 // Shuffle the operands around so the lane index operand is in the 6508 // right place. 6509 unsigned Spacing; 6510 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6511 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6512 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6513 Spacing)); 6514 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6515 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6516 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6517 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6518 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6519 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6520 Spacing)); 6521 TmpInst.addOperand(Inst.getOperand(1)); // lane 6522 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6523 TmpInst.addOperand(Inst.getOperand(5)); 6524 Inst = TmpInst; 6525 return true; 6526 } 6527 6528 case ARM::VLD3LNdWB_fixed_Asm_8: 6529 case ARM::VLD3LNdWB_fixed_Asm_16: 6530 case ARM::VLD3LNdWB_fixed_Asm_32: 6531 case ARM::VLD3LNqWB_fixed_Asm_16: 6532 case ARM::VLD3LNqWB_fixed_Asm_32: { 6533 MCInst TmpInst; 6534 // Shuffle the operands around so the lane index operand is in the 6535 // right place. 6536 unsigned Spacing; 6537 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6538 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6539 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6540 Spacing)); 6541 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6542 Spacing * 2)); 6543 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6544 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6545 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6546 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6547 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6548 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6549 Spacing)); 6550 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6551 Spacing * 2)); 6552 TmpInst.addOperand(Inst.getOperand(1)); // lane 6553 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6554 TmpInst.addOperand(Inst.getOperand(5)); 6555 Inst = TmpInst; 6556 return true; 6557 } 6558 6559 case ARM::VLD4LNdWB_fixed_Asm_8: 6560 case ARM::VLD4LNdWB_fixed_Asm_16: 6561 case ARM::VLD4LNdWB_fixed_Asm_32: 6562 case ARM::VLD4LNqWB_fixed_Asm_16: 6563 case ARM::VLD4LNqWB_fixed_Asm_32: { 6564 MCInst TmpInst; 6565 // Shuffle the operands around so the lane index operand is in the 6566 // right place. 6567 unsigned Spacing; 6568 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6569 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6570 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6571 Spacing)); 6572 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6573 Spacing * 2)); 6574 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6575 Spacing * 3)); 6576 TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb 6577 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6578 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6579 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6580 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6581 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6582 Spacing)); 6583 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6584 Spacing * 2)); 6585 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6586 Spacing * 3)); 6587 TmpInst.addOperand(Inst.getOperand(1)); // lane 6588 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6589 TmpInst.addOperand(Inst.getOperand(5)); 6590 Inst = TmpInst; 6591 return true; 6592 } 6593 6594 case ARM::VLD1LNdAsm_8: 6595 case ARM::VLD1LNdAsm_16: 6596 case ARM::VLD1LNdAsm_32: { 6597 MCInst TmpInst; 6598 // Shuffle the operands around so the lane index operand is in the 6599 // right place. 6600 unsigned Spacing; 6601 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6602 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6603 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6604 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6605 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6606 TmpInst.addOperand(Inst.getOperand(1)); // lane 6607 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6608 TmpInst.addOperand(Inst.getOperand(5)); 6609 Inst = TmpInst; 6610 return true; 6611 } 6612 6613 case ARM::VLD2LNdAsm_8: 6614 case ARM::VLD2LNdAsm_16: 6615 case ARM::VLD2LNdAsm_32: 6616 case ARM::VLD2LNqAsm_16: 6617 case ARM::VLD2LNqAsm_32: { 6618 MCInst TmpInst; 6619 // Shuffle the operands around so the lane index operand is in the 6620 // right place. 6621 unsigned Spacing; 6622 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6623 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6624 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6625 Spacing)); 6626 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6627 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6628 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6629 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6630 Spacing)); 6631 TmpInst.addOperand(Inst.getOperand(1)); // lane 6632 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6633 TmpInst.addOperand(Inst.getOperand(5)); 6634 Inst = TmpInst; 6635 return true; 6636 } 6637 6638 case ARM::VLD3LNdAsm_8: 6639 case ARM::VLD3LNdAsm_16: 6640 case ARM::VLD3LNdAsm_32: 6641 case ARM::VLD3LNqAsm_16: 6642 case ARM::VLD3LNqAsm_32: { 6643 MCInst TmpInst; 6644 // Shuffle the operands around so the lane index operand is in the 6645 // right place. 6646 unsigned Spacing; 6647 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6648 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6649 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6650 Spacing)); 6651 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6652 Spacing * 2)); 6653 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6654 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6655 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6656 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6657 Spacing)); 6658 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6659 Spacing * 2)); 6660 TmpInst.addOperand(Inst.getOperand(1)); // lane 6661 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6662 TmpInst.addOperand(Inst.getOperand(5)); 6663 Inst = TmpInst; 6664 return true; 6665 } 6666 6667 case ARM::VLD4LNdAsm_8: 6668 case ARM::VLD4LNdAsm_16: 6669 case ARM::VLD4LNdAsm_32: 6670 case ARM::VLD4LNqAsm_16: 6671 case ARM::VLD4LNqAsm_32: { 6672 MCInst TmpInst; 6673 // Shuffle the operands around so the lane index operand is in the 6674 // right place. 6675 unsigned Spacing; 6676 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6677 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6678 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6679 Spacing)); 6680 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6681 Spacing * 2)); 6682 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6683 Spacing * 3)); 6684 TmpInst.addOperand(Inst.getOperand(2)); // Rn 6685 TmpInst.addOperand(Inst.getOperand(3)); // alignment 6686 TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd) 6687 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6688 Spacing)); 6689 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6690 Spacing * 2)); 6691 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6692 Spacing * 3)); 6693 TmpInst.addOperand(Inst.getOperand(1)); // lane 6694 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6695 TmpInst.addOperand(Inst.getOperand(5)); 6696 Inst = TmpInst; 6697 return true; 6698 } 6699 6700 // VLD3DUP single 3-element structure to all lanes instructions. 6701 case ARM::VLD3DUPdAsm_8: 6702 case ARM::VLD3DUPdAsm_16: 6703 case ARM::VLD3DUPdAsm_32: 6704 case ARM::VLD3DUPqAsm_8: 6705 case ARM::VLD3DUPqAsm_16: 6706 case ARM::VLD3DUPqAsm_32: { 6707 MCInst TmpInst; 6708 unsigned Spacing; 6709 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6710 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6711 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6712 Spacing)); 6713 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6714 Spacing * 2)); 6715 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6716 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6717 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 6718 TmpInst.addOperand(Inst.getOperand(4)); 6719 Inst = TmpInst; 6720 return true; 6721 } 6722 6723 case ARM::VLD3DUPdWB_fixed_Asm_8: 6724 case ARM::VLD3DUPdWB_fixed_Asm_16: 6725 case ARM::VLD3DUPdWB_fixed_Asm_32: 6726 case ARM::VLD3DUPqWB_fixed_Asm_8: 6727 case ARM::VLD3DUPqWB_fixed_Asm_16: 6728 case ARM::VLD3DUPqWB_fixed_Asm_32: { 6729 MCInst TmpInst; 6730 unsigned Spacing; 6731 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6732 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6733 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6734 Spacing)); 6735 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6736 Spacing * 2)); 6737 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6738 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 6739 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6740 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6741 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 6742 TmpInst.addOperand(Inst.getOperand(4)); 6743 Inst = TmpInst; 6744 return true; 6745 } 6746 6747 case ARM::VLD3DUPdWB_register_Asm_8: 6748 case ARM::VLD3DUPdWB_register_Asm_16: 6749 case ARM::VLD3DUPdWB_register_Asm_32: 6750 case ARM::VLD3DUPqWB_register_Asm_8: 6751 case ARM::VLD3DUPqWB_register_Asm_16: 6752 case ARM::VLD3DUPqWB_register_Asm_32: { 6753 MCInst TmpInst; 6754 unsigned Spacing; 6755 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6756 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6757 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6758 Spacing)); 6759 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6760 Spacing * 2)); 6761 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6762 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 6763 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6764 TmpInst.addOperand(Inst.getOperand(3)); // Rm 6765 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6766 TmpInst.addOperand(Inst.getOperand(5)); 6767 Inst = TmpInst; 6768 return true; 6769 } 6770 6771 // VLD3 multiple 3-element structure instructions. 6772 case ARM::VLD3dAsm_8: 6773 case ARM::VLD3dAsm_16: 6774 case ARM::VLD3dAsm_32: 6775 case ARM::VLD3qAsm_8: 6776 case ARM::VLD3qAsm_16: 6777 case ARM::VLD3qAsm_32: { 6778 MCInst TmpInst; 6779 unsigned Spacing; 6780 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6781 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6782 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6783 Spacing)); 6784 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6785 Spacing * 2)); 6786 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6787 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6788 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 6789 TmpInst.addOperand(Inst.getOperand(4)); 6790 Inst = TmpInst; 6791 return true; 6792 } 6793 6794 case ARM::VLD3dWB_fixed_Asm_8: 6795 case ARM::VLD3dWB_fixed_Asm_16: 6796 case ARM::VLD3dWB_fixed_Asm_32: 6797 case ARM::VLD3qWB_fixed_Asm_8: 6798 case ARM::VLD3qWB_fixed_Asm_16: 6799 case ARM::VLD3qWB_fixed_Asm_32: { 6800 MCInst TmpInst; 6801 unsigned Spacing; 6802 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6803 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6804 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6805 Spacing)); 6806 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6807 Spacing * 2)); 6808 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6809 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 6810 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6811 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6812 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 6813 TmpInst.addOperand(Inst.getOperand(4)); 6814 Inst = TmpInst; 6815 return true; 6816 } 6817 6818 case ARM::VLD3dWB_register_Asm_8: 6819 case ARM::VLD3dWB_register_Asm_16: 6820 case ARM::VLD3dWB_register_Asm_32: 6821 case ARM::VLD3qWB_register_Asm_8: 6822 case ARM::VLD3qWB_register_Asm_16: 6823 case ARM::VLD3qWB_register_Asm_32: { 6824 MCInst TmpInst; 6825 unsigned Spacing; 6826 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6827 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6828 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6829 Spacing)); 6830 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6831 Spacing * 2)); 6832 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6833 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 6834 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6835 TmpInst.addOperand(Inst.getOperand(3)); // Rm 6836 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6837 TmpInst.addOperand(Inst.getOperand(5)); 6838 Inst = TmpInst; 6839 return true; 6840 } 6841 6842 // VLD4DUP single 3-element structure to all lanes instructions. 6843 case ARM::VLD4DUPdAsm_8: 6844 case ARM::VLD4DUPdAsm_16: 6845 case ARM::VLD4DUPdAsm_32: 6846 case ARM::VLD4DUPqAsm_8: 6847 case ARM::VLD4DUPqAsm_16: 6848 case ARM::VLD4DUPqAsm_32: { 6849 MCInst TmpInst; 6850 unsigned Spacing; 6851 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6852 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6853 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6854 Spacing)); 6855 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6856 Spacing * 2)); 6857 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6858 Spacing * 3)); 6859 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6860 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6861 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 6862 TmpInst.addOperand(Inst.getOperand(4)); 6863 Inst = TmpInst; 6864 return true; 6865 } 6866 6867 case ARM::VLD4DUPdWB_fixed_Asm_8: 6868 case ARM::VLD4DUPdWB_fixed_Asm_16: 6869 case ARM::VLD4DUPdWB_fixed_Asm_32: 6870 case ARM::VLD4DUPqWB_fixed_Asm_8: 6871 case ARM::VLD4DUPqWB_fixed_Asm_16: 6872 case ARM::VLD4DUPqWB_fixed_Asm_32: { 6873 MCInst TmpInst; 6874 unsigned Spacing; 6875 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6876 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6877 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6878 Spacing)); 6879 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6880 Spacing * 2)); 6881 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6882 Spacing * 3)); 6883 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6884 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 6885 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6886 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6887 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 6888 TmpInst.addOperand(Inst.getOperand(4)); 6889 Inst = TmpInst; 6890 return true; 6891 } 6892 6893 case ARM::VLD4DUPdWB_register_Asm_8: 6894 case ARM::VLD4DUPdWB_register_Asm_16: 6895 case ARM::VLD4DUPdWB_register_Asm_32: 6896 case ARM::VLD4DUPqWB_register_Asm_8: 6897 case ARM::VLD4DUPqWB_register_Asm_16: 6898 case ARM::VLD4DUPqWB_register_Asm_32: { 6899 MCInst TmpInst; 6900 unsigned Spacing; 6901 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6902 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6903 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6904 Spacing)); 6905 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6906 Spacing * 2)); 6907 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6908 Spacing * 3)); 6909 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6910 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 6911 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6912 TmpInst.addOperand(Inst.getOperand(3)); // Rm 6913 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6914 TmpInst.addOperand(Inst.getOperand(5)); 6915 Inst = TmpInst; 6916 return true; 6917 } 6918 6919 // VLD4 multiple 4-element structure instructions. 6920 case ARM::VLD4dAsm_8: 6921 case ARM::VLD4dAsm_16: 6922 case ARM::VLD4dAsm_32: 6923 case ARM::VLD4qAsm_8: 6924 case ARM::VLD4qAsm_16: 6925 case ARM::VLD4qAsm_32: { 6926 MCInst TmpInst; 6927 unsigned Spacing; 6928 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6929 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6930 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6931 Spacing)); 6932 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6933 Spacing * 2)); 6934 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6935 Spacing * 3)); 6936 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6937 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6938 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 6939 TmpInst.addOperand(Inst.getOperand(4)); 6940 Inst = TmpInst; 6941 return true; 6942 } 6943 6944 case ARM::VLD4dWB_fixed_Asm_8: 6945 case ARM::VLD4dWB_fixed_Asm_16: 6946 case ARM::VLD4dWB_fixed_Asm_32: 6947 case ARM::VLD4qWB_fixed_Asm_8: 6948 case ARM::VLD4qWB_fixed_Asm_16: 6949 case ARM::VLD4qWB_fixed_Asm_32: { 6950 MCInst TmpInst; 6951 unsigned Spacing; 6952 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6953 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6954 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6955 Spacing)); 6956 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6957 Spacing * 2)); 6958 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6959 Spacing * 3)); 6960 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6961 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 6962 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6963 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 6964 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 6965 TmpInst.addOperand(Inst.getOperand(4)); 6966 Inst = TmpInst; 6967 return true; 6968 } 6969 6970 case ARM::VLD4dWB_register_Asm_8: 6971 case ARM::VLD4dWB_register_Asm_16: 6972 case ARM::VLD4dWB_register_Asm_32: 6973 case ARM::VLD4qWB_register_Asm_8: 6974 case ARM::VLD4qWB_register_Asm_16: 6975 case ARM::VLD4qWB_register_Asm_32: { 6976 MCInst TmpInst; 6977 unsigned Spacing; 6978 TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing)); 6979 TmpInst.addOperand(Inst.getOperand(0)); // Vd 6980 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6981 Spacing)); 6982 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6983 Spacing * 2)); 6984 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 6985 Spacing * 3)); 6986 TmpInst.addOperand(Inst.getOperand(1)); // Rn 6987 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 6988 TmpInst.addOperand(Inst.getOperand(2)); // alignment 6989 TmpInst.addOperand(Inst.getOperand(3)); // Rm 6990 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 6991 TmpInst.addOperand(Inst.getOperand(5)); 6992 Inst = TmpInst; 6993 return true; 6994 } 6995 6996 // VST3 multiple 3-element structure instructions. 6997 case ARM::VST3dAsm_8: 6998 case ARM::VST3dAsm_16: 6999 case ARM::VST3dAsm_32: 7000 case ARM::VST3qAsm_8: 7001 case ARM::VST3qAsm_16: 7002 case ARM::VST3qAsm_32: { 7003 MCInst TmpInst; 7004 unsigned Spacing; 7005 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 7006 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7007 TmpInst.addOperand(Inst.getOperand(2)); // alignment 7008 TmpInst.addOperand(Inst.getOperand(0)); // Vd 7009 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7010 Spacing)); 7011 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7012 Spacing * 2)); 7013 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 7014 TmpInst.addOperand(Inst.getOperand(4)); 7015 Inst = TmpInst; 7016 return true; 7017 } 7018 7019 case ARM::VST3dWB_fixed_Asm_8: 7020 case ARM::VST3dWB_fixed_Asm_16: 7021 case ARM::VST3dWB_fixed_Asm_32: 7022 case ARM::VST3qWB_fixed_Asm_8: 7023 case ARM::VST3qWB_fixed_Asm_16: 7024 case ARM::VST3qWB_fixed_Asm_32: { 7025 MCInst TmpInst; 7026 unsigned Spacing; 7027 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 7028 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7029 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 7030 TmpInst.addOperand(Inst.getOperand(2)); // alignment 7031 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 7032 TmpInst.addOperand(Inst.getOperand(0)); // Vd 7033 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7034 Spacing)); 7035 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7036 Spacing * 2)); 7037 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 7038 TmpInst.addOperand(Inst.getOperand(4)); 7039 Inst = TmpInst; 7040 return true; 7041 } 7042 7043 case ARM::VST3dWB_register_Asm_8: 7044 case ARM::VST3dWB_register_Asm_16: 7045 case ARM::VST3dWB_register_Asm_32: 7046 case ARM::VST3qWB_register_Asm_8: 7047 case ARM::VST3qWB_register_Asm_16: 7048 case ARM::VST3qWB_register_Asm_32: { 7049 MCInst TmpInst; 7050 unsigned Spacing; 7051 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 7052 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7053 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 7054 TmpInst.addOperand(Inst.getOperand(2)); // alignment 7055 TmpInst.addOperand(Inst.getOperand(3)); // Rm 7056 TmpInst.addOperand(Inst.getOperand(0)); // Vd 7057 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7058 Spacing)); 7059 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7060 Spacing * 2)); 7061 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 7062 TmpInst.addOperand(Inst.getOperand(5)); 7063 Inst = TmpInst; 7064 return true; 7065 } 7066 7067 // VST4 multiple 3-element structure instructions. 7068 case ARM::VST4dAsm_8: 7069 case ARM::VST4dAsm_16: 7070 case ARM::VST4dAsm_32: 7071 case ARM::VST4qAsm_8: 7072 case ARM::VST4qAsm_16: 7073 case ARM::VST4qAsm_32: { 7074 MCInst TmpInst; 7075 unsigned Spacing; 7076 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 7077 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7078 TmpInst.addOperand(Inst.getOperand(2)); // alignment 7079 TmpInst.addOperand(Inst.getOperand(0)); // Vd 7080 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7081 Spacing)); 7082 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7083 Spacing * 2)); 7084 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7085 Spacing * 3)); 7086 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 7087 TmpInst.addOperand(Inst.getOperand(4)); 7088 Inst = TmpInst; 7089 return true; 7090 } 7091 7092 case ARM::VST4dWB_fixed_Asm_8: 7093 case ARM::VST4dWB_fixed_Asm_16: 7094 case ARM::VST4dWB_fixed_Asm_32: 7095 case ARM::VST4qWB_fixed_Asm_8: 7096 case ARM::VST4qWB_fixed_Asm_16: 7097 case ARM::VST4qWB_fixed_Asm_32: { 7098 MCInst TmpInst; 7099 unsigned Spacing; 7100 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 7101 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7102 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 7103 TmpInst.addOperand(Inst.getOperand(2)); // alignment 7104 TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm 7105 TmpInst.addOperand(Inst.getOperand(0)); // Vd 7106 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7107 Spacing)); 7108 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7109 Spacing * 2)); 7110 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7111 Spacing * 3)); 7112 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 7113 TmpInst.addOperand(Inst.getOperand(4)); 7114 Inst = TmpInst; 7115 return true; 7116 } 7117 7118 case ARM::VST4dWB_register_Asm_8: 7119 case ARM::VST4dWB_register_Asm_16: 7120 case ARM::VST4dWB_register_Asm_32: 7121 case ARM::VST4qWB_register_Asm_8: 7122 case ARM::VST4qWB_register_Asm_16: 7123 case ARM::VST4qWB_register_Asm_32: { 7124 MCInst TmpInst; 7125 unsigned Spacing; 7126 TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing)); 7127 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7128 TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn 7129 TmpInst.addOperand(Inst.getOperand(2)); // alignment 7130 TmpInst.addOperand(Inst.getOperand(3)); // Rm 7131 TmpInst.addOperand(Inst.getOperand(0)); // Vd 7132 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7133 Spacing)); 7134 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7135 Spacing * 2)); 7136 TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() + 7137 Spacing * 3)); 7138 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 7139 TmpInst.addOperand(Inst.getOperand(5)); 7140 Inst = TmpInst; 7141 return true; 7142 } 7143 7144 // Handle encoding choice for the shift-immediate instructions. 7145 case ARM::t2LSLri: 7146 case ARM::t2LSRri: 7147 case ARM::t2ASRri: { 7148 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 7149 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && 7150 Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) && 7151 !(static_cast<ARMOperand*>(Operands[3])->isToken() && 7152 static_cast<ARMOperand*>(Operands[3])->getToken() == ".w")) { 7153 unsigned NewOpc; 7154 switch (Inst.getOpcode()) { 7155 default: llvm_unreachable("unexpected opcode"); 7156 case ARM::t2LSLri: NewOpc = ARM::tLSLri; break; 7157 case ARM::t2LSRri: NewOpc = ARM::tLSRri; break; 7158 case ARM::t2ASRri: NewOpc = ARM::tASRri; break; 7159 } 7160 // The Thumb1 operands aren't in the same order. Awesome, eh? 7161 MCInst TmpInst; 7162 TmpInst.setOpcode(NewOpc); 7163 TmpInst.addOperand(Inst.getOperand(0)); 7164 TmpInst.addOperand(Inst.getOperand(5)); 7165 TmpInst.addOperand(Inst.getOperand(1)); 7166 TmpInst.addOperand(Inst.getOperand(2)); 7167 TmpInst.addOperand(Inst.getOperand(3)); 7168 TmpInst.addOperand(Inst.getOperand(4)); 7169 Inst = TmpInst; 7170 return true; 7171 } 7172 return false; 7173 } 7174 7175 // Handle the Thumb2 mode MOV complex aliases. 7176 case ARM::t2MOVsr: 7177 case ARM::t2MOVSsr: { 7178 // Which instruction to expand to depends on the CCOut operand and 7179 // whether we're in an IT block if the register operands are low 7180 // registers. 7181 bool isNarrow = false; 7182 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 7183 isARMLowRegister(Inst.getOperand(1).getReg()) && 7184 isARMLowRegister(Inst.getOperand(2).getReg()) && 7185 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && 7186 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr)) 7187 isNarrow = true; 7188 MCInst TmpInst; 7189 unsigned newOpc; 7190 switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) { 7191 default: llvm_unreachable("unexpected opcode!"); 7192 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break; 7193 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break; 7194 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break; 7195 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break; 7196 } 7197 TmpInst.setOpcode(newOpc); 7198 TmpInst.addOperand(Inst.getOperand(0)); // Rd 7199 if (isNarrow) 7200 TmpInst.addOperand(MCOperand::CreateReg( 7201 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0)); 7202 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7203 TmpInst.addOperand(Inst.getOperand(2)); // Rm 7204 TmpInst.addOperand(Inst.getOperand(4)); // CondCode 7205 TmpInst.addOperand(Inst.getOperand(5)); 7206 if (!isNarrow) 7207 TmpInst.addOperand(MCOperand::CreateReg( 7208 Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0)); 7209 Inst = TmpInst; 7210 return true; 7211 } 7212 case ARM::t2MOVsi: 7213 case ARM::t2MOVSsi: { 7214 // Which instruction to expand to depends on the CCOut operand and 7215 // whether we're in an IT block if the register operands are low 7216 // registers. 7217 bool isNarrow = false; 7218 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 7219 isARMLowRegister(Inst.getOperand(1).getReg()) && 7220 inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi)) 7221 isNarrow = true; 7222 MCInst TmpInst; 7223 unsigned newOpc; 7224 switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) { 7225 default: llvm_unreachable("unexpected opcode!"); 7226 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break; 7227 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break; 7228 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break; 7229 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break; 7230 case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break; 7231 } 7232 unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()); 7233 if (Amount == 32) Amount = 0; 7234 TmpInst.setOpcode(newOpc); 7235 TmpInst.addOperand(Inst.getOperand(0)); // Rd 7236 if (isNarrow) 7237 TmpInst.addOperand(MCOperand::CreateReg( 7238 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0)); 7239 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7240 if (newOpc != ARM::t2RRX) 7241 TmpInst.addOperand(MCOperand::CreateImm(Amount)); 7242 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 7243 TmpInst.addOperand(Inst.getOperand(4)); 7244 if (!isNarrow) 7245 TmpInst.addOperand(MCOperand::CreateReg( 7246 Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0)); 7247 Inst = TmpInst; 7248 return true; 7249 } 7250 // Handle the ARM mode MOV complex aliases. 7251 case ARM::ASRr: 7252 case ARM::LSRr: 7253 case ARM::LSLr: 7254 case ARM::RORr: { 7255 ARM_AM::ShiftOpc ShiftTy; 7256 switch(Inst.getOpcode()) { 7257 default: llvm_unreachable("unexpected opcode!"); 7258 case ARM::ASRr: ShiftTy = ARM_AM::asr; break; 7259 case ARM::LSRr: ShiftTy = ARM_AM::lsr; break; 7260 case ARM::LSLr: ShiftTy = ARM_AM::lsl; break; 7261 case ARM::RORr: ShiftTy = ARM_AM::ror; break; 7262 } 7263 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0); 7264 MCInst TmpInst; 7265 TmpInst.setOpcode(ARM::MOVsr); 7266 TmpInst.addOperand(Inst.getOperand(0)); // Rd 7267 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7268 TmpInst.addOperand(Inst.getOperand(2)); // Rm 7269 TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 7270 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 7271 TmpInst.addOperand(Inst.getOperand(4)); 7272 TmpInst.addOperand(Inst.getOperand(5)); // cc_out 7273 Inst = TmpInst; 7274 return true; 7275 } 7276 case ARM::ASRi: 7277 case ARM::LSRi: 7278 case ARM::LSLi: 7279 case ARM::RORi: { 7280 ARM_AM::ShiftOpc ShiftTy; 7281 switch(Inst.getOpcode()) { 7282 default: llvm_unreachable("unexpected opcode!"); 7283 case ARM::ASRi: ShiftTy = ARM_AM::asr; break; 7284 case ARM::LSRi: ShiftTy = ARM_AM::lsr; break; 7285 case ARM::LSLi: ShiftTy = ARM_AM::lsl; break; 7286 case ARM::RORi: ShiftTy = ARM_AM::ror; break; 7287 } 7288 // A shift by zero is a plain MOVr, not a MOVsi. 7289 unsigned Amt = Inst.getOperand(2).getImm(); 7290 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi; 7291 // A shift by 32 should be encoded as 0 when permitted 7292 if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr)) 7293 Amt = 0; 7294 unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt); 7295 MCInst TmpInst; 7296 TmpInst.setOpcode(Opc); 7297 TmpInst.addOperand(Inst.getOperand(0)); // Rd 7298 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7299 if (Opc == ARM::MOVsi) 7300 TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 7301 TmpInst.addOperand(Inst.getOperand(3)); // CondCode 7302 TmpInst.addOperand(Inst.getOperand(4)); 7303 TmpInst.addOperand(Inst.getOperand(5)); // cc_out 7304 Inst = TmpInst; 7305 return true; 7306 } 7307 case ARM::RRXi: { 7308 unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0); 7309 MCInst TmpInst; 7310 TmpInst.setOpcode(ARM::MOVsi); 7311 TmpInst.addOperand(Inst.getOperand(0)); // Rd 7312 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7313 TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty 7314 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 7315 TmpInst.addOperand(Inst.getOperand(3)); 7316 TmpInst.addOperand(Inst.getOperand(4)); // cc_out 7317 Inst = TmpInst; 7318 return true; 7319 } 7320 case ARM::t2LDMIA_UPD: { 7321 // If this is a load of a single register, then we should use 7322 // a post-indexed LDR instruction instead, per the ARM ARM. 7323 if (Inst.getNumOperands() != 5) 7324 return false; 7325 MCInst TmpInst; 7326 TmpInst.setOpcode(ARM::t2LDR_POST); 7327 TmpInst.addOperand(Inst.getOperand(4)); // Rt 7328 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 7329 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7330 TmpInst.addOperand(MCOperand::CreateImm(4)); 7331 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 7332 TmpInst.addOperand(Inst.getOperand(3)); 7333 Inst = TmpInst; 7334 return true; 7335 } 7336 case ARM::t2STMDB_UPD: { 7337 // If this is a store of a single register, then we should use 7338 // a pre-indexed STR instruction instead, per the ARM ARM. 7339 if (Inst.getNumOperands() != 5) 7340 return false; 7341 MCInst TmpInst; 7342 TmpInst.setOpcode(ARM::t2STR_PRE); 7343 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 7344 TmpInst.addOperand(Inst.getOperand(4)); // Rt 7345 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7346 TmpInst.addOperand(MCOperand::CreateImm(-4)); 7347 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 7348 TmpInst.addOperand(Inst.getOperand(3)); 7349 Inst = TmpInst; 7350 return true; 7351 } 7352 case ARM::LDMIA_UPD: 7353 // If this is a load of a single register via a 'pop', then we should use 7354 // a post-indexed LDR instruction instead, per the ARM ARM. 7355 if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 7356 Inst.getNumOperands() == 5) { 7357 MCInst TmpInst; 7358 TmpInst.setOpcode(ARM::LDR_POST_IMM); 7359 TmpInst.addOperand(Inst.getOperand(4)); // Rt 7360 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 7361 TmpInst.addOperand(Inst.getOperand(1)); // Rn 7362 TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 7363 TmpInst.addOperand(MCOperand::CreateImm(4)); 7364 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 7365 TmpInst.addOperand(Inst.getOperand(3)); 7366 Inst = TmpInst; 7367 return true; 7368 } 7369 break; 7370 case ARM::STMDB_UPD: 7371 // If this is a store of a single register via a 'push', then we should use 7372 // a pre-indexed STR instruction instead, per the ARM ARM. 7373 if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 7374 Inst.getNumOperands() == 5) { 7375 MCInst TmpInst; 7376 TmpInst.setOpcode(ARM::STR_PRE_IMM); 7377 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 7378 TmpInst.addOperand(Inst.getOperand(4)); // Rt 7379 TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 7380 TmpInst.addOperand(MCOperand::CreateImm(-4)); 7381 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 7382 TmpInst.addOperand(Inst.getOperand(3)); 7383 Inst = TmpInst; 7384 } 7385 break; 7386 case ARM::t2ADDri12: 7387 // If the immediate fits for encoding T3 (t2ADDri) and the generic "add" 7388 // mnemonic was used (not "addw"), encoding T3 is preferred. 7389 if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" || 7390 ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 7391 break; 7392 Inst.setOpcode(ARM::t2ADDri); 7393 Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 7394 break; 7395 case ARM::t2SUBri12: 7396 // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub" 7397 // mnemonic was used (not "subw"), encoding T3 is preferred. 7398 if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" || 7399 ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1) 7400 break; 7401 Inst.setOpcode(ARM::t2SUBri); 7402 Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 7403 break; 7404 case ARM::tADDi8: 7405 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 7406 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 7407 // to encoding T2 if <Rd> is specified and encoding T2 is preferred 7408 // to encoding T1 if <Rd> is omitted." 7409 if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 7410 Inst.setOpcode(ARM::tADDi3); 7411 return true; 7412 } 7413 break; 7414 case ARM::tSUBi8: 7415 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 7416 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 7417 // to encoding T2 if <Rd> is specified and encoding T2 is preferred 7418 // to encoding T1 if <Rd> is omitted." 7419 if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) { 7420 Inst.setOpcode(ARM::tSUBi3); 7421 return true; 7422 } 7423 break; 7424 case ARM::t2ADDri: 7425 case ARM::t2SUBri: { 7426 // If the destination and first source operand are the same, and 7427 // the flags are compatible with the current IT status, use encoding T2 7428 // instead of T3. For compatibility with the system 'as'. Make sure the 7429 // wide encoding wasn't explicit. 7430 if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() || 7431 !isARMLowRegister(Inst.getOperand(0).getReg()) || 7432 (unsigned)Inst.getOperand(2).getImm() > 255 || 7433 ((!inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR) || 7434 (inITBlock() && Inst.getOperand(5).getReg() != 0)) || 7435 (static_cast<ARMOperand*>(Operands[3])->isToken() && 7436 static_cast<ARMOperand*>(Operands[3])->getToken() == ".w")) 7437 break; 7438 MCInst TmpInst; 7439 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ? 7440 ARM::tADDi8 : ARM::tSUBi8); 7441 TmpInst.addOperand(Inst.getOperand(0)); 7442 TmpInst.addOperand(Inst.getOperand(5)); 7443 TmpInst.addOperand(Inst.getOperand(0)); 7444 TmpInst.addOperand(Inst.getOperand(2)); 7445 TmpInst.addOperand(Inst.getOperand(3)); 7446 TmpInst.addOperand(Inst.getOperand(4)); 7447 Inst = TmpInst; 7448 return true; 7449 } 7450 case ARM::t2ADDrr: { 7451 // If the destination and first source operand are the same, and 7452 // there's no setting of the flags, use encoding T2 instead of T3. 7453 // Note that this is only for ADD, not SUB. This mirrors the system 7454 // 'as' behaviour. Make sure the wide encoding wasn't explicit. 7455 if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() || 7456 Inst.getOperand(5).getReg() != 0 || 7457 (static_cast<ARMOperand*>(Operands[3])->isToken() && 7458 static_cast<ARMOperand*>(Operands[3])->getToken() == ".w")) 7459 break; 7460 MCInst TmpInst; 7461 TmpInst.setOpcode(ARM::tADDhirr); 7462 TmpInst.addOperand(Inst.getOperand(0)); 7463 TmpInst.addOperand(Inst.getOperand(0)); 7464 TmpInst.addOperand(Inst.getOperand(2)); 7465 TmpInst.addOperand(Inst.getOperand(3)); 7466 TmpInst.addOperand(Inst.getOperand(4)); 7467 Inst = TmpInst; 7468 return true; 7469 } 7470 case ARM::tADDrSP: { 7471 // If the non-SP source operand and the destination operand are not the 7472 // same, we need to use the 32-bit encoding if it's available. 7473 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) { 7474 Inst.setOpcode(ARM::t2ADDrr); 7475 Inst.addOperand(MCOperand::CreateReg(0)); // cc_out 7476 return true; 7477 } 7478 break; 7479 } 7480 case ARM::tB: 7481 // A Thumb conditional branch outside of an IT block is a tBcc. 7482 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) { 7483 Inst.setOpcode(ARM::tBcc); 7484 return true; 7485 } 7486 break; 7487 case ARM::t2B: 7488 // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 7489 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){ 7490 Inst.setOpcode(ARM::t2Bcc); 7491 return true; 7492 } 7493 break; 7494 case ARM::t2Bcc: 7495 // If the conditional is AL or we're in an IT block, we really want t2B. 7496 if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) { 7497 Inst.setOpcode(ARM::t2B); 7498 return true; 7499 } 7500 break; 7501 case ARM::tBcc: 7502 // If the conditional is AL, we really want tB. 7503 if (Inst.getOperand(1).getImm() == ARMCC::AL) { 7504 Inst.setOpcode(ARM::tB); 7505 return true; 7506 } 7507 break; 7508 case ARM::tLDMIA: { 7509 // If the register list contains any high registers, or if the writeback 7510 // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 7511 // instead if we're in Thumb2. Otherwise, this should have generated 7512 // an error in validateInstruction(). 7513 unsigned Rn = Inst.getOperand(0).getReg(); 7514 bool hasWritebackToken = 7515 (static_cast<ARMOperand*>(Operands[3])->isToken() && 7516 static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 7517 bool listContainsBase; 7518 if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 7519 (!listContainsBase && !hasWritebackToken) || 7520 (listContainsBase && hasWritebackToken)) { 7521 // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 7522 assert (isThumbTwo()); 7523 Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 7524 // If we're switching to the updating version, we need to insert 7525 // the writeback tied operand. 7526 if (hasWritebackToken) 7527 Inst.insert(Inst.begin(), 7528 MCOperand::CreateReg(Inst.getOperand(0).getReg())); 7529 return true; 7530 } 7531 break; 7532 } 7533 case ARM::tSTMIA_UPD: { 7534 // If the register list contains any high registers, we need to use 7535 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 7536 // should have generated an error in validateInstruction(). 7537 unsigned Rn = Inst.getOperand(0).getReg(); 7538 bool listContainsBase; 7539 if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 7540 // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 7541 assert (isThumbTwo()); 7542 Inst.setOpcode(ARM::t2STMIA_UPD); 7543 return true; 7544 } 7545 break; 7546 } 7547 case ARM::tPOP: { 7548 bool listContainsBase; 7549 // If the register list contains any high registers, we need to use 7550 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 7551 // should have generated an error in validateInstruction(). 7552 if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase)) 7553 return false; 7554 assert (isThumbTwo()); 7555 Inst.setOpcode(ARM::t2LDMIA_UPD); 7556 // Add the base register and writeback operands. 7557 Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 7558 Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 7559 return true; 7560 } 7561 case ARM::tPUSH: { 7562 bool listContainsBase; 7563 if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase)) 7564 return false; 7565 assert (isThumbTwo()); 7566 Inst.setOpcode(ARM::t2STMDB_UPD); 7567 // Add the base register and writeback operands. 7568 Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 7569 Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP)); 7570 return true; 7571 } 7572 case ARM::t2MOVi: { 7573 // If we can use the 16-bit encoding and the user didn't explicitly 7574 // request the 32-bit variant, transform it here. 7575 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 7576 (unsigned)Inst.getOperand(1).getImm() <= 255 && 7577 ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 7578 Inst.getOperand(4).getReg() == ARM::CPSR) || 7579 (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 7580 (!static_cast<ARMOperand*>(Operands[2])->isToken() || 7581 static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 7582 // The operands aren't in the same order for tMOVi8... 7583 MCInst TmpInst; 7584 TmpInst.setOpcode(ARM::tMOVi8); 7585 TmpInst.addOperand(Inst.getOperand(0)); 7586 TmpInst.addOperand(Inst.getOperand(4)); 7587 TmpInst.addOperand(Inst.getOperand(1)); 7588 TmpInst.addOperand(Inst.getOperand(2)); 7589 TmpInst.addOperand(Inst.getOperand(3)); 7590 Inst = TmpInst; 7591 return true; 7592 } 7593 break; 7594 } 7595 case ARM::t2MOVr: { 7596 // If we can use the 16-bit encoding and the user didn't explicitly 7597 // request the 32-bit variant, transform it here. 7598 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 7599 isARMLowRegister(Inst.getOperand(1).getReg()) && 7600 Inst.getOperand(2).getImm() == ARMCC::AL && 7601 Inst.getOperand(4).getReg() == ARM::CPSR && 7602 (!static_cast<ARMOperand*>(Operands[2])->isToken() || 7603 static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 7604 // The operands aren't the same for tMOV[S]r... (no cc_out) 7605 MCInst TmpInst; 7606 TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 7607 TmpInst.addOperand(Inst.getOperand(0)); 7608 TmpInst.addOperand(Inst.getOperand(1)); 7609 TmpInst.addOperand(Inst.getOperand(2)); 7610 TmpInst.addOperand(Inst.getOperand(3)); 7611 Inst = TmpInst; 7612 return true; 7613 } 7614 break; 7615 } 7616 case ARM::t2SXTH: 7617 case ARM::t2SXTB: 7618 case ARM::t2UXTH: 7619 case ARM::t2UXTB: { 7620 // If we can use the 16-bit encoding and the user didn't explicitly 7621 // request the 32-bit variant, transform it here. 7622 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 7623 isARMLowRegister(Inst.getOperand(1).getReg()) && 7624 Inst.getOperand(2).getImm() == 0 && 7625 (!static_cast<ARMOperand*>(Operands[2])->isToken() || 7626 static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 7627 unsigned NewOpc; 7628 switch (Inst.getOpcode()) { 7629 default: llvm_unreachable("Illegal opcode!"); 7630 case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 7631 case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 7632 case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 7633 case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 7634 } 7635 // The operands aren't the same for thumb1 (no rotate operand). 7636 MCInst TmpInst; 7637 TmpInst.setOpcode(NewOpc); 7638 TmpInst.addOperand(Inst.getOperand(0)); 7639 TmpInst.addOperand(Inst.getOperand(1)); 7640 TmpInst.addOperand(Inst.getOperand(3)); 7641 TmpInst.addOperand(Inst.getOperand(4)); 7642 Inst = TmpInst; 7643 return true; 7644 } 7645 break; 7646 } 7647 case ARM::MOVsi: { 7648 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm()); 7649 // rrx shifts and asr/lsr of #32 is encoded as 0 7650 if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr) 7651 return false; 7652 if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) { 7653 // Shifting by zero is accepted as a vanilla 'MOVr' 7654 MCInst TmpInst; 7655 TmpInst.setOpcode(ARM::MOVr); 7656 TmpInst.addOperand(Inst.getOperand(0)); 7657 TmpInst.addOperand(Inst.getOperand(1)); 7658 TmpInst.addOperand(Inst.getOperand(3)); 7659 TmpInst.addOperand(Inst.getOperand(4)); 7660 TmpInst.addOperand(Inst.getOperand(5)); 7661 Inst = TmpInst; 7662 return true; 7663 } 7664 return false; 7665 } 7666 case ARM::ANDrsi: 7667 case ARM::ORRrsi: 7668 case ARM::EORrsi: 7669 case ARM::BICrsi: 7670 case ARM::SUBrsi: 7671 case ARM::ADDrsi: { 7672 unsigned newOpc; 7673 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm()); 7674 if (SOpc == ARM_AM::rrx) return false; 7675 switch (Inst.getOpcode()) { 7676 default: llvm_unreachable("unexpected opcode!"); 7677 case ARM::ANDrsi: newOpc = ARM::ANDrr; break; 7678 case ARM::ORRrsi: newOpc = ARM::ORRrr; break; 7679 case ARM::EORrsi: newOpc = ARM::EORrr; break; 7680 case ARM::BICrsi: newOpc = ARM::BICrr; break; 7681 case ARM::SUBrsi: newOpc = ARM::SUBrr; break; 7682 case ARM::ADDrsi: newOpc = ARM::ADDrr; break; 7683 } 7684 // If the shift is by zero, use the non-shifted instruction definition. 7685 // The exception is for right shifts, where 0 == 32 7686 if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 && 7687 !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) { 7688 MCInst TmpInst; 7689 TmpInst.setOpcode(newOpc); 7690 TmpInst.addOperand(Inst.getOperand(0)); 7691 TmpInst.addOperand(Inst.getOperand(1)); 7692 TmpInst.addOperand(Inst.getOperand(2)); 7693 TmpInst.addOperand(Inst.getOperand(4)); 7694 TmpInst.addOperand(Inst.getOperand(5)); 7695 TmpInst.addOperand(Inst.getOperand(6)); 7696 Inst = TmpInst; 7697 return true; 7698 } 7699 return false; 7700 } 7701 case ARM::ITasm: 7702 case ARM::t2IT: { 7703 // The mask bits for all but the first condition are represented as 7704 // the low bit of the condition code value implies 't'. We currently 7705 // always have 1 implies 't', so XOR toggle the bits if the low bit 7706 // of the condition code is zero. 7707 MCOperand &MO = Inst.getOperand(1); 7708 unsigned Mask = MO.getImm(); 7709 unsigned OrigMask = Mask; 7710 unsigned TZ = countTrailingZeros(Mask); 7711 if ((Inst.getOperand(0).getImm() & 1) == 0) { 7712 assert(Mask && TZ <= 3 && "illegal IT mask value!"); 7713 Mask ^= (0xE << TZ) & 0xF; 7714 } 7715 MO.setImm(Mask); 7716 7717 // Set up the IT block state according to the IT instruction we just 7718 // matched. 7719 assert(!inITBlock() && "nested IT blocks?!"); 7720 ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 7721 ITState.Mask = OrigMask; // Use the original mask, not the updated one. 7722 ITState.CurPosition = 0; 7723 ITState.FirstCond = true; 7724 break; 7725 } 7726 case ARM::t2LSLrr: 7727 case ARM::t2LSRrr: 7728 case ARM::t2ASRrr: 7729 case ARM::t2SBCrr: 7730 case ARM::t2RORrr: 7731 case ARM::t2BICrr: 7732 { 7733 // Assemblers should use the narrow encodings of these instructions when permissible. 7734 if ((isARMLowRegister(Inst.getOperand(1).getReg()) && 7735 isARMLowRegister(Inst.getOperand(2).getReg())) && 7736 Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && 7737 ((!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR) || 7738 (inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR)) && 7739 (!static_cast<ARMOperand*>(Operands[3])->isToken() || 7740 !static_cast<ARMOperand*>(Operands[3])->getToken().equals_lower(".w"))) { 7741 unsigned NewOpc; 7742 switch (Inst.getOpcode()) { 7743 default: llvm_unreachable("unexpected opcode"); 7744 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break; 7745 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break; 7746 case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break; 7747 case ARM::t2SBCrr: NewOpc = ARM::tSBC; break; 7748 case ARM::t2RORrr: NewOpc = ARM::tROR; break; 7749 case ARM::t2BICrr: NewOpc = ARM::tBIC; break; 7750 } 7751 MCInst TmpInst; 7752 TmpInst.setOpcode(NewOpc); 7753 TmpInst.addOperand(Inst.getOperand(0)); 7754 TmpInst.addOperand(Inst.getOperand(5)); 7755 TmpInst.addOperand(Inst.getOperand(1)); 7756 TmpInst.addOperand(Inst.getOperand(2)); 7757 TmpInst.addOperand(Inst.getOperand(3)); 7758 TmpInst.addOperand(Inst.getOperand(4)); 7759 Inst = TmpInst; 7760 return true; 7761 } 7762 return false; 7763 } 7764 case ARM::t2ANDrr: 7765 case ARM::t2EORrr: 7766 case ARM::t2ADCrr: 7767 case ARM::t2ORRrr: 7768 { 7769 // Assemblers should use the narrow encodings of these instructions when permissible. 7770 // These instructions are special in that they are commutable, so shorter encodings 7771 // are available more often. 7772 if ((isARMLowRegister(Inst.getOperand(1).getReg()) && 7773 isARMLowRegister(Inst.getOperand(2).getReg())) && 7774 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() || 7775 Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) && 7776 ((!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR) || 7777 (inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR)) && 7778 (!static_cast<ARMOperand*>(Operands[3])->isToken() || 7779 !static_cast<ARMOperand*>(Operands[3])->getToken().equals_lower(".w"))) { 7780 unsigned NewOpc; 7781 switch (Inst.getOpcode()) { 7782 default: llvm_unreachable("unexpected opcode"); 7783 case ARM::t2ADCrr: NewOpc = ARM::tADC; break; 7784 case ARM::t2ANDrr: NewOpc = ARM::tAND; break; 7785 case ARM::t2EORrr: NewOpc = ARM::tEOR; break; 7786 case ARM::t2ORRrr: NewOpc = ARM::tORR; break; 7787 } 7788 MCInst TmpInst; 7789 TmpInst.setOpcode(NewOpc); 7790 TmpInst.addOperand(Inst.getOperand(0)); 7791 TmpInst.addOperand(Inst.getOperand(5)); 7792 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) { 7793 TmpInst.addOperand(Inst.getOperand(1)); 7794 TmpInst.addOperand(Inst.getOperand(2)); 7795 } else { 7796 TmpInst.addOperand(Inst.getOperand(2)); 7797 TmpInst.addOperand(Inst.getOperand(1)); 7798 } 7799 TmpInst.addOperand(Inst.getOperand(3)); 7800 TmpInst.addOperand(Inst.getOperand(4)); 7801 Inst = TmpInst; 7802 return true; 7803 } 7804 return false; 7805 } 7806 } 7807 return false; 7808 } 7809 7810 unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 7811 // 16-bit thumb arithmetic instructions either require or preclude the 'S' 7812 // suffix depending on whether they're in an IT block or not. 7813 unsigned Opc = Inst.getOpcode(); 7814 const MCInstrDesc &MCID = MII.get(Opc); 7815 if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 7816 assert(MCID.hasOptionalDef() && 7817 "optionally flag setting instruction missing optional def operand"); 7818 assert(MCID.NumOperands == Inst.getNumOperands() && 7819 "operand count mismatch!"); 7820 // Find the optional-def operand (cc_out). 7821 unsigned OpNo; 7822 for (OpNo = 0; 7823 !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 7824 ++OpNo) 7825 ; 7826 // If we're parsing Thumb1, reject it completely. 7827 if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 7828 return Match_MnemonicFail; 7829 // If we're parsing Thumb2, which form is legal depends on whether we're 7830 // in an IT block. 7831 if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 7832 !inITBlock()) 7833 return Match_RequiresITBlock; 7834 if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 7835 inITBlock()) 7836 return Match_RequiresNotITBlock; 7837 } 7838 // Some high-register supporting Thumb1 encodings only allow both registers 7839 // to be from r0-r7 when in Thumb2. 7840 else if (Opc == ARM::tADDhirr && isThumbOne() && 7841 isARMLowRegister(Inst.getOperand(1).getReg()) && 7842 isARMLowRegister(Inst.getOperand(2).getReg())) 7843 return Match_RequiresThumb2; 7844 // Others only require ARMv6 or later. 7845 else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 7846 isARMLowRegister(Inst.getOperand(0).getReg()) && 7847 isARMLowRegister(Inst.getOperand(1).getReg())) 7848 return Match_RequiresV6; 7849 return Match_Success; 7850 } 7851 7852 static const char *getSubtargetFeatureName(unsigned Val); 7853 bool ARMAsmParser:: 7854 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 7855 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 7856 MCStreamer &Out, unsigned &ErrorInfo, 7857 bool MatchingInlineAsm) { 7858 MCInst Inst; 7859 unsigned MatchResult; 7860 7861 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 7862 MatchingInlineAsm); 7863 switch (MatchResult) { 7864 default: break; 7865 case Match_Success: 7866 // Context sensitive operand constraints aren't handled by the matcher, 7867 // so check them here. 7868 if (validateInstruction(Inst, Operands)) { 7869 // Still progress the IT block, otherwise one wrong condition causes 7870 // nasty cascading errors. 7871 forwardITPosition(); 7872 return true; 7873 } 7874 7875 { // processInstruction() updates inITBlock state, we need to save it away 7876 bool wasInITBlock = inITBlock(); 7877 7878 // Some instructions need post-processing to, for example, tweak which 7879 // encoding is selected. Loop on it while changes happen so the 7880 // individual transformations can chain off each other. E.g., 7881 // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8) 7882 while (processInstruction(Inst, Operands)) 7883 ; 7884 7885 // Only after the instruction is fully processed, we can validate it 7886 if (wasInITBlock && hasV8Ops() && isThumb() && 7887 !isV8EligibleForIT(&Inst)) { 7888 Warning(IDLoc, "deprecated instruction in IT block"); 7889 } 7890 } 7891 7892 // Only move forward at the very end so that everything in validate 7893 // and process gets a consistent answer about whether we're in an IT 7894 // block. 7895 forwardITPosition(); 7896 7897 // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and 7898 // doesn't actually encode. 7899 if (Inst.getOpcode() == ARM::ITasm) 7900 return false; 7901 7902 Inst.setLoc(IDLoc); 7903 Out.EmitInstruction(Inst, STI); 7904 return false; 7905 case Match_MissingFeature: { 7906 assert(ErrorInfo && "Unknown missing feature!"); 7907 // Special case the error message for the very common case where only 7908 // a single subtarget feature is missing (Thumb vs. ARM, e.g.). 7909 std::string Msg = "instruction requires:"; 7910 unsigned Mask = 1; 7911 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { 7912 if (ErrorInfo & Mask) { 7913 Msg += " "; 7914 Msg += getSubtargetFeatureName(ErrorInfo & Mask); 7915 } 7916 Mask <<= 1; 7917 } 7918 return Error(IDLoc, Msg); 7919 } 7920 case Match_InvalidOperand: { 7921 SMLoc ErrorLoc = IDLoc; 7922 if (ErrorInfo != ~0U) { 7923 if (ErrorInfo >= Operands.size()) 7924 return Error(IDLoc, "too few operands for instruction"); 7925 7926 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 7927 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 7928 } 7929 7930 return Error(ErrorLoc, "invalid operand for instruction"); 7931 } 7932 case Match_MnemonicFail: 7933 return Error(IDLoc, "invalid instruction", 7934 ((ARMOperand*)Operands[0])->getLocRange()); 7935 case Match_RequiresNotITBlock: 7936 return Error(IDLoc, "flag setting instruction only valid outside IT block"); 7937 case Match_RequiresITBlock: 7938 return Error(IDLoc, "instruction only valid inside IT block"); 7939 case Match_RequiresV6: 7940 return Error(IDLoc, "instruction variant requires ARMv6 or later"); 7941 case Match_RequiresThumb2: 7942 return Error(IDLoc, "instruction variant requires Thumb2"); 7943 case Match_ImmRange0_15: { 7944 SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 7945 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 7946 return Error(ErrorLoc, "immediate operand must be in the range [0,15]"); 7947 } 7948 case Match_ImmRange0_239: { 7949 SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 7950 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 7951 return Error(ErrorLoc, "immediate operand must be in the range [0,239]"); 7952 } 7953 } 7954 7955 llvm_unreachable("Implement any new match types added!"); 7956 } 7957 7958 /// parseDirective parses the arm specific directives 7959 bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 7960 StringRef IDVal = DirectiveID.getIdentifier(); 7961 if (IDVal == ".word") 7962 return parseDirectiveWord(4, DirectiveID.getLoc()); 7963 else if (IDVal == ".thumb") 7964 return parseDirectiveThumb(DirectiveID.getLoc()); 7965 else if (IDVal == ".arm") 7966 return parseDirectiveARM(DirectiveID.getLoc()); 7967 else if (IDVal == ".thumb_func") 7968 return parseDirectiveThumbFunc(DirectiveID.getLoc()); 7969 else if (IDVal == ".code") 7970 return parseDirectiveCode(DirectiveID.getLoc()); 7971 else if (IDVal == ".syntax") 7972 return parseDirectiveSyntax(DirectiveID.getLoc()); 7973 else if (IDVal == ".unreq") 7974 return parseDirectiveUnreq(DirectiveID.getLoc()); 7975 else if (IDVal == ".arch") 7976 return parseDirectiveArch(DirectiveID.getLoc()); 7977 else if (IDVal == ".eabi_attribute") 7978 return parseDirectiveEabiAttr(DirectiveID.getLoc()); 7979 else if (IDVal == ".cpu") 7980 return parseDirectiveCPU(DirectiveID.getLoc()); 7981 else if (IDVal == ".fpu") 7982 return parseDirectiveFPU(DirectiveID.getLoc()); 7983 else if (IDVal == ".fnstart") 7984 return parseDirectiveFnStart(DirectiveID.getLoc()); 7985 else if (IDVal == ".fnend") 7986 return parseDirectiveFnEnd(DirectiveID.getLoc()); 7987 else if (IDVal == ".cantunwind") 7988 return parseDirectiveCantUnwind(DirectiveID.getLoc()); 7989 else if (IDVal == ".personality") 7990 return parseDirectivePersonality(DirectiveID.getLoc()); 7991 else if (IDVal == ".handlerdata") 7992 return parseDirectiveHandlerData(DirectiveID.getLoc()); 7993 else if (IDVal == ".setfp") 7994 return parseDirectiveSetFP(DirectiveID.getLoc()); 7995 else if (IDVal == ".pad") 7996 return parseDirectivePad(DirectiveID.getLoc()); 7997 else if (IDVal == ".save") 7998 return parseDirectiveRegSave(DirectiveID.getLoc(), false); 7999 else if (IDVal == ".vsave") 8000 return parseDirectiveRegSave(DirectiveID.getLoc(), true); 8001 else if (IDVal == ".inst") 8002 return parseDirectiveInst(DirectiveID.getLoc()); 8003 else if (IDVal == ".inst.n") 8004 return parseDirectiveInst(DirectiveID.getLoc(), 'n'); 8005 else if (IDVal == ".inst.w") 8006 return parseDirectiveInst(DirectiveID.getLoc(), 'w'); 8007 else if (IDVal == ".ltorg" || IDVal == ".pool") 8008 return parseDirectiveLtorg(DirectiveID.getLoc()); 8009 else if (IDVal == ".even") 8010 return parseDirectiveEven(DirectiveID.getLoc()); 8011 else if (IDVal == ".personalityindex") 8012 return parseDirectivePersonalityIndex(DirectiveID.getLoc()); 8013 else if (IDVal == ".unwind_raw") 8014 return parseDirectiveUnwindRaw(DirectiveID.getLoc()); 8015 else if (IDVal == ".tlsdescseq") 8016 return parseDirectiveTLSDescSeq(DirectiveID.getLoc()); 8017 else if (IDVal == ".movsp") 8018 return parseDirectiveMovSP(DirectiveID.getLoc()); 8019 else if (IDVal == ".object_arch") 8020 return parseDirectiveObjectArch(DirectiveID.getLoc()); 8021 else if (IDVal == ".arch_extension") 8022 return parseDirectiveArchExtension(DirectiveID.getLoc()); 8023 return true; 8024 } 8025 8026 /// parseDirectiveWord 8027 /// ::= .word [ expression (, expression)* ] 8028 bool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 8029 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8030 for (;;) { 8031 const MCExpr *Value; 8032 if (getParser().parseExpression(Value)) { 8033 Parser.eatToEndOfStatement(); 8034 return false; 8035 } 8036 8037 getParser().getStreamer().EmitValue(Value, Size); 8038 8039 if (getLexer().is(AsmToken::EndOfStatement)) 8040 break; 8041 8042 // FIXME: Improve diagnostic. 8043 if (getLexer().isNot(AsmToken::Comma)) { 8044 Error(L, "unexpected token in directive"); 8045 return false; 8046 } 8047 Parser.Lex(); 8048 } 8049 } 8050 8051 Parser.Lex(); 8052 return false; 8053 } 8054 8055 /// parseDirectiveThumb 8056 /// ::= .thumb 8057 bool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 8058 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8059 Error(L, "unexpected token in directive"); 8060 return false; 8061 } 8062 Parser.Lex(); 8063 8064 if (!hasThumb()) { 8065 Error(L, "target does not support Thumb mode"); 8066 return false; 8067 } 8068 8069 if (!isThumb()) 8070 SwitchMode(); 8071 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 8072 return false; 8073 } 8074 8075 /// parseDirectiveARM 8076 /// ::= .arm 8077 bool ARMAsmParser::parseDirectiveARM(SMLoc L) { 8078 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8079 Error(L, "unexpected token in directive"); 8080 return false; 8081 } 8082 Parser.Lex(); 8083 8084 if (!hasARM()) { 8085 Error(L, "target does not support ARM mode"); 8086 return false; 8087 } 8088 8089 if (isThumb()) 8090 SwitchMode(); 8091 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 8092 return false; 8093 } 8094 8095 void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) { 8096 if (NextSymbolIsThumb) { 8097 getParser().getStreamer().EmitThumbFunc(Symbol); 8098 NextSymbolIsThumb = false; 8099 } 8100 } 8101 8102 /// parseDirectiveThumbFunc 8103 /// ::= .thumbfunc symbol_name 8104 bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 8105 const MCAsmInfo *MAI = getParser().getStreamer().getContext().getAsmInfo(); 8106 bool isMachO = MAI->hasSubsectionsViaSymbols(); 8107 8108 // Darwin asm has (optionally) function name after .thumb_func direction 8109 // ELF doesn't 8110 if (isMachO) { 8111 const AsmToken &Tok = Parser.getTok(); 8112 if (Tok.isNot(AsmToken::EndOfStatement)) { 8113 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) { 8114 Error(L, "unexpected token in .thumb_func directive"); 8115 return false; 8116 } 8117 8118 MCSymbol *Func = 8119 getParser().getContext().GetOrCreateSymbol(Tok.getIdentifier()); 8120 getParser().getStreamer().EmitThumbFunc(Func); 8121 Parser.Lex(); // Consume the identifier token. 8122 return false; 8123 } 8124 } 8125 8126 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8127 Error(L, "unexpected token in directive"); 8128 return false; 8129 } 8130 8131 NextSymbolIsThumb = true; 8132 return false; 8133 } 8134 8135 /// parseDirectiveSyntax 8136 /// ::= .syntax unified | divided 8137 bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 8138 const AsmToken &Tok = Parser.getTok(); 8139 if (Tok.isNot(AsmToken::Identifier)) { 8140 Error(L, "unexpected token in .syntax directive"); 8141 return false; 8142 } 8143 8144 StringRef Mode = Tok.getString(); 8145 if (Mode == "unified" || Mode == "UNIFIED") { 8146 Parser.Lex(); 8147 } else if (Mode == "divided" || Mode == "DIVIDED") { 8148 Error(L, "'.syntax divided' arm asssembly not supported"); 8149 return false; 8150 } else { 8151 Error(L, "unrecognized syntax mode in .syntax directive"); 8152 return false; 8153 } 8154 8155 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8156 Error(Parser.getTok().getLoc(), "unexpected token in directive"); 8157 return false; 8158 } 8159 Parser.Lex(); 8160 8161 // TODO tell the MC streamer the mode 8162 // getParser().getStreamer().Emit???(); 8163 return false; 8164 } 8165 8166 /// parseDirectiveCode 8167 /// ::= .code 16 | 32 8168 bool ARMAsmParser::parseDirectiveCode(SMLoc L) { 8169 const AsmToken &Tok = Parser.getTok(); 8170 if (Tok.isNot(AsmToken::Integer)) { 8171 Error(L, "unexpected token in .code directive"); 8172 return false; 8173 } 8174 int64_t Val = Parser.getTok().getIntVal(); 8175 if (Val != 16 && Val != 32) { 8176 Error(L, "invalid operand to .code directive"); 8177 return false; 8178 } 8179 Parser.Lex(); 8180 8181 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8182 Error(Parser.getTok().getLoc(), "unexpected token in directive"); 8183 return false; 8184 } 8185 Parser.Lex(); 8186 8187 if (Val == 16) { 8188 if (!hasThumb()) { 8189 Error(L, "target does not support Thumb mode"); 8190 return false; 8191 } 8192 8193 if (!isThumb()) 8194 SwitchMode(); 8195 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 8196 } else { 8197 if (!hasARM()) { 8198 Error(L, "target does not support ARM mode"); 8199 return false; 8200 } 8201 8202 if (isThumb()) 8203 SwitchMode(); 8204 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 8205 } 8206 8207 return false; 8208 } 8209 8210 /// parseDirectiveReq 8211 /// ::= name .req registername 8212 bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { 8213 Parser.Lex(); // Eat the '.req' token. 8214 unsigned Reg; 8215 SMLoc SRegLoc, ERegLoc; 8216 if (ParseRegister(Reg, SRegLoc, ERegLoc)) { 8217 Parser.eatToEndOfStatement(); 8218 Error(SRegLoc, "register name expected"); 8219 return false; 8220 } 8221 8222 // Shouldn't be anything else. 8223 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 8224 Parser.eatToEndOfStatement(); 8225 Error(Parser.getTok().getLoc(), "unexpected input in .req directive."); 8226 return false; 8227 } 8228 8229 Parser.Lex(); // Consume the EndOfStatement 8230 8231 if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg) { 8232 Error(SRegLoc, "redefinition of '" + Name + "' does not match original."); 8233 return false; 8234 } 8235 8236 return false; 8237 } 8238 8239 /// parseDirectiveUneq 8240 /// ::= .unreq registername 8241 bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) { 8242 if (Parser.getTok().isNot(AsmToken::Identifier)) { 8243 Parser.eatToEndOfStatement(); 8244 Error(L, "unexpected input in .unreq directive."); 8245 return false; 8246 } 8247 RegisterReqs.erase(Parser.getTok().getIdentifier()); 8248 Parser.Lex(); // Eat the identifier. 8249 return false; 8250 } 8251 8252 /// parseDirectiveArch 8253 /// ::= .arch token 8254 bool ARMAsmParser::parseDirectiveArch(SMLoc L) { 8255 StringRef Arch = getParser().parseStringToEndOfStatement().trim(); 8256 8257 unsigned ID = StringSwitch<unsigned>(Arch) 8258 #define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \ 8259 .Case(NAME, ARM::ID) 8260 #define ARM_ARCH_ALIAS(NAME, ID) \ 8261 .Case(NAME, ARM::ID) 8262 #include "MCTargetDesc/ARMArchName.def" 8263 .Default(ARM::INVALID_ARCH); 8264 8265 if (ID == ARM::INVALID_ARCH) { 8266 Error(L, "Unknown arch name"); 8267 return false; 8268 } 8269 8270 getTargetStreamer().emitArch(ID); 8271 return false; 8272 } 8273 8274 /// parseDirectiveEabiAttr 8275 /// ::= .eabi_attribute int, int [, "str"] 8276 /// ::= .eabi_attribute Tag_name, int [, "str"] 8277 bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) { 8278 int64_t Tag; 8279 SMLoc TagLoc; 8280 8281 TagLoc = Parser.getTok().getLoc(); 8282 if (Parser.getTok().is(AsmToken::Identifier)) { 8283 StringRef Name = Parser.getTok().getIdentifier(); 8284 Tag = ARMBuildAttrs::AttrTypeFromString(Name); 8285 if (Tag == -1) { 8286 Error(TagLoc, "attribute name not recognised: " + Name); 8287 Parser.eatToEndOfStatement(); 8288 return false; 8289 } 8290 Parser.Lex(); 8291 } else { 8292 const MCExpr *AttrExpr; 8293 8294 TagLoc = Parser.getTok().getLoc(); 8295 if (Parser.parseExpression(AttrExpr)) { 8296 Parser.eatToEndOfStatement(); 8297 return false; 8298 } 8299 8300 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 8301 if (!CE) { 8302 Error(TagLoc, "expected numeric constant"); 8303 Parser.eatToEndOfStatement(); 8304 return false; 8305 } 8306 8307 Tag = CE->getValue(); 8308 } 8309 8310 if (Parser.getTok().isNot(AsmToken::Comma)) { 8311 Error(Parser.getTok().getLoc(), "comma expected"); 8312 Parser.eatToEndOfStatement(); 8313 return false; 8314 } 8315 Parser.Lex(); // skip comma 8316 8317 StringRef StringValue = ""; 8318 bool IsStringValue = false; 8319 8320 int64_t IntegerValue = 0; 8321 bool IsIntegerValue = false; 8322 8323 if (Tag == ARMBuildAttrs::CPU_raw_name || Tag == ARMBuildAttrs::CPU_name) 8324 IsStringValue = true; 8325 else if (Tag == ARMBuildAttrs::compatibility) { 8326 IsStringValue = true; 8327 IsIntegerValue = true; 8328 } else if (Tag < 32 || Tag % 2 == 0) 8329 IsIntegerValue = true; 8330 else if (Tag % 2 == 1) 8331 IsStringValue = true; 8332 else 8333 llvm_unreachable("invalid tag type"); 8334 8335 if (IsIntegerValue) { 8336 const MCExpr *ValueExpr; 8337 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 8338 if (Parser.parseExpression(ValueExpr)) { 8339 Parser.eatToEndOfStatement(); 8340 return false; 8341 } 8342 8343 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 8344 if (!CE) { 8345 Error(ValueExprLoc, "expected numeric constant"); 8346 Parser.eatToEndOfStatement(); 8347 return false; 8348 } 8349 8350 IntegerValue = CE->getValue(); 8351 } 8352 8353 if (Tag == ARMBuildAttrs::compatibility) { 8354 if (Parser.getTok().isNot(AsmToken::Comma)) 8355 IsStringValue = false; 8356 else 8357 Parser.Lex(); 8358 } 8359 8360 if (IsStringValue) { 8361 if (Parser.getTok().isNot(AsmToken::String)) { 8362 Error(Parser.getTok().getLoc(), "bad string constant"); 8363 Parser.eatToEndOfStatement(); 8364 return false; 8365 } 8366 8367 StringValue = Parser.getTok().getStringContents(); 8368 Parser.Lex(); 8369 } 8370 8371 if (IsIntegerValue && IsStringValue) { 8372 assert(Tag == ARMBuildAttrs::compatibility); 8373 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue); 8374 } else if (IsIntegerValue) 8375 getTargetStreamer().emitAttribute(Tag, IntegerValue); 8376 else if (IsStringValue) 8377 getTargetStreamer().emitTextAttribute(Tag, StringValue); 8378 return false; 8379 } 8380 8381 /// parseDirectiveCPU 8382 /// ::= .cpu str 8383 bool ARMAsmParser::parseDirectiveCPU(SMLoc L) { 8384 StringRef CPU = getParser().parseStringToEndOfStatement().trim(); 8385 getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU); 8386 return false; 8387 } 8388 8389 /// parseDirectiveFPU 8390 /// ::= .fpu str 8391 bool ARMAsmParser::parseDirectiveFPU(SMLoc L) { 8392 StringRef FPU = getParser().parseStringToEndOfStatement().trim(); 8393 8394 unsigned ID = StringSwitch<unsigned>(FPU) 8395 #define ARM_FPU_NAME(NAME, ID) .Case(NAME, ARM::ID) 8396 #include "ARMFPUName.def" 8397 .Default(ARM::INVALID_FPU); 8398 8399 if (ID == ARM::INVALID_FPU) { 8400 Error(L, "Unknown FPU name"); 8401 return false; 8402 } 8403 8404 getTargetStreamer().emitFPU(ID); 8405 return false; 8406 } 8407 8408 /// parseDirectiveFnStart 8409 /// ::= .fnstart 8410 bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) { 8411 if (UC.hasFnStart()) { 8412 Error(L, ".fnstart starts before the end of previous one"); 8413 UC.emitFnStartLocNotes(); 8414 return false; 8415 } 8416 8417 // Reset the unwind directives parser state 8418 UC.reset(); 8419 8420 getTargetStreamer().emitFnStart(); 8421 8422 UC.recordFnStart(L); 8423 return false; 8424 } 8425 8426 /// parseDirectiveFnEnd 8427 /// ::= .fnend 8428 bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) { 8429 // Check the ordering of unwind directives 8430 if (!UC.hasFnStart()) { 8431 Error(L, ".fnstart must precede .fnend directive"); 8432 return false; 8433 } 8434 8435 // Reset the unwind directives parser state 8436 getTargetStreamer().emitFnEnd(); 8437 8438 UC.reset(); 8439 return false; 8440 } 8441 8442 /// parseDirectiveCantUnwind 8443 /// ::= .cantunwind 8444 bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) { 8445 UC.recordCantUnwind(L); 8446 8447 // Check the ordering of unwind directives 8448 if (!UC.hasFnStart()) { 8449 Error(L, ".fnstart must precede .cantunwind directive"); 8450 return false; 8451 } 8452 if (UC.hasHandlerData()) { 8453 Error(L, ".cantunwind can't be used with .handlerdata directive"); 8454 UC.emitHandlerDataLocNotes(); 8455 return false; 8456 } 8457 if (UC.hasPersonality()) { 8458 Error(L, ".cantunwind can't be used with .personality directive"); 8459 UC.emitPersonalityLocNotes(); 8460 return false; 8461 } 8462 8463 getTargetStreamer().emitCantUnwind(); 8464 return false; 8465 } 8466 8467 /// parseDirectivePersonality 8468 /// ::= .personality name 8469 bool ARMAsmParser::parseDirectivePersonality(SMLoc L) { 8470 bool HasExistingPersonality = UC.hasPersonality(); 8471 8472 UC.recordPersonality(L); 8473 8474 // Check the ordering of unwind directives 8475 if (!UC.hasFnStart()) { 8476 Error(L, ".fnstart must precede .personality directive"); 8477 return false; 8478 } 8479 if (UC.cantUnwind()) { 8480 Error(L, ".personality can't be used with .cantunwind directive"); 8481 UC.emitCantUnwindLocNotes(); 8482 return false; 8483 } 8484 if (UC.hasHandlerData()) { 8485 Error(L, ".personality must precede .handlerdata directive"); 8486 UC.emitHandlerDataLocNotes(); 8487 return false; 8488 } 8489 if (HasExistingPersonality) { 8490 Parser.eatToEndOfStatement(); 8491 Error(L, "multiple personality directives"); 8492 UC.emitPersonalityLocNotes(); 8493 return false; 8494 } 8495 8496 // Parse the name of the personality routine 8497 if (Parser.getTok().isNot(AsmToken::Identifier)) { 8498 Parser.eatToEndOfStatement(); 8499 Error(L, "unexpected input in .personality directive."); 8500 return false; 8501 } 8502 StringRef Name(Parser.getTok().getIdentifier()); 8503 Parser.Lex(); 8504 8505 MCSymbol *PR = getParser().getContext().GetOrCreateSymbol(Name); 8506 getTargetStreamer().emitPersonality(PR); 8507 return false; 8508 } 8509 8510 /// parseDirectiveHandlerData 8511 /// ::= .handlerdata 8512 bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) { 8513 UC.recordHandlerData(L); 8514 8515 // Check the ordering of unwind directives 8516 if (!UC.hasFnStart()) { 8517 Error(L, ".fnstart must precede .personality directive"); 8518 return false; 8519 } 8520 if (UC.cantUnwind()) { 8521 Error(L, ".handlerdata can't be used with .cantunwind directive"); 8522 UC.emitCantUnwindLocNotes(); 8523 return false; 8524 } 8525 8526 getTargetStreamer().emitHandlerData(); 8527 return false; 8528 } 8529 8530 /// parseDirectiveSetFP 8531 /// ::= .setfp fpreg, spreg [, offset] 8532 bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) { 8533 // Check the ordering of unwind directives 8534 if (!UC.hasFnStart()) { 8535 Error(L, ".fnstart must precede .setfp directive"); 8536 return false; 8537 } 8538 if (UC.hasHandlerData()) { 8539 Error(L, ".setfp must precede .handlerdata directive"); 8540 return false; 8541 } 8542 8543 // Parse fpreg 8544 SMLoc FPRegLoc = Parser.getTok().getLoc(); 8545 int FPReg = tryParseRegister(); 8546 if (FPReg == -1) { 8547 Error(FPRegLoc, "frame pointer register expected"); 8548 return false; 8549 } 8550 8551 // Consume comma 8552 if (Parser.getTok().isNot(AsmToken::Comma)) { 8553 Error(Parser.getTok().getLoc(), "comma expected"); 8554 return false; 8555 } 8556 Parser.Lex(); // skip comma 8557 8558 // Parse spreg 8559 SMLoc SPRegLoc = Parser.getTok().getLoc(); 8560 int SPReg = tryParseRegister(); 8561 if (SPReg == -1) { 8562 Error(SPRegLoc, "stack pointer register expected"); 8563 return false; 8564 } 8565 8566 if (SPReg != ARM::SP && SPReg != UC.getFPReg()) { 8567 Error(SPRegLoc, "register should be either $sp or the latest fp register"); 8568 return false; 8569 } 8570 8571 // Update the frame pointer register 8572 UC.saveFPReg(FPReg); 8573 8574 // Parse offset 8575 int64_t Offset = 0; 8576 if (Parser.getTok().is(AsmToken::Comma)) { 8577 Parser.Lex(); // skip comma 8578 8579 if (Parser.getTok().isNot(AsmToken::Hash) && 8580 Parser.getTok().isNot(AsmToken::Dollar)) { 8581 Error(Parser.getTok().getLoc(), "'#' expected"); 8582 return false; 8583 } 8584 Parser.Lex(); // skip hash token. 8585 8586 const MCExpr *OffsetExpr; 8587 SMLoc ExLoc = Parser.getTok().getLoc(); 8588 SMLoc EndLoc; 8589 if (getParser().parseExpression(OffsetExpr, EndLoc)) { 8590 Error(ExLoc, "malformed setfp offset"); 8591 return false; 8592 } 8593 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr); 8594 if (!CE) { 8595 Error(ExLoc, "setfp offset must be an immediate"); 8596 return false; 8597 } 8598 8599 Offset = CE->getValue(); 8600 } 8601 8602 getTargetStreamer().emitSetFP(static_cast<unsigned>(FPReg), 8603 static_cast<unsigned>(SPReg), Offset); 8604 return false; 8605 } 8606 8607 /// parseDirective 8608 /// ::= .pad offset 8609 bool ARMAsmParser::parseDirectivePad(SMLoc L) { 8610 // Check the ordering of unwind directives 8611 if (!UC.hasFnStart()) { 8612 Error(L, ".fnstart must precede .pad directive"); 8613 return false; 8614 } 8615 if (UC.hasHandlerData()) { 8616 Error(L, ".pad must precede .handlerdata directive"); 8617 return false; 8618 } 8619 8620 // Parse the offset 8621 if (Parser.getTok().isNot(AsmToken::Hash) && 8622 Parser.getTok().isNot(AsmToken::Dollar)) { 8623 Error(Parser.getTok().getLoc(), "'#' expected"); 8624 return false; 8625 } 8626 Parser.Lex(); // skip hash token. 8627 8628 const MCExpr *OffsetExpr; 8629 SMLoc ExLoc = Parser.getTok().getLoc(); 8630 SMLoc EndLoc; 8631 if (getParser().parseExpression(OffsetExpr, EndLoc)) { 8632 Error(ExLoc, "malformed pad offset"); 8633 return false; 8634 } 8635 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr); 8636 if (!CE) { 8637 Error(ExLoc, "pad offset must be an immediate"); 8638 return false; 8639 } 8640 8641 getTargetStreamer().emitPad(CE->getValue()); 8642 return false; 8643 } 8644 8645 /// parseDirectiveRegSave 8646 /// ::= .save { registers } 8647 /// ::= .vsave { registers } 8648 bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) { 8649 // Check the ordering of unwind directives 8650 if (!UC.hasFnStart()) { 8651 Error(L, ".fnstart must precede .save or .vsave directives"); 8652 return false; 8653 } 8654 if (UC.hasHandlerData()) { 8655 Error(L, ".save or .vsave must precede .handlerdata directive"); 8656 return false; 8657 } 8658 8659 // RAII object to make sure parsed operands are deleted. 8660 struct CleanupObject { 8661 SmallVector<MCParsedAsmOperand *, 1> Operands; 8662 ~CleanupObject() { 8663 for (unsigned I = 0, E = Operands.size(); I != E; ++I) 8664 delete Operands[I]; 8665 } 8666 } CO; 8667 8668 // Parse the register list 8669 if (parseRegisterList(CO.Operands)) 8670 return false; 8671 ARMOperand *Op = (ARMOperand*)CO.Operands[0]; 8672 if (!IsVector && !Op->isRegList()) { 8673 Error(L, ".save expects GPR registers"); 8674 return false; 8675 } 8676 if (IsVector && !Op->isDPRRegList()) { 8677 Error(L, ".vsave expects DPR registers"); 8678 return false; 8679 } 8680 8681 getTargetStreamer().emitRegSave(Op->getRegList(), IsVector); 8682 return false; 8683 } 8684 8685 /// parseDirectiveInst 8686 /// ::= .inst opcode [, ...] 8687 /// ::= .inst.n opcode [, ...] 8688 /// ::= .inst.w opcode [, ...] 8689 bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) { 8690 int Width; 8691 8692 if (isThumb()) { 8693 switch (Suffix) { 8694 case 'n': 8695 Width = 2; 8696 break; 8697 case 'w': 8698 Width = 4; 8699 break; 8700 default: 8701 Parser.eatToEndOfStatement(); 8702 Error(Loc, "cannot determine Thumb instruction size, " 8703 "use inst.n/inst.w instead"); 8704 return false; 8705 } 8706 } else { 8707 if (Suffix) { 8708 Parser.eatToEndOfStatement(); 8709 Error(Loc, "width suffixes are invalid in ARM mode"); 8710 return false; 8711 } 8712 Width = 4; 8713 } 8714 8715 if (getLexer().is(AsmToken::EndOfStatement)) { 8716 Parser.eatToEndOfStatement(); 8717 Error(Loc, "expected expression following directive"); 8718 return false; 8719 } 8720 8721 for (;;) { 8722 const MCExpr *Expr; 8723 8724 if (getParser().parseExpression(Expr)) { 8725 Error(Loc, "expected expression"); 8726 return false; 8727 } 8728 8729 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr); 8730 if (!Value) { 8731 Error(Loc, "expected constant expression"); 8732 return false; 8733 } 8734 8735 switch (Width) { 8736 case 2: 8737 if (Value->getValue() > 0xffff) { 8738 Error(Loc, "inst.n operand is too big, use inst.w instead"); 8739 return false; 8740 } 8741 break; 8742 case 4: 8743 if (Value->getValue() > 0xffffffff) { 8744 Error(Loc, 8745 StringRef(Suffix ? "inst.w" : "inst") + " operand is too big"); 8746 return false; 8747 } 8748 break; 8749 default: 8750 llvm_unreachable("only supported widths are 2 and 4"); 8751 } 8752 8753 getTargetStreamer().emitInst(Value->getValue(), Suffix); 8754 8755 if (getLexer().is(AsmToken::EndOfStatement)) 8756 break; 8757 8758 if (getLexer().isNot(AsmToken::Comma)) { 8759 Error(Loc, "unexpected token in directive"); 8760 return false; 8761 } 8762 8763 Parser.Lex(); 8764 } 8765 8766 Parser.Lex(); 8767 return false; 8768 } 8769 8770 /// parseDirectiveLtorg 8771 /// ::= .ltorg | .pool 8772 bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) { 8773 getTargetStreamer().emitCurrentConstantPool(); 8774 return false; 8775 } 8776 8777 bool ARMAsmParser::parseDirectiveEven(SMLoc L) { 8778 const MCSection *Section = getStreamer().getCurrentSection().first; 8779 8780 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8781 TokError("unexpected token in directive"); 8782 return false; 8783 } 8784 8785 if (!Section) { 8786 getStreamer().InitSections(); 8787 Section = getStreamer().getCurrentSection().first; 8788 } 8789 8790 if (Section->UseCodeAlign()) 8791 getStreamer().EmitCodeAlignment(2); 8792 else 8793 getStreamer().EmitValueToAlignment(2); 8794 8795 return false; 8796 } 8797 8798 /// parseDirectivePersonalityIndex 8799 /// ::= .personalityindex index 8800 bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) { 8801 bool HasExistingPersonality = UC.hasPersonality(); 8802 8803 UC.recordPersonalityIndex(L); 8804 8805 if (!UC.hasFnStart()) { 8806 Parser.eatToEndOfStatement(); 8807 Error(L, ".fnstart must precede .personalityindex directive"); 8808 return false; 8809 } 8810 if (UC.cantUnwind()) { 8811 Parser.eatToEndOfStatement(); 8812 Error(L, ".personalityindex cannot be used with .cantunwind"); 8813 UC.emitCantUnwindLocNotes(); 8814 return false; 8815 } 8816 if (UC.hasHandlerData()) { 8817 Parser.eatToEndOfStatement(); 8818 Error(L, ".personalityindex must precede .handlerdata directive"); 8819 UC.emitHandlerDataLocNotes(); 8820 return false; 8821 } 8822 if (HasExistingPersonality) { 8823 Parser.eatToEndOfStatement(); 8824 Error(L, "multiple personality directives"); 8825 UC.emitPersonalityLocNotes(); 8826 return false; 8827 } 8828 8829 const MCExpr *IndexExpression; 8830 SMLoc IndexLoc = Parser.getTok().getLoc(); 8831 if (Parser.parseExpression(IndexExpression)) { 8832 Parser.eatToEndOfStatement(); 8833 return false; 8834 } 8835 8836 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression); 8837 if (!CE) { 8838 Parser.eatToEndOfStatement(); 8839 Error(IndexLoc, "index must be a constant number"); 8840 return false; 8841 } 8842 if (CE->getValue() < 0 || 8843 CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX) { 8844 Parser.eatToEndOfStatement(); 8845 Error(IndexLoc, "personality routine index should be in range [0-3]"); 8846 return false; 8847 } 8848 8849 getTargetStreamer().emitPersonalityIndex(CE->getValue()); 8850 return false; 8851 } 8852 8853 /// parseDirectiveUnwindRaw 8854 /// ::= .unwind_raw offset, opcode [, opcode...] 8855 bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) { 8856 if (!UC.hasFnStart()) { 8857 Parser.eatToEndOfStatement(); 8858 Error(L, ".fnstart must precede .unwind_raw directives"); 8859 return false; 8860 } 8861 8862 int64_t StackOffset; 8863 8864 const MCExpr *OffsetExpr; 8865 SMLoc OffsetLoc = getLexer().getLoc(); 8866 if (getLexer().is(AsmToken::EndOfStatement) || 8867 getParser().parseExpression(OffsetExpr)) { 8868 Error(OffsetLoc, "expected expression"); 8869 Parser.eatToEndOfStatement(); 8870 return false; 8871 } 8872 8873 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr); 8874 if (!CE) { 8875 Error(OffsetLoc, "offset must be a constant"); 8876 Parser.eatToEndOfStatement(); 8877 return false; 8878 } 8879 8880 StackOffset = CE->getValue(); 8881 8882 if (getLexer().isNot(AsmToken::Comma)) { 8883 Error(getLexer().getLoc(), "expected comma"); 8884 Parser.eatToEndOfStatement(); 8885 return false; 8886 } 8887 Parser.Lex(); 8888 8889 SmallVector<uint8_t, 16> Opcodes; 8890 for (;;) { 8891 const MCExpr *OE; 8892 8893 SMLoc OpcodeLoc = getLexer().getLoc(); 8894 if (getLexer().is(AsmToken::EndOfStatement) || Parser.parseExpression(OE)) { 8895 Error(OpcodeLoc, "expected opcode expression"); 8896 Parser.eatToEndOfStatement(); 8897 return false; 8898 } 8899 8900 const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE); 8901 if (!OC) { 8902 Error(OpcodeLoc, "opcode value must be a constant"); 8903 Parser.eatToEndOfStatement(); 8904 return false; 8905 } 8906 8907 const int64_t Opcode = OC->getValue(); 8908 if (Opcode & ~0xff) { 8909 Error(OpcodeLoc, "invalid opcode"); 8910 Parser.eatToEndOfStatement(); 8911 return false; 8912 } 8913 8914 Opcodes.push_back(uint8_t(Opcode)); 8915 8916 if (getLexer().is(AsmToken::EndOfStatement)) 8917 break; 8918 8919 if (getLexer().isNot(AsmToken::Comma)) { 8920 Error(getLexer().getLoc(), "unexpected token in directive"); 8921 Parser.eatToEndOfStatement(); 8922 return false; 8923 } 8924 8925 Parser.Lex(); 8926 } 8927 8928 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes); 8929 8930 Parser.Lex(); 8931 return false; 8932 } 8933 8934 /// parseDirectiveTLSDescSeq 8935 /// ::= .tlsdescseq tls-variable 8936 bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) { 8937 if (getLexer().isNot(AsmToken::Identifier)) { 8938 TokError("expected variable after '.tlsdescseq' directive"); 8939 Parser.eatToEndOfStatement(); 8940 return false; 8941 } 8942 8943 const MCSymbolRefExpr *SRE = 8944 MCSymbolRefExpr::Create(Parser.getTok().getIdentifier(), 8945 MCSymbolRefExpr::VK_ARM_TLSDESCSEQ, getContext()); 8946 Lex(); 8947 8948 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8949 Error(Parser.getTok().getLoc(), "unexpected token"); 8950 Parser.eatToEndOfStatement(); 8951 return false; 8952 } 8953 8954 getTargetStreamer().AnnotateTLSDescriptorSequence(SRE); 8955 return false; 8956 } 8957 8958 /// parseDirectiveMovSP 8959 /// ::= .movsp reg [, #offset] 8960 bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) { 8961 if (!UC.hasFnStart()) { 8962 Parser.eatToEndOfStatement(); 8963 Error(L, ".fnstart must precede .movsp directives"); 8964 return false; 8965 } 8966 if (UC.getFPReg() != ARM::SP) { 8967 Parser.eatToEndOfStatement(); 8968 Error(L, "unexpected .movsp directive"); 8969 return false; 8970 } 8971 8972 SMLoc SPRegLoc = Parser.getTok().getLoc(); 8973 int SPReg = tryParseRegister(); 8974 if (SPReg == -1) { 8975 Parser.eatToEndOfStatement(); 8976 Error(SPRegLoc, "register expected"); 8977 return false; 8978 } 8979 8980 if (SPReg == ARM::SP || SPReg == ARM::PC) { 8981 Parser.eatToEndOfStatement(); 8982 Error(SPRegLoc, "sp and pc are not permitted in .movsp directive"); 8983 return false; 8984 } 8985 8986 int64_t Offset = 0; 8987 if (Parser.getTok().is(AsmToken::Comma)) { 8988 Parser.Lex(); 8989 8990 if (Parser.getTok().isNot(AsmToken::Hash)) { 8991 Error(Parser.getTok().getLoc(), "expected #constant"); 8992 Parser.eatToEndOfStatement(); 8993 return false; 8994 } 8995 Parser.Lex(); 8996 8997 const MCExpr *OffsetExpr; 8998 SMLoc OffsetLoc = Parser.getTok().getLoc(); 8999 if (Parser.parseExpression(OffsetExpr)) { 9000 Parser.eatToEndOfStatement(); 9001 Error(OffsetLoc, "malformed offset expression"); 9002 return false; 9003 } 9004 9005 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr); 9006 if (!CE) { 9007 Parser.eatToEndOfStatement(); 9008 Error(OffsetLoc, "offset must be an immediate constant"); 9009 return false; 9010 } 9011 9012 Offset = CE->getValue(); 9013 } 9014 9015 getTargetStreamer().emitMovSP(SPReg, Offset); 9016 UC.saveFPReg(SPReg); 9017 9018 return false; 9019 } 9020 9021 /// parseDirectiveObjectArch 9022 /// ::= .object_arch name 9023 bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) { 9024 if (getLexer().isNot(AsmToken::Identifier)) { 9025 Error(getLexer().getLoc(), "unexpected token"); 9026 Parser.eatToEndOfStatement(); 9027 return false; 9028 } 9029 9030 StringRef Arch = Parser.getTok().getString(); 9031 SMLoc ArchLoc = Parser.getTok().getLoc(); 9032 getLexer().Lex(); 9033 9034 unsigned ID = StringSwitch<unsigned>(Arch) 9035 #define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \ 9036 .Case(NAME, ARM::ID) 9037 #define ARM_ARCH_ALIAS(NAME, ID) \ 9038 .Case(NAME, ARM::ID) 9039 #include "MCTargetDesc/ARMArchName.def" 9040 #undef ARM_ARCH_NAME 9041 #undef ARM_ARCH_ALIAS 9042 .Default(ARM::INVALID_ARCH); 9043 9044 if (ID == ARM::INVALID_ARCH) { 9045 Error(ArchLoc, "unknown architecture '" + Arch + "'"); 9046 Parser.eatToEndOfStatement(); 9047 return false; 9048 } 9049 9050 getTargetStreamer().emitObjectArch(ID); 9051 9052 if (getLexer().isNot(AsmToken::EndOfStatement)) { 9053 Error(getLexer().getLoc(), "unexpected token"); 9054 Parser.eatToEndOfStatement(); 9055 } 9056 9057 return false; 9058 } 9059 9060 /// Force static initialization. 9061 extern "C" void LLVMInitializeARMAsmParser() { 9062 RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 9063 RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 9064 } 9065 9066 #define GET_REGISTER_MATCHER 9067 #define GET_SUBTARGET_FEATURE_NAME 9068 #define GET_MATCHER_IMPLEMENTATION 9069 #include "ARMGenAsmMatcher.inc" 9070 9071 static const struct ExtMapEntry { 9072 const char *Extension; 9073 const unsigned ArchCheck; 9074 const uint64_t Features; 9075 } Extensions[] = { 9076 { "crc", Feature_HasV8, ARM::FeatureCRC }, 9077 { "crypto", Feature_HasV8, 9078 ARM::FeatureCrypto | ARM::FeatureNEON | ARM::FeatureFPARMv8 }, 9079 { "fp", Feature_HasV8, ARM::FeatureFPARMv8 }, 9080 { "idiv", Feature_HasV7 | Feature_IsNotMClass, 9081 ARM::FeatureHWDiv | ARM::FeatureHWDivARM }, 9082 // FIXME: iWMMXT not supported 9083 { "iwmmxt", Feature_None, 0 }, 9084 // FIXME: iWMMXT2 not supported 9085 { "iwmmxt2", Feature_None, 0 }, 9086 // FIXME: Maverick not supported 9087 { "maverick", Feature_None, 0 }, 9088 { "mp", Feature_HasV7 | Feature_IsNotMClass, ARM::FeatureMP }, 9089 // FIXME: ARMv6-m OS Extensions feature not checked 9090 { "os", Feature_None, 0 }, 9091 // FIXME: Also available in ARMv6-K 9092 { "sec", Feature_HasV7, ARM::FeatureTrustZone }, 9093 { "simd", Feature_HasV8, ARM::FeatureNEON | ARM::FeatureFPARMv8 }, 9094 // FIXME: Only available in A-class, isel not predicated 9095 { "virt", Feature_HasV7, ARM::FeatureVirtualization }, 9096 // FIXME: xscale not supported 9097 { "xscale", Feature_None, 0 }, 9098 }; 9099 9100 template <typename T, size_t N> 9101 size_t countof(const T (&)[N]) { return N; } 9102 9103 /// parseDirectiveArchExtension 9104 /// ::= .arch_extension [no]feature 9105 bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) { 9106 if (getLexer().isNot(AsmToken::Identifier)) { 9107 Error(getLexer().getLoc(), "unexpected token"); 9108 Parser.eatToEndOfStatement(); 9109 return false; 9110 } 9111 9112 StringRef Extension = Parser.getTok().getString(); 9113 SMLoc ExtLoc = Parser.getTok().getLoc(); 9114 getLexer().Lex(); 9115 9116 bool EnableFeature = true; 9117 if (!Extension.lower().compare(0, 2, "no")) { 9118 EnableFeature = false; 9119 Extension = Extension.substr(2); 9120 } 9121 9122 for (unsigned EI = 0, EE = countof(Extensions); EI != EE; ++EI) { 9123 if (Extensions[EI].Extension != Extension) 9124 continue; 9125 9126 unsigned FB = getAvailableFeatures(); 9127 if ((FB & Extensions[EI].ArchCheck) != Extensions[EI].ArchCheck) { 9128 Error(ExtLoc, "architectural extension '" + Extension + "' is not " 9129 "allowed for the current base architecture"); 9130 return false; 9131 } 9132 9133 if (!Extensions[EI].Features) 9134 report_fatal_error("unsupported architectural extension: " + Extension); 9135 9136 if (EnableFeature) 9137 FB |= ComputeAvailableFeatures(Extensions[EI].Features); 9138 else 9139 FB &= ~ComputeAvailableFeatures(Extensions[EI].Features); 9140 9141 setAvailableFeatures(FB); 9142 return false; 9143 } 9144 9145 Error(ExtLoc, "unknown architectural extension: " + Extension); 9146 Parser.eatToEndOfStatement(); 9147 return false; 9148 } 9149 9150 // Define this matcher function after the auto-generated include so we 9151 // have the match class enum definitions. 9152 unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp, 9153 unsigned Kind) { 9154 ARMOperand *Op = static_cast<ARMOperand*>(AsmOp); 9155 // If the kind is a token for a literal immediate, check if our asm 9156 // operand matches. This is for InstAliases which have a fixed-value 9157 // immediate in the syntax. 9158 switch (Kind) { 9159 default: break; 9160 case MCK__35_0: 9161 if (Op->isImm()) 9162 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm())) 9163 if (CE->getValue() == 0) 9164 return Match_Success; 9165 break; 9166 case MCK_ARMSOImm: 9167 if (Op->isImm()) { 9168 const MCExpr *SOExpr = Op->getImm(); 9169 int64_t Value; 9170 if (!SOExpr->EvaluateAsAbsolute(Value)) 9171 return Match_Success; 9172 assert((Value >= INT32_MIN && Value <= INT32_MAX) && 9173 "expression value must be representiable in 32 bits"); 9174 } 9175 break; 9176 case MCK_GPRPair: 9177 if (Op->isReg() && 9178 MRI->getRegClass(ARM::GPRRegClassID).contains(Op->getReg())) 9179 return Match_Success; 9180 break; 9181 } 9182 return Match_InvalidOperand; 9183 } 9184