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