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