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