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