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