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