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