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