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