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