ARMAsmParser.cpp revision a2b6e4151b75248f9dbf8067186cba673520f8f4
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 "ARM.h" 11#include "ARMAddressingModes.h" 12#include "ARMMCExpr.h" 13#include "ARMBaseRegisterInfo.h" 14#include "ARMSubtarget.h" 15#include "llvm/MC/MCParser/MCAsmLexer.h" 16#include "llvm/MC/MCParser/MCAsmParser.h" 17#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 18#include "llvm/MC/MCContext.h" 19#include "llvm/MC/MCStreamer.h" 20#include "llvm/MC/MCExpr.h" 21#include "llvm/MC/MCInst.h" 22#include "llvm/Target/TargetRegistry.h" 23#include "llvm/Target/TargetAsmParser.h" 24#include "llvm/Support/SourceMgr.h" 25#include "llvm/Support/raw_ostream.h" 26#include "llvm/ADT/SmallVector.h" 27#include "llvm/ADT/StringExtras.h" 28#include "llvm/ADT/StringSwitch.h" 29#include "llvm/ADT/Twine.h" 30using namespace llvm; 31 32/// Shift types used for register controlled shifts in ARM memory addressing. 33enum ShiftType { 34 Lsl, 35 Lsr, 36 Asr, 37 Ror, 38 Rrx 39}; 40 41namespace { 42 43class ARMOperand; 44 45class ARMAsmParser : public TargetAsmParser { 46 MCAsmParser &Parser; 47 TargetMachine &TM; 48 49 MCAsmParser &getParser() const { return Parser; } 50 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 51 52 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 53 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 54 55 int TryParseRegister(); 56 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 57 bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 58 bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 59 bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 60 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 61 bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); 62 const MCExpr *ApplyPrefixToExpr(const MCExpr *E, 63 MCSymbolRefExpr::VariantKind Variant); 64 65 66 bool ParseMemoryOffsetReg(bool &Negative, 67 bool &OffsetRegShifted, 68 enum ShiftType &ShiftType, 69 const MCExpr *&ShiftAmount, 70 const MCExpr *&Offset, 71 bool &OffsetIsReg, 72 int &OffsetRegNum, 73 SMLoc &E); 74 bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E); 75 bool ParseDirectiveWord(unsigned Size, SMLoc L); 76 bool ParseDirectiveThumb(SMLoc L); 77 bool ParseDirectiveThumbFunc(SMLoc L); 78 bool ParseDirectiveCode(SMLoc L); 79 bool ParseDirectiveSyntax(SMLoc L); 80 81 bool MatchAndEmitInstruction(SMLoc IDLoc, 82 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 83 MCStreamer &Out); 84 void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 85 bool &CanAcceptPredicationCode); 86 87 /// @name Auto-generated Match Functions 88 /// { 89 90#define GET_ASSEMBLER_HEADER 91#include "ARMGenAsmMatcher.inc" 92 93 /// } 94 95 OperandMatchResultTy tryParseCoprocNumOperand( 96 SmallVectorImpl<MCParsedAsmOperand*>&); 97 OperandMatchResultTy tryParseCoprocRegOperand( 98 SmallVectorImpl<MCParsedAsmOperand*>&); 99 OperandMatchResultTy tryParseMemBarrierOptOperand( 100 SmallVectorImpl<MCParsedAsmOperand*> &); 101 OperandMatchResultTy tryParseProcIFlagsOperand( 102 SmallVectorImpl<MCParsedAsmOperand*> &); 103 104public: 105 ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) 106 : TargetAsmParser(T), Parser(_Parser), TM(_TM) { 107 // Initialize the set of available features. 108 setAvailableFeatures(ComputeAvailableFeatures( 109 &TM.getSubtarget<ARMSubtarget>())); 110 } 111 112 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 113 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 114 virtual bool ParseDirective(AsmToken DirectiveID); 115}; 116} // end anonymous namespace 117 118namespace { 119 120/// ARMOperand - Instances of this class represent a parsed ARM machine 121/// instruction. 122class ARMOperand : public MCParsedAsmOperand { 123 enum KindTy { 124 CondCode, 125 CCOut, 126 CoprocNum, 127 CoprocReg, 128 Immediate, 129 MemBarrierOpt, 130 Memory, 131 ProcIFlags, 132 Register, 133 RegisterList, 134 DPRRegisterList, 135 SPRRegisterList, 136 Token 137 } Kind; 138 139 SMLoc StartLoc, EndLoc; 140 SmallVector<unsigned, 8> Registers; 141 142 union { 143 struct { 144 ARMCC::CondCodes Val; 145 } CC; 146 147 struct { 148 ARM_MB::MemBOpt Val; 149 } MBOpt; 150 151 struct { 152 unsigned Val; 153 } Cop; 154 155 struct { 156 ARM_PROC::IFlags Val; 157 } IFlags; 158 159 struct { 160 const char *Data; 161 unsigned Length; 162 } Tok; 163 164 struct { 165 unsigned RegNum; 166 } Reg; 167 168 struct { 169 const MCExpr *Val; 170 } Imm; 171 172 /// Combined record for all forms of ARM address expressions. 173 struct { 174 unsigned BaseRegNum; 175 union { 176 unsigned RegNum; ///< Offset register num, when OffsetIsReg. 177 const MCExpr *Value; ///< Offset value, when !OffsetIsReg. 178 } Offset; 179 const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 180 enum ShiftType ShiftType; // used when OffsetRegShifted is true 181 unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true 182 unsigned Preindexed : 1; 183 unsigned Postindexed : 1; 184 unsigned OffsetIsReg : 1; 185 unsigned Negative : 1; // only used when OffsetIsReg is true 186 unsigned Writeback : 1; 187 } Mem; 188 }; 189 190 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 191public: 192 ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 193 Kind = o.Kind; 194 StartLoc = o.StartLoc; 195 EndLoc = o.EndLoc; 196 switch (Kind) { 197 case CondCode: 198 CC = o.CC; 199 break; 200 case Token: 201 Tok = o.Tok; 202 break; 203 case CCOut: 204 case Register: 205 Reg = o.Reg; 206 break; 207 case RegisterList: 208 case DPRRegisterList: 209 case SPRRegisterList: 210 Registers = o.Registers; 211 break; 212 case CoprocNum: 213 case CoprocReg: 214 Cop = o.Cop; 215 break; 216 case Immediate: 217 Imm = o.Imm; 218 break; 219 case MemBarrierOpt: 220 MBOpt = o.MBOpt; 221 break; 222 case Memory: 223 Mem = o.Mem; 224 break; 225 case ProcIFlags: 226 IFlags = o.IFlags; 227 } 228 } 229 230 /// getStartLoc - Get the location of the first token of this operand. 231 SMLoc getStartLoc() const { return StartLoc; } 232 /// getEndLoc - Get the location of the last token of this operand. 233 SMLoc getEndLoc() const { return EndLoc; } 234 235 ARMCC::CondCodes getCondCode() const { 236 assert(Kind == CondCode && "Invalid access!"); 237 return CC.Val; 238 } 239 240 unsigned getCoproc() const { 241 assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 242 return Cop.Val; 243 } 244 245 StringRef getToken() const { 246 assert(Kind == Token && "Invalid access!"); 247 return StringRef(Tok.Data, Tok.Length); 248 } 249 250 unsigned getReg() const { 251 assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 252 return Reg.RegNum; 253 } 254 255 const SmallVectorImpl<unsigned> &getRegList() const { 256 assert((Kind == RegisterList || Kind == DPRRegisterList || 257 Kind == SPRRegisterList) && "Invalid access!"); 258 return Registers; 259 } 260 261 const MCExpr *getImm() const { 262 assert(Kind == Immediate && "Invalid access!"); 263 return Imm.Val; 264 } 265 266 ARM_MB::MemBOpt getMemBarrierOpt() const { 267 assert(Kind == MemBarrierOpt && "Invalid access!"); 268 return MBOpt.Val; 269 } 270 271 ARM_PROC::IFlags getProcIFlags() const { 272 assert(Kind == ProcIFlags && "Invalid access!"); 273 return IFlags.Val; 274 } 275 276 /// @name Memory Operand Accessors 277 /// @{ 278 279 unsigned getMemBaseRegNum() const { 280 return Mem.BaseRegNum; 281 } 282 unsigned getMemOffsetRegNum() const { 283 assert(Mem.OffsetIsReg && "Invalid access!"); 284 return Mem.Offset.RegNum; 285 } 286 const MCExpr *getMemOffset() const { 287 assert(!Mem.OffsetIsReg && "Invalid access!"); 288 return Mem.Offset.Value; 289 } 290 unsigned getMemOffsetRegShifted() const { 291 assert(Mem.OffsetIsReg && "Invalid access!"); 292 return Mem.OffsetRegShifted; 293 } 294 const MCExpr *getMemShiftAmount() const { 295 assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 296 return Mem.ShiftAmount; 297 } 298 enum ShiftType getMemShiftType() const { 299 assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 300 return Mem.ShiftType; 301 } 302 bool getMemPreindexed() const { return Mem.Preindexed; } 303 bool getMemPostindexed() const { return Mem.Postindexed; } 304 bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; } 305 bool getMemNegative() const { return Mem.Negative; } 306 bool getMemWriteback() const { return Mem.Writeback; } 307 308 /// @} 309 310 bool isCoprocNum() const { return Kind == CoprocNum; } 311 bool isCoprocReg() const { return Kind == CoprocReg; } 312 bool isCondCode() const { return Kind == CondCode; } 313 bool isCCOut() const { return Kind == CCOut; } 314 bool isImm() const { return Kind == Immediate; } 315 bool isReg() const { return Kind == Register; } 316 bool isRegList() const { return Kind == RegisterList; } 317 bool isDPRRegList() const { return Kind == DPRRegisterList; } 318 bool isSPRRegList() const { return Kind == SPRRegisterList; } 319 bool isToken() const { return Kind == Token; } 320 bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 321 bool isMemory() const { return Kind == Memory; } 322 bool isMemMode5() const { 323 if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || 324 getMemNegative()) 325 return false; 326 327 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 328 if (!CE) return false; 329 330 // The offset must be a multiple of 4 in the range 0-1020. 331 int64_t Value = CE->getValue(); 332 return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); 333 } 334 bool isMemModeRegThumb() const { 335 if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback()) 336 return false; 337 return true; 338 } 339 bool isMemModeImmThumb() const { 340 if (!isMemory() || getMemOffsetIsReg() || getMemWriteback()) 341 return false; 342 343 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 344 if (!CE) return false; 345 346 // The offset must be a multiple of 4 in the range 0-124. 347 uint64_t Value = CE->getValue(); 348 return ((Value & 0x3) == 0 && Value <= 124); 349 } 350 bool isProcIFlags() const { return Kind == ProcIFlags; } 351 352 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 353 // Add as immediates when possible. Null MCExpr = 0. 354 if (Expr == 0) 355 Inst.addOperand(MCOperand::CreateImm(0)); 356 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 357 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 358 else 359 Inst.addOperand(MCOperand::CreateExpr(Expr)); 360 } 361 362 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 363 assert(N == 2 && "Invalid number of operands!"); 364 Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 365 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 366 Inst.addOperand(MCOperand::CreateReg(RegNum)); 367 } 368 369 void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 370 assert(N == 1 && "Invalid number of operands!"); 371 Inst.addOperand(MCOperand::CreateImm(getCoproc())); 372 } 373 374 void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 375 assert(N == 1 && "Invalid number of operands!"); 376 Inst.addOperand(MCOperand::CreateImm(getCoproc())); 377 } 378 379 void addCCOutOperands(MCInst &Inst, unsigned N) const { 380 assert(N == 1 && "Invalid number of operands!"); 381 Inst.addOperand(MCOperand::CreateReg(getReg())); 382 } 383 384 void addRegOperands(MCInst &Inst, unsigned N) const { 385 assert(N == 1 && "Invalid number of operands!"); 386 Inst.addOperand(MCOperand::CreateReg(getReg())); 387 } 388 389 void addRegListOperands(MCInst &Inst, unsigned N) const { 390 assert(N == 1 && "Invalid number of operands!"); 391 const SmallVectorImpl<unsigned> &RegList = getRegList(); 392 for (SmallVectorImpl<unsigned>::const_iterator 393 I = RegList.begin(), E = RegList.end(); I != E; ++I) 394 Inst.addOperand(MCOperand::CreateReg(*I)); 395 } 396 397 void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 398 addRegListOperands(Inst, N); 399 } 400 401 void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 402 addRegListOperands(Inst, N); 403 } 404 405 void addImmOperands(MCInst &Inst, unsigned N) const { 406 assert(N == 1 && "Invalid number of operands!"); 407 addExpr(Inst, getImm()); 408 } 409 410 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 411 assert(N == 1 && "Invalid number of operands!"); 412 Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 413 } 414 415 void addMemMode5Operands(MCInst &Inst, unsigned N) const { 416 assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 417 418 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 419 assert(!getMemOffsetIsReg() && "Invalid mode 5 operand"); 420 421 // FIXME: #-0 is encoded differently than #0. Does the parser preserve 422 // the difference? 423 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 424 assert(CE && "Non-constant mode 5 offset operand!"); 425 426 // The MCInst offset operand doesn't include the low two bits (like 427 // the instruction encoding). 428 int64_t Offset = CE->getValue() / 4; 429 if (Offset >= 0) 430 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, 431 Offset))); 432 else 433 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, 434 -Offset))); 435 } 436 437 void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const { 438 assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!"); 439 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 440 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 441 } 442 443 void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const { 444 assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!"); 445 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 446 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 447 assert(CE && "Non-constant mode offset operand!"); 448 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 449 } 450 451 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 452 assert(N == 1 && "Invalid number of operands!"); 453 Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 454 } 455 456 virtual void dump(raw_ostream &OS) const; 457 458 static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 459 ARMOperand *Op = new ARMOperand(CondCode); 460 Op->CC.Val = CC; 461 Op->StartLoc = S; 462 Op->EndLoc = S; 463 return Op; 464 } 465 466 static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 467 ARMOperand *Op = new ARMOperand(CoprocNum); 468 Op->Cop.Val = CopVal; 469 Op->StartLoc = S; 470 Op->EndLoc = S; 471 return Op; 472 } 473 474 static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 475 ARMOperand *Op = new ARMOperand(CoprocReg); 476 Op->Cop.Val = CopVal; 477 Op->StartLoc = S; 478 Op->EndLoc = S; 479 return Op; 480 } 481 482 static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 483 ARMOperand *Op = new ARMOperand(CCOut); 484 Op->Reg.RegNum = RegNum; 485 Op->StartLoc = S; 486 Op->EndLoc = S; 487 return Op; 488 } 489 490 static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 491 ARMOperand *Op = new ARMOperand(Token); 492 Op->Tok.Data = Str.data(); 493 Op->Tok.Length = Str.size(); 494 Op->StartLoc = S; 495 Op->EndLoc = S; 496 return Op; 497 } 498 499 static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 500 ARMOperand *Op = new ARMOperand(Register); 501 Op->Reg.RegNum = RegNum; 502 Op->StartLoc = S; 503 Op->EndLoc = E; 504 return Op; 505 } 506 507 static ARMOperand * 508 CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 509 SMLoc StartLoc, SMLoc EndLoc) { 510 KindTy Kind = RegisterList; 511 512 if (ARM::DPRRegClass.contains(Regs.front().first)) 513 Kind = DPRRegisterList; 514 else if (ARM::SPRRegClass.contains(Regs.front().first)) 515 Kind = SPRRegisterList; 516 517 ARMOperand *Op = new ARMOperand(Kind); 518 for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 519 I = Regs.begin(), E = Regs.end(); I != E; ++I) 520 Op->Registers.push_back(I->first); 521 array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 522 Op->StartLoc = StartLoc; 523 Op->EndLoc = EndLoc; 524 return Op; 525 } 526 527 static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 528 ARMOperand *Op = new ARMOperand(Immediate); 529 Op->Imm.Val = Val; 530 Op->StartLoc = S; 531 Op->EndLoc = E; 532 return Op; 533 } 534 535 static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, 536 const MCExpr *Offset, int OffsetRegNum, 537 bool OffsetRegShifted, enum ShiftType ShiftType, 538 const MCExpr *ShiftAmount, bool Preindexed, 539 bool Postindexed, bool Negative, bool Writeback, 540 SMLoc S, SMLoc E) { 541 assert((OffsetRegNum == -1 || OffsetIsReg) && 542 "OffsetRegNum must imply OffsetIsReg!"); 543 assert((!OffsetRegShifted || OffsetIsReg) && 544 "OffsetRegShifted must imply OffsetIsReg!"); 545 assert((Offset || OffsetIsReg) && 546 "Offset must exists unless register offset is used!"); 547 assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) && 548 "Cannot have shift amount without shifted register offset!"); 549 assert((!Offset || !OffsetIsReg) && 550 "Cannot have expression offset and register offset!"); 551 552 ARMOperand *Op = new ARMOperand(Memory); 553 Op->Mem.BaseRegNum = BaseRegNum; 554 Op->Mem.OffsetIsReg = OffsetIsReg; 555 if (OffsetIsReg) 556 Op->Mem.Offset.RegNum = OffsetRegNum; 557 else 558 Op->Mem.Offset.Value = Offset; 559 Op->Mem.OffsetRegShifted = OffsetRegShifted; 560 Op->Mem.ShiftType = ShiftType; 561 Op->Mem.ShiftAmount = ShiftAmount; 562 Op->Mem.Preindexed = Preindexed; 563 Op->Mem.Postindexed = Postindexed; 564 Op->Mem.Negative = Negative; 565 Op->Mem.Writeback = Writeback; 566 567 Op->StartLoc = S; 568 Op->EndLoc = E; 569 return Op; 570 } 571 572 static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 573 ARMOperand *Op = new ARMOperand(MemBarrierOpt); 574 Op->MBOpt.Val = Opt; 575 Op->StartLoc = S; 576 Op->EndLoc = S; 577 return Op; 578 } 579 580 static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 581 ARMOperand *Op = new ARMOperand(ProcIFlags); 582 Op->IFlags.Val = IFlags; 583 Op->StartLoc = S; 584 Op->EndLoc = S; 585 return Op; 586 } 587}; 588 589} // end anonymous namespace. 590 591void ARMOperand::dump(raw_ostream &OS) const { 592 switch (Kind) { 593 case CondCode: 594 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 595 break; 596 case CCOut: 597 OS << "<ccout " << getReg() << ">"; 598 break; 599 case CoprocNum: 600 OS << "<coprocessor number: " << getCoproc() << ">"; 601 break; 602 case CoprocReg: 603 OS << "<coprocessor register: " << getCoproc() << ">"; 604 break; 605 case Immediate: 606 getImm()->print(OS); 607 break; 608 case MemBarrierOpt: 609 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 610 break; 611 case Memory: 612 OS << "<memory " 613 << "base:" << getMemBaseRegNum(); 614 if (getMemOffsetIsReg()) { 615 OS << " offset:<register " << getMemOffsetRegNum(); 616 if (getMemOffsetRegShifted()) { 617 OS << " offset-shift-type:" << getMemShiftType(); 618 OS << " offset-shift-amount:" << *getMemShiftAmount(); 619 } 620 } else { 621 OS << " offset:" << *getMemOffset(); 622 } 623 if (getMemOffsetIsReg()) 624 OS << " (offset-is-reg)"; 625 if (getMemPreindexed()) 626 OS << " (pre-indexed)"; 627 if (getMemPostindexed()) 628 OS << " (post-indexed)"; 629 if (getMemNegative()) 630 OS << " (negative)"; 631 if (getMemWriteback()) 632 OS << " (writeback)"; 633 OS << ">"; 634 break; 635 case ProcIFlags: { 636 OS << "<ARM_PROC::"; 637 unsigned IFlags = getProcIFlags(); 638 for (int i=2; i >= 0; --i) 639 if (IFlags & (1 << i)) 640 OS << ARM_PROC::IFlagsToString(1 << i); 641 OS << ">"; 642 break; 643 } 644 case Register: 645 OS << "<register " << getReg() << ">"; 646 break; 647 case RegisterList: 648 case DPRRegisterList: 649 case SPRRegisterList: { 650 OS << "<register_list "; 651 652 const SmallVectorImpl<unsigned> &RegList = getRegList(); 653 for (SmallVectorImpl<unsigned>::const_iterator 654 I = RegList.begin(), E = RegList.end(); I != E; ) { 655 OS << *I; 656 if (++I < E) OS << ", "; 657 } 658 659 OS << ">"; 660 break; 661 } 662 case Token: 663 OS << "'" << getToken() << "'"; 664 break; 665 } 666} 667 668/// @name Auto-generated Match Functions 669/// { 670 671static unsigned MatchRegisterName(StringRef Name); 672 673/// } 674 675bool ARMAsmParser::ParseRegister(unsigned &RegNo, 676 SMLoc &StartLoc, SMLoc &EndLoc) { 677 RegNo = TryParseRegister(); 678 679 return (RegNo == (unsigned)-1); 680} 681 682/// Try to parse a register name. The token must be an Identifier when called, 683/// and if it is a register name the token is eaten and the register number is 684/// returned. Otherwise return -1. 685/// 686int ARMAsmParser::TryParseRegister() { 687 const AsmToken &Tok = Parser.getTok(); 688 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 689 690 // FIXME: Validate register for the current architecture; we have to do 691 // validation later, so maybe there is no need for this here. 692 std::string upperCase = Tok.getString().str(); 693 std::string lowerCase = LowercaseString(upperCase); 694 unsigned RegNum = MatchRegisterName(lowerCase); 695 if (!RegNum) { 696 RegNum = StringSwitch<unsigned>(lowerCase) 697 .Case("r13", ARM::SP) 698 .Case("r14", ARM::LR) 699 .Case("r15", ARM::PC) 700 .Case("ip", ARM::R12) 701 .Default(0); 702 } 703 if (!RegNum) return -1; 704 705 Parser.Lex(); // Eat identifier token. 706 return RegNum; 707} 708 709/// Try to parse a register name. The token must be an Identifier when called. 710/// If it's a register, an AsmOperand is created. Another AsmOperand is created 711/// if there is a "writeback". 'true' if it's not a register. 712/// 713/// TODO this is likely to change to allow different register types and or to 714/// parse for a specific register type. 715bool ARMAsmParser:: 716TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 717 SMLoc S = Parser.getTok().getLoc(); 718 int RegNo = TryParseRegister(); 719 if (RegNo == -1) 720 return true; 721 722 Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 723 724 const AsmToken &ExclaimTok = Parser.getTok(); 725 if (ExclaimTok.is(AsmToken::Exclaim)) { 726 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 727 ExclaimTok.getLoc())); 728 Parser.Lex(); // Eat exclaim token 729 } 730 731 return false; 732} 733 734/// MatchCoprocessorOperandName - Try to parse an coprocessor related 735/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 736/// "c5", ... 737static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 738 // Use the same layout as the tablegen'erated register name matcher. Ugly, 739 // but efficient. 740 switch (Name.size()) { 741 default: break; 742 case 2: 743 if (Name[0] != CoprocOp) 744 return -1; 745 switch (Name[1]) { 746 default: return -1; 747 case '0': return 0; 748 case '1': return 1; 749 case '2': return 2; 750 case '3': return 3; 751 case '4': return 4; 752 case '5': return 5; 753 case '6': return 6; 754 case '7': return 7; 755 case '8': return 8; 756 case '9': return 9; 757 } 758 break; 759 case 3: 760 if (Name[0] != CoprocOp || Name[1] != '1') 761 return -1; 762 switch (Name[2]) { 763 default: return -1; 764 case '0': return 10; 765 case '1': return 11; 766 case '2': return 12; 767 case '3': return 13; 768 case '4': return 14; 769 case '5': return 15; 770 } 771 break; 772 } 773 774 llvm_unreachable("Unhandled coprocessor operand string!"); 775 return -1; 776} 777 778/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The 779/// token must be an Identifier when called, and if it is a coprocessor 780/// number, the token is eaten and the operand is added to the operand list. 781ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 782tryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 783 SMLoc S = Parser.getTok().getLoc(); 784 const AsmToken &Tok = Parser.getTok(); 785 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 786 787 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 788 if (Num == -1) 789 return MatchOperand_NoMatch; 790 791 Parser.Lex(); // Eat identifier token. 792 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 793 return MatchOperand_Success; 794} 795 796/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The 797/// token must be an Identifier when called, and if it is a coprocessor 798/// number, the token is eaten and the operand is added to the operand list. 799ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 800tryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 801 SMLoc S = Parser.getTok().getLoc(); 802 const AsmToken &Tok = Parser.getTok(); 803 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 804 805 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 806 if (Reg == -1) 807 return MatchOperand_NoMatch; 808 809 Parser.Lex(); // Eat identifier token. 810 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 811 return MatchOperand_Success; 812} 813 814/// Parse a register list, return it if successful else return null. The first 815/// token must be a '{' when called. 816bool ARMAsmParser:: 817ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 818 assert(Parser.getTok().is(AsmToken::LCurly) && 819 "Token is not a Left Curly Brace"); 820 SMLoc S = Parser.getTok().getLoc(); 821 822 // Read the rest of the registers in the list. 823 unsigned PrevRegNum = 0; 824 SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 825 826 do { 827 bool IsRange = Parser.getTok().is(AsmToken::Minus); 828 Parser.Lex(); // Eat non-identifier token. 829 830 const AsmToken &RegTok = Parser.getTok(); 831 SMLoc RegLoc = RegTok.getLoc(); 832 if (RegTok.isNot(AsmToken::Identifier)) { 833 Error(RegLoc, "register expected"); 834 return true; 835 } 836 837 int RegNum = TryParseRegister(); 838 if (RegNum == -1) { 839 Error(RegLoc, "register expected"); 840 return true; 841 } 842 843 if (IsRange) { 844 int Reg = PrevRegNum; 845 do { 846 ++Reg; 847 Registers.push_back(std::make_pair(Reg, RegLoc)); 848 } while (Reg != RegNum); 849 } else { 850 Registers.push_back(std::make_pair(RegNum, RegLoc)); 851 } 852 853 PrevRegNum = RegNum; 854 } while (Parser.getTok().is(AsmToken::Comma) || 855 Parser.getTok().is(AsmToken::Minus)); 856 857 // Process the right curly brace of the list. 858 const AsmToken &RCurlyTok = Parser.getTok(); 859 if (RCurlyTok.isNot(AsmToken::RCurly)) { 860 Error(RCurlyTok.getLoc(), "'}' expected"); 861 return true; 862 } 863 864 SMLoc E = RCurlyTok.getLoc(); 865 Parser.Lex(); // Eat right curly brace token. 866 867 // Verify the register list. 868 SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 869 RI = Registers.begin(), RE = Registers.end(); 870 871 unsigned HighRegNum = getARMRegisterNumbering(RI->first); 872 bool EmittedWarning = false; 873 874 DenseMap<unsigned, bool> RegMap; 875 RegMap[HighRegNum] = true; 876 877 for (++RI; RI != RE; ++RI) { 878 const std::pair<unsigned, SMLoc> &RegInfo = *RI; 879 unsigned Reg = getARMRegisterNumbering(RegInfo.first); 880 881 if (RegMap[Reg]) { 882 Error(RegInfo.second, "register duplicated in register list"); 883 return true; 884 } 885 886 if (!EmittedWarning && Reg < HighRegNum) 887 Warning(RegInfo.second, 888 "register not in ascending order in register list"); 889 890 RegMap[Reg] = true; 891 HighRegNum = std::max(Reg, HighRegNum); 892 } 893 894 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 895 return false; 896} 897 898/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 899ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 900tryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 901 SMLoc S = Parser.getTok().getLoc(); 902 const AsmToken &Tok = Parser.getTok(); 903 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 904 StringRef OptStr = Tok.getString(); 905 906 unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 907 .Case("sy", ARM_MB::SY) 908 .Case("st", ARM_MB::ST) 909 .Case("ish", ARM_MB::ISH) 910 .Case("ishst", ARM_MB::ISHST) 911 .Case("nsh", ARM_MB::NSH) 912 .Case("nshst", ARM_MB::NSHST) 913 .Case("osh", ARM_MB::OSH) 914 .Case("oshst", ARM_MB::OSHST) 915 .Default(~0U); 916 917 if (Opt == ~0U) 918 return MatchOperand_NoMatch; 919 920 Parser.Lex(); // Eat identifier token. 921 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 922 return MatchOperand_Success; 923} 924 925/// ParseProcIFlagsOperand - Try to parse iflags from CPS instruction. 926ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 927tryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 928 SMLoc S = Parser.getTok().getLoc(); 929 const AsmToken &Tok = Parser.getTok(); 930 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 931 StringRef IFlagsStr = Tok.getString(); 932 933 unsigned IFlags = 0; 934 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 935 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 936 .Case("a", ARM_PROC::A) 937 .Case("i", ARM_PROC::I) 938 .Case("f", ARM_PROC::F) 939 .Default(~0U); 940 941 // If some specific iflag is already set, it means that some letter is 942 // present more than once, this is not acceptable. 943 if (Flag == ~0U || (IFlags & Flag)) 944 return MatchOperand_NoMatch; 945 946 IFlags |= Flag; 947 } 948 949 Parser.Lex(); // Eat identifier token. 950 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 951 return MatchOperand_Success; 952} 953 954/// Parse an ARM memory expression, return false if successful else return true 955/// or an error. The first token must be a '[' when called. 956/// 957/// TODO Only preindexing and postindexing addressing are started, unindexed 958/// with option, etc are still to do. 959bool ARMAsmParser:: 960ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 961 SMLoc S, E; 962 assert(Parser.getTok().is(AsmToken::LBrac) && 963 "Token is not a Left Bracket"); 964 S = Parser.getTok().getLoc(); 965 Parser.Lex(); // Eat left bracket token. 966 967 const AsmToken &BaseRegTok = Parser.getTok(); 968 if (BaseRegTok.isNot(AsmToken::Identifier)) { 969 Error(BaseRegTok.getLoc(), "register expected"); 970 return true; 971 } 972 int BaseRegNum = TryParseRegister(); 973 if (BaseRegNum == -1) { 974 Error(BaseRegTok.getLoc(), "register expected"); 975 return true; 976 } 977 978 // The next token must either be a comma or a closing bracket. 979 const AsmToken &Tok = Parser.getTok(); 980 if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 981 return true; 982 983 bool Preindexed = false; 984 bool Postindexed = false; 985 bool OffsetIsReg = false; 986 bool Negative = false; 987 bool Writeback = false; 988 ARMOperand *WBOp = 0; 989 int OffsetRegNum = -1; 990 bool OffsetRegShifted = false; 991 enum ShiftType ShiftType = Lsl; 992 const MCExpr *ShiftAmount = 0; 993 const MCExpr *Offset = 0; 994 995 // First look for preindexed address forms, that is after the "[Rn" we now 996 // have to see if the next token is a comma. 997 if (Tok.is(AsmToken::Comma)) { 998 Preindexed = true; 999 Parser.Lex(); // Eat comma token. 1000 1001 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 1002 Offset, OffsetIsReg, OffsetRegNum, E)) 1003 return true; 1004 const AsmToken &RBracTok = Parser.getTok(); 1005 if (RBracTok.isNot(AsmToken::RBrac)) { 1006 Error(RBracTok.getLoc(), "']' expected"); 1007 return true; 1008 } 1009 E = RBracTok.getLoc(); 1010 Parser.Lex(); // Eat right bracket token. 1011 1012 const AsmToken &ExclaimTok = Parser.getTok(); 1013 if (ExclaimTok.is(AsmToken::Exclaim)) { 1014 WBOp = ARMOperand::CreateToken(ExclaimTok.getString(), 1015 ExclaimTok.getLoc()); 1016 Writeback = true; 1017 Parser.Lex(); // Eat exclaim token 1018 } 1019 } else { 1020 // The "[Rn" we have so far was not followed by a comma. 1021 1022 // If there's anything other than the right brace, this is a post indexing 1023 // addressing form. 1024 E = Tok.getLoc(); 1025 Parser.Lex(); // Eat right bracket token. 1026 1027 const AsmToken &NextTok = Parser.getTok(); 1028 1029 if (NextTok.isNot(AsmToken::EndOfStatement)) { 1030 Postindexed = true; 1031 Writeback = true; 1032 1033 if (NextTok.isNot(AsmToken::Comma)) { 1034 Error(NextTok.getLoc(), "',' expected"); 1035 return true; 1036 } 1037 1038 Parser.Lex(); // Eat comma token. 1039 1040 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 1041 ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 1042 E)) 1043 return true; 1044 } 1045 } 1046 1047 // Force Offset to exist if used. 1048 if (!OffsetIsReg) { 1049 if (!Offset) 1050 Offset = MCConstantExpr::Create(0, getContext()); 1051 } 1052 1053 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, 1054 OffsetRegNum, OffsetRegShifted, 1055 ShiftType, ShiftAmount, Preindexed, 1056 Postindexed, Negative, Writeback, 1057 S, E)); 1058 if (WBOp) 1059 Operands.push_back(WBOp); 1060 1061 return false; 1062} 1063 1064/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 1065/// we will parse the following (were +/- means that a plus or minus is 1066/// optional): 1067/// +/-Rm 1068/// +/-Rm, shift 1069/// #offset 1070/// we return false on success or an error otherwise. 1071bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 1072 bool &OffsetRegShifted, 1073 enum ShiftType &ShiftType, 1074 const MCExpr *&ShiftAmount, 1075 const MCExpr *&Offset, 1076 bool &OffsetIsReg, 1077 int &OffsetRegNum, 1078 SMLoc &E) { 1079 Negative = false; 1080 OffsetRegShifted = false; 1081 OffsetIsReg = false; 1082 OffsetRegNum = -1; 1083 const AsmToken &NextTok = Parser.getTok(); 1084 E = NextTok.getLoc(); 1085 if (NextTok.is(AsmToken::Plus)) 1086 Parser.Lex(); // Eat plus token. 1087 else if (NextTok.is(AsmToken::Minus)) { 1088 Negative = true; 1089 Parser.Lex(); // Eat minus token 1090 } 1091 // See if there is a register following the "[Rn," or "[Rn]," we have so far. 1092 const AsmToken &OffsetRegTok = Parser.getTok(); 1093 if (OffsetRegTok.is(AsmToken::Identifier)) { 1094 SMLoc CurLoc = OffsetRegTok.getLoc(); 1095 OffsetRegNum = TryParseRegister(); 1096 if (OffsetRegNum != -1) { 1097 OffsetIsReg = true; 1098 E = CurLoc; 1099 } 1100 } 1101 1102 // If we parsed a register as the offset then there can be a shift after that. 1103 if (OffsetRegNum != -1) { 1104 // Look for a comma then a shift 1105 const AsmToken &Tok = Parser.getTok(); 1106 if (Tok.is(AsmToken::Comma)) { 1107 Parser.Lex(); // Eat comma token. 1108 1109 const AsmToken &Tok = Parser.getTok(); 1110 if (ParseShift(ShiftType, ShiftAmount, E)) 1111 return Error(Tok.getLoc(), "shift expected"); 1112 OffsetRegShifted = true; 1113 } 1114 } 1115 else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 1116 // Look for #offset following the "[Rn," or "[Rn]," 1117 const AsmToken &HashTok = Parser.getTok(); 1118 if (HashTok.isNot(AsmToken::Hash)) 1119 return Error(HashTok.getLoc(), "'#' expected"); 1120 1121 Parser.Lex(); // Eat hash token. 1122 1123 if (getParser().ParseExpression(Offset)) 1124 return true; 1125 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1126 } 1127 return false; 1128} 1129 1130/// ParseShift as one of these two: 1131/// ( lsl | lsr | asr | ror ) , # shift_amount 1132/// rrx 1133/// and returns true if it parses a shift otherwise it returns false. 1134bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount, 1135 SMLoc &E) { 1136 const AsmToken &Tok = Parser.getTok(); 1137 if (Tok.isNot(AsmToken::Identifier)) 1138 return true; 1139 StringRef ShiftName = Tok.getString(); 1140 if (ShiftName == "lsl" || ShiftName == "LSL") 1141 St = Lsl; 1142 else if (ShiftName == "lsr" || ShiftName == "LSR") 1143 St = Lsr; 1144 else if (ShiftName == "asr" || ShiftName == "ASR") 1145 St = Asr; 1146 else if (ShiftName == "ror" || ShiftName == "ROR") 1147 St = Ror; 1148 else if (ShiftName == "rrx" || ShiftName == "RRX") 1149 St = Rrx; 1150 else 1151 return true; 1152 Parser.Lex(); // Eat shift type token. 1153 1154 // Rrx stands alone. 1155 if (St == Rrx) 1156 return false; 1157 1158 // Otherwise, there must be a '#' and a shift amount. 1159 const AsmToken &HashTok = Parser.getTok(); 1160 if (HashTok.isNot(AsmToken::Hash)) 1161 return Error(HashTok.getLoc(), "'#' expected"); 1162 Parser.Lex(); // Eat hash token. 1163 1164 if (getParser().ParseExpression(ShiftAmount)) 1165 return true; 1166 1167 return false; 1168} 1169 1170/// Parse a arm instruction operand. For now this parses the operand regardless 1171/// of the mnemonic. 1172bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1173 StringRef Mnemonic) { 1174 SMLoc S, E; 1175 1176 // Check if the current operand has a custom associated parser, if so, try to 1177 // custom parse the operand, or fallback to the general approach. 1178 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1179 if (ResTy == MatchOperand_Success) 1180 return false; 1181 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1182 // there was a match, but an error occurred, in which case, just return that 1183 // the operand parsing failed. 1184 if (ResTy == MatchOperand_ParseFail) 1185 return true; 1186 1187 switch (getLexer().getKind()) { 1188 default: 1189 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1190 return true; 1191 case AsmToken::Identifier: 1192 if (!TryParseRegisterWithWriteBack(Operands)) 1193 return false; 1194 1195 // Fall though for the Identifier case that is not a register or a 1196 // special name. 1197 case AsmToken::Integer: // things like 1f and 2b as a branch targets 1198 case AsmToken::Dot: { // . as a branch target 1199 // This was not a register so parse other operands that start with an 1200 // identifier (like labels) as expressions and create them as immediates. 1201 const MCExpr *IdVal; 1202 S = Parser.getTok().getLoc(); 1203 if (getParser().ParseExpression(IdVal)) 1204 return true; 1205 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1206 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 1207 return false; 1208 } 1209 case AsmToken::LBrac: 1210 return ParseMemory(Operands); 1211 case AsmToken::LCurly: 1212 return ParseRegisterList(Operands); 1213 case AsmToken::Hash: 1214 // #42 -> immediate. 1215 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 1216 S = Parser.getTok().getLoc(); 1217 Parser.Lex(); 1218 const MCExpr *ImmVal; 1219 if (getParser().ParseExpression(ImmVal)) 1220 return true; 1221 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1222 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 1223 return false; 1224 case AsmToken::Colon: { 1225 // ":lower16:" and ":upper16:" expression prefixes 1226 // FIXME: Check it's an expression prefix, 1227 // e.g. (FOO - :lower16:BAR) isn't legal. 1228 ARMMCExpr::VariantKind RefKind; 1229 if (ParsePrefix(RefKind)) 1230 return true; 1231 1232 const MCExpr *SubExprVal; 1233 if (getParser().ParseExpression(SubExprVal)) 1234 return true; 1235 1236 const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 1237 getContext()); 1238 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1239 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 1240 return false; 1241 } 1242 } 1243} 1244 1245// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 1246// :lower16: and :upper16:. 1247bool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) { 1248 RefKind = ARMMCExpr::VK_ARM_None; 1249 1250 // :lower16: and :upper16: modifiers 1251 assert(getLexer().is(AsmToken::Colon) && "expected a :"); 1252 Parser.Lex(); // Eat ':' 1253 1254 if (getLexer().isNot(AsmToken::Identifier)) { 1255 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 1256 return true; 1257 } 1258 1259 StringRef IDVal = Parser.getTok().getIdentifier(); 1260 if (IDVal == "lower16") { 1261 RefKind = ARMMCExpr::VK_ARM_LO16; 1262 } else if (IDVal == "upper16") { 1263 RefKind = ARMMCExpr::VK_ARM_HI16; 1264 } else { 1265 Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 1266 return true; 1267 } 1268 Parser.Lex(); 1269 1270 if (getLexer().isNot(AsmToken::Colon)) { 1271 Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 1272 return true; 1273 } 1274 Parser.Lex(); // Eat the last ':' 1275 return false; 1276} 1277 1278const MCExpr * 1279ARMAsmParser::ApplyPrefixToExpr(const MCExpr *E, 1280 MCSymbolRefExpr::VariantKind Variant) { 1281 // Recurse over the given expression, rebuilding it to apply the given variant 1282 // to the leftmost symbol. 1283 if (Variant == MCSymbolRefExpr::VK_None) 1284 return E; 1285 1286 switch (E->getKind()) { 1287 case MCExpr::Target: 1288 llvm_unreachable("Can't handle target expr yet"); 1289 case MCExpr::Constant: 1290 llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 1291 1292 case MCExpr::SymbolRef: { 1293 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 1294 1295 if (SRE->getKind() != MCSymbolRefExpr::VK_None) 1296 return 0; 1297 1298 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 1299 } 1300 1301 case MCExpr::Unary: 1302 llvm_unreachable("Can't handle unary expressions yet"); 1303 1304 case MCExpr::Binary: { 1305 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 1306 const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant); 1307 const MCExpr *RHS = BE->getRHS(); 1308 if (!LHS) 1309 return 0; 1310 1311 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 1312 } 1313 } 1314 1315 assert(0 && "Invalid expression kind!"); 1316 return 0; 1317} 1318 1319/// \brief Given a mnemonic, split out possible predication code and carry 1320/// setting letters to form a canonical mnemonic and flags. 1321// 1322// FIXME: Would be nice to autogen this. 1323static StringRef SplitMnemonic(StringRef Mnemonic, 1324 unsigned &PredicationCode, 1325 bool &CarrySetting, 1326 unsigned &ProcessorIMod) { 1327 PredicationCode = ARMCC::AL; 1328 CarrySetting = false; 1329 ProcessorIMod = 0; 1330 1331 // Ignore some mnemonics we know aren't predicated forms. 1332 // 1333 // FIXME: Would be nice to autogen this. 1334 if (Mnemonic == "teq" || Mnemonic == "vceq" || 1335 Mnemonic == "movs" || 1336 Mnemonic == "svc" || 1337 (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 1338 Mnemonic == "vmls" || Mnemonic == "vnmls") || 1339 Mnemonic == "vacge" || Mnemonic == "vcge" || 1340 Mnemonic == "vclt" || 1341 Mnemonic == "vacgt" || Mnemonic == "vcgt" || 1342 Mnemonic == "vcle" || 1343 (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" || 1344 Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" || 1345 Mnemonic == "vqdmlal")) 1346 return Mnemonic; 1347 1348 // First, split out any predication code. 1349 unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 1350 .Case("eq", ARMCC::EQ) 1351 .Case("ne", ARMCC::NE) 1352 .Case("hs", ARMCC::HS) 1353 .Case("lo", ARMCC::LO) 1354 .Case("mi", ARMCC::MI) 1355 .Case("pl", ARMCC::PL) 1356 .Case("vs", ARMCC::VS) 1357 .Case("vc", ARMCC::VC) 1358 .Case("hi", ARMCC::HI) 1359 .Case("ls", ARMCC::LS) 1360 .Case("ge", ARMCC::GE) 1361 .Case("lt", ARMCC::LT) 1362 .Case("gt", ARMCC::GT) 1363 .Case("le", ARMCC::LE) 1364 .Case("al", ARMCC::AL) 1365 .Default(~0U); 1366 if (CC != ~0U) { 1367 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 1368 PredicationCode = CC; 1369 } 1370 1371 // Next, determine if we have a carry setting bit. We explicitly ignore all 1372 // the instructions we know end in 's'. 1373 if (Mnemonic.endswith("s") && 1374 !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 1375 Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" || 1376 Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" || 1377 Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" || 1378 Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) { 1379 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 1380 CarrySetting = true; 1381 } 1382 1383 // The "cps" instruction can have a interrupt mode operand which is glued into 1384 // the mnemonic. Check if this is the case, split it and parse the imod op 1385 if (Mnemonic.startswith("cps")) { 1386 // Split out any imod code. 1387 unsigned IMod = 1388 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 1389 .Case("ie", ARM_PROC::IE) 1390 .Case("id", ARM_PROC::ID) 1391 .Default(~0U); 1392 if (IMod != ~0U) { 1393 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 1394 ProcessorIMod = IMod; 1395 } 1396 } 1397 1398 return Mnemonic; 1399} 1400 1401/// \brief Given a canonical mnemonic, determine if the instruction ever allows 1402/// inclusion of carry set or predication code operands. 1403// 1404// FIXME: It would be nice to autogen this. 1405void ARMAsmParser:: 1406GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 1407 bool &CanAcceptPredicationCode) { 1408 bool isThumb = TM.getSubtarget<ARMSubtarget>().isThumb(); 1409 1410 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 1411 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 1412 Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 1413 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 1414 Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mov" || 1415 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 1416 Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 1417 Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "mvn") { 1418 CanAcceptCarrySet = true; 1419 } else { 1420 CanAcceptCarrySet = false; 1421 } 1422 1423 if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 1424 Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 1425 Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 1426 Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 1427 Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" || 1428 Mnemonic == "clrex" || Mnemonic.startswith("cps")) { 1429 CanAcceptPredicationCode = false; 1430 } else { 1431 CanAcceptPredicationCode = true; 1432 } 1433 1434 if (isThumb) 1435 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 1436 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 1437 CanAcceptPredicationCode = false; 1438} 1439 1440/// Parse an arm instruction mnemonic followed by its operands. 1441bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 1442 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1443 // Create the leading tokens for the mnemonic, split by '.' characters. 1444 size_t Start = 0, Next = Name.find('.'); 1445 StringRef Head = Name.slice(Start, Next); 1446 1447 // Split out the predication code and carry setting flag from the mnemonic. 1448 unsigned PredicationCode; 1449 unsigned ProcessorIMod; 1450 bool CarrySetting; 1451 Head = SplitMnemonic(Head, PredicationCode, CarrySetting, 1452 ProcessorIMod); 1453 1454 Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 1455 1456 // Next, add the CCOut and ConditionCode operands, if needed. 1457 // 1458 // For mnemonics which can ever incorporate a carry setting bit or predication 1459 // code, our matching model involves us always generating CCOut and 1460 // ConditionCode operands to match the mnemonic "as written" and then we let 1461 // the matcher deal with finding the right instruction or generating an 1462 // appropriate error. 1463 bool CanAcceptCarrySet, CanAcceptPredicationCode; 1464 GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode); 1465 1466 // Add the carry setting operand, if necessary. 1467 // 1468 // FIXME: It would be awesome if we could somehow invent a location such that 1469 // match errors on this operand would print a nice diagnostic about how the 1470 // 's' character in the mnemonic resulted in a CCOut operand. 1471 if (CanAcceptCarrySet) { 1472 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 1473 NameLoc)); 1474 } else { 1475 // This mnemonic can't ever accept a carry set, but the user wrote one (or 1476 // misspelled another mnemonic). 1477 1478 // FIXME: Issue a nice error. 1479 } 1480 1481 // Add the predication code operand, if necessary. 1482 if (CanAcceptPredicationCode) { 1483 Operands.push_back(ARMOperand::CreateCondCode( 1484 ARMCC::CondCodes(PredicationCode), NameLoc)); 1485 } else { 1486 // This mnemonic can't ever accept a predication code, but the user wrote 1487 // one (or misspelled another mnemonic). 1488 1489 // FIXME: Issue a nice error. 1490 } 1491 1492 // Add the processor imod operand, if necessary. 1493 if (ProcessorIMod) { 1494 Operands.push_back(ARMOperand::CreateImm( 1495 MCConstantExpr::Create(ProcessorIMod, getContext()), 1496 NameLoc, NameLoc)); 1497 } else { 1498 // This mnemonic can't ever accept a imod, but the user wrote 1499 // one (or misspelled another mnemonic). 1500 1501 // FIXME: Issue a nice error. 1502 } 1503 1504 // Add the remaining tokens in the mnemonic. 1505 while (Next != StringRef::npos) { 1506 Start = Next; 1507 Next = Name.find('.', Start + 1); 1508 StringRef ExtraToken = Name.slice(Start, Next); 1509 1510 Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 1511 } 1512 1513 // Read the remaining operands. 1514 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1515 // Read the first operand. 1516 if (ParseOperand(Operands, Head)) { 1517 Parser.EatToEndOfStatement(); 1518 return true; 1519 } 1520 1521 while (getLexer().is(AsmToken::Comma)) { 1522 Parser.Lex(); // Eat the comma. 1523 1524 // Parse and remember the operand. 1525 if (ParseOperand(Operands, Head)) { 1526 Parser.EatToEndOfStatement(); 1527 return true; 1528 } 1529 } 1530 } 1531 1532 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1533 Parser.EatToEndOfStatement(); 1534 return TokError("unexpected token in argument list"); 1535 } 1536 1537 Parser.Lex(); // Consume the EndOfStatement 1538 return false; 1539} 1540 1541bool ARMAsmParser:: 1542MatchAndEmitInstruction(SMLoc IDLoc, 1543 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1544 MCStreamer &Out) { 1545 MCInst Inst; 1546 unsigned ErrorInfo; 1547 MatchResultTy MatchResult, MatchResult2; 1548 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1549 if (MatchResult != Match_Success) { 1550 // If we get a Match_InvalidOperand it might be some arithmetic instruction 1551 // that does not update the condition codes. So try adding a CCOut operand 1552 // with a value of reg0. 1553 if (MatchResult == Match_InvalidOperand) { 1554 Operands.insert(Operands.begin() + 1, 1555 ARMOperand::CreateCCOut(0, 1556 ((ARMOperand*)Operands[0])->getStartLoc())); 1557 MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1558 if (MatchResult2 == Match_Success) 1559 MatchResult = Match_Success; 1560 else { 1561 ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 1562 Operands.erase(Operands.begin() + 1); 1563 delete CCOut; 1564 } 1565 } 1566 // If we get a Match_MnemonicFail it might be some arithmetic instruction 1567 // that updates the condition codes if it ends in 's'. So see if the 1568 // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut 1569 // operand with a value of CPSR. 1570 else if(MatchResult == Match_MnemonicFail) { 1571 // Get the instruction mnemonic, which is the first token. 1572 StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken(); 1573 if (Mnemonic.substr(Mnemonic.size()-1) == "s") { 1574 // removed the 's' from the mnemonic for matching. 1575 StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1); 1576 SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc(); 1577 ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 1578 Operands.erase(Operands.begin()); 1579 delete OldMnemonic; 1580 Operands.insert(Operands.begin(), 1581 ARMOperand::CreateToken(MnemonicNoS, NameLoc)); 1582 Operands.insert(Operands.begin() + 1, 1583 ARMOperand::CreateCCOut(ARM::CPSR, NameLoc)); 1584 MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1585 if (MatchResult2 == Match_Success) 1586 MatchResult = Match_Success; 1587 else { 1588 ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 1589 Operands.erase(Operands.begin()); 1590 delete OldMnemonic; 1591 Operands.insert(Operands.begin(), 1592 ARMOperand::CreateToken(Mnemonic, NameLoc)); 1593 ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 1594 Operands.erase(Operands.begin() + 1); 1595 delete CCOut; 1596 } 1597 } 1598 } 1599 } 1600 switch (MatchResult) { 1601 case Match_Success: 1602 Out.EmitInstruction(Inst); 1603 return false; 1604 case Match_MissingFeature: 1605 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1606 return true; 1607 case Match_InvalidOperand: { 1608 SMLoc ErrorLoc = IDLoc; 1609 if (ErrorInfo != ~0U) { 1610 if (ErrorInfo >= Operands.size()) 1611 return Error(IDLoc, "too few operands for instruction"); 1612 1613 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 1614 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 1615 } 1616 1617 return Error(ErrorLoc, "invalid operand for instruction"); 1618 } 1619 case Match_MnemonicFail: 1620 return Error(IDLoc, "unrecognized instruction mnemonic"); 1621 case Match_ConversionFail: 1622 return Error(IDLoc, "unable to convert operands to instruction"); 1623 } 1624 1625 llvm_unreachable("Implement any new match types added!"); 1626 return true; 1627} 1628 1629/// ParseDirective parses the arm specific directives 1630bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 1631 StringRef IDVal = DirectiveID.getIdentifier(); 1632 if (IDVal == ".word") 1633 return ParseDirectiveWord(4, DirectiveID.getLoc()); 1634 else if (IDVal == ".thumb") 1635 return ParseDirectiveThumb(DirectiveID.getLoc()); 1636 else if (IDVal == ".thumb_func") 1637 return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 1638 else if (IDVal == ".code") 1639 return ParseDirectiveCode(DirectiveID.getLoc()); 1640 else if (IDVal == ".syntax") 1641 return ParseDirectiveSyntax(DirectiveID.getLoc()); 1642 return true; 1643} 1644 1645/// ParseDirectiveWord 1646/// ::= .word [ expression (, expression)* ] 1647bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 1648 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1649 for (;;) { 1650 const MCExpr *Value; 1651 if (getParser().ParseExpression(Value)) 1652 return true; 1653 1654 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 1655 1656 if (getLexer().is(AsmToken::EndOfStatement)) 1657 break; 1658 1659 // FIXME: Improve diagnostic. 1660 if (getLexer().isNot(AsmToken::Comma)) 1661 return Error(L, "unexpected token in directive"); 1662 Parser.Lex(); 1663 } 1664 } 1665 1666 Parser.Lex(); 1667 return false; 1668} 1669 1670/// ParseDirectiveThumb 1671/// ::= .thumb 1672bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 1673 if (getLexer().isNot(AsmToken::EndOfStatement)) 1674 return Error(L, "unexpected token in directive"); 1675 Parser.Lex(); 1676 1677 // TODO: set thumb mode 1678 // TODO: tell the MC streamer the mode 1679 // getParser().getStreamer().Emit???(); 1680 return false; 1681} 1682 1683/// ParseDirectiveThumbFunc 1684/// ::= .thumbfunc symbol_name 1685bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 1686 const AsmToken &Tok = Parser.getTok(); 1687 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 1688 return Error(L, "unexpected token in .thumb_func directive"); 1689 StringRef Name = Tok.getString(); 1690 Parser.Lex(); // Consume the identifier token. 1691 if (getLexer().isNot(AsmToken::EndOfStatement)) 1692 return Error(L, "unexpected token in directive"); 1693 Parser.Lex(); 1694 1695 // Mark symbol as a thumb symbol. 1696 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 1697 getParser().getStreamer().EmitThumbFunc(Func); 1698 return false; 1699} 1700 1701/// ParseDirectiveSyntax 1702/// ::= .syntax unified | divided 1703bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 1704 const AsmToken &Tok = Parser.getTok(); 1705 if (Tok.isNot(AsmToken::Identifier)) 1706 return Error(L, "unexpected token in .syntax directive"); 1707 StringRef Mode = Tok.getString(); 1708 if (Mode == "unified" || Mode == "UNIFIED") 1709 Parser.Lex(); 1710 else if (Mode == "divided" || Mode == "DIVIDED") 1711 return Error(L, "'.syntax divided' arm asssembly not supported"); 1712 else 1713 return Error(L, "unrecognized syntax mode in .syntax directive"); 1714 1715 if (getLexer().isNot(AsmToken::EndOfStatement)) 1716 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 1717 Parser.Lex(); 1718 1719 // TODO tell the MC streamer the mode 1720 // getParser().getStreamer().Emit???(); 1721 return false; 1722} 1723 1724/// ParseDirectiveCode 1725/// ::= .code 16 | 32 1726bool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 1727 const AsmToken &Tok = Parser.getTok(); 1728 if (Tok.isNot(AsmToken::Integer)) 1729 return Error(L, "unexpected token in .code directive"); 1730 int64_t Val = Parser.getTok().getIntVal(); 1731 if (Val == 16) 1732 Parser.Lex(); 1733 else if (Val == 32) 1734 Parser.Lex(); 1735 else 1736 return Error(L, "invalid operand to .code directive"); 1737 1738 if (getLexer().isNot(AsmToken::EndOfStatement)) 1739 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 1740 Parser.Lex(); 1741 1742 // FIXME: We need to be able switch subtargets at this point so that 1743 // MatchInstructionImpl() will work when it gets the AvailableFeatures which 1744 // includes Feature_IsThumb or not to match the right instructions. This is 1745 // blocked on the FIXME in llvm-mc.cpp when creating the TargetMachine. 1746 if (Val == 16){ 1747 assert(TM.getSubtarget<ARMSubtarget>().isThumb() && 1748 "switching between arm/thumb not yet suppported via .code 16)"); 1749 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 1750 } 1751 else{ 1752 assert(!TM.getSubtarget<ARMSubtarget>().isThumb() && 1753 "switching between thumb/arm not yet suppported via .code 32)"); 1754 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 1755 } 1756 1757 return false; 1758} 1759 1760extern "C" void LLVMInitializeARMAsmLexer(); 1761 1762/// Force static initialization. 1763extern "C" void LLVMInitializeARMAsmParser() { 1764 RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 1765 RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 1766 LLVMInitializeARMAsmLexer(); 1767} 1768 1769#define GET_REGISTER_MATCHER 1770#define GET_MATCHER_IMPLEMENTATION 1771#include "ARMGenAsmMatcher.inc" 1772