ARMAsmParser.cpp revision 03f44a04e63ff77af12df33e10ffdc473609dfe2
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 "ARMSubtarget.h" 13#include "llvm/MC/MCParser/MCAsmLexer.h" 14#include "llvm/MC/MCParser/MCAsmParser.h" 15#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 16#include "llvm/MC/MCContext.h" 17#include "llvm/MC/MCStreamer.h" 18#include "llvm/MC/MCExpr.h" 19#include "llvm/MC/MCInst.h" 20#include "llvm/Target/TargetRegistry.h" 21#include "llvm/Target/TargetAsmParser.h" 22#include "llvm/Support/SourceMgr.h" 23#include "llvm/Support/raw_ostream.h" 24#include "llvm/ADT/SmallVector.h" 25#include "llvm/ADT/StringSwitch.h" 26#include "llvm/ADT/Twine.h" 27using namespace llvm; 28 29// The shift types for register controlled shifts in arm memory addressing 30enum ShiftType { 31 Lsl, 32 Lsr, 33 Asr, 34 Ror, 35 Rrx 36}; 37 38namespace { 39 40class ARMOperand; 41 42class ARMAsmParser : public TargetAsmParser { 43 MCAsmParser &Parser; 44 TargetMachine &TM; 45 46 MCAsmParser &getParser() const { return Parser; } 47 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 48 49 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 50 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 51 52 int TryParseRegister(); 53 bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 54 bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 55 bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 56 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &); 57 58 bool ParseMemoryOffsetReg(bool &Negative, 59 bool &OffsetRegShifted, 60 enum ShiftType &ShiftType, 61 const MCExpr *&ShiftAmount, 62 const MCExpr *&Offset, 63 bool &OffsetIsReg, 64 int &OffsetRegNum, 65 SMLoc &E); 66 bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E); 67 bool ParseDirectiveWord(unsigned Size, SMLoc L); 68 bool ParseDirectiveThumb(SMLoc L); 69 bool ParseDirectiveThumbFunc(SMLoc L); 70 bool ParseDirectiveCode(SMLoc L); 71 bool ParseDirectiveSyntax(SMLoc L); 72 73 bool MatchAndEmitInstruction(SMLoc IDLoc, 74 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 75 MCStreamer &Out); 76 77 /// @name Auto-generated Match Functions 78 /// { 79 80#define GET_ASSEMBLER_HEADER 81#include "ARMGenAsmMatcher.inc" 82 83 /// } 84 85public: 86 ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) 87 : TargetAsmParser(T), Parser(_Parser), TM(_TM) { 88 // Initialize the set of available features. 89 setAvailableFeatures(ComputeAvailableFeatures( 90 &TM.getSubtarget<ARMSubtarget>())); 91 } 92 93 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 94 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 95 virtual bool ParseDirective(AsmToken DirectiveID); 96}; 97} // end anonymous namespace 98 99namespace { 100 101/// ARMOperand - Instances of this class represent a parsed ARM machine 102/// instruction. 103class ARMOperand : public MCParsedAsmOperand { 104 enum KindTy { 105 CondCode, 106 Immediate, 107 Memory, 108 Register, 109 RegisterList, 110 DPRRegisterList, 111 SPRRegisterList, 112 Token 113 } Kind; 114 115 SMLoc StartLoc, EndLoc; 116 SmallVector<unsigned, 8> Registers; 117 118 union { 119 struct { 120 ARMCC::CondCodes Val; 121 } CC; 122 123 struct { 124 const char *Data; 125 unsigned Length; 126 } Tok; 127 128 struct { 129 unsigned RegNum; 130 } Reg; 131 132 struct { 133 const MCExpr *Val; 134 } Imm; 135 136 // This is for all forms of ARM address expressions 137 struct { 138 unsigned BaseRegNum; 139 unsigned OffsetRegNum; // used when OffsetIsReg is true 140 const MCExpr *Offset; // used when OffsetIsReg is false 141 const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 142 enum ShiftType ShiftType; // used when OffsetRegShifted is true 143 unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true 144 unsigned Preindexed : 1; 145 unsigned Postindexed : 1; 146 unsigned OffsetIsReg : 1; 147 unsigned Negative : 1; // only used when OffsetIsReg is true 148 unsigned Writeback : 1; 149 } Mem; 150 }; 151 152 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 153public: 154 ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 155 Kind = o.Kind; 156 StartLoc = o.StartLoc; 157 EndLoc = o.EndLoc; 158 switch (Kind) { 159 case CondCode: 160 CC = o.CC; 161 break; 162 case Token: 163 Tok = o.Tok; 164 break; 165 case Register: 166 Reg = o.Reg; 167 break; 168 case RegisterList: 169 case DPRRegisterList: 170 case SPRRegisterList: 171 Registers = o.Registers; 172 break; 173 case Immediate: 174 Imm = o.Imm; 175 break; 176 case Memory: 177 Mem = o.Mem; 178 break; 179 } 180 } 181 182 /// getStartLoc - Get the location of the first token of this operand. 183 SMLoc getStartLoc() const { return StartLoc; } 184 /// getEndLoc - Get the location of the last token of this operand. 185 SMLoc getEndLoc() const { return EndLoc; } 186 187 ARMCC::CondCodes getCondCode() const { 188 assert(Kind == CondCode && "Invalid access!"); 189 return CC.Val; 190 } 191 192 StringRef getToken() const { 193 assert(Kind == Token && "Invalid access!"); 194 return StringRef(Tok.Data, Tok.Length); 195 } 196 197 unsigned getReg() const { 198 assert(Kind == Register && "Invalid access!"); 199 return Reg.RegNum; 200 } 201 202 const SmallVectorImpl<unsigned> &getRegList() const { 203 assert((Kind == RegisterList || Kind == DPRRegisterList || 204 Kind == SPRRegisterList) && "Invalid access!"); 205 return Registers; 206 } 207 208 const MCExpr *getImm() const { 209 assert(Kind == Immediate && "Invalid access!"); 210 return Imm.Val; 211 } 212 213 bool isCondCode() const { return Kind == CondCode; } 214 bool isImm() const { return Kind == Immediate; } 215 bool isReg() const { return Kind == Register; } 216 bool isRegList() const { return Kind == RegisterList; } 217 bool isDPRRegList() const { return Kind == DPRRegisterList; } 218 bool isSPRRegList() const { return Kind == SPRRegisterList; } 219 bool isToken() const { return Kind == Token; } 220 bool isMemory() const { return Kind == Memory; } 221 bool isMemMode5() const { 222 if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted || 223 Mem.Writeback || Mem.Negative) 224 return false; 225 // If there is an offset expression, make sure it's valid. 226 if (!Mem.Offset) 227 return true; 228 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset); 229 if (!CE) 230 return false; 231 // The offset must be a multiple of 4 in the range 0-1020. 232 int64_t Value = CE->getValue(); 233 return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); 234 } 235 236 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 237 // Add as immediates when possible. Null MCExpr = 0. 238 if (Expr == 0) 239 Inst.addOperand(MCOperand::CreateImm(0)); 240 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 241 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 242 else 243 Inst.addOperand(MCOperand::CreateExpr(Expr)); 244 } 245 246 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 247 assert(N == 2 && "Invalid number of operands!"); 248 Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 249 // FIXME: What belongs here? 250 Inst.addOperand(MCOperand::CreateReg(0)); 251 } 252 253 void addRegOperands(MCInst &Inst, unsigned N) const { 254 assert(N == 1 && "Invalid number of operands!"); 255 Inst.addOperand(MCOperand::CreateReg(getReg())); 256 } 257 258 void addRegListOperands(MCInst &Inst, unsigned N) const { 259 assert(N == 1 && "Invalid number of operands!"); 260 const SmallVectorImpl<unsigned> &RegList = getRegList(); 261 for (SmallVectorImpl<unsigned>::const_iterator 262 I = RegList.begin(), E = RegList.end(); I != E; ++I) 263 Inst.addOperand(MCOperand::CreateReg(*I)); 264 } 265 266 void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 267 addRegListOperands(Inst, N); 268 } 269 270 void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 271 addRegListOperands(Inst, N); 272 } 273 274 void addImmOperands(MCInst &Inst, unsigned N) const { 275 assert(N == 1 && "Invalid number of operands!"); 276 addExpr(Inst, getImm()); 277 } 278 279 void addMemMode5Operands(MCInst &Inst, unsigned N) const { 280 assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 281 282 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 283 assert(!Mem.OffsetIsReg && "Invalid mode 5 operand"); 284 285 // FIXME: #-0 is encoded differently than #0. Does the parser preserve 286 // the difference? 287 if (Mem.Offset) { 288 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset); 289 assert(CE && "Non-constant mode 5 offset operand!"); 290 291 // The MCInst offset operand doesn't include the low two bits (like 292 // the instruction encoding). 293 int64_t Offset = CE->getValue() / 4; 294 if (Offset >= 0) 295 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, 296 Offset))); 297 else 298 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, 299 -Offset))); 300 } else { 301 Inst.addOperand(MCOperand::CreateImm(0)); 302 } 303 } 304 305 virtual void dump(raw_ostream &OS) const; 306 307 static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 308 ARMOperand *Op = new ARMOperand(CondCode); 309 Op->CC.Val = CC; 310 Op->StartLoc = S; 311 Op->EndLoc = S; 312 return Op; 313 } 314 315 static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 316 ARMOperand *Op = new ARMOperand(Token); 317 Op->Tok.Data = Str.data(); 318 Op->Tok.Length = Str.size(); 319 Op->StartLoc = S; 320 Op->EndLoc = S; 321 return Op; 322 } 323 324 static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 325 ARMOperand *Op = new ARMOperand(Register); 326 Op->Reg.RegNum = RegNum; 327 Op->StartLoc = S; 328 Op->EndLoc = E; 329 return Op; 330 } 331 332 static ARMOperand * 333 CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 334 SMLoc StartLoc, SMLoc EndLoc) { 335 KindTy Kind = RegisterList; 336 337 if (ARM::DPRRegClass.contains(Regs.front().first)) 338 Kind = DPRRegisterList; 339 else if (ARM::SPRRegClass.contains(Regs.front().first)) 340 Kind = SPRRegisterList; 341 342 ARMOperand *Op = new ARMOperand(Kind); 343 for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 344 I = Regs.begin(), E = Regs.end(); I != E; ++I) 345 Op->Registers.push_back(I->first); 346 array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 347 Op->StartLoc = StartLoc; 348 Op->EndLoc = EndLoc; 349 return Op; 350 } 351 352 static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 353 ARMOperand *Op = new ARMOperand(Immediate); 354 Op->Imm.Val = Val; 355 Op->StartLoc = S; 356 Op->EndLoc = E; 357 return Op; 358 } 359 360 static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, 361 const MCExpr *Offset, unsigned OffsetRegNum, 362 bool OffsetRegShifted, enum ShiftType ShiftType, 363 const MCExpr *ShiftAmount, bool Preindexed, 364 bool Postindexed, bool Negative, bool Writeback, 365 SMLoc S, SMLoc E) { 366 ARMOperand *Op = new ARMOperand(Memory); 367 Op->Mem.BaseRegNum = BaseRegNum; 368 Op->Mem.OffsetIsReg = OffsetIsReg; 369 Op->Mem.Offset = Offset; 370 Op->Mem.OffsetRegNum = OffsetRegNum; 371 Op->Mem.OffsetRegShifted = OffsetRegShifted; 372 Op->Mem.ShiftType = ShiftType; 373 Op->Mem.ShiftAmount = ShiftAmount; 374 Op->Mem.Preindexed = Preindexed; 375 Op->Mem.Postindexed = Postindexed; 376 Op->Mem.Negative = Negative; 377 Op->Mem.Writeback = Writeback; 378 379 Op->StartLoc = S; 380 Op->EndLoc = E; 381 return Op; 382 } 383}; 384 385} // end anonymous namespace. 386 387void ARMOperand::dump(raw_ostream &OS) const { 388 switch (Kind) { 389 case CondCode: 390 OS << ARMCondCodeToString(getCondCode()); 391 break; 392 case Immediate: 393 getImm()->print(OS); 394 break; 395 case Memory: 396 OS << "<memory>"; 397 break; 398 case Register: 399 OS << "<register " << getReg() << ">"; 400 break; 401 case RegisterList: 402 case DPRRegisterList: 403 case SPRRegisterList: { 404 OS << "<register_list "; 405 406 const SmallVectorImpl<unsigned> &RegList = getRegList(); 407 for (SmallVectorImpl<unsigned>::const_iterator 408 I = RegList.begin(), E = RegList.end(); I != E; ) { 409 OS << *I; 410 if (++I < E) OS << ", "; 411 } 412 413 OS << ">"; 414 break; 415 } 416 case Token: 417 OS << "'" << getToken() << "'"; 418 break; 419 } 420} 421 422/// @name Auto-generated Match Functions 423/// { 424 425static unsigned MatchRegisterName(StringRef Name); 426 427/// } 428 429/// Try to parse a register name. The token must be an Identifier when called, 430/// and if it is a register name the token is eaten and the register number is 431/// returned. Otherwise return -1. 432/// 433int ARMAsmParser::TryParseRegister() { 434 const AsmToken &Tok = Parser.getTok(); 435 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 436 437 // FIXME: Validate register for the current architecture; we have to do 438 // validation later, so maybe there is no need for this here. 439 unsigned RegNum = MatchRegisterName(Tok.getString()); 440 if (RegNum == 0) 441 return -1; 442 Parser.Lex(); // Eat identifier token. 443 return RegNum; 444} 445 446 447/// Try to parse a register name. The token must be an Identifier when called. 448/// If it's a register, an AsmOperand is created. Another AsmOperand is created 449/// if there is a "writeback". 'true' if it's not a register. 450/// 451/// TODO this is likely to change to allow different register types and or to 452/// parse for a specific register type. 453bool ARMAsmParser:: 454TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 455 SMLoc S = Parser.getTok().getLoc(); 456 int RegNo = TryParseRegister(); 457 if (RegNo == -1) 458 return true; 459 460 Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 461 462 const AsmToken &ExclaimTok = Parser.getTok(); 463 if (ExclaimTok.is(AsmToken::Exclaim)) { 464 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 465 ExclaimTok.getLoc())); 466 Parser.Lex(); // Eat exclaim token 467 } 468 469 return false; 470} 471 472/// Parse a register list, return it if successful else return null. The first 473/// token must be a '{' when called. 474bool ARMAsmParser:: 475ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 476 assert(Parser.getTok().is(AsmToken::LCurly) && 477 "Token is not a Left Curly Brace"); 478 SMLoc S = Parser.getTok().getLoc(); 479 480 // Read the rest of the registers in the list. 481 unsigned PrevRegNum = 0; 482 SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 483 484 do { 485 bool IsRange = Parser.getTok().is(AsmToken::Minus); 486 Parser.Lex(); // Eat non-identifier token. 487 488 const AsmToken &RegTok = Parser.getTok(); 489 SMLoc RegLoc = RegTok.getLoc(); 490 if (RegTok.isNot(AsmToken::Identifier)) { 491 Error(RegLoc, "register expected"); 492 return true; 493 } 494 495 int RegNum = TryParseRegister(); 496 if (RegNum == -1) { 497 Error(RegLoc, "register expected"); 498 return true; 499 } 500 501 if (IsRange) { 502 int Reg = PrevRegNum; 503 do { 504 ++Reg; 505 Registers.push_back(std::make_pair(Reg, RegLoc)); 506 } while (Reg != RegNum); 507 } else { 508 Registers.push_back(std::make_pair(RegNum, RegLoc)); 509 } 510 511 PrevRegNum = RegNum; 512 } while (Parser.getTok().is(AsmToken::Comma) || 513 Parser.getTok().is(AsmToken::Minus)); 514 515 // Process the right curly brace of the list. 516 const AsmToken &RCurlyTok = Parser.getTok(); 517 if (RCurlyTok.isNot(AsmToken::RCurly)) { 518 Error(RCurlyTok.getLoc(), "'}' expected"); 519 return true; 520 } 521 522 SMLoc E = RCurlyTok.getLoc(); 523 Parser.Lex(); // Eat right curly brace token. 524 525 // Verify the register list. 526 SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 527 RI = Registers.begin(), RE = Registers.end(); 528 529 DenseMap<unsigned, bool> RegMap; 530 RegMap[RI->first] = true; 531 532 unsigned HighRegNum = RI->first; 533 bool EmittedWarning = false; 534 535 for (++RI; RI != RE; ++RI) { 536 const std::pair<unsigned, SMLoc> &RegInfo = *RI; 537 unsigned Reg = RegInfo.first; 538 539 if (RegMap[Reg]) { 540 Error(RegInfo.second, "register duplicated in register list"); 541 return true; 542 } 543 544 if (!EmittedWarning && Reg < HighRegNum) 545 Warning(RegInfo.second, 546 "register not in ascending order in register list"); 547 548 RegMap[Reg] = true; 549 HighRegNum = std::max(Reg, HighRegNum); 550 } 551 552 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 553 return false; 554} 555 556/// Parse an ARM memory expression, return false if successful else return true 557/// or an error. The first token must be a '[' when called. 558/// 559/// TODO Only preindexing and postindexing addressing are started, unindexed 560/// with option, etc are still to do. 561bool ARMAsmParser:: 562ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 563 SMLoc S, E; 564 assert(Parser.getTok().is(AsmToken::LBrac) && 565 "Token is not a Left Bracket"); 566 S = Parser.getTok().getLoc(); 567 Parser.Lex(); // Eat left bracket token. 568 569 const AsmToken &BaseRegTok = Parser.getTok(); 570 if (BaseRegTok.isNot(AsmToken::Identifier)) { 571 Error(BaseRegTok.getLoc(), "register expected"); 572 return true; 573 } 574 int BaseRegNum = TryParseRegister(); 575 if (BaseRegNum == -1) { 576 Error(BaseRegTok.getLoc(), "register expected"); 577 return true; 578 } 579 580 bool Preindexed = false; 581 bool Postindexed = false; 582 bool OffsetIsReg = false; 583 bool Negative = false; 584 bool Writeback = false; 585 586 // First look for preindexed address forms, that is after the "[Rn" we now 587 // have to see if the next token is a comma. 588 const AsmToken &Tok = Parser.getTok(); 589 if (Tok.is(AsmToken::Comma)) { 590 Preindexed = true; 591 Parser.Lex(); // Eat comma token. 592 int OffsetRegNum; 593 bool OffsetRegShifted; 594 enum ShiftType ShiftType; 595 const MCExpr *ShiftAmount; 596 const MCExpr *Offset; 597 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 598 Offset, OffsetIsReg, OffsetRegNum, E)) 599 return true; 600 const AsmToken &RBracTok = Parser.getTok(); 601 if (RBracTok.isNot(AsmToken::RBrac)) { 602 Error(RBracTok.getLoc(), "']' expected"); 603 return true; 604 } 605 E = RBracTok.getLoc(); 606 Parser.Lex(); // Eat right bracket token. 607 608 609 const AsmToken &ExclaimTok = Parser.getTok(); 610 ARMOperand *WBOp = 0; 611 if (ExclaimTok.is(AsmToken::Exclaim)) { 612 WBOp = ARMOperand::CreateToken(ExclaimTok.getString(), 613 ExclaimTok.getLoc()); 614 Writeback = true; 615 Parser.Lex(); // Eat exclaim token 616 } 617 618 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, 619 OffsetRegNum, OffsetRegShifted, 620 ShiftType, ShiftAmount, Preindexed, 621 Postindexed, Negative, Writeback, 622 S, E)); 623 if (WBOp) 624 Operands.push_back(WBOp); 625 626 return false; 627 } 628 // The "[Rn" we have so far was not followed by a comma. 629 else if (Tok.is(AsmToken::RBrac)) { 630 // If there's anything other than the right brace, this is a post indexing 631 // addressing form. 632 E = Tok.getLoc(); 633 Parser.Lex(); // Eat right bracket token. 634 635 int OffsetRegNum = 0; 636 bool OffsetRegShifted = false; 637 enum ShiftType ShiftType; 638 const MCExpr *ShiftAmount; 639 const MCExpr *Offset = 0; 640 641 const AsmToken &NextTok = Parser.getTok(); 642 643 if (NextTok.isNot(AsmToken::EndOfStatement)) { 644 Postindexed = true; 645 Writeback = true; 646 647 if (NextTok.isNot(AsmToken::Comma)) { 648 Error(NextTok.getLoc(), "',' expected"); 649 return true; 650 } 651 652 Parser.Lex(); // Eat comma token. 653 654 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 655 ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 656 E)) 657 return true; 658 } 659 660 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, 661 OffsetRegNum, OffsetRegShifted, 662 ShiftType, ShiftAmount, Preindexed, 663 Postindexed, Negative, Writeback, 664 S, E)); 665 return false; 666 } 667 668 return true; 669} 670 671/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 672/// we will parse the following (were +/- means that a plus or minus is 673/// optional): 674/// +/-Rm 675/// +/-Rm, shift 676/// #offset 677/// we return false on success or an error otherwise. 678bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 679 bool &OffsetRegShifted, 680 enum ShiftType &ShiftType, 681 const MCExpr *&ShiftAmount, 682 const MCExpr *&Offset, 683 bool &OffsetIsReg, 684 int &OffsetRegNum, 685 SMLoc &E) { 686 Negative = false; 687 OffsetRegShifted = false; 688 OffsetIsReg = false; 689 OffsetRegNum = -1; 690 const AsmToken &NextTok = Parser.getTok(); 691 E = NextTok.getLoc(); 692 if (NextTok.is(AsmToken::Plus)) 693 Parser.Lex(); // Eat plus token. 694 else if (NextTok.is(AsmToken::Minus)) { 695 Negative = true; 696 Parser.Lex(); // Eat minus token 697 } 698 // See if there is a register following the "[Rn," or "[Rn]," we have so far. 699 const AsmToken &OffsetRegTok = Parser.getTok(); 700 if (OffsetRegTok.is(AsmToken::Identifier)) { 701 SMLoc CurLoc = OffsetRegTok.getLoc(); 702 OffsetRegNum = TryParseRegister(); 703 if (OffsetRegNum != -1) { 704 OffsetIsReg = true; 705 E = CurLoc; 706 } 707 } 708 709 // If we parsed a register as the offset then there can be a shift after that. 710 if (OffsetRegNum != -1) { 711 // Look for a comma then a shift 712 const AsmToken &Tok = Parser.getTok(); 713 if (Tok.is(AsmToken::Comma)) { 714 Parser.Lex(); // Eat comma token. 715 716 const AsmToken &Tok = Parser.getTok(); 717 if (ParseShift(ShiftType, ShiftAmount, E)) 718 return Error(Tok.getLoc(), "shift expected"); 719 OffsetRegShifted = true; 720 } 721 } 722 else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 723 // Look for #offset following the "[Rn," or "[Rn]," 724 const AsmToken &HashTok = Parser.getTok(); 725 if (HashTok.isNot(AsmToken::Hash)) 726 return Error(HashTok.getLoc(), "'#' expected"); 727 728 Parser.Lex(); // Eat hash token. 729 730 if (getParser().ParseExpression(Offset)) 731 return true; 732 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 733 } 734 return false; 735} 736 737/// ParseShift as one of these two: 738/// ( lsl | lsr | asr | ror ) , # shift_amount 739/// rrx 740/// and returns true if it parses a shift otherwise it returns false. 741bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount, 742 SMLoc &E) { 743 const AsmToken &Tok = Parser.getTok(); 744 if (Tok.isNot(AsmToken::Identifier)) 745 return true; 746 StringRef ShiftName = Tok.getString(); 747 if (ShiftName == "lsl" || ShiftName == "LSL") 748 St = Lsl; 749 else if (ShiftName == "lsr" || ShiftName == "LSR") 750 St = Lsr; 751 else if (ShiftName == "asr" || ShiftName == "ASR") 752 St = Asr; 753 else if (ShiftName == "ror" || ShiftName == "ROR") 754 St = Ror; 755 else if (ShiftName == "rrx" || ShiftName == "RRX") 756 St = Rrx; 757 else 758 return true; 759 Parser.Lex(); // Eat shift type token. 760 761 // Rrx stands alone. 762 if (St == Rrx) 763 return false; 764 765 // Otherwise, there must be a '#' and a shift amount. 766 const AsmToken &HashTok = Parser.getTok(); 767 if (HashTok.isNot(AsmToken::Hash)) 768 return Error(HashTok.getLoc(), "'#' expected"); 769 Parser.Lex(); // Eat hash token. 770 771 if (getParser().ParseExpression(ShiftAmount)) 772 return true; 773 774 return false; 775} 776 777/// Parse a arm instruction operand. For now this parses the operand regardless 778/// of the mnemonic. 779bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands){ 780 SMLoc S, E; 781 switch (getLexer().getKind()) { 782 default: 783 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 784 return true; 785 case AsmToken::Identifier: { 786 if (!TryParseRegisterWithWriteBack(Operands)) 787 return false; 788 789 // This was not a register so parse other operands that start with an 790 // identifier (like labels) as expressions and create them as immediates. 791 const MCExpr *IdVal; 792 S = Parser.getTok().getLoc(); 793 if (getParser().ParseExpression(IdVal)) 794 return true; 795 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 796 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 797 return false; 798 } 799 case AsmToken::LBrac: 800 return ParseMemory(Operands); 801 case AsmToken::LCurly: 802 return ParseRegisterList(Operands); 803 case AsmToken::Hash: 804 // #42 -> immediate. 805 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 806 S = Parser.getTok().getLoc(); 807 Parser.Lex(); 808 const MCExpr *ImmVal; 809 if (getParser().ParseExpression(ImmVal)) 810 return true; 811 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 812 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 813 return false; 814 } 815} 816 817/// Parse an arm instruction mnemonic followed by its operands. 818bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 819 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 820 // Create the leading tokens for the mnemonic, split by '.' characters. 821 size_t Start = 0, Next = Name.find('.'); 822 StringRef Head = Name.slice(Start, Next); 823 824 // Determine the predicate, if any. 825 // 826 // FIXME: We need a way to check whether a prefix supports predication, 827 // otherwise we will end up with an ambiguity for instructions that happen to 828 // end with a predicate name. 829 // FIXME: Likewise, some arithmetic instructions have an 's' prefix which 830 // indicates to update the condition codes. Those instructions have an 831 // additional immediate operand which encodes the prefix as reg0 or CPSR. 832 // Just checking for a suffix of 's' definitely creates ambiguities; e.g, 833 // the SMMLS instruction. 834 unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2)) 835 .Case("eq", ARMCC::EQ) 836 .Case("ne", ARMCC::NE) 837 .Case("hs", ARMCC::HS) 838 .Case("lo", ARMCC::LO) 839 .Case("mi", ARMCC::MI) 840 .Case("pl", ARMCC::PL) 841 .Case("vs", ARMCC::VS) 842 .Case("vc", ARMCC::VC) 843 .Case("hi", ARMCC::HI) 844 .Case("ls", ARMCC::LS) 845 .Case("ge", ARMCC::GE) 846 .Case("lt", ARMCC::LT) 847 .Case("gt", ARMCC::GT) 848 .Case("le", ARMCC::LE) 849 .Case("al", ARMCC::AL) 850 .Default(~0U); 851 852 if (CC == ~0U || 853 (CC == ARMCC::LS && (Head == "vmls" || Head == "vnmls"))) { 854 CC = ARMCC::AL; 855 } else { 856 Head = Head.slice(0, Head.size() - 2); 857 } 858 859 Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 860 861 if (Head != "trap") 862 // FIXME: Should only add this operand for predicated instructions 863 Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), 864 NameLoc)); 865 866 // Add the remaining tokens in the mnemonic. 867 while (Next != StringRef::npos) { 868 Start = Next; 869 Next = Name.find('.', Start + 1); 870 Head = Name.slice(Start, Next); 871 872 Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 873 } 874 875 // Read the remaining operands. 876 if (getLexer().isNot(AsmToken::EndOfStatement)) { 877 // Read the first operand. 878 if (ParseOperand(Operands)) { 879 Parser.EatToEndOfStatement(); 880 return true; 881 } 882 883 while (getLexer().is(AsmToken::Comma)) { 884 Parser.Lex(); // Eat the comma. 885 886 // Parse and remember the operand. 887 if (ParseOperand(Operands)) { 888 Parser.EatToEndOfStatement(); 889 return true; 890 } 891 } 892 } 893 894 if (getLexer().isNot(AsmToken::EndOfStatement)) { 895 Parser.EatToEndOfStatement(); 896 return TokError("unexpected token in argument list"); 897 } 898 899 Parser.Lex(); // Consume the EndOfStatement 900 return false; 901} 902 903bool ARMAsmParser:: 904MatchAndEmitInstruction(SMLoc IDLoc, 905 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 906 MCStreamer &Out) { 907 MCInst Inst; 908 unsigned ErrorInfo; 909 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) { 910 case Match_Success: 911 Out.EmitInstruction(Inst); 912 return false; 913 case Match_MissingFeature: 914 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 915 return true; 916 case Match_InvalidOperand: { 917 SMLoc ErrorLoc = IDLoc; 918 if (ErrorInfo != ~0U) { 919 if (ErrorInfo >= Operands.size()) 920 return Error(IDLoc, "too few operands for instruction"); 921 922 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 923 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 924 } 925 926 return Error(ErrorLoc, "invalid operand for instruction"); 927 } 928 case Match_MnemonicFail: 929 return Error(IDLoc, "unrecognized instruction mnemonic"); 930 } 931 932 llvm_unreachable("Implement any new match types added!"); 933 return true; 934} 935 936/// ParseDirective parses the arm specific directives 937bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 938 StringRef IDVal = DirectiveID.getIdentifier(); 939 if (IDVal == ".word") 940 return ParseDirectiveWord(4, DirectiveID.getLoc()); 941 else if (IDVal == ".thumb") 942 return ParseDirectiveThumb(DirectiveID.getLoc()); 943 else if (IDVal == ".thumb_func") 944 return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 945 else if (IDVal == ".code") 946 return ParseDirectiveCode(DirectiveID.getLoc()); 947 else if (IDVal == ".syntax") 948 return ParseDirectiveSyntax(DirectiveID.getLoc()); 949 return true; 950} 951 952/// ParseDirectiveWord 953/// ::= .word [ expression (, expression)* ] 954bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 955 if (getLexer().isNot(AsmToken::EndOfStatement)) { 956 for (;;) { 957 const MCExpr *Value; 958 if (getParser().ParseExpression(Value)) 959 return true; 960 961 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 962 963 if (getLexer().is(AsmToken::EndOfStatement)) 964 break; 965 966 // FIXME: Improve diagnostic. 967 if (getLexer().isNot(AsmToken::Comma)) 968 return Error(L, "unexpected token in directive"); 969 Parser.Lex(); 970 } 971 } 972 973 Parser.Lex(); 974 return false; 975} 976 977/// ParseDirectiveThumb 978/// ::= .thumb 979bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 980 if (getLexer().isNot(AsmToken::EndOfStatement)) 981 return Error(L, "unexpected token in directive"); 982 Parser.Lex(); 983 984 // TODO: set thumb mode 985 // TODO: tell the MC streamer the mode 986 // getParser().getStreamer().Emit???(); 987 return false; 988} 989 990/// ParseDirectiveThumbFunc 991/// ::= .thumbfunc symbol_name 992bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 993 const AsmToken &Tok = Parser.getTok(); 994 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 995 return Error(L, "unexpected token in .thumb_func directive"); 996 StringRef Name = Tok.getString(); 997 Parser.Lex(); // Consume the identifier token. 998 if (getLexer().isNot(AsmToken::EndOfStatement)) 999 return Error(L, "unexpected token in directive"); 1000 Parser.Lex(); 1001 1002 // Mark symbol as a thumb symbol. 1003 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 1004 getParser().getStreamer().EmitThumbFunc(Func); 1005 return false; 1006} 1007 1008/// ParseDirectiveSyntax 1009/// ::= .syntax unified | divided 1010bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 1011 const AsmToken &Tok = Parser.getTok(); 1012 if (Tok.isNot(AsmToken::Identifier)) 1013 return Error(L, "unexpected token in .syntax directive"); 1014 StringRef Mode = Tok.getString(); 1015 if (Mode == "unified" || Mode == "UNIFIED") 1016 Parser.Lex(); 1017 else if (Mode == "divided" || Mode == "DIVIDED") 1018 Parser.Lex(); 1019 else 1020 return Error(L, "unrecognized syntax mode in .syntax directive"); 1021 1022 if (getLexer().isNot(AsmToken::EndOfStatement)) 1023 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 1024 Parser.Lex(); 1025 1026 // TODO tell the MC streamer the mode 1027 // getParser().getStreamer().Emit???(); 1028 return false; 1029} 1030 1031/// ParseDirectiveCode 1032/// ::= .code 16 | 32 1033bool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 1034 const AsmToken &Tok = Parser.getTok(); 1035 if (Tok.isNot(AsmToken::Integer)) 1036 return Error(L, "unexpected token in .code directive"); 1037 int64_t Val = Parser.getTok().getIntVal(); 1038 if (Val == 16) 1039 Parser.Lex(); 1040 else if (Val == 32) 1041 Parser.Lex(); 1042 else 1043 return Error(L, "invalid operand to .code directive"); 1044 1045 if (getLexer().isNot(AsmToken::EndOfStatement)) 1046 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 1047 Parser.Lex(); 1048 1049 if (Val == 16) 1050 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 1051 else 1052 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 1053 1054 return false; 1055} 1056 1057extern "C" void LLVMInitializeARMAsmLexer(); 1058 1059/// Force static initialization. 1060extern "C" void LLVMInitializeARMAsmParser() { 1061 RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 1062 RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 1063 LLVMInitializeARMAsmLexer(); 1064} 1065 1066#define GET_REGISTER_MATCHER 1067#define GET_MATCHER_IMPLEMENTATION 1068#include "ARMGenAsmMatcher.inc" 1069