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