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