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