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