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