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