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