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