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