ARMAsmParser.cpp revision e98d646b1194c522b121e1a70906efe4ea578fc8
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 return -1; 775} 776 777/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The 778/// token must be an Identifier when called, and if it is a coprocessor 779/// number, the token is eaten and the operand is added to the operand list. 780ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 781tryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 782 SMLoc S = Parser.getTok().getLoc(); 783 const AsmToken &Tok = Parser.getTok(); 784 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 785 786 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 787 if (Num == -1) 788 return MatchOperand_NoMatch; 789 790 Parser.Lex(); // Eat identifier token. 791 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 792 return MatchOperand_Success; 793} 794 795/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The 796/// token must be an Identifier when called, and if it is a coprocessor 797/// number, the token is eaten and the operand is added to the operand list. 798ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 799tryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 800 SMLoc S = Parser.getTok().getLoc(); 801 const AsmToken &Tok = Parser.getTok(); 802 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 803 804 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 805 if (Reg == -1) 806 return MatchOperand_NoMatch; 807 808 Parser.Lex(); // Eat identifier token. 809 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 810 return MatchOperand_Success; 811} 812 813/// Parse a register list, return it if successful else return null. The first 814/// token must be a '{' when called. 815bool ARMAsmParser:: 816ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 817 assert(Parser.getTok().is(AsmToken::LCurly) && 818 "Token is not a Left Curly Brace"); 819 SMLoc S = Parser.getTok().getLoc(); 820 821 // Read the rest of the registers in the list. 822 unsigned PrevRegNum = 0; 823 SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 824 825 do { 826 bool IsRange = Parser.getTok().is(AsmToken::Minus); 827 Parser.Lex(); // Eat non-identifier token. 828 829 const AsmToken &RegTok = Parser.getTok(); 830 SMLoc RegLoc = RegTok.getLoc(); 831 if (RegTok.isNot(AsmToken::Identifier)) { 832 Error(RegLoc, "register expected"); 833 return true; 834 } 835 836 int RegNum = TryParseRegister(); 837 if (RegNum == -1) { 838 Error(RegLoc, "register expected"); 839 return true; 840 } 841 842 if (IsRange) { 843 int Reg = PrevRegNum; 844 do { 845 ++Reg; 846 Registers.push_back(std::make_pair(Reg, RegLoc)); 847 } while (Reg != RegNum); 848 } else { 849 Registers.push_back(std::make_pair(RegNum, RegLoc)); 850 } 851 852 PrevRegNum = RegNum; 853 } while (Parser.getTok().is(AsmToken::Comma) || 854 Parser.getTok().is(AsmToken::Minus)); 855 856 // Process the right curly brace of the list. 857 const AsmToken &RCurlyTok = Parser.getTok(); 858 if (RCurlyTok.isNot(AsmToken::RCurly)) { 859 Error(RCurlyTok.getLoc(), "'}' expected"); 860 return true; 861 } 862 863 SMLoc E = RCurlyTok.getLoc(); 864 Parser.Lex(); // Eat right curly brace token. 865 866 // Verify the register list. 867 SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 868 RI = Registers.begin(), RE = Registers.end(); 869 870 unsigned HighRegNum = getARMRegisterNumbering(RI->first); 871 bool EmittedWarning = false; 872 873 DenseMap<unsigned, bool> RegMap; 874 RegMap[HighRegNum] = true; 875 876 for (++RI; RI != RE; ++RI) { 877 const std::pair<unsigned, SMLoc> &RegInfo = *RI; 878 unsigned Reg = getARMRegisterNumbering(RegInfo.first); 879 880 if (RegMap[Reg]) { 881 Error(RegInfo.second, "register duplicated in register list"); 882 return true; 883 } 884 885 if (!EmittedWarning && Reg < HighRegNum) 886 Warning(RegInfo.second, 887 "register not in ascending order in register list"); 888 889 RegMap[Reg] = true; 890 HighRegNum = std::max(Reg, HighRegNum); 891 } 892 893 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 894 return false; 895} 896 897/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 898ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 899tryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 900 SMLoc S = Parser.getTok().getLoc(); 901 const AsmToken &Tok = Parser.getTok(); 902 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 903 StringRef OptStr = Tok.getString(); 904 905 unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 906 .Case("sy", ARM_MB::SY) 907 .Case("st", ARM_MB::ST) 908 .Case("ish", ARM_MB::ISH) 909 .Case("ishst", ARM_MB::ISHST) 910 .Case("nsh", ARM_MB::NSH) 911 .Case("nshst", ARM_MB::NSHST) 912 .Case("osh", ARM_MB::OSH) 913 .Case("oshst", ARM_MB::OSHST) 914 .Default(~0U); 915 916 if (Opt == ~0U) 917 return MatchOperand_NoMatch; 918 919 Parser.Lex(); // Eat identifier token. 920 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 921 return MatchOperand_Success; 922} 923 924/// ParseProcIFlagsOperand - Try to parse iflags from CPS instruction. 925ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 926tryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 927 SMLoc S = Parser.getTok().getLoc(); 928 const AsmToken &Tok = Parser.getTok(); 929 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 930 StringRef IFlagsStr = Tok.getString(); 931 932 unsigned IFlags = 0; 933 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 934 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 935 .Case("a", ARM_PROC::A) 936 .Case("i", ARM_PROC::I) 937 .Case("f", ARM_PROC::F) 938 .Default(~0U); 939 940 // If some specific iflag is already set, it means that some letter is 941 // present more than once, this is not acceptable. 942 if (Flag == ~0U || (IFlags & Flag)) 943 return MatchOperand_NoMatch; 944 945 IFlags |= Flag; 946 } 947 948 Parser.Lex(); // Eat identifier token. 949 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 950 return MatchOperand_Success; 951} 952 953/// Parse an ARM memory expression, return false if successful else return true 954/// or an error. The first token must be a '[' when called. 955/// 956/// TODO Only preindexing and postindexing addressing are started, unindexed 957/// with option, etc are still to do. 958bool ARMAsmParser:: 959ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 960 SMLoc S, E; 961 assert(Parser.getTok().is(AsmToken::LBrac) && 962 "Token is not a Left Bracket"); 963 S = Parser.getTok().getLoc(); 964 Parser.Lex(); // Eat left bracket token. 965 966 const AsmToken &BaseRegTok = Parser.getTok(); 967 if (BaseRegTok.isNot(AsmToken::Identifier)) { 968 Error(BaseRegTok.getLoc(), "register expected"); 969 return true; 970 } 971 int BaseRegNum = TryParseRegister(); 972 if (BaseRegNum == -1) { 973 Error(BaseRegTok.getLoc(), "register expected"); 974 return true; 975 } 976 977 // The next token must either be a comma or a closing bracket. 978 const AsmToken &Tok = Parser.getTok(); 979 if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 980 return true; 981 982 bool Preindexed = false; 983 bool Postindexed = false; 984 bool OffsetIsReg = false; 985 bool Negative = false; 986 bool Writeback = false; 987 ARMOperand *WBOp = 0; 988 int OffsetRegNum = -1; 989 bool OffsetRegShifted = false; 990 enum ShiftType ShiftType = Lsl; 991 const MCExpr *ShiftAmount = 0; 992 const MCExpr *Offset = 0; 993 994 // First look for preindexed address forms, that is after the "[Rn" we now 995 // have to see if the next token is a comma. 996 if (Tok.is(AsmToken::Comma)) { 997 Preindexed = true; 998 Parser.Lex(); // Eat comma token. 999 1000 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 1001 Offset, OffsetIsReg, OffsetRegNum, E)) 1002 return true; 1003 const AsmToken &RBracTok = Parser.getTok(); 1004 if (RBracTok.isNot(AsmToken::RBrac)) { 1005 Error(RBracTok.getLoc(), "']' expected"); 1006 return true; 1007 } 1008 E = RBracTok.getLoc(); 1009 Parser.Lex(); // Eat right bracket token. 1010 1011 const AsmToken &ExclaimTok = Parser.getTok(); 1012 if (ExclaimTok.is(AsmToken::Exclaim)) { 1013 WBOp = ARMOperand::CreateToken(ExclaimTok.getString(), 1014 ExclaimTok.getLoc()); 1015 Writeback = true; 1016 Parser.Lex(); // Eat exclaim token 1017 } 1018 } else { 1019 // The "[Rn" we have so far was not followed by a comma. 1020 1021 // If there's anything other than the right brace, this is a post indexing 1022 // addressing form. 1023 E = Tok.getLoc(); 1024 Parser.Lex(); // Eat right bracket token. 1025 1026 const AsmToken &NextTok = Parser.getTok(); 1027 1028 if (NextTok.isNot(AsmToken::EndOfStatement)) { 1029 Postindexed = true; 1030 Writeback = true; 1031 1032 if (NextTok.isNot(AsmToken::Comma)) { 1033 Error(NextTok.getLoc(), "',' expected"); 1034 return true; 1035 } 1036 1037 Parser.Lex(); // Eat comma token. 1038 1039 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 1040 ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 1041 E)) 1042 return true; 1043 } 1044 } 1045 1046 // Force Offset to exist if used. 1047 if (!OffsetIsReg) { 1048 if (!Offset) 1049 Offset = MCConstantExpr::Create(0, getContext()); 1050 } 1051 1052 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, 1053 OffsetRegNum, OffsetRegShifted, 1054 ShiftType, ShiftAmount, Preindexed, 1055 Postindexed, Negative, Writeback, 1056 S, E)); 1057 if (WBOp) 1058 Operands.push_back(WBOp); 1059 1060 return false; 1061} 1062 1063/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 1064/// we will parse the following (were +/- means that a plus or minus is 1065/// optional): 1066/// +/-Rm 1067/// +/-Rm, shift 1068/// #offset 1069/// we return false on success or an error otherwise. 1070bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 1071 bool &OffsetRegShifted, 1072 enum ShiftType &ShiftType, 1073 const MCExpr *&ShiftAmount, 1074 const MCExpr *&Offset, 1075 bool &OffsetIsReg, 1076 int &OffsetRegNum, 1077 SMLoc &E) { 1078 Negative = false; 1079 OffsetRegShifted = false; 1080 OffsetIsReg = false; 1081 OffsetRegNum = -1; 1082 const AsmToken &NextTok = Parser.getTok(); 1083 E = NextTok.getLoc(); 1084 if (NextTok.is(AsmToken::Plus)) 1085 Parser.Lex(); // Eat plus token. 1086 else if (NextTok.is(AsmToken::Minus)) { 1087 Negative = true; 1088 Parser.Lex(); // Eat minus token 1089 } 1090 // See if there is a register following the "[Rn," or "[Rn]," we have so far. 1091 const AsmToken &OffsetRegTok = Parser.getTok(); 1092 if (OffsetRegTok.is(AsmToken::Identifier)) { 1093 SMLoc CurLoc = OffsetRegTok.getLoc(); 1094 OffsetRegNum = TryParseRegister(); 1095 if (OffsetRegNum != -1) { 1096 OffsetIsReg = true; 1097 E = CurLoc; 1098 } 1099 } 1100 1101 // If we parsed a register as the offset then there can be a shift after that. 1102 if (OffsetRegNum != -1) { 1103 // Look for a comma then a shift 1104 const AsmToken &Tok = Parser.getTok(); 1105 if (Tok.is(AsmToken::Comma)) { 1106 Parser.Lex(); // Eat comma token. 1107 1108 const AsmToken &Tok = Parser.getTok(); 1109 if (ParseShift(ShiftType, ShiftAmount, E)) 1110 return Error(Tok.getLoc(), "shift expected"); 1111 OffsetRegShifted = true; 1112 } 1113 } 1114 else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 1115 // Look for #offset following the "[Rn," or "[Rn]," 1116 const AsmToken &HashTok = Parser.getTok(); 1117 if (HashTok.isNot(AsmToken::Hash)) 1118 return Error(HashTok.getLoc(), "'#' expected"); 1119 1120 Parser.Lex(); // Eat hash token. 1121 1122 if (getParser().ParseExpression(Offset)) 1123 return true; 1124 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1125 } 1126 return false; 1127} 1128 1129/// ParseShift as one of these two: 1130/// ( lsl | lsr | asr | ror ) , # shift_amount 1131/// rrx 1132/// and returns true if it parses a shift otherwise it returns false. 1133bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount, 1134 SMLoc &E) { 1135 const AsmToken &Tok = Parser.getTok(); 1136 if (Tok.isNot(AsmToken::Identifier)) 1137 return true; 1138 StringRef ShiftName = Tok.getString(); 1139 if (ShiftName == "lsl" || ShiftName == "LSL") 1140 St = Lsl; 1141 else if (ShiftName == "lsr" || ShiftName == "LSR") 1142 St = Lsr; 1143 else if (ShiftName == "asr" || ShiftName == "ASR") 1144 St = Asr; 1145 else if (ShiftName == "ror" || ShiftName == "ROR") 1146 St = Ror; 1147 else if (ShiftName == "rrx" || ShiftName == "RRX") 1148 St = Rrx; 1149 else 1150 return true; 1151 Parser.Lex(); // Eat shift type token. 1152 1153 // Rrx stands alone. 1154 if (St == Rrx) 1155 return false; 1156 1157 // Otherwise, there must be a '#' and a shift amount. 1158 const AsmToken &HashTok = Parser.getTok(); 1159 if (HashTok.isNot(AsmToken::Hash)) 1160 return Error(HashTok.getLoc(), "'#' expected"); 1161 Parser.Lex(); // Eat hash token. 1162 1163 if (getParser().ParseExpression(ShiftAmount)) 1164 return true; 1165 1166 return false; 1167} 1168 1169/// Parse a arm instruction operand. For now this parses the operand regardless 1170/// of the mnemonic. 1171bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1172 StringRef Mnemonic) { 1173 SMLoc S, E; 1174 1175 // Check if the current operand has a custom associated parser, if so, try to 1176 // custom parse the operand, or fallback to the general approach. 1177 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1178 if (ResTy == MatchOperand_Success) 1179 return false; 1180 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1181 // there was a match, but an error occurred, in which case, just return that 1182 // the operand parsing failed. 1183 if (ResTy == MatchOperand_ParseFail) 1184 return true; 1185 1186 switch (getLexer().getKind()) { 1187 default: 1188 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1189 return true; 1190 case AsmToken::Identifier: 1191 if (!TryParseRegisterWithWriteBack(Operands)) 1192 return false; 1193 1194 // Fall though for the Identifier case that is not a register or a 1195 // special name. 1196 case AsmToken::Integer: // things like 1f and 2b as a branch targets 1197 case AsmToken::Dot: { // . as a branch target 1198 // This was not a register so parse other operands that start with an 1199 // identifier (like labels) as expressions and create them as immediates. 1200 const MCExpr *IdVal; 1201 S = Parser.getTok().getLoc(); 1202 if (getParser().ParseExpression(IdVal)) 1203 return true; 1204 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1205 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 1206 return false; 1207 } 1208 case AsmToken::LBrac: 1209 return ParseMemory(Operands); 1210 case AsmToken::LCurly: 1211 return ParseRegisterList(Operands); 1212 case AsmToken::Hash: 1213 // #42 -> immediate. 1214 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 1215 S = Parser.getTok().getLoc(); 1216 Parser.Lex(); 1217 const MCExpr *ImmVal; 1218 if (getParser().ParseExpression(ImmVal)) 1219 return true; 1220 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1221 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 1222 return false; 1223 case AsmToken::Colon: { 1224 // ":lower16:" and ":upper16:" expression prefixes 1225 // FIXME: Check it's an expression prefix, 1226 // e.g. (FOO - :lower16:BAR) isn't legal. 1227 ARMMCExpr::VariantKind RefKind; 1228 if (ParsePrefix(RefKind)) 1229 return true; 1230 1231 const MCExpr *SubExprVal; 1232 if (getParser().ParseExpression(SubExprVal)) 1233 return true; 1234 1235 const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 1236 getContext()); 1237 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1238 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 1239 return false; 1240 } 1241 } 1242} 1243 1244// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 1245// :lower16: and :upper16:. 1246bool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) { 1247 RefKind = ARMMCExpr::VK_ARM_None; 1248 1249 // :lower16: and :upper16: modifiers 1250 assert(getLexer().is(AsmToken::Colon) && "expected a :"); 1251 Parser.Lex(); // Eat ':' 1252 1253 if (getLexer().isNot(AsmToken::Identifier)) { 1254 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 1255 return true; 1256 } 1257 1258 StringRef IDVal = Parser.getTok().getIdentifier(); 1259 if (IDVal == "lower16") { 1260 RefKind = ARMMCExpr::VK_ARM_LO16; 1261 } else if (IDVal == "upper16") { 1262 RefKind = ARMMCExpr::VK_ARM_HI16; 1263 } else { 1264 Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 1265 return true; 1266 } 1267 Parser.Lex(); 1268 1269 if (getLexer().isNot(AsmToken::Colon)) { 1270 Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 1271 return true; 1272 } 1273 Parser.Lex(); // Eat the last ':' 1274 return false; 1275} 1276 1277const MCExpr * 1278ARMAsmParser::ApplyPrefixToExpr(const MCExpr *E, 1279 MCSymbolRefExpr::VariantKind Variant) { 1280 // Recurse over the given expression, rebuilding it to apply the given variant 1281 // to the leftmost symbol. 1282 if (Variant == MCSymbolRefExpr::VK_None) 1283 return E; 1284 1285 switch (E->getKind()) { 1286 case MCExpr::Target: 1287 llvm_unreachable("Can't handle target expr yet"); 1288 case MCExpr::Constant: 1289 llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 1290 1291 case MCExpr::SymbolRef: { 1292 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 1293 1294 if (SRE->getKind() != MCSymbolRefExpr::VK_None) 1295 return 0; 1296 1297 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 1298 } 1299 1300 case MCExpr::Unary: 1301 llvm_unreachable("Can't handle unary expressions yet"); 1302 1303 case MCExpr::Binary: { 1304 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 1305 const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant); 1306 const MCExpr *RHS = BE->getRHS(); 1307 if (!LHS) 1308 return 0; 1309 1310 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 1311 } 1312 } 1313 1314 assert(0 && "Invalid expression kind!"); 1315 return 0; 1316} 1317 1318/// \brief Given a mnemonic, split out possible predication code and carry 1319/// setting letters to form a canonical mnemonic and flags. 1320// 1321// FIXME: Would be nice to autogen this. 1322static StringRef SplitMnemonic(StringRef Mnemonic, 1323 unsigned &PredicationCode, 1324 bool &CarrySetting, 1325 unsigned &ProcessorIMod) { 1326 PredicationCode = ARMCC::AL; 1327 CarrySetting = false; 1328 ProcessorIMod = 0; 1329 1330 // Ignore some mnemonics we know aren't predicated forms. 1331 // 1332 // FIXME: Would be nice to autogen this. 1333 if (Mnemonic == "teq" || Mnemonic == "vceq" || 1334 Mnemonic == "movs" || 1335 Mnemonic == "svc" || 1336 (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 1337 Mnemonic == "vmls" || Mnemonic == "vnmls") || 1338 Mnemonic == "vacge" || Mnemonic == "vcge" || 1339 Mnemonic == "vclt" || 1340 Mnemonic == "vacgt" || Mnemonic == "vcgt" || 1341 Mnemonic == "vcle" || 1342 (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" || 1343 Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" || 1344 Mnemonic == "vqdmlal")) 1345 return Mnemonic; 1346 1347 // First, split out any predication code. 1348 unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 1349 .Case("eq", ARMCC::EQ) 1350 .Case("ne", ARMCC::NE) 1351 .Case("hs", ARMCC::HS) 1352 .Case("lo", ARMCC::LO) 1353 .Case("mi", ARMCC::MI) 1354 .Case("pl", ARMCC::PL) 1355 .Case("vs", ARMCC::VS) 1356 .Case("vc", ARMCC::VC) 1357 .Case("hi", ARMCC::HI) 1358 .Case("ls", ARMCC::LS) 1359 .Case("ge", ARMCC::GE) 1360 .Case("lt", ARMCC::LT) 1361 .Case("gt", ARMCC::GT) 1362 .Case("le", ARMCC::LE) 1363 .Case("al", ARMCC::AL) 1364 .Default(~0U); 1365 if (CC != ~0U) { 1366 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 1367 PredicationCode = CC; 1368 } 1369 1370 // Next, determine if we have a carry setting bit. We explicitly ignore all 1371 // the instructions we know end in 's'. 1372 if (Mnemonic.endswith("s") && 1373 !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 1374 Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" || 1375 Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" || 1376 Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" || 1377 Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) { 1378 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 1379 CarrySetting = true; 1380 } 1381 1382 // The "cps" instruction can have a interrupt mode operand which is glued into 1383 // the mnemonic. Check if this is the case, split it and parse the imod op 1384 if (Mnemonic.startswith("cps")) { 1385 // Split out any imod code. 1386 unsigned IMod = 1387 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 1388 .Case("ie", ARM_PROC::IE) 1389 .Case("id", ARM_PROC::ID) 1390 .Default(~0U); 1391 if (IMod != ~0U) { 1392 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 1393 ProcessorIMod = IMod; 1394 } 1395 } 1396 1397 return Mnemonic; 1398} 1399 1400/// \brief Given a canonical mnemonic, determine if the instruction ever allows 1401/// inclusion of carry set or predication code operands. 1402// 1403// FIXME: It would be nice to autogen this. 1404void ARMAsmParser:: 1405GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 1406 bool &CanAcceptPredicationCode) { 1407 bool isThumb = TM.getSubtarget<ARMSubtarget>().isThumb(); 1408 1409 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 1410 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 1411 Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 1412 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 1413 Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mov" || 1414 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 1415 Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 1416 Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "mvn") { 1417 CanAcceptCarrySet = true; 1418 } else { 1419 CanAcceptCarrySet = false; 1420 } 1421 1422 if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 1423 Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 1424 Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 1425 Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 1426 Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" || 1427 Mnemonic == "clrex" || Mnemonic.startswith("cps")) { 1428 CanAcceptPredicationCode = false; 1429 } else { 1430 CanAcceptPredicationCode = true; 1431 } 1432 1433 if (isThumb) 1434 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 1435 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 1436 CanAcceptPredicationCode = false; 1437} 1438 1439/// Parse an arm instruction mnemonic followed by its operands. 1440bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 1441 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1442 // Create the leading tokens for the mnemonic, split by '.' characters. 1443 size_t Start = 0, Next = Name.find('.'); 1444 StringRef Head = Name.slice(Start, Next); 1445 1446 // Split out the predication code and carry setting flag from the mnemonic. 1447 unsigned PredicationCode; 1448 unsigned ProcessorIMod; 1449 bool CarrySetting; 1450 Head = SplitMnemonic(Head, PredicationCode, CarrySetting, 1451 ProcessorIMod); 1452 1453 Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 1454 1455 // Next, add the CCOut and ConditionCode operands, if needed. 1456 // 1457 // For mnemonics which can ever incorporate a carry setting bit or predication 1458 // code, our matching model involves us always generating CCOut and 1459 // ConditionCode operands to match the mnemonic "as written" and then we let 1460 // the matcher deal with finding the right instruction or generating an 1461 // appropriate error. 1462 bool CanAcceptCarrySet, CanAcceptPredicationCode; 1463 GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode); 1464 1465 // Add the carry setting operand, if necessary. 1466 // 1467 // FIXME: It would be awesome if we could somehow invent a location such that 1468 // match errors on this operand would print a nice diagnostic about how the 1469 // 's' character in the mnemonic resulted in a CCOut operand. 1470 if (CanAcceptCarrySet) { 1471 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 1472 NameLoc)); 1473 } else { 1474 // This mnemonic can't ever accept a carry set, but the user wrote one (or 1475 // misspelled another mnemonic). 1476 1477 // FIXME: Issue a nice error. 1478 } 1479 1480 // Add the predication code operand, if necessary. 1481 if (CanAcceptPredicationCode) { 1482 Operands.push_back(ARMOperand::CreateCondCode( 1483 ARMCC::CondCodes(PredicationCode), NameLoc)); 1484 } else { 1485 // This mnemonic can't ever accept a predication code, but the user wrote 1486 // one (or misspelled another mnemonic). 1487 1488 // FIXME: Issue a nice error. 1489 } 1490 1491 // Add the processor imod operand, if necessary. 1492 if (ProcessorIMod) { 1493 Operands.push_back(ARMOperand::CreateImm( 1494 MCConstantExpr::Create(ProcessorIMod, getContext()), 1495 NameLoc, NameLoc)); 1496 } else { 1497 // This mnemonic can't ever accept a imod, but the user wrote 1498 // one (or misspelled another mnemonic). 1499 1500 // FIXME: Issue a nice error. 1501 } 1502 1503 // Add the remaining tokens in the mnemonic. 1504 while (Next != StringRef::npos) { 1505 Start = Next; 1506 Next = Name.find('.', Start + 1); 1507 StringRef ExtraToken = Name.slice(Start, Next); 1508 1509 Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 1510 } 1511 1512 // Read the remaining operands. 1513 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1514 // Read the first operand. 1515 if (ParseOperand(Operands, Head)) { 1516 Parser.EatToEndOfStatement(); 1517 return true; 1518 } 1519 1520 while (getLexer().is(AsmToken::Comma)) { 1521 Parser.Lex(); // Eat the comma. 1522 1523 // Parse and remember the operand. 1524 if (ParseOperand(Operands, Head)) { 1525 Parser.EatToEndOfStatement(); 1526 return true; 1527 } 1528 } 1529 } 1530 1531 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1532 Parser.EatToEndOfStatement(); 1533 return TokError("unexpected token in argument list"); 1534 } 1535 1536 Parser.Lex(); // Consume the EndOfStatement 1537 return false; 1538} 1539 1540bool ARMAsmParser:: 1541MatchAndEmitInstruction(SMLoc IDLoc, 1542 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1543 MCStreamer &Out) { 1544 MCInst Inst; 1545 unsigned ErrorInfo; 1546 MatchResultTy MatchResult, MatchResult2; 1547 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1548 if (MatchResult != Match_Success) { 1549 // If we get a Match_InvalidOperand it might be some arithmetic instruction 1550 // that does not update the condition codes. So try adding a CCOut operand 1551 // with a value of reg0. 1552 if (MatchResult == Match_InvalidOperand) { 1553 Operands.insert(Operands.begin() + 1, 1554 ARMOperand::CreateCCOut(0, 1555 ((ARMOperand*)Operands[0])->getStartLoc())); 1556 MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1557 if (MatchResult2 == Match_Success) 1558 MatchResult = Match_Success; 1559 else { 1560 ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 1561 Operands.erase(Operands.begin() + 1); 1562 delete CCOut; 1563 } 1564 } 1565 // If we get a Match_MnemonicFail it might be some arithmetic instruction 1566 // that updates the condition codes if it ends in 's'. So see if the 1567 // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut 1568 // operand with a value of CPSR. 1569 else if(MatchResult == Match_MnemonicFail) { 1570 // Get the instruction mnemonic, which is the first token. 1571 StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken(); 1572 if (Mnemonic.substr(Mnemonic.size()-1) == "s") { 1573 // removed the 's' from the mnemonic for matching. 1574 StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1); 1575 SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc(); 1576 ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 1577 Operands.erase(Operands.begin()); 1578 delete OldMnemonic; 1579 Operands.insert(Operands.begin(), 1580 ARMOperand::CreateToken(MnemonicNoS, NameLoc)); 1581 Operands.insert(Operands.begin() + 1, 1582 ARMOperand::CreateCCOut(ARM::CPSR, NameLoc)); 1583 MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1584 if (MatchResult2 == Match_Success) 1585 MatchResult = Match_Success; 1586 else { 1587 ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 1588 Operands.erase(Operands.begin()); 1589 delete OldMnemonic; 1590 Operands.insert(Operands.begin(), 1591 ARMOperand::CreateToken(Mnemonic, NameLoc)); 1592 ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 1593 Operands.erase(Operands.begin() + 1); 1594 delete CCOut; 1595 } 1596 } 1597 } 1598 } 1599 switch (MatchResult) { 1600 case Match_Success: 1601 Out.EmitInstruction(Inst); 1602 return false; 1603 case Match_MissingFeature: 1604 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1605 return true; 1606 case Match_InvalidOperand: { 1607 SMLoc ErrorLoc = IDLoc; 1608 if (ErrorInfo != ~0U) { 1609 if (ErrorInfo >= Operands.size()) 1610 return Error(IDLoc, "too few operands for instruction"); 1611 1612 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 1613 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 1614 } 1615 1616 return Error(ErrorLoc, "invalid operand for instruction"); 1617 } 1618 case Match_MnemonicFail: 1619 return Error(IDLoc, "unrecognized instruction mnemonic"); 1620 case Match_ConversionFail: 1621 return Error(IDLoc, "unable to convert operands to instruction"); 1622 } 1623 1624 llvm_unreachable("Implement any new match types added!"); 1625 return true; 1626} 1627 1628/// ParseDirective parses the arm specific directives 1629bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 1630 StringRef IDVal = DirectiveID.getIdentifier(); 1631 if (IDVal == ".word") 1632 return ParseDirectiveWord(4, DirectiveID.getLoc()); 1633 else if (IDVal == ".thumb") 1634 return ParseDirectiveThumb(DirectiveID.getLoc()); 1635 else if (IDVal == ".thumb_func") 1636 return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 1637 else if (IDVal == ".code") 1638 return ParseDirectiveCode(DirectiveID.getLoc()); 1639 else if (IDVal == ".syntax") 1640 return ParseDirectiveSyntax(DirectiveID.getLoc()); 1641 return true; 1642} 1643 1644/// ParseDirectiveWord 1645/// ::= .word [ expression (, expression)* ] 1646bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 1647 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1648 for (;;) { 1649 const MCExpr *Value; 1650 if (getParser().ParseExpression(Value)) 1651 return true; 1652 1653 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 1654 1655 if (getLexer().is(AsmToken::EndOfStatement)) 1656 break; 1657 1658 // FIXME: Improve diagnostic. 1659 if (getLexer().isNot(AsmToken::Comma)) 1660 return Error(L, "unexpected token in directive"); 1661 Parser.Lex(); 1662 } 1663 } 1664 1665 Parser.Lex(); 1666 return false; 1667} 1668 1669/// ParseDirectiveThumb 1670/// ::= .thumb 1671bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 1672 if (getLexer().isNot(AsmToken::EndOfStatement)) 1673 return Error(L, "unexpected token in directive"); 1674 Parser.Lex(); 1675 1676 // TODO: set thumb mode 1677 // TODO: tell the MC streamer the mode 1678 // getParser().getStreamer().Emit???(); 1679 return false; 1680} 1681 1682/// ParseDirectiveThumbFunc 1683/// ::= .thumbfunc symbol_name 1684bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 1685 const AsmToken &Tok = Parser.getTok(); 1686 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 1687 return Error(L, "unexpected token in .thumb_func directive"); 1688 StringRef Name = Tok.getString(); 1689 Parser.Lex(); // Consume the identifier token. 1690 if (getLexer().isNot(AsmToken::EndOfStatement)) 1691 return Error(L, "unexpected token in directive"); 1692 Parser.Lex(); 1693 1694 // Mark symbol as a thumb symbol. 1695 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 1696 getParser().getStreamer().EmitThumbFunc(Func); 1697 return false; 1698} 1699 1700/// ParseDirectiveSyntax 1701/// ::= .syntax unified | divided 1702bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 1703 const AsmToken &Tok = Parser.getTok(); 1704 if (Tok.isNot(AsmToken::Identifier)) 1705 return Error(L, "unexpected token in .syntax directive"); 1706 StringRef Mode = Tok.getString(); 1707 if (Mode == "unified" || Mode == "UNIFIED") 1708 Parser.Lex(); 1709 else if (Mode == "divided" || Mode == "DIVIDED") 1710 return Error(L, "'.syntax divided' arm asssembly not supported"); 1711 else 1712 return Error(L, "unrecognized syntax mode in .syntax directive"); 1713 1714 if (getLexer().isNot(AsmToken::EndOfStatement)) 1715 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 1716 Parser.Lex(); 1717 1718 // TODO tell the MC streamer the mode 1719 // getParser().getStreamer().Emit???(); 1720 return false; 1721} 1722 1723/// ParseDirectiveCode 1724/// ::= .code 16 | 32 1725bool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 1726 const AsmToken &Tok = Parser.getTok(); 1727 if (Tok.isNot(AsmToken::Integer)) 1728 return Error(L, "unexpected token in .code directive"); 1729 int64_t Val = Parser.getTok().getIntVal(); 1730 if (Val == 16) 1731 Parser.Lex(); 1732 else if (Val == 32) 1733 Parser.Lex(); 1734 else 1735 return Error(L, "invalid operand to .code directive"); 1736 1737 if (getLexer().isNot(AsmToken::EndOfStatement)) 1738 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 1739 Parser.Lex(); 1740 1741 // FIXME: We need to be able switch subtargets at this point so that 1742 // MatchInstructionImpl() will work when it gets the AvailableFeatures which 1743 // includes Feature_IsThumb or not to match the right instructions. This is 1744 // blocked on the FIXME in llvm-mc.cpp when creating the TargetMachine. 1745 if (Val == 16){ 1746 assert(TM.getSubtarget<ARMSubtarget>().isThumb() && 1747 "switching between arm/thumb not yet suppported via .code 16)"); 1748 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 1749 } 1750 else{ 1751 assert(!TM.getSubtarget<ARMSubtarget>().isThumb() && 1752 "switching between thumb/arm not yet suppported via .code 32)"); 1753 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 1754 } 1755 1756 return false; 1757} 1758 1759extern "C" void LLVMInitializeARMAsmLexer(); 1760 1761/// Force static initialization. 1762extern "C" void LLVMInitializeARMAsmParser() { 1763 RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 1764 RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 1765 LLVMInitializeARMAsmLexer(); 1766} 1767 1768#define GET_REGISTER_MATCHER 1769#define GET_MATCHER_IMPLEMENTATION 1770#include "ARMGenAsmMatcher.inc" 1771