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