ARMAsmParser.cpp revision d1f0bbee189ea7cd18d03c4f9f55d0a33b070814
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" || Mnemonic == "bics")) 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("cs", ARMCC::HS) 1773 .Case("lo", ARMCC::LO) 1774 .Case("cc", ARMCC::LO) 1775 .Case("mi", ARMCC::MI) 1776 .Case("pl", ARMCC::PL) 1777 .Case("vs", ARMCC::VS) 1778 .Case("vc", ARMCC::VC) 1779 .Case("hi", ARMCC::HI) 1780 .Case("ls", ARMCC::LS) 1781 .Case("ge", ARMCC::GE) 1782 .Case("lt", ARMCC::LT) 1783 .Case("gt", ARMCC::GT) 1784 .Case("le", ARMCC::LE) 1785 .Case("al", ARMCC::AL) 1786 .Default(~0U); 1787 if (CC != ~0U) { 1788 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 1789 PredicationCode = CC; 1790 } 1791 1792 // Next, determine if we have a carry setting bit. We explicitly ignore all 1793 // the instructions we know end in 's'. 1794 if (Mnemonic.endswith("s") && 1795 !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 1796 Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" || 1797 Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" || 1798 Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" || 1799 Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) { 1800 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 1801 CarrySetting = true; 1802 } 1803 1804 // The "cps" instruction can have a interrupt mode operand which is glued into 1805 // the mnemonic. Check if this is the case, split it and parse the imod op 1806 if (Mnemonic.startswith("cps")) { 1807 // Split out any imod code. 1808 unsigned IMod = 1809 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 1810 .Case("ie", ARM_PROC::IE) 1811 .Case("id", ARM_PROC::ID) 1812 .Default(~0U); 1813 if (IMod != ~0U) { 1814 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 1815 ProcessorIMod = IMod; 1816 } 1817 } 1818 1819 return Mnemonic; 1820} 1821 1822/// \brief Given a canonical mnemonic, determine if the instruction ever allows 1823/// inclusion of carry set or predication code operands. 1824// 1825// FIXME: It would be nice to autogen this. 1826void ARMAsmParser:: 1827GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 1828 bool &CanAcceptPredicationCode) { 1829 bool isThumb = TM.getSubtarget<ARMSubtarget>().isThumb(); 1830 1831 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 1832 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 1833 Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 1834 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 1835 Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 1836 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 1837 Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 1838 Mnemonic == "eor" || Mnemonic == "smlal" || 1839 (Mnemonic == "mov" && !isThumb)) { 1840 CanAcceptCarrySet = true; 1841 } else { 1842 CanAcceptCarrySet = false; 1843 } 1844 1845 if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 1846 Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 1847 Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 1848 Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 1849 Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" || 1850 Mnemonic == "clrex" || Mnemonic.startswith("cps")) { 1851 CanAcceptPredicationCode = false; 1852 } else { 1853 CanAcceptPredicationCode = true; 1854 } 1855 1856 if (isThumb) 1857 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 1858 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp" || 1859 Mnemonic == "mov") 1860 CanAcceptPredicationCode = false; 1861} 1862 1863/// Parse an arm instruction mnemonic followed by its operands. 1864bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 1865 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1866 // Create the leading tokens for the mnemonic, split by '.' characters. 1867 size_t Start = 0, Next = Name.find('.'); 1868 StringRef Head = Name.slice(Start, Next); 1869 1870 // Split out the predication code and carry setting flag from the mnemonic. 1871 unsigned PredicationCode; 1872 unsigned ProcessorIMod; 1873 bool CarrySetting; 1874 Head = SplitMnemonic(Head, PredicationCode, CarrySetting, 1875 ProcessorIMod); 1876 1877 Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 1878 1879 // Next, add the CCOut and ConditionCode operands, if needed. 1880 // 1881 // For mnemonics which can ever incorporate a carry setting bit or predication 1882 // code, our matching model involves us always generating CCOut and 1883 // ConditionCode operands to match the mnemonic "as written" and then we let 1884 // the matcher deal with finding the right instruction or generating an 1885 // appropriate error. 1886 bool CanAcceptCarrySet, CanAcceptPredicationCode; 1887 GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode); 1888 1889 // Add the carry setting operand, if necessary. 1890 // 1891 // FIXME: It would be awesome if we could somehow invent a location such that 1892 // match errors on this operand would print a nice diagnostic about how the 1893 // 's' character in the mnemonic resulted in a CCOut operand. 1894 if (CanAcceptCarrySet) { 1895 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 1896 NameLoc)); 1897 } else { 1898 // This mnemonic can't ever accept a carry set, but the user wrote one (or 1899 // misspelled another mnemonic). 1900 1901 // FIXME: Issue a nice error. 1902 } 1903 1904 // Add the predication code operand, if necessary. 1905 if (CanAcceptPredicationCode) { 1906 Operands.push_back(ARMOperand::CreateCondCode( 1907 ARMCC::CondCodes(PredicationCode), NameLoc)); 1908 } else { 1909 // This mnemonic can't ever accept a predication code, but the user wrote 1910 // one (or misspelled another mnemonic). 1911 1912 // FIXME: Issue a nice error. 1913 } 1914 1915 // Add the processor imod operand, if necessary. 1916 if (ProcessorIMod) { 1917 Operands.push_back(ARMOperand::CreateImm( 1918 MCConstantExpr::Create(ProcessorIMod, getContext()), 1919 NameLoc, NameLoc)); 1920 } else { 1921 // This mnemonic can't ever accept a imod, but the user wrote 1922 // one (or misspelled another mnemonic). 1923 1924 // FIXME: Issue a nice error. 1925 } 1926 1927 // Add the remaining tokens in the mnemonic. 1928 while (Next != StringRef::npos) { 1929 Start = Next; 1930 Next = Name.find('.', Start + 1); 1931 StringRef ExtraToken = Name.slice(Start, Next); 1932 1933 Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 1934 } 1935 1936 // Read the remaining operands. 1937 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1938 // Read the first operand. 1939 if (ParseOperand(Operands, Head)) { 1940 Parser.EatToEndOfStatement(); 1941 return true; 1942 } 1943 1944 while (getLexer().is(AsmToken::Comma)) { 1945 Parser.Lex(); // Eat the comma. 1946 1947 // Parse and remember the operand. 1948 if (ParseOperand(Operands, Head)) { 1949 Parser.EatToEndOfStatement(); 1950 return true; 1951 } 1952 } 1953 } 1954 1955 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1956 Parser.EatToEndOfStatement(); 1957 return TokError("unexpected token in argument list"); 1958 } 1959 1960 Parser.Lex(); // Consume the EndOfStatement 1961 return false; 1962} 1963 1964bool ARMAsmParser:: 1965MatchAndEmitInstruction(SMLoc IDLoc, 1966 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1967 MCStreamer &Out) { 1968 MCInst Inst; 1969 unsigned ErrorInfo; 1970 MatchResultTy MatchResult, MatchResult2; 1971 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1972 if (MatchResult != Match_Success) { 1973 // If we get a Match_InvalidOperand it might be some arithmetic instruction 1974 // that does not update the condition codes. So try adding a CCOut operand 1975 // with a value of reg0. 1976 if (MatchResult == Match_InvalidOperand) { 1977 Operands.insert(Operands.begin() + 1, 1978 ARMOperand::CreateCCOut(0, 1979 ((ARMOperand*)Operands[0])->getStartLoc())); 1980 MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1981 if (MatchResult2 == Match_Success) 1982 MatchResult = Match_Success; 1983 else { 1984 ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 1985 Operands.erase(Operands.begin() + 1); 1986 delete CCOut; 1987 } 1988 } 1989 // If we get a Match_MnemonicFail it might be some arithmetic instruction 1990 // that updates the condition codes if it ends in 's'. So see if the 1991 // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut 1992 // operand with a value of CPSR. 1993 else if(MatchResult == Match_MnemonicFail) { 1994 // Get the instruction mnemonic, which is the first token. 1995 StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken(); 1996 if (Mnemonic.substr(Mnemonic.size()-1) == "s") { 1997 // removed the 's' from the mnemonic for matching. 1998 StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1); 1999 SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc(); 2000 ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 2001 Operands.erase(Operands.begin()); 2002 delete OldMnemonic; 2003 Operands.insert(Operands.begin(), 2004 ARMOperand::CreateToken(MnemonicNoS, NameLoc)); 2005 Operands.insert(Operands.begin() + 1, 2006 ARMOperand::CreateCCOut(ARM::CPSR, NameLoc)); 2007 MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2008 if (MatchResult2 == Match_Success) 2009 MatchResult = Match_Success; 2010 else { 2011 ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 2012 Operands.erase(Operands.begin()); 2013 delete OldMnemonic; 2014 Operands.insert(Operands.begin(), 2015 ARMOperand::CreateToken(Mnemonic, NameLoc)); 2016 ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 2017 Operands.erase(Operands.begin() + 1); 2018 delete CCOut; 2019 } 2020 } 2021 } 2022 } 2023 switch (MatchResult) { 2024 case Match_Success: 2025 Out.EmitInstruction(Inst); 2026 return false; 2027 case Match_MissingFeature: 2028 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2029 return true; 2030 case Match_InvalidOperand: { 2031 SMLoc ErrorLoc = IDLoc; 2032 if (ErrorInfo != ~0U) { 2033 if (ErrorInfo >= Operands.size()) 2034 return Error(IDLoc, "too few operands for instruction"); 2035 2036 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2037 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2038 } 2039 2040 return Error(ErrorLoc, "invalid operand for instruction"); 2041 } 2042 case Match_MnemonicFail: 2043 return Error(IDLoc, "unrecognized instruction mnemonic"); 2044 case Match_ConversionFail: 2045 return Error(IDLoc, "unable to convert operands to instruction"); 2046 } 2047 2048 llvm_unreachable("Implement any new match types added!"); 2049 return true; 2050} 2051 2052/// ParseDirective parses the arm specific directives 2053bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2054 StringRef IDVal = DirectiveID.getIdentifier(); 2055 if (IDVal == ".word") 2056 return ParseDirectiveWord(4, DirectiveID.getLoc()); 2057 else if (IDVal == ".thumb") 2058 return ParseDirectiveThumb(DirectiveID.getLoc()); 2059 else if (IDVal == ".thumb_func") 2060 return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 2061 else if (IDVal == ".code") 2062 return ParseDirectiveCode(DirectiveID.getLoc()); 2063 else if (IDVal == ".syntax") 2064 return ParseDirectiveSyntax(DirectiveID.getLoc()); 2065 return true; 2066} 2067 2068/// ParseDirectiveWord 2069/// ::= .word [ expression (, expression)* ] 2070bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 2071 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2072 for (;;) { 2073 const MCExpr *Value; 2074 if (getParser().ParseExpression(Value)) 2075 return true; 2076 2077 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2078 2079 if (getLexer().is(AsmToken::EndOfStatement)) 2080 break; 2081 2082 // FIXME: Improve diagnostic. 2083 if (getLexer().isNot(AsmToken::Comma)) 2084 return Error(L, "unexpected token in directive"); 2085 Parser.Lex(); 2086 } 2087 } 2088 2089 Parser.Lex(); 2090 return false; 2091} 2092 2093/// ParseDirectiveThumb 2094/// ::= .thumb 2095bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 2096 if (getLexer().isNot(AsmToken::EndOfStatement)) 2097 return Error(L, "unexpected token in directive"); 2098 Parser.Lex(); 2099 2100 // TODO: set thumb mode 2101 // TODO: tell the MC streamer the mode 2102 // getParser().getStreamer().Emit???(); 2103 return false; 2104} 2105 2106/// ParseDirectiveThumbFunc 2107/// ::= .thumbfunc symbol_name 2108bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 2109 const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 2110 bool isMachO = MAI.hasSubsectionsViaSymbols(); 2111 StringRef Name; 2112 2113 // Darwin asm has function name after .thumb_func direction 2114 // ELF doesn't 2115 if (isMachO) { 2116 const AsmToken &Tok = Parser.getTok(); 2117 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 2118 return Error(L, "unexpected token in .thumb_func directive"); 2119 Name = Tok.getString(); 2120 Parser.Lex(); // Consume the identifier token. 2121 } 2122 2123 if (getLexer().isNot(AsmToken::EndOfStatement)) 2124 return Error(L, "unexpected token in directive"); 2125 Parser.Lex(); 2126 2127 // FIXME: assuming function name will be the line following .thumb_func 2128 if (!isMachO) { 2129 Name = Parser.getTok().getString(); 2130 } 2131 2132 // Mark symbol as a thumb symbol. 2133 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2134 getParser().getStreamer().EmitThumbFunc(Func); 2135 return false; 2136} 2137 2138/// ParseDirectiveSyntax 2139/// ::= .syntax unified | divided 2140bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 2141 const AsmToken &Tok = Parser.getTok(); 2142 if (Tok.isNot(AsmToken::Identifier)) 2143 return Error(L, "unexpected token in .syntax directive"); 2144 StringRef Mode = Tok.getString(); 2145 if (Mode == "unified" || Mode == "UNIFIED") 2146 Parser.Lex(); 2147 else if (Mode == "divided" || Mode == "DIVIDED") 2148 return Error(L, "'.syntax divided' arm asssembly not supported"); 2149 else 2150 return Error(L, "unrecognized syntax mode in .syntax directive"); 2151 2152 if (getLexer().isNot(AsmToken::EndOfStatement)) 2153 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2154 Parser.Lex(); 2155 2156 // TODO tell the MC streamer the mode 2157 // getParser().getStreamer().Emit???(); 2158 return false; 2159} 2160 2161/// ParseDirectiveCode 2162/// ::= .code 16 | 32 2163bool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 2164 const AsmToken &Tok = Parser.getTok(); 2165 if (Tok.isNot(AsmToken::Integer)) 2166 return Error(L, "unexpected token in .code directive"); 2167 int64_t Val = Parser.getTok().getIntVal(); 2168 if (Val == 16) 2169 Parser.Lex(); 2170 else if (Val == 32) 2171 Parser.Lex(); 2172 else 2173 return Error(L, "invalid operand to .code directive"); 2174 2175 if (getLexer().isNot(AsmToken::EndOfStatement)) 2176 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2177 Parser.Lex(); 2178 2179 // FIXME: We need to be able switch subtargets at this point so that 2180 // MatchInstructionImpl() will work when it gets the AvailableFeatures which 2181 // includes Feature_IsThumb or not to match the right instructions. This is 2182 // blocked on the FIXME in llvm-mc.cpp when creating the TargetMachine. 2183 if (Val == 16){ 2184 assert(TM.getSubtarget<ARMSubtarget>().isThumb() && 2185 "switching between arm/thumb not yet suppported via .code 16)"); 2186 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 2187 } 2188 else{ 2189 assert(!TM.getSubtarget<ARMSubtarget>().isThumb() && 2190 "switching between thumb/arm not yet suppported via .code 32)"); 2191 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2192 } 2193 2194 return false; 2195} 2196 2197extern "C" void LLVMInitializeARMAsmLexer(); 2198 2199/// Force static initialization. 2200extern "C" void LLVMInitializeARMAsmParser() { 2201 RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 2202 RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 2203 LLVMInitializeARMAsmLexer(); 2204} 2205 2206#define GET_REGISTER_MATCHER 2207#define GET_MATCHER_IMPLEMENTATION 2208#include "ARMGenAsmMatcher.inc" 2209