ARMAsmParser.cpp revision f4fa3d6e463e88743983ccfa027a7555a8720917
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 "MCTargetDesc/ARMBaseInfo.h" 11#include "MCTargetDesc/ARMAddressingModes.h" 12#include "MCTargetDesc/ARMMCExpr.h" 13#include "llvm/MC/MCParser/MCAsmLexer.h" 14#include "llvm/MC/MCParser/MCAsmParser.h" 15#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 16#include "llvm/MC/MCAsmInfo.h" 17#include "llvm/MC/MCContext.h" 18#include "llvm/MC/MCStreamer.h" 19#include "llvm/MC/MCExpr.h" 20#include "llvm/MC/MCInst.h" 21#include "llvm/MC/MCRegisterInfo.h" 22#include "llvm/MC/MCSubtargetInfo.h" 23#include "llvm/MC/MCTargetAsmParser.h" 24#include "llvm/Target/TargetRegistry.h" 25#include "llvm/Support/SourceMgr.h" 26#include "llvm/Support/raw_ostream.h" 27#include "llvm/ADT/OwningPtr.h" 28#include "llvm/ADT/STLExtras.h" 29#include "llvm/ADT/SmallVector.h" 30#include "llvm/ADT/StringExtras.h" 31#include "llvm/ADT/StringSwitch.h" 32#include "llvm/ADT/Twine.h" 33 34using namespace llvm; 35 36namespace { 37 38class ARMOperand; 39 40class ARMAsmParser : public MCTargetAsmParser { 41 MCSubtargetInfo &STI; 42 MCAsmParser &Parser; 43 44 MCAsmParser &getParser() const { return Parser; } 45 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 46 47 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 48 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 49 50 int tryParseRegister(); 51 bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 52 int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 53 bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 54 bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 55 bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 56 bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 57 const MCExpr *applyPrefixToExpr(const MCExpr *E, 58 MCSymbolRefExpr::VariantKind Variant); 59 60 61 bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 62 unsigned &ShiftAmount); 63 bool parseDirectiveWord(unsigned Size, SMLoc L); 64 bool parseDirectiveThumb(SMLoc L); 65 bool parseDirectiveThumbFunc(SMLoc L); 66 bool parseDirectiveCode(SMLoc L); 67 bool parseDirectiveSyntax(SMLoc L); 68 69 StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 70 bool &CarrySetting, unsigned &ProcessorIMod); 71 void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 72 bool &CanAcceptPredicationCode); 73 74 bool isThumb() const { 75 // FIXME: Can tablegen auto-generate this? 76 return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 77 } 78 bool isThumbOne() const { 79 return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 80 } 81 void SwitchMode() { 82 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 83 setAvailableFeatures(FB); 84 } 85 86 /// @name Auto-generated Match Functions 87 /// { 88 89#define GET_ASSEMBLER_HEADER 90#include "ARMGenAsmMatcher.inc" 91 92 /// } 93 94 OperandMatchResultTy parseCoprocNumOperand( 95 SmallVectorImpl<MCParsedAsmOperand*>&); 96 OperandMatchResultTy parseCoprocRegOperand( 97 SmallVectorImpl<MCParsedAsmOperand*>&); 98 OperandMatchResultTy parseMemBarrierOptOperand( 99 SmallVectorImpl<MCParsedAsmOperand*>&); 100 OperandMatchResultTy parseProcIFlagsOperand( 101 SmallVectorImpl<MCParsedAsmOperand*>&); 102 OperandMatchResultTy parseMSRMaskOperand( 103 SmallVectorImpl<MCParsedAsmOperand*>&); 104 OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 105 StringRef Op, int Low, int High); 106 OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 107 return parsePKHImm(O, "lsl", 0, 31); 108 } 109 OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 110 return parsePKHImm(O, "asr", 1, 32); 111 } 112 OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 113 OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 114 OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 115 OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 116 OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 117 118 // Asm Match Converter Methods 119 bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 120 const SmallVectorImpl<MCParsedAsmOperand*> &); 121 bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 122 const SmallVectorImpl<MCParsedAsmOperand*> &); 123 bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 124 const SmallVectorImpl<MCParsedAsmOperand*> &); 125 bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 126 const SmallVectorImpl<MCParsedAsmOperand*> &); 127 bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 128 const SmallVectorImpl<MCParsedAsmOperand*> &); 129 bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 130 const SmallVectorImpl<MCParsedAsmOperand*> &); 131 132 bool validateInstruction(MCInst &Inst, 133 const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 134 135public: 136 ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 137 : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 138 MCAsmParserExtension::Initialize(_Parser); 139 140 // Initialize the set of available features. 141 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 142 } 143 144 // Implementation of the MCTargetAsmParser interface: 145 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 146 bool ParseInstruction(StringRef Name, SMLoc NameLoc, 147 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 148 bool ParseDirective(AsmToken DirectiveID); 149 150 bool MatchAndEmitInstruction(SMLoc IDLoc, 151 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 152 MCStreamer &Out); 153}; 154} // end anonymous namespace 155 156namespace { 157 158/// ARMOperand - Instances of this class represent a parsed ARM machine 159/// instruction. 160class ARMOperand : public MCParsedAsmOperand { 161 enum KindTy { 162 CondCode, 163 CCOut, 164 CoprocNum, 165 CoprocReg, 166 Immediate, 167 MemBarrierOpt, 168 Memory, 169 PostIndexRegister, 170 MSRMask, 171 ProcIFlags, 172 Register, 173 RegisterList, 174 DPRRegisterList, 175 SPRRegisterList, 176 ShiftedRegister, 177 ShiftedImmediate, 178 ShifterImmediate, 179 RotateImmediate, 180 BitfieldDescriptor, 181 Token 182 } Kind; 183 184 SMLoc StartLoc, EndLoc; 185 SmallVector<unsigned, 8> Registers; 186 187 union { 188 struct { 189 ARMCC::CondCodes Val; 190 } CC; 191 192 struct { 193 ARM_MB::MemBOpt Val; 194 } MBOpt; 195 196 struct { 197 unsigned Val; 198 } Cop; 199 200 struct { 201 ARM_PROC::IFlags Val; 202 } IFlags; 203 204 struct { 205 unsigned Val; 206 } MMask; 207 208 struct { 209 const char *Data; 210 unsigned Length; 211 } Tok; 212 213 struct { 214 unsigned RegNum; 215 } Reg; 216 217 struct { 218 const MCExpr *Val; 219 } Imm; 220 221 /// Combined record for all forms of ARM address expressions. 222 struct { 223 unsigned BaseRegNum; 224 // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 225 // was specified. 226 const MCConstantExpr *OffsetImm; // Offset immediate value 227 unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 228 ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 229 unsigned ShiftValue; // shift for OffsetReg. 230 unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 231 } Mem; 232 233 struct { 234 unsigned RegNum; 235 bool isAdd; 236 ARM_AM::ShiftOpc ShiftTy; 237 unsigned ShiftImm; 238 } PostIdxReg; 239 240 struct { 241 bool isASR; 242 unsigned Imm; 243 } ShifterImm; 244 struct { 245 ARM_AM::ShiftOpc ShiftTy; 246 unsigned SrcReg; 247 unsigned ShiftReg; 248 unsigned ShiftImm; 249 } RegShiftedReg; 250 struct { 251 ARM_AM::ShiftOpc ShiftTy; 252 unsigned SrcReg; 253 unsigned ShiftImm; 254 } RegShiftedImm; 255 struct { 256 unsigned Imm; 257 } RotImm; 258 struct { 259 unsigned LSB; 260 unsigned Width; 261 } Bitfield; 262 }; 263 264 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 265public: 266 ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 267 Kind = o.Kind; 268 StartLoc = o.StartLoc; 269 EndLoc = o.EndLoc; 270 switch (Kind) { 271 case CondCode: 272 CC = o.CC; 273 break; 274 case Token: 275 Tok = o.Tok; 276 break; 277 case CCOut: 278 case Register: 279 Reg = o.Reg; 280 break; 281 case RegisterList: 282 case DPRRegisterList: 283 case SPRRegisterList: 284 Registers = o.Registers; 285 break; 286 case CoprocNum: 287 case CoprocReg: 288 Cop = o.Cop; 289 break; 290 case Immediate: 291 Imm = o.Imm; 292 break; 293 case MemBarrierOpt: 294 MBOpt = o.MBOpt; 295 break; 296 case Memory: 297 Mem = o.Mem; 298 break; 299 case PostIndexRegister: 300 PostIdxReg = o.PostIdxReg; 301 break; 302 case MSRMask: 303 MMask = o.MMask; 304 break; 305 case ProcIFlags: 306 IFlags = o.IFlags; 307 break; 308 case ShifterImmediate: 309 ShifterImm = o.ShifterImm; 310 break; 311 case ShiftedRegister: 312 RegShiftedReg = o.RegShiftedReg; 313 break; 314 case ShiftedImmediate: 315 RegShiftedImm = o.RegShiftedImm; 316 break; 317 case RotateImmediate: 318 RotImm = o.RotImm; 319 break; 320 case BitfieldDescriptor: 321 Bitfield = o.Bitfield; 322 break; 323 } 324 } 325 326 /// getStartLoc - Get the location of the first token of this operand. 327 SMLoc getStartLoc() const { return StartLoc; } 328 /// getEndLoc - Get the location of the last token of this operand. 329 SMLoc getEndLoc() const { return EndLoc; } 330 331 ARMCC::CondCodes getCondCode() const { 332 assert(Kind == CondCode && "Invalid access!"); 333 return CC.Val; 334 } 335 336 unsigned getCoproc() const { 337 assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 338 return Cop.Val; 339 } 340 341 StringRef getToken() const { 342 assert(Kind == Token && "Invalid access!"); 343 return StringRef(Tok.Data, Tok.Length); 344 } 345 346 unsigned getReg() const { 347 assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 348 return Reg.RegNum; 349 } 350 351 const SmallVectorImpl<unsigned> &getRegList() const { 352 assert((Kind == RegisterList || Kind == DPRRegisterList || 353 Kind == SPRRegisterList) && "Invalid access!"); 354 return Registers; 355 } 356 357 const MCExpr *getImm() const { 358 assert(Kind == Immediate && "Invalid access!"); 359 return Imm.Val; 360 } 361 362 ARM_MB::MemBOpt getMemBarrierOpt() const { 363 assert(Kind == MemBarrierOpt && "Invalid access!"); 364 return MBOpt.Val; 365 } 366 367 ARM_PROC::IFlags getProcIFlags() const { 368 assert(Kind == ProcIFlags && "Invalid access!"); 369 return IFlags.Val; 370 } 371 372 unsigned getMSRMask() const { 373 assert(Kind == MSRMask && "Invalid access!"); 374 return MMask.Val; 375 } 376 377 bool isCoprocNum() const { return Kind == CoprocNum; } 378 bool isCoprocReg() const { return Kind == CoprocReg; } 379 bool isCondCode() const { return Kind == CondCode; } 380 bool isCCOut() const { return Kind == CCOut; } 381 bool isImm() const { return Kind == Immediate; } 382 bool isImm0_255() const { 383 if (Kind != Immediate) 384 return false; 385 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 386 if (!CE) return false; 387 int64_t Value = CE->getValue(); 388 return Value >= 0 && Value < 256; 389 } 390 bool isImm0_7() const { 391 if (Kind != Immediate) 392 return false; 393 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 394 if (!CE) return false; 395 int64_t Value = CE->getValue(); 396 return Value >= 0 && Value < 8; 397 } 398 bool isImm0_15() const { 399 if (Kind != Immediate) 400 return false; 401 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 402 if (!CE) return false; 403 int64_t Value = CE->getValue(); 404 return Value >= 0 && Value < 16; 405 } 406 bool isImm0_31() const { 407 if (Kind != Immediate) 408 return false; 409 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 410 if (!CE) return false; 411 int64_t Value = CE->getValue(); 412 return Value >= 0 && Value < 32; 413 } 414 bool isImm1_16() const { 415 if (Kind != Immediate) 416 return false; 417 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 418 if (!CE) return false; 419 int64_t Value = CE->getValue(); 420 return Value > 0 && Value < 17; 421 } 422 bool isImm1_32() const { 423 if (Kind != Immediate) 424 return false; 425 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 426 if (!CE) return false; 427 int64_t Value = CE->getValue(); 428 return Value > 0 && Value < 33; 429 } 430 bool isImm0_65535() const { 431 if (Kind != Immediate) 432 return false; 433 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 434 if (!CE) return false; 435 int64_t Value = CE->getValue(); 436 return Value >= 0 && Value < 65536; 437 } 438 bool isImm0_65535Expr() const { 439 if (Kind != Immediate) 440 return false; 441 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 442 // If it's not a constant expression, it'll generate a fixup and be 443 // handled later. 444 if (!CE) return true; 445 int64_t Value = CE->getValue(); 446 return Value >= 0 && Value < 65536; 447 } 448 bool isImm24bit() const { 449 if (Kind != Immediate) 450 return false; 451 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 452 if (!CE) return false; 453 int64_t Value = CE->getValue(); 454 return Value >= 0 && Value <= 0xffffff; 455 } 456 bool isPKHLSLImm() const { 457 if (Kind != Immediate) 458 return false; 459 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 460 if (!CE) return false; 461 int64_t Value = CE->getValue(); 462 return Value >= 0 && Value < 32; 463 } 464 bool isPKHASRImm() const { 465 if (Kind != Immediate) 466 return false; 467 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 468 if (!CE) return false; 469 int64_t Value = CE->getValue(); 470 return Value > 0 && Value <= 32; 471 } 472 bool isARMSOImm() const { 473 if (Kind != Immediate) 474 return false; 475 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 476 if (!CE) return false; 477 int64_t Value = CE->getValue(); 478 return ARM_AM::getSOImmVal(Value) != -1; 479 } 480 bool isT2SOImm() const { 481 if (Kind != Immediate) 482 return false; 483 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 484 if (!CE) return false; 485 int64_t Value = CE->getValue(); 486 return ARM_AM::getT2SOImmVal(Value) != -1; 487 } 488 bool isSetEndImm() const { 489 if (Kind != Immediate) 490 return false; 491 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 492 if (!CE) return false; 493 int64_t Value = CE->getValue(); 494 return Value == 1 || Value == 0; 495 } 496 bool isReg() const { return Kind == Register; } 497 bool isRegList() const { return Kind == RegisterList; } 498 bool isDPRRegList() const { return Kind == DPRRegisterList; } 499 bool isSPRRegList() const { return Kind == SPRRegisterList; } 500 bool isToken() const { return Kind == Token; } 501 bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 502 bool isMemory() const { return Kind == Memory; } 503 bool isShifterImm() const { return Kind == ShifterImmediate; } 504 bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 505 bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 506 bool isRotImm() const { return Kind == RotateImmediate; } 507 bool isBitfield() const { return Kind == BitfieldDescriptor; } 508 bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; } 509 bool isPostIdxReg() const { 510 return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 511 } 512 bool isMemNoOffset() const { 513 if (Kind != Memory) 514 return false; 515 // No offset of any kind. 516 return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 517 } 518 bool isAddrMode2() const { 519 if (Kind != Memory) 520 return false; 521 // Check for register offset. 522 if (Mem.OffsetRegNum) return true; 523 // Immediate offset in range [-4095, 4095]. 524 if (!Mem.OffsetImm) return true; 525 int64_t Val = Mem.OffsetImm->getValue(); 526 return Val > -4096 && Val < 4096; 527 } 528 bool isAM2OffsetImm() const { 529 if (Kind != Immediate) 530 return false; 531 // Immediate offset in range [-4095, 4095]. 532 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 533 if (!CE) return false; 534 int64_t Val = CE->getValue(); 535 return Val > -4096 && Val < 4096; 536 } 537 bool isAddrMode5() const { 538 if (Kind != Memory) 539 return false; 540 // Check for register offset. 541 if (Mem.OffsetRegNum) return false; 542 // Immediate offset in range [-1020, 1020] and a multiple of 4. 543 if (!Mem.OffsetImm) return true; 544 int64_t Val = Mem.OffsetImm->getValue(); 545 return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0); 546 } 547 bool isMemRegOffset() const { 548 if (Kind != Memory || !Mem.OffsetRegNum) 549 return false; 550 return true; 551 } 552 bool isMemThumbRR() const { 553 // Thumb reg+reg addressing is simple. Just two registers, a base and 554 // an offset. No shifts, negations or any other complicating factors. 555 if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 556 Mem.ShiftType != ARM_AM::no_shift) 557 return false; 558 return true; 559 } 560 bool isMemImm8Offset() const { 561 if (Kind != Memory || Mem.OffsetRegNum != 0) 562 return false; 563 // Immediate offset in range [-255, 255]. 564 if (!Mem.OffsetImm) return true; 565 int64_t Val = Mem.OffsetImm->getValue(); 566 return Val > -256 && Val < 256; 567 } 568 bool isMemImm12Offset() const { 569 if (Kind != Memory || Mem.OffsetRegNum != 0) 570 return false; 571 // Immediate offset in range [-4095, 4095]. 572 if (!Mem.OffsetImm) return true; 573 int64_t Val = Mem.OffsetImm->getValue(); 574 return Val > -4096 && Val < 4096; 575 } 576 bool isPostIdxImm8() const { 577 if (Kind != Immediate) 578 return false; 579 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 580 if (!CE) return false; 581 int64_t Val = CE->getValue(); 582 return Val > -256 && Val < 256; 583 } 584 585 bool isMSRMask() const { return Kind == MSRMask; } 586 bool isProcIFlags() const { return Kind == ProcIFlags; } 587 588 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 589 // Add as immediates when possible. Null MCExpr = 0. 590 if (Expr == 0) 591 Inst.addOperand(MCOperand::CreateImm(0)); 592 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 593 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 594 else 595 Inst.addOperand(MCOperand::CreateExpr(Expr)); 596 } 597 598 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 599 assert(N == 2 && "Invalid number of operands!"); 600 Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 601 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 602 Inst.addOperand(MCOperand::CreateReg(RegNum)); 603 } 604 605 void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 606 assert(N == 1 && "Invalid number of operands!"); 607 Inst.addOperand(MCOperand::CreateImm(getCoproc())); 608 } 609 610 void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 611 assert(N == 1 && "Invalid number of operands!"); 612 Inst.addOperand(MCOperand::CreateImm(getCoproc())); 613 } 614 615 void addCCOutOperands(MCInst &Inst, unsigned N) const { 616 assert(N == 1 && "Invalid number of operands!"); 617 Inst.addOperand(MCOperand::CreateReg(getReg())); 618 } 619 620 void addRegOperands(MCInst &Inst, unsigned N) const { 621 assert(N == 1 && "Invalid number of operands!"); 622 Inst.addOperand(MCOperand::CreateReg(getReg())); 623 } 624 625 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 626 assert(N == 3 && "Invalid number of operands!"); 627 assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 628 Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 629 Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 630 Inst.addOperand(MCOperand::CreateImm( 631 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 632 } 633 634 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 635 assert(N == 2 && "Invalid number of operands!"); 636 assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 637 Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 638 Inst.addOperand(MCOperand::CreateImm( 639 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 640 } 641 642 643 void addShifterImmOperands(MCInst &Inst, unsigned N) const { 644 assert(N == 1 && "Invalid number of operands!"); 645 Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 646 ShifterImm.Imm)); 647 } 648 649 void addRegListOperands(MCInst &Inst, unsigned N) const { 650 assert(N == 1 && "Invalid number of operands!"); 651 const SmallVectorImpl<unsigned> &RegList = getRegList(); 652 for (SmallVectorImpl<unsigned>::const_iterator 653 I = RegList.begin(), E = RegList.end(); I != E; ++I) 654 Inst.addOperand(MCOperand::CreateReg(*I)); 655 } 656 657 void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 658 addRegListOperands(Inst, N); 659 } 660 661 void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 662 addRegListOperands(Inst, N); 663 } 664 665 void addRotImmOperands(MCInst &Inst, unsigned N) const { 666 assert(N == 1 && "Invalid number of operands!"); 667 // Encoded as val>>3. The printer handles display as 8, 16, 24. 668 Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 669 } 670 671 void addBitfieldOperands(MCInst &Inst, unsigned N) const { 672 assert(N == 1 && "Invalid number of operands!"); 673 // Munge the lsb/width into a bitfield mask. 674 unsigned lsb = Bitfield.LSB; 675 unsigned width = Bitfield.Width; 676 // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 677 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 678 (32 - (lsb + width))); 679 Inst.addOperand(MCOperand::CreateImm(Mask)); 680 } 681 682 void addImmOperands(MCInst &Inst, unsigned N) const { 683 assert(N == 1 && "Invalid number of operands!"); 684 addExpr(Inst, getImm()); 685 } 686 687 void addImm0_255Operands(MCInst &Inst, unsigned N) const { 688 assert(N == 1 && "Invalid number of operands!"); 689 addExpr(Inst, getImm()); 690 } 691 692 void addImm0_7Operands(MCInst &Inst, unsigned N) const { 693 assert(N == 1 && "Invalid number of operands!"); 694 addExpr(Inst, getImm()); 695 } 696 697 void addImm0_15Operands(MCInst &Inst, unsigned N) const { 698 assert(N == 1 && "Invalid number of operands!"); 699 addExpr(Inst, getImm()); 700 } 701 702 void addImm0_31Operands(MCInst &Inst, unsigned N) const { 703 assert(N == 1 && "Invalid number of operands!"); 704 addExpr(Inst, getImm()); 705 } 706 707 void addImm1_16Operands(MCInst &Inst, unsigned N) const { 708 assert(N == 1 && "Invalid number of operands!"); 709 // The constant encodes as the immediate-1, and we store in the instruction 710 // the bits as encoded, so subtract off one here. 711 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 712 Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 713 } 714 715 void addImm1_32Operands(MCInst &Inst, unsigned N) const { 716 assert(N == 1 && "Invalid number of operands!"); 717 // The constant encodes as the immediate-1, and we store in the instruction 718 // the bits as encoded, so subtract off one here. 719 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 720 Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 721 } 722 723 void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 724 assert(N == 1 && "Invalid number of operands!"); 725 addExpr(Inst, getImm()); 726 } 727 728 void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 729 assert(N == 1 && "Invalid number of operands!"); 730 addExpr(Inst, getImm()); 731 } 732 733 void addImm24bitOperands(MCInst &Inst, unsigned N) const { 734 assert(N == 1 && "Invalid number of operands!"); 735 addExpr(Inst, getImm()); 736 } 737 738 void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 739 assert(N == 1 && "Invalid number of operands!"); 740 addExpr(Inst, getImm()); 741 } 742 743 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 744 assert(N == 1 && "Invalid number of operands!"); 745 // An ASR value of 32 encodes as 0, so that's how we want to add it to 746 // the instruction as well. 747 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 748 int Val = CE->getValue(); 749 Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 750 } 751 752 void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 753 assert(N == 1 && "Invalid number of operands!"); 754 addExpr(Inst, getImm()); 755 } 756 757 void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 758 assert(N == 1 && "Invalid number of operands!"); 759 addExpr(Inst, getImm()); 760 } 761 762 void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 763 assert(N == 1 && "Invalid number of operands!"); 764 addExpr(Inst, getImm()); 765 } 766 767 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 768 assert(N == 1 && "Invalid number of operands!"); 769 Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 770 } 771 772 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 773 assert(N == 1 && "Invalid number of operands!"); 774 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 775 } 776 777 void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 778 assert(N == 3 && "Invalid number of operands!"); 779 int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 780 if (!Mem.OffsetRegNum) { 781 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 782 // Special case for #-0 783 if (Val == INT32_MIN) Val = 0; 784 if (Val < 0) Val = -Val; 785 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 786 } else { 787 // For register offset, we encode the shift type and negation flag 788 // here. 789 Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 790 0, Mem.ShiftType); 791 } 792 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 793 Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 794 Inst.addOperand(MCOperand::CreateImm(Val)); 795 } 796 797 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 798 assert(N == 2 && "Invalid number of operands!"); 799 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 800 assert(CE && "non-constant AM2OffsetImm operand!"); 801 int32_t Val = CE->getValue(); 802 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 803 // Special case for #-0 804 if (Val == INT32_MIN) Val = 0; 805 if (Val < 0) Val = -Val; 806 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 807 Inst.addOperand(MCOperand::CreateReg(0)); 808 Inst.addOperand(MCOperand::CreateImm(Val)); 809 } 810 811 void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 812 assert(N == 2 && "Invalid number of operands!"); 813 // The lower two bits are always zero and as such are not encoded. 814 int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 815 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 816 // Special case for #-0 817 if (Val == INT32_MIN) Val = 0; 818 if (Val < 0) Val = -Val; 819 Val = ARM_AM::getAM5Opc(AddSub, Val); 820 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 821 Inst.addOperand(MCOperand::CreateImm(Val)); 822 } 823 824 void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 825 assert(N == 2 && "Invalid number of operands!"); 826 int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 827 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 828 Inst.addOperand(MCOperand::CreateImm(Val)); 829 } 830 831 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 832 assert(N == 2 && "Invalid number of operands!"); 833 int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 834 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 835 Inst.addOperand(MCOperand::CreateImm(Val)); 836 } 837 838 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 839 assert(N == 3 && "Invalid number of operands!"); 840 unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 841 Mem.ShiftValue, Mem.ShiftType); 842 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 843 Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 844 Inst.addOperand(MCOperand::CreateImm(Val)); 845 } 846 847 void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 848 assert(N == 2 && "Invalid number of operands!"); 849 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 850 Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 851 } 852 853 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 854 assert(N == 1 && "Invalid number of operands!"); 855 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 856 assert(CE && "non-constant post-idx-imm8 operand!"); 857 int Imm = CE->getValue(); 858 bool isAdd = Imm >= 0; 859 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 860 Inst.addOperand(MCOperand::CreateImm(Imm)); 861 } 862 863 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 864 assert(N == 2 && "Invalid number of operands!"); 865 Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 866 Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 867 } 868 869 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 870 assert(N == 2 && "Invalid number of operands!"); 871 Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 872 // The sign, shift type, and shift amount are encoded in a single operand 873 // using the AM2 encoding helpers. 874 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 875 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 876 PostIdxReg.ShiftTy); 877 Inst.addOperand(MCOperand::CreateImm(Imm)); 878 } 879 880 void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 881 assert(N == 1 && "Invalid number of operands!"); 882 Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 883 } 884 885 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 886 assert(N == 1 && "Invalid number of operands!"); 887 Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 888 } 889 890 virtual void print(raw_ostream &OS) const; 891 892 static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 893 ARMOperand *Op = new ARMOperand(CondCode); 894 Op->CC.Val = CC; 895 Op->StartLoc = S; 896 Op->EndLoc = S; 897 return Op; 898 } 899 900 static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 901 ARMOperand *Op = new ARMOperand(CoprocNum); 902 Op->Cop.Val = CopVal; 903 Op->StartLoc = S; 904 Op->EndLoc = S; 905 return Op; 906 } 907 908 static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 909 ARMOperand *Op = new ARMOperand(CoprocReg); 910 Op->Cop.Val = CopVal; 911 Op->StartLoc = S; 912 Op->EndLoc = S; 913 return Op; 914 } 915 916 static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 917 ARMOperand *Op = new ARMOperand(CCOut); 918 Op->Reg.RegNum = RegNum; 919 Op->StartLoc = S; 920 Op->EndLoc = S; 921 return Op; 922 } 923 924 static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 925 ARMOperand *Op = new ARMOperand(Token); 926 Op->Tok.Data = Str.data(); 927 Op->Tok.Length = Str.size(); 928 Op->StartLoc = S; 929 Op->EndLoc = S; 930 return Op; 931 } 932 933 static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 934 ARMOperand *Op = new ARMOperand(Register); 935 Op->Reg.RegNum = RegNum; 936 Op->StartLoc = S; 937 Op->EndLoc = E; 938 return Op; 939 } 940 941 static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 942 unsigned SrcReg, 943 unsigned ShiftReg, 944 unsigned ShiftImm, 945 SMLoc S, SMLoc E) { 946 ARMOperand *Op = new ARMOperand(ShiftedRegister); 947 Op->RegShiftedReg.ShiftTy = ShTy; 948 Op->RegShiftedReg.SrcReg = SrcReg; 949 Op->RegShiftedReg.ShiftReg = ShiftReg; 950 Op->RegShiftedReg.ShiftImm = ShiftImm; 951 Op->StartLoc = S; 952 Op->EndLoc = E; 953 return Op; 954 } 955 956 static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 957 unsigned SrcReg, 958 unsigned ShiftImm, 959 SMLoc S, SMLoc E) { 960 ARMOperand *Op = new ARMOperand(ShiftedImmediate); 961 Op->RegShiftedImm.ShiftTy = ShTy; 962 Op->RegShiftedImm.SrcReg = SrcReg; 963 Op->RegShiftedImm.ShiftImm = ShiftImm; 964 Op->StartLoc = S; 965 Op->EndLoc = E; 966 return Op; 967 } 968 969 static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 970 SMLoc S, SMLoc E) { 971 ARMOperand *Op = new ARMOperand(ShifterImmediate); 972 Op->ShifterImm.isASR = isASR; 973 Op->ShifterImm.Imm = Imm; 974 Op->StartLoc = S; 975 Op->EndLoc = E; 976 return Op; 977 } 978 979 static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 980 ARMOperand *Op = new ARMOperand(RotateImmediate); 981 Op->RotImm.Imm = Imm; 982 Op->StartLoc = S; 983 Op->EndLoc = E; 984 return Op; 985 } 986 987 static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 988 SMLoc S, SMLoc E) { 989 ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 990 Op->Bitfield.LSB = LSB; 991 Op->Bitfield.Width = Width; 992 Op->StartLoc = S; 993 Op->EndLoc = E; 994 return Op; 995 } 996 997 static ARMOperand * 998 CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 999 SMLoc StartLoc, SMLoc EndLoc) { 1000 KindTy Kind = RegisterList; 1001 1002 if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 1003 contains(Regs.front().first)) 1004 Kind = DPRRegisterList; 1005 else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 1006 contains(Regs.front().first)) 1007 Kind = SPRRegisterList; 1008 1009 ARMOperand *Op = new ARMOperand(Kind); 1010 for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1011 I = Regs.begin(), E = Regs.end(); I != E; ++I) 1012 Op->Registers.push_back(I->first); 1013 array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1014 Op->StartLoc = StartLoc; 1015 Op->EndLoc = EndLoc; 1016 return Op; 1017 } 1018 1019 static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 1020 ARMOperand *Op = new ARMOperand(Immediate); 1021 Op->Imm.Val = Val; 1022 Op->StartLoc = S; 1023 Op->EndLoc = E; 1024 return Op; 1025 } 1026 1027 static ARMOperand *CreateMem(unsigned BaseRegNum, 1028 const MCConstantExpr *OffsetImm, 1029 unsigned OffsetRegNum, 1030 ARM_AM::ShiftOpc ShiftType, 1031 unsigned ShiftValue, 1032 bool isNegative, 1033 SMLoc S, SMLoc E) { 1034 ARMOperand *Op = new ARMOperand(Memory); 1035 Op->Mem.BaseRegNum = BaseRegNum; 1036 Op->Mem.OffsetImm = OffsetImm; 1037 Op->Mem.OffsetRegNum = OffsetRegNum; 1038 Op->Mem.ShiftType = ShiftType; 1039 Op->Mem.ShiftValue = ShiftValue; 1040 Op->Mem.isNegative = isNegative; 1041 Op->StartLoc = S; 1042 Op->EndLoc = E; 1043 return Op; 1044 } 1045 1046 static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1047 ARM_AM::ShiftOpc ShiftTy, 1048 unsigned ShiftImm, 1049 SMLoc S, SMLoc E) { 1050 ARMOperand *Op = new ARMOperand(PostIndexRegister); 1051 Op->PostIdxReg.RegNum = RegNum; 1052 Op->PostIdxReg.isAdd = isAdd; 1053 Op->PostIdxReg.ShiftTy = ShiftTy; 1054 Op->PostIdxReg.ShiftImm = ShiftImm; 1055 Op->StartLoc = S; 1056 Op->EndLoc = E; 1057 return Op; 1058 } 1059 1060 static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1061 ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1062 Op->MBOpt.Val = Opt; 1063 Op->StartLoc = S; 1064 Op->EndLoc = S; 1065 return Op; 1066 } 1067 1068 static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1069 ARMOperand *Op = new ARMOperand(ProcIFlags); 1070 Op->IFlags.Val = IFlags; 1071 Op->StartLoc = S; 1072 Op->EndLoc = S; 1073 return Op; 1074 } 1075 1076 static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1077 ARMOperand *Op = new ARMOperand(MSRMask); 1078 Op->MMask.Val = MMask; 1079 Op->StartLoc = S; 1080 Op->EndLoc = S; 1081 return Op; 1082 } 1083}; 1084 1085} // end anonymous namespace. 1086 1087void ARMOperand::print(raw_ostream &OS) const { 1088 switch (Kind) { 1089 case CondCode: 1090 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1091 break; 1092 case CCOut: 1093 OS << "<ccout " << getReg() << ">"; 1094 break; 1095 case CoprocNum: 1096 OS << "<coprocessor number: " << getCoproc() << ">"; 1097 break; 1098 case CoprocReg: 1099 OS << "<coprocessor register: " << getCoproc() << ">"; 1100 break; 1101 case MSRMask: 1102 OS << "<mask: " << getMSRMask() << ">"; 1103 break; 1104 case Immediate: 1105 getImm()->print(OS); 1106 break; 1107 case MemBarrierOpt: 1108 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1109 break; 1110 case Memory: 1111 OS << "<memory " 1112 << " base:" << Mem.BaseRegNum; 1113 OS << ">"; 1114 break; 1115 case PostIndexRegister: 1116 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1117 << PostIdxReg.RegNum; 1118 if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1119 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1120 << PostIdxReg.ShiftImm; 1121 OS << ">"; 1122 break; 1123 case ProcIFlags: { 1124 OS << "<ARM_PROC::"; 1125 unsigned IFlags = getProcIFlags(); 1126 for (int i=2; i >= 0; --i) 1127 if (IFlags & (1 << i)) 1128 OS << ARM_PROC::IFlagsToString(1 << i); 1129 OS << ">"; 1130 break; 1131 } 1132 case Register: 1133 OS << "<register " << getReg() << ">"; 1134 break; 1135 case ShifterImmediate: 1136 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1137 << " #" << ShifterImm.Imm << ">"; 1138 break; 1139 case ShiftedRegister: 1140 OS << "<so_reg_reg " 1141 << RegShiftedReg.SrcReg 1142 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1143 << ", " << RegShiftedReg.ShiftReg << ", " 1144 << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1145 << ">"; 1146 break; 1147 case ShiftedImmediate: 1148 OS << "<so_reg_imm " 1149 << RegShiftedImm.SrcReg 1150 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1151 << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 1152 << ">"; 1153 break; 1154 case RotateImmediate: 1155 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 1156 break; 1157 case BitfieldDescriptor: 1158 OS << "<bitfield " << "lsb: " << Bitfield.LSB 1159 << ", width: " << Bitfield.Width << ">"; 1160 break; 1161 case RegisterList: 1162 case DPRRegisterList: 1163 case SPRRegisterList: { 1164 OS << "<register_list "; 1165 1166 const SmallVectorImpl<unsigned> &RegList = getRegList(); 1167 for (SmallVectorImpl<unsigned>::const_iterator 1168 I = RegList.begin(), E = RegList.end(); I != E; ) { 1169 OS << *I; 1170 if (++I < E) OS << ", "; 1171 } 1172 1173 OS << ">"; 1174 break; 1175 } 1176 case Token: 1177 OS << "'" << getToken() << "'"; 1178 break; 1179 } 1180} 1181 1182/// @name Auto-generated Match Functions 1183/// { 1184 1185static unsigned MatchRegisterName(StringRef Name); 1186 1187/// } 1188 1189bool ARMAsmParser::ParseRegister(unsigned &RegNo, 1190 SMLoc &StartLoc, SMLoc &EndLoc) { 1191 RegNo = tryParseRegister(); 1192 1193 return (RegNo == (unsigned)-1); 1194} 1195 1196/// Try to parse a register name. The token must be an Identifier when called, 1197/// and if it is a register name the token is eaten and the register number is 1198/// returned. Otherwise return -1. 1199/// 1200int ARMAsmParser::tryParseRegister() { 1201 const AsmToken &Tok = Parser.getTok(); 1202 if (Tok.isNot(AsmToken::Identifier)) return -1; 1203 1204 // FIXME: Validate register for the current architecture; we have to do 1205 // validation later, so maybe there is no need for this here. 1206 std::string upperCase = Tok.getString().str(); 1207 std::string lowerCase = LowercaseString(upperCase); 1208 unsigned RegNum = MatchRegisterName(lowerCase); 1209 if (!RegNum) { 1210 RegNum = StringSwitch<unsigned>(lowerCase) 1211 .Case("r13", ARM::SP) 1212 .Case("r14", ARM::LR) 1213 .Case("r15", ARM::PC) 1214 .Case("ip", ARM::R12) 1215 .Default(0); 1216 } 1217 if (!RegNum) return -1; 1218 1219 Parser.Lex(); // Eat identifier token. 1220 return RegNum; 1221} 1222 1223// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 1224// If a recoverable error occurs, return 1. If an irrecoverable error 1225// occurs, return -1. An irrecoverable error is one where tokens have been 1226// consumed in the process of trying to parse the shifter (i.e., when it is 1227// indeed a shifter operand, but malformed). 1228int ARMAsmParser::tryParseShiftRegister( 1229 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1230 SMLoc S = Parser.getTok().getLoc(); 1231 const AsmToken &Tok = Parser.getTok(); 1232 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1233 1234 std::string upperCase = Tok.getString().str(); 1235 std::string lowerCase = LowercaseString(upperCase); 1236 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 1237 .Case("lsl", ARM_AM::lsl) 1238 .Case("lsr", ARM_AM::lsr) 1239 .Case("asr", ARM_AM::asr) 1240 .Case("ror", ARM_AM::ror) 1241 .Case("rrx", ARM_AM::rrx) 1242 .Default(ARM_AM::no_shift); 1243 1244 if (ShiftTy == ARM_AM::no_shift) 1245 return 1; 1246 1247 Parser.Lex(); // Eat the operator. 1248 1249 // The source register for the shift has already been added to the 1250 // operand list, so we need to pop it off and combine it into the shifted 1251 // register operand instead. 1252 OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1253 if (!PrevOp->isReg()) 1254 return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1255 int SrcReg = PrevOp->getReg(); 1256 int64_t Imm = 0; 1257 int ShiftReg = 0; 1258 if (ShiftTy == ARM_AM::rrx) { 1259 // RRX Doesn't have an explicit shift amount. The encoder expects 1260 // the shift register to be the same as the source register. Seems odd, 1261 // but OK. 1262 ShiftReg = SrcReg; 1263 } else { 1264 // Figure out if this is shifted by a constant or a register (for non-RRX). 1265 if (Parser.getTok().is(AsmToken::Hash)) { 1266 Parser.Lex(); // Eat hash. 1267 SMLoc ImmLoc = Parser.getTok().getLoc(); 1268 const MCExpr *ShiftExpr = 0; 1269 if (getParser().ParseExpression(ShiftExpr)) { 1270 Error(ImmLoc, "invalid immediate shift value"); 1271 return -1; 1272 } 1273 // The expression must be evaluatable as an immediate. 1274 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 1275 if (!CE) { 1276 Error(ImmLoc, "invalid immediate shift value"); 1277 return -1; 1278 } 1279 // Range check the immediate. 1280 // lsl, ror: 0 <= imm <= 31 1281 // lsr, asr: 0 <= imm <= 32 1282 Imm = CE->getValue(); 1283 if (Imm < 0 || 1284 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1285 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 1286 Error(ImmLoc, "immediate shift value out of range"); 1287 return -1; 1288 } 1289 } else if (Parser.getTok().is(AsmToken::Identifier)) { 1290 ShiftReg = tryParseRegister(); 1291 SMLoc L = Parser.getTok().getLoc(); 1292 if (ShiftReg == -1) { 1293 Error (L, "expected immediate or register in shift operand"); 1294 return -1; 1295 } 1296 } else { 1297 Error (Parser.getTok().getLoc(), 1298 "expected immediate or register in shift operand"); 1299 return -1; 1300 } 1301 } 1302 1303 if (ShiftReg && ShiftTy != ARM_AM::rrx) 1304 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1305 ShiftReg, Imm, 1306 S, Parser.getTok().getLoc())); 1307 else 1308 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 1309 S, Parser.getTok().getLoc())); 1310 1311 return 0; 1312} 1313 1314 1315/// Try to parse a register name. The token must be an Identifier when called. 1316/// If it's a register, an AsmOperand is created. Another AsmOperand is created 1317/// if there is a "writeback". 'true' if it's not a register. 1318/// 1319/// TODO this is likely to change to allow different register types and or to 1320/// parse for a specific register type. 1321bool ARMAsmParser:: 1322tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1323 SMLoc S = Parser.getTok().getLoc(); 1324 int RegNo = tryParseRegister(); 1325 if (RegNo == -1) 1326 return true; 1327 1328 Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1329 1330 const AsmToken &ExclaimTok = Parser.getTok(); 1331 if (ExclaimTok.is(AsmToken::Exclaim)) { 1332 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 1333 ExclaimTok.getLoc())); 1334 Parser.Lex(); // Eat exclaim token 1335 } 1336 1337 return false; 1338} 1339 1340/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1341/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1342/// "c5", ... 1343static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1344 // Use the same layout as the tablegen'erated register name matcher. Ugly, 1345 // but efficient. 1346 switch (Name.size()) { 1347 default: break; 1348 case 2: 1349 if (Name[0] != CoprocOp) 1350 return -1; 1351 switch (Name[1]) { 1352 default: return -1; 1353 case '0': return 0; 1354 case '1': return 1; 1355 case '2': return 2; 1356 case '3': return 3; 1357 case '4': return 4; 1358 case '5': return 5; 1359 case '6': return 6; 1360 case '7': return 7; 1361 case '8': return 8; 1362 case '9': return 9; 1363 } 1364 break; 1365 case 3: 1366 if (Name[0] != CoprocOp || Name[1] != '1') 1367 return -1; 1368 switch (Name[2]) { 1369 default: return -1; 1370 case '0': return 10; 1371 case '1': return 11; 1372 case '2': return 12; 1373 case '3': return 13; 1374 case '4': return 14; 1375 case '5': return 15; 1376 } 1377 break; 1378 } 1379 1380 return -1; 1381} 1382 1383/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1384/// token must be an Identifier when called, and if it is a coprocessor 1385/// number, the token is eaten and the operand is added to the operand list. 1386ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1387parseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1388 SMLoc S = Parser.getTok().getLoc(); 1389 const AsmToken &Tok = Parser.getTok(); 1390 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1391 1392 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1393 if (Num == -1) 1394 return MatchOperand_NoMatch; 1395 1396 Parser.Lex(); // Eat identifier token. 1397 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1398 return MatchOperand_Success; 1399} 1400 1401/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1402/// token must be an Identifier when called, and if it is a coprocessor 1403/// number, the token is eaten and the operand is added to the operand list. 1404ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1405parseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1406 SMLoc S = Parser.getTok().getLoc(); 1407 const AsmToken &Tok = Parser.getTok(); 1408 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1409 1410 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1411 if (Reg == -1) 1412 return MatchOperand_NoMatch; 1413 1414 Parser.Lex(); // Eat identifier token. 1415 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1416 return MatchOperand_Success; 1417} 1418 1419/// Parse a register list, return it if successful else return null. The first 1420/// token must be a '{' when called. 1421bool ARMAsmParser:: 1422parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1423 assert(Parser.getTok().is(AsmToken::LCurly) && 1424 "Token is not a Left Curly Brace"); 1425 SMLoc S = Parser.getTok().getLoc(); 1426 1427 // Read the rest of the registers in the list. 1428 unsigned PrevRegNum = 0; 1429 SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1430 1431 do { 1432 bool IsRange = Parser.getTok().is(AsmToken::Minus); 1433 Parser.Lex(); // Eat non-identifier token. 1434 1435 const AsmToken &RegTok = Parser.getTok(); 1436 SMLoc RegLoc = RegTok.getLoc(); 1437 if (RegTok.isNot(AsmToken::Identifier)) { 1438 Error(RegLoc, "register expected"); 1439 return true; 1440 } 1441 1442 int RegNum = tryParseRegister(); 1443 if (RegNum == -1) { 1444 Error(RegLoc, "register expected"); 1445 return true; 1446 } 1447 1448 if (IsRange) { 1449 int Reg = PrevRegNum; 1450 do { 1451 ++Reg; 1452 Registers.push_back(std::make_pair(Reg, RegLoc)); 1453 } while (Reg != RegNum); 1454 } else { 1455 Registers.push_back(std::make_pair(RegNum, RegLoc)); 1456 } 1457 1458 PrevRegNum = RegNum; 1459 } while (Parser.getTok().is(AsmToken::Comma) || 1460 Parser.getTok().is(AsmToken::Minus)); 1461 1462 // Process the right curly brace of the list. 1463 const AsmToken &RCurlyTok = Parser.getTok(); 1464 if (RCurlyTok.isNot(AsmToken::RCurly)) { 1465 Error(RCurlyTok.getLoc(), "'}' expected"); 1466 return true; 1467 } 1468 1469 SMLoc E = RCurlyTok.getLoc(); 1470 Parser.Lex(); // Eat right curly brace token. 1471 1472 // Verify the register list. 1473 SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1474 RI = Registers.begin(), RE = Registers.end(); 1475 1476 unsigned HighRegNum = getARMRegisterNumbering(RI->first); 1477 bool EmittedWarning = false; 1478 1479 DenseMap<unsigned, bool> RegMap; 1480 RegMap[HighRegNum] = true; 1481 1482 for (++RI; RI != RE; ++RI) { 1483 const std::pair<unsigned, SMLoc> &RegInfo = *RI; 1484 unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1485 1486 if (RegMap[Reg]) { 1487 Error(RegInfo.second, "register duplicated in register list"); 1488 return true; 1489 } 1490 1491 if (!EmittedWarning && Reg < HighRegNum) 1492 Warning(RegInfo.second, 1493 "register not in ascending order in register list"); 1494 1495 RegMap[Reg] = true; 1496 HighRegNum = std::max(Reg, HighRegNum); 1497 } 1498 1499 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 1500 return false; 1501} 1502 1503/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1504ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1505parseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1506 SMLoc S = Parser.getTok().getLoc(); 1507 const AsmToken &Tok = Parser.getTok(); 1508 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1509 StringRef OptStr = Tok.getString(); 1510 1511 unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1512 .Case("sy", ARM_MB::SY) 1513 .Case("st", ARM_MB::ST) 1514 .Case("sh", ARM_MB::ISH) 1515 .Case("ish", ARM_MB::ISH) 1516 .Case("shst", ARM_MB::ISHST) 1517 .Case("ishst", ARM_MB::ISHST) 1518 .Case("nsh", ARM_MB::NSH) 1519 .Case("un", ARM_MB::NSH) 1520 .Case("nshst", ARM_MB::NSHST) 1521 .Case("unst", ARM_MB::NSHST) 1522 .Case("osh", ARM_MB::OSH) 1523 .Case("oshst", ARM_MB::OSHST) 1524 .Default(~0U); 1525 1526 if (Opt == ~0U) 1527 return MatchOperand_NoMatch; 1528 1529 Parser.Lex(); // Eat identifier token. 1530 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1531 return MatchOperand_Success; 1532} 1533 1534/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1535ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1536parseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1537 SMLoc S = Parser.getTok().getLoc(); 1538 const AsmToken &Tok = Parser.getTok(); 1539 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1540 StringRef IFlagsStr = Tok.getString(); 1541 1542 unsigned IFlags = 0; 1543 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1544 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1545 .Case("a", ARM_PROC::A) 1546 .Case("i", ARM_PROC::I) 1547 .Case("f", ARM_PROC::F) 1548 .Default(~0U); 1549 1550 // If some specific iflag is already set, it means that some letter is 1551 // present more than once, this is not acceptable. 1552 if (Flag == ~0U || (IFlags & Flag)) 1553 return MatchOperand_NoMatch; 1554 1555 IFlags |= Flag; 1556 } 1557 1558 Parser.Lex(); // Eat identifier token. 1559 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1560 return MatchOperand_Success; 1561} 1562 1563/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1564ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1565parseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1566 SMLoc S = Parser.getTok().getLoc(); 1567 const AsmToken &Tok = Parser.getTok(); 1568 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1569 StringRef Mask = Tok.getString(); 1570 1571 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1572 size_t Start = 0, Next = Mask.find('_'); 1573 StringRef Flags = ""; 1574 std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1575 if (Next != StringRef::npos) 1576 Flags = Mask.slice(Next+1, Mask.size()); 1577 1578 // FlagsVal contains the complete mask: 1579 // 3-0: Mask 1580 // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1581 unsigned FlagsVal = 0; 1582 1583 if (SpecReg == "apsr") { 1584 FlagsVal = StringSwitch<unsigned>(Flags) 1585 .Case("nzcvq", 0x8) // same as CPSR_f 1586 .Case("g", 0x4) // same as CPSR_s 1587 .Case("nzcvqg", 0xc) // same as CPSR_fs 1588 .Default(~0U); 1589 1590 if (FlagsVal == ~0U) { 1591 if (!Flags.empty()) 1592 return MatchOperand_NoMatch; 1593 else 1594 FlagsVal = 0; // No flag 1595 } 1596 } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 1597 if (Flags == "all") // cpsr_all is an alias for cpsr_fc 1598 Flags = "fc"; 1599 for (int i = 0, e = Flags.size(); i != e; ++i) { 1600 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1601 .Case("c", 1) 1602 .Case("x", 2) 1603 .Case("s", 4) 1604 .Case("f", 8) 1605 .Default(~0U); 1606 1607 // If some specific flag is already set, it means that some letter is 1608 // present more than once, this is not acceptable. 1609 if (FlagsVal == ~0U || (FlagsVal & Flag)) 1610 return MatchOperand_NoMatch; 1611 FlagsVal |= Flag; 1612 } 1613 } else // No match for special register. 1614 return MatchOperand_NoMatch; 1615 1616 // Special register without flags are equivalent to "fc" flags. 1617 if (!FlagsVal) 1618 FlagsVal = 0x9; 1619 1620 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1621 if (SpecReg == "spsr") 1622 FlagsVal |= 16; 1623 1624 Parser.Lex(); // Eat identifier token. 1625 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1626 return MatchOperand_Success; 1627} 1628 1629ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1630parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1631 int Low, int High) { 1632 const AsmToken &Tok = Parser.getTok(); 1633 if (Tok.isNot(AsmToken::Identifier)) { 1634 Error(Parser.getTok().getLoc(), Op + " operand expected."); 1635 return MatchOperand_ParseFail; 1636 } 1637 StringRef ShiftName = Tok.getString(); 1638 std::string LowerOp = LowercaseString(Op); 1639 std::string UpperOp = UppercaseString(Op); 1640 if (ShiftName != LowerOp && ShiftName != UpperOp) { 1641 Error(Parser.getTok().getLoc(), Op + " operand expected."); 1642 return MatchOperand_ParseFail; 1643 } 1644 Parser.Lex(); // Eat shift type token. 1645 1646 // There must be a '#' and a shift amount. 1647 if (Parser.getTok().isNot(AsmToken::Hash)) { 1648 Error(Parser.getTok().getLoc(), "'#' expected"); 1649 return MatchOperand_ParseFail; 1650 } 1651 Parser.Lex(); // Eat hash token. 1652 1653 const MCExpr *ShiftAmount; 1654 SMLoc Loc = Parser.getTok().getLoc(); 1655 if (getParser().ParseExpression(ShiftAmount)) { 1656 Error(Loc, "illegal expression"); 1657 return MatchOperand_ParseFail; 1658 } 1659 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1660 if (!CE) { 1661 Error(Loc, "constant expression expected"); 1662 return MatchOperand_ParseFail; 1663 } 1664 int Val = CE->getValue(); 1665 if (Val < Low || Val > High) { 1666 Error(Loc, "immediate value out of range"); 1667 return MatchOperand_ParseFail; 1668 } 1669 1670 Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1671 1672 return MatchOperand_Success; 1673} 1674 1675ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1676parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1677 const AsmToken &Tok = Parser.getTok(); 1678 SMLoc S = Tok.getLoc(); 1679 if (Tok.isNot(AsmToken::Identifier)) { 1680 Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1681 return MatchOperand_ParseFail; 1682 } 1683 int Val = StringSwitch<int>(Tok.getString()) 1684 .Case("be", 1) 1685 .Case("le", 0) 1686 .Default(-1); 1687 Parser.Lex(); // Eat the token. 1688 1689 if (Val == -1) { 1690 Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1691 return MatchOperand_ParseFail; 1692 } 1693 Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1694 getContext()), 1695 S, Parser.getTok().getLoc())); 1696 return MatchOperand_Success; 1697} 1698 1699/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1700/// instructions. Legal values are: 1701/// lsl #n 'n' in [0,31] 1702/// asr #n 'n' in [1,32] 1703/// n == 32 encoded as n == 0. 1704ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1705parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1706 const AsmToken &Tok = Parser.getTok(); 1707 SMLoc S = Tok.getLoc(); 1708 if (Tok.isNot(AsmToken::Identifier)) { 1709 Error(S, "shift operator 'asr' or 'lsl' expected"); 1710 return MatchOperand_ParseFail; 1711 } 1712 StringRef ShiftName = Tok.getString(); 1713 bool isASR; 1714 if (ShiftName == "lsl" || ShiftName == "LSL") 1715 isASR = false; 1716 else if (ShiftName == "asr" || ShiftName == "ASR") 1717 isASR = true; 1718 else { 1719 Error(S, "shift operator 'asr' or 'lsl' expected"); 1720 return MatchOperand_ParseFail; 1721 } 1722 Parser.Lex(); // Eat the operator. 1723 1724 // A '#' and a shift amount. 1725 if (Parser.getTok().isNot(AsmToken::Hash)) { 1726 Error(Parser.getTok().getLoc(), "'#' expected"); 1727 return MatchOperand_ParseFail; 1728 } 1729 Parser.Lex(); // Eat hash token. 1730 1731 const MCExpr *ShiftAmount; 1732 SMLoc E = Parser.getTok().getLoc(); 1733 if (getParser().ParseExpression(ShiftAmount)) { 1734 Error(E, "malformed shift expression"); 1735 return MatchOperand_ParseFail; 1736 } 1737 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1738 if (!CE) { 1739 Error(E, "shift amount must be an immediate"); 1740 return MatchOperand_ParseFail; 1741 } 1742 1743 int64_t Val = CE->getValue(); 1744 if (isASR) { 1745 // Shift amount must be in [1,32] 1746 if (Val < 1 || Val > 32) { 1747 Error(E, "'asr' shift amount must be in range [1,32]"); 1748 return MatchOperand_ParseFail; 1749 } 1750 // asr #32 encoded as asr #0. 1751 if (Val == 32) Val = 0; 1752 } else { 1753 // Shift amount must be in [1,32] 1754 if (Val < 0 || Val > 31) { 1755 Error(E, "'lsr' shift amount must be in range [0,31]"); 1756 return MatchOperand_ParseFail; 1757 } 1758 } 1759 1760 E = Parser.getTok().getLoc(); 1761 Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 1762 1763 return MatchOperand_Success; 1764} 1765 1766/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 1767/// of instructions. Legal values are: 1768/// ror #n 'n' in {0, 8, 16, 24} 1769ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1770parseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1771 const AsmToken &Tok = Parser.getTok(); 1772 SMLoc S = Tok.getLoc(); 1773 if (Tok.isNot(AsmToken::Identifier)) { 1774 Error(S, "rotate operator 'ror' expected"); 1775 return MatchOperand_ParseFail; 1776 } 1777 StringRef ShiftName = Tok.getString(); 1778 if (ShiftName != "ror" && ShiftName != "ROR") { 1779 Error(S, "rotate operator 'ror' expected"); 1780 return MatchOperand_ParseFail; 1781 } 1782 Parser.Lex(); // Eat the operator. 1783 1784 // A '#' and a rotate amount. 1785 if (Parser.getTok().isNot(AsmToken::Hash)) { 1786 Error(Parser.getTok().getLoc(), "'#' expected"); 1787 return MatchOperand_ParseFail; 1788 } 1789 Parser.Lex(); // Eat hash token. 1790 1791 const MCExpr *ShiftAmount; 1792 SMLoc E = Parser.getTok().getLoc(); 1793 if (getParser().ParseExpression(ShiftAmount)) { 1794 Error(E, "malformed rotate expression"); 1795 return MatchOperand_ParseFail; 1796 } 1797 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1798 if (!CE) { 1799 Error(E, "rotate amount must be an immediate"); 1800 return MatchOperand_ParseFail; 1801 } 1802 1803 int64_t Val = CE->getValue(); 1804 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 1805 // normally, zero is represented in asm by omitting the rotate operand 1806 // entirely. 1807 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 1808 Error(E, "'ror' rotate amount must be 8, 16, or 24"); 1809 return MatchOperand_ParseFail; 1810 } 1811 1812 E = Parser.getTok().getLoc(); 1813 Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 1814 1815 return MatchOperand_Success; 1816} 1817 1818ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1819parseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1820 SMLoc S = Parser.getTok().getLoc(); 1821 // The bitfield descriptor is really two operands, the LSB and the width. 1822 if (Parser.getTok().isNot(AsmToken::Hash)) { 1823 Error(Parser.getTok().getLoc(), "'#' expected"); 1824 return MatchOperand_ParseFail; 1825 } 1826 Parser.Lex(); // Eat hash token. 1827 1828 const MCExpr *LSBExpr; 1829 SMLoc E = Parser.getTok().getLoc(); 1830 if (getParser().ParseExpression(LSBExpr)) { 1831 Error(E, "malformed immediate expression"); 1832 return MatchOperand_ParseFail; 1833 } 1834 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 1835 if (!CE) { 1836 Error(E, "'lsb' operand must be an immediate"); 1837 return MatchOperand_ParseFail; 1838 } 1839 1840 int64_t LSB = CE->getValue(); 1841 // The LSB must be in the range [0,31] 1842 if (LSB < 0 || LSB > 31) { 1843 Error(E, "'lsb' operand must be in the range [0,31]"); 1844 return MatchOperand_ParseFail; 1845 } 1846 E = Parser.getTok().getLoc(); 1847 1848 // Expect another immediate operand. 1849 if (Parser.getTok().isNot(AsmToken::Comma)) { 1850 Error(Parser.getTok().getLoc(), "too few operands"); 1851 return MatchOperand_ParseFail; 1852 } 1853 Parser.Lex(); // Eat hash token. 1854 if (Parser.getTok().isNot(AsmToken::Hash)) { 1855 Error(Parser.getTok().getLoc(), "'#' expected"); 1856 return MatchOperand_ParseFail; 1857 } 1858 Parser.Lex(); // Eat hash token. 1859 1860 const MCExpr *WidthExpr; 1861 if (getParser().ParseExpression(WidthExpr)) { 1862 Error(E, "malformed immediate expression"); 1863 return MatchOperand_ParseFail; 1864 } 1865 CE = dyn_cast<MCConstantExpr>(WidthExpr); 1866 if (!CE) { 1867 Error(E, "'width' operand must be an immediate"); 1868 return MatchOperand_ParseFail; 1869 } 1870 1871 int64_t Width = CE->getValue(); 1872 // The LSB must be in the range [1,32-lsb] 1873 if (Width < 1 || Width > 32 - LSB) { 1874 Error(E, "'width' operand must be in the range [1,32-lsb]"); 1875 return MatchOperand_ParseFail; 1876 } 1877 E = Parser.getTok().getLoc(); 1878 1879 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 1880 1881 return MatchOperand_Success; 1882} 1883 1884ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1885parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1886 // Check for a post-index addressing register operand. Specifically: 1887 // postidx_reg := '+' register {, shift} 1888 // | '-' register {, shift} 1889 // | register {, shift} 1890 1891 // This method must return MatchOperand_NoMatch without consuming any tokens 1892 // in the case where there is no match, as other alternatives take other 1893 // parse methods. 1894 AsmToken Tok = Parser.getTok(); 1895 SMLoc S = Tok.getLoc(); 1896 bool haveEaten = false; 1897 bool isAdd = true; 1898 int Reg = -1; 1899 if (Tok.is(AsmToken::Plus)) { 1900 Parser.Lex(); // Eat the '+' token. 1901 haveEaten = true; 1902 } else if (Tok.is(AsmToken::Minus)) { 1903 Parser.Lex(); // Eat the '-' token. 1904 isAdd = false; 1905 haveEaten = true; 1906 } 1907 if (Parser.getTok().is(AsmToken::Identifier)) 1908 Reg = tryParseRegister(); 1909 if (Reg == -1) { 1910 if (!haveEaten) 1911 return MatchOperand_NoMatch; 1912 Error(Parser.getTok().getLoc(), "register expected"); 1913 return MatchOperand_ParseFail; 1914 } 1915 SMLoc E = Parser.getTok().getLoc(); 1916 1917 ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 1918 unsigned ShiftImm = 0; 1919 1920 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 1921 ShiftImm, S, E)); 1922 1923 return MatchOperand_Success; 1924} 1925 1926/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1927/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1928/// when they refer multiple MIOperands inside a single one. 1929bool ARMAsmParser:: 1930cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1931 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1932 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1933 1934 // Create a writeback register dummy placeholder. 1935 Inst.addOperand(MCOperand::CreateImm(0)); 1936 1937 ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 1938 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1939 return true; 1940} 1941 1942/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1943/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1944/// when they refer multiple MIOperands inside a single one. 1945bool ARMAsmParser:: 1946cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1947 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1948 // Create a writeback register dummy placeholder. 1949 Inst.addOperand(MCOperand::CreateImm(0)); 1950 assert(0 && "cvtStWriteBackRegAddrMode2 not implemented yet!"); 1951 return true; 1952} 1953 1954/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 1955/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1956/// when they refer multiple MIOperands inside a single one. 1957bool ARMAsmParser:: 1958cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1959 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1960 // Rt 1961 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1962 // Create a writeback register dummy placeholder. 1963 Inst.addOperand(MCOperand::CreateImm(0)); 1964 // addr 1965 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 1966 // offset 1967 ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 1968 // pred 1969 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1970 return true; 1971} 1972 1973/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 1974/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1975/// when they refer multiple MIOperands inside a single one. 1976bool ARMAsmParser:: 1977cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1978 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1979 // Rt 1980 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1981 // Create a writeback register dummy placeholder. 1982 Inst.addOperand(MCOperand::CreateImm(0)); 1983 // addr 1984 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 1985 // offset 1986 ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 1987 // pred 1988 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1989 return true; 1990} 1991 1992/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 1993/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1994/// when they refer multiple MIOperands inside a single one. 1995bool ARMAsmParser:: 1996cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1997 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1998 // Create a writeback register dummy placeholder. 1999 Inst.addOperand(MCOperand::CreateImm(0)); 2000 // Rt 2001 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2002 // addr 2003 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2004 // offset 2005 ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 2006 // pred 2007 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2008 return true; 2009} 2010 2011/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2012/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2013/// when they refer multiple MIOperands inside a single one. 2014bool ARMAsmParser:: 2015cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 2016 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2017 // Create a writeback register dummy placeholder. 2018 Inst.addOperand(MCOperand::CreateImm(0)); 2019 // Rt 2020 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2021 // addr 2022 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2023 // offset 2024 ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 2025 // pred 2026 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2027 return true; 2028} 2029 2030/// Parse an ARM memory expression, return false if successful else return true 2031/// or an error. The first token must be a '[' when called. 2032bool ARMAsmParser:: 2033parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2034 SMLoc S, E; 2035 assert(Parser.getTok().is(AsmToken::LBrac) && 2036 "Token is not a Left Bracket"); 2037 S = Parser.getTok().getLoc(); 2038 Parser.Lex(); // Eat left bracket token. 2039 2040 const AsmToken &BaseRegTok = Parser.getTok(); 2041 int BaseRegNum = tryParseRegister(); 2042 if (BaseRegNum == -1) 2043 return Error(BaseRegTok.getLoc(), "register expected"); 2044 2045 // The next token must either be a comma or a closing bracket. 2046 const AsmToken &Tok = Parser.getTok(); 2047 if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 2048 return Error(Tok.getLoc(), "malformed memory operand"); 2049 2050 if (Tok.is(AsmToken::RBrac)) { 2051 E = Tok.getLoc(); 2052 Parser.Lex(); // Eat right bracket token. 2053 2054 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 2055 0, false, S, E)); 2056 2057 return false; 2058 } 2059 2060 assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 2061 Parser.Lex(); // Eat the comma. 2062 2063 // If we have a '#' it's an immediate offset, else assume it's a register 2064 // offset. 2065 if (Parser.getTok().is(AsmToken::Hash)) { 2066 Parser.Lex(); // Eat the '#'. 2067 E = Parser.getTok().getLoc(); 2068 2069 // FIXME: Special case #-0 so we can correctly set the U bit. 2070 2071 const MCExpr *Offset; 2072 if (getParser().ParseExpression(Offset)) 2073 return true; 2074 2075 // The expression has to be a constant. Memory references with relocations 2076 // don't come through here, as they use the <label> forms of the relevant 2077 // instructions. 2078 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2079 if (!CE) 2080 return Error (E, "constant expression expected"); 2081 2082 // Now we should have the closing ']' 2083 E = Parser.getTok().getLoc(); 2084 if (Parser.getTok().isNot(AsmToken::RBrac)) 2085 return Error(E, "']' expected"); 2086 Parser.Lex(); // Eat right bracket token. 2087 2088 // Don't worry about range checking the value here. That's handled by 2089 // the is*() predicates. 2090 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 2091 ARM_AM::no_shift, 0, false, S,E)); 2092 2093 // If there's a pre-indexing writeback marker, '!', just add it as a token 2094 // operand. 2095 if (Parser.getTok().is(AsmToken::Exclaim)) { 2096 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2097 Parser.Lex(); // Eat the '!'. 2098 } 2099 2100 return false; 2101 } 2102 2103 // The register offset is optionally preceded by a '+' or '-' 2104 bool isNegative = false; 2105 if (Parser.getTok().is(AsmToken::Minus)) { 2106 isNegative = true; 2107 Parser.Lex(); // Eat the '-'. 2108 } else if (Parser.getTok().is(AsmToken::Plus)) { 2109 // Nothing to do. 2110 Parser.Lex(); // Eat the '+'. 2111 } 2112 2113 E = Parser.getTok().getLoc(); 2114 int OffsetRegNum = tryParseRegister(); 2115 if (OffsetRegNum == -1) 2116 return Error(E, "register expected"); 2117 2118 // If there's a shift operator, handle it. 2119 ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 2120 unsigned ShiftValue = 0; 2121 if (Parser.getTok().is(AsmToken::Comma)) { 2122 Parser.Lex(); // Eat the ','. 2123 if (parseMemRegOffsetShift(ShiftType, ShiftValue)) 2124 return true; 2125 } 2126 2127 // Now we should have the closing ']' 2128 E = Parser.getTok().getLoc(); 2129 if (Parser.getTok().isNot(AsmToken::RBrac)) 2130 return Error(E, "']' expected"); 2131 Parser.Lex(); // Eat right bracket token. 2132 2133 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 2134 ShiftType, ShiftValue, isNegative, 2135 S, E)); 2136 2137 // If there's a pre-indexing writeback marker, '!', just add it as a token 2138 // operand. 2139 if (Parser.getTok().is(AsmToken::Exclaim)) { 2140 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2141 Parser.Lex(); // Eat the '!'. 2142 } 2143 2144 return false; 2145} 2146 2147/// parseMemRegOffsetShift - one of these two: 2148/// ( lsl | lsr | asr | ror ) , # shift_amount 2149/// rrx 2150/// return true if it parses a shift otherwise it returns false. 2151bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 2152 unsigned &Amount) { 2153 SMLoc Loc = Parser.getTok().getLoc(); 2154 const AsmToken &Tok = Parser.getTok(); 2155 if (Tok.isNot(AsmToken::Identifier)) 2156 return true; 2157 StringRef ShiftName = Tok.getString(); 2158 if (ShiftName == "lsl" || ShiftName == "LSL") 2159 St = ARM_AM::lsl; 2160 else if (ShiftName == "lsr" || ShiftName == "LSR") 2161 St = ARM_AM::lsr; 2162 else if (ShiftName == "asr" || ShiftName == "ASR") 2163 St = ARM_AM::asr; 2164 else if (ShiftName == "ror" || ShiftName == "ROR") 2165 St = ARM_AM::ror; 2166 else if (ShiftName == "rrx" || ShiftName == "RRX") 2167 St = ARM_AM::rrx; 2168 else 2169 return Error(Loc, "illegal shift operator"); 2170 Parser.Lex(); // Eat shift type token. 2171 2172 // rrx stands alone. 2173 Amount = 0; 2174 if (St != ARM_AM::rrx) { 2175 Loc = Parser.getTok().getLoc(); 2176 // A '#' and a shift amount. 2177 const AsmToken &HashTok = Parser.getTok(); 2178 if (HashTok.isNot(AsmToken::Hash)) 2179 return Error(HashTok.getLoc(), "'#' expected"); 2180 Parser.Lex(); // Eat hash token. 2181 2182 const MCExpr *Expr; 2183 if (getParser().ParseExpression(Expr)) 2184 return true; 2185 // Range check the immediate. 2186 // lsl, ror: 0 <= imm <= 31 2187 // lsr, asr: 0 <= imm <= 32 2188 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 2189 if (!CE) 2190 return Error(Loc, "shift amount must be an immediate"); 2191 int64_t Imm = CE->getValue(); 2192 if (Imm < 0 || 2193 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 2194 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 2195 return Error(Loc, "immediate shift value out of range"); 2196 Amount = Imm; 2197 } 2198 2199 return false; 2200} 2201 2202/// Parse a arm instruction operand. For now this parses the operand regardless 2203/// of the mnemonic. 2204bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2205 StringRef Mnemonic) { 2206 SMLoc S, E; 2207 2208 // Check if the current operand has a custom associated parser, if so, try to 2209 // custom parse the operand, or fallback to the general approach. 2210 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2211 if (ResTy == MatchOperand_Success) 2212 return false; 2213 // If there wasn't a custom match, try the generic matcher below. Otherwise, 2214 // there was a match, but an error occurred, in which case, just return that 2215 // the operand parsing failed. 2216 if (ResTy == MatchOperand_ParseFail) 2217 return true; 2218 2219 switch (getLexer().getKind()) { 2220 default: 2221 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 2222 return true; 2223 case AsmToken::Identifier: { 2224 if (!tryParseRegisterWithWriteBack(Operands)) 2225 return false; 2226 int Res = tryParseShiftRegister(Operands); 2227 if (Res == 0) // success 2228 return false; 2229 else if (Res == -1) // irrecoverable error 2230 return true; 2231 2232 // Fall though for the Identifier case that is not a register or a 2233 // special name. 2234 } 2235 case AsmToken::Integer: // things like 1f and 2b as a branch targets 2236 case AsmToken::Dot: { // . as a branch target 2237 // This was not a register so parse other operands that start with an 2238 // identifier (like labels) as expressions and create them as immediates. 2239 const MCExpr *IdVal; 2240 S = Parser.getTok().getLoc(); 2241 if (getParser().ParseExpression(IdVal)) 2242 return true; 2243 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2244 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 2245 return false; 2246 } 2247 case AsmToken::LBrac: 2248 return parseMemory(Operands); 2249 case AsmToken::LCurly: 2250 return parseRegisterList(Operands); 2251 case AsmToken::Hash: 2252 // #42 -> immediate. 2253 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2254 S = Parser.getTok().getLoc(); 2255 Parser.Lex(); 2256 const MCExpr *ImmVal; 2257 if (getParser().ParseExpression(ImmVal)) 2258 return true; 2259 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2260 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 2261 return false; 2262 case AsmToken::Colon: { 2263 // ":lower16:" and ":upper16:" expression prefixes 2264 // FIXME: Check it's an expression prefix, 2265 // e.g. (FOO - :lower16:BAR) isn't legal. 2266 ARMMCExpr::VariantKind RefKind; 2267 if (parsePrefix(RefKind)) 2268 return true; 2269 2270 const MCExpr *SubExprVal; 2271 if (getParser().ParseExpression(SubExprVal)) 2272 return true; 2273 2274 const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 2275 getContext()); 2276 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2277 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 2278 return false; 2279 } 2280 } 2281} 2282 2283// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 2284// :lower16: and :upper16:. 2285bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 2286 RefKind = ARMMCExpr::VK_ARM_None; 2287 2288 // :lower16: and :upper16: modifiers 2289 assert(getLexer().is(AsmToken::Colon) && "expected a :"); 2290 Parser.Lex(); // Eat ':' 2291 2292 if (getLexer().isNot(AsmToken::Identifier)) { 2293 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 2294 return true; 2295 } 2296 2297 StringRef IDVal = Parser.getTok().getIdentifier(); 2298 if (IDVal == "lower16") { 2299 RefKind = ARMMCExpr::VK_ARM_LO16; 2300 } else if (IDVal == "upper16") { 2301 RefKind = ARMMCExpr::VK_ARM_HI16; 2302 } else { 2303 Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 2304 return true; 2305 } 2306 Parser.Lex(); 2307 2308 if (getLexer().isNot(AsmToken::Colon)) { 2309 Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 2310 return true; 2311 } 2312 Parser.Lex(); // Eat the last ':' 2313 return false; 2314} 2315 2316const MCExpr * 2317ARMAsmParser::applyPrefixToExpr(const MCExpr *E, 2318 MCSymbolRefExpr::VariantKind Variant) { 2319 // Recurse over the given expression, rebuilding it to apply the given variant 2320 // to the leftmost symbol. 2321 if (Variant == MCSymbolRefExpr::VK_None) 2322 return E; 2323 2324 switch (E->getKind()) { 2325 case MCExpr::Target: 2326 llvm_unreachable("Can't handle target expr yet"); 2327 case MCExpr::Constant: 2328 llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 2329 2330 case MCExpr::SymbolRef: { 2331 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 2332 2333 if (SRE->getKind() != MCSymbolRefExpr::VK_None) 2334 return 0; 2335 2336 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 2337 } 2338 2339 case MCExpr::Unary: 2340 llvm_unreachable("Can't handle unary expressions yet"); 2341 2342 case MCExpr::Binary: { 2343 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 2344 const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant); 2345 const MCExpr *RHS = BE->getRHS(); 2346 if (!LHS) 2347 return 0; 2348 2349 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 2350 } 2351 } 2352 2353 assert(0 && "Invalid expression kind!"); 2354 return 0; 2355} 2356 2357/// \brief Given a mnemonic, split out possible predication code and carry 2358/// setting letters to form a canonical mnemonic and flags. 2359// 2360// FIXME: Would be nice to autogen this. 2361StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 2362 unsigned &PredicationCode, 2363 bool &CarrySetting, 2364 unsigned &ProcessorIMod) { 2365 PredicationCode = ARMCC::AL; 2366 CarrySetting = false; 2367 ProcessorIMod = 0; 2368 2369 // Ignore some mnemonics we know aren't predicated forms. 2370 // 2371 // FIXME: Would be nice to autogen this. 2372 if ((Mnemonic == "movs" && isThumb()) || 2373 Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 2374 Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 2375 Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 2376 Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 2377 Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 2378 Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 2379 Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2380 return Mnemonic; 2381 2382 // First, split out any predication code. Ignore mnemonics we know aren't 2383 // predicated but do have a carry-set and so weren't caught above. 2384 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 2385 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 2386 Mnemonic != "umlals" && Mnemonic != "umulls") { 2387 unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 2388 .Case("eq", ARMCC::EQ) 2389 .Case("ne", ARMCC::NE) 2390 .Case("hs", ARMCC::HS) 2391 .Case("cs", ARMCC::HS) 2392 .Case("lo", ARMCC::LO) 2393 .Case("cc", ARMCC::LO) 2394 .Case("mi", ARMCC::MI) 2395 .Case("pl", ARMCC::PL) 2396 .Case("vs", ARMCC::VS) 2397 .Case("vc", ARMCC::VC) 2398 .Case("hi", ARMCC::HI) 2399 .Case("ls", ARMCC::LS) 2400 .Case("ge", ARMCC::GE) 2401 .Case("lt", ARMCC::LT) 2402 .Case("gt", ARMCC::GT) 2403 .Case("le", ARMCC::LE) 2404 .Case("al", ARMCC::AL) 2405 .Default(~0U); 2406 if (CC != ~0U) { 2407 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 2408 PredicationCode = CC; 2409 } 2410 } 2411 2412 // Next, determine if we have a carry setting bit. We explicitly ignore all 2413 // the instructions we know end in 's'. 2414 if (Mnemonic.endswith("s") && 2415 !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 2416 Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 2417 Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 2418 Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 2419 Mnemonic == "vrsqrts" || Mnemonic == "srs" || 2420 (Mnemonic == "movs" && isThumb()))) { 2421 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2422 CarrySetting = true; 2423 } 2424 2425 // The "cps" instruction can have a interrupt mode operand which is glued into 2426 // the mnemonic. Check if this is the case, split it and parse the imod op 2427 if (Mnemonic.startswith("cps")) { 2428 // Split out any imod code. 2429 unsigned IMod = 2430 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2431 .Case("ie", ARM_PROC::IE) 2432 .Case("id", ARM_PROC::ID) 2433 .Default(~0U); 2434 if (IMod != ~0U) { 2435 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2436 ProcessorIMod = IMod; 2437 } 2438 } 2439 2440 return Mnemonic; 2441} 2442 2443/// \brief Given a canonical mnemonic, determine if the instruction ever allows 2444/// inclusion of carry set or predication code operands. 2445// 2446// FIXME: It would be nice to autogen this. 2447void ARMAsmParser:: 2448getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2449 bool &CanAcceptPredicationCode) { 2450 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2451 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2452 Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2453 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2454 Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2455 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2456 Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 2457 Mnemonic == "eor" || Mnemonic == "smlal" || 2458 (Mnemonic == "mov" && !isThumbOne())) { 2459 CanAcceptCarrySet = true; 2460 } else { 2461 CanAcceptCarrySet = false; 2462 } 2463 2464 if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2465 Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2466 Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2467 Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 2468 Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2469 Mnemonic == "setend" || 2470 ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) || 2471 ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) 2472 && !isThumb()) || 2473 Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 2474 CanAcceptPredicationCode = false; 2475 } else { 2476 CanAcceptPredicationCode = true; 2477 } 2478 2479 if (isThumb()) 2480 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 2481 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2482 CanAcceptPredicationCode = false; 2483} 2484 2485/// Parse an arm instruction mnemonic followed by its operands. 2486bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2487 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2488 // Create the leading tokens for the mnemonic, split by '.' characters. 2489 size_t Start = 0, Next = Name.find('.'); 2490 StringRef Mnemonic = Name.slice(Start, Next); 2491 2492 // Split out the predication code and carry setting flag from the mnemonic. 2493 unsigned PredicationCode; 2494 unsigned ProcessorIMod; 2495 bool CarrySetting; 2496 Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2497 ProcessorIMod); 2498 2499 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2500 2501 // FIXME: This is all a pretty gross hack. We should automatically handle 2502 // optional operands like this via tblgen. 2503 2504 // Next, add the CCOut and ConditionCode operands, if needed. 2505 // 2506 // For mnemonics which can ever incorporate a carry setting bit or predication 2507 // code, our matching model involves us always generating CCOut and 2508 // ConditionCode operands to match the mnemonic "as written" and then we let 2509 // the matcher deal with finding the right instruction or generating an 2510 // appropriate error. 2511 bool CanAcceptCarrySet, CanAcceptPredicationCode; 2512 getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 2513 2514 // If we had a carry-set on an instruction that can't do that, issue an 2515 // error. 2516 if (!CanAcceptCarrySet && CarrySetting) { 2517 Parser.EatToEndOfStatement(); 2518 return Error(NameLoc, "instruction '" + Mnemonic + 2519 "' can not set flags, but 's' suffix specified"); 2520 } 2521 // If we had a predication code on an instruction that can't do that, issue an 2522 // error. 2523 if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 2524 Parser.EatToEndOfStatement(); 2525 return Error(NameLoc, "instruction '" + Mnemonic + 2526 "' is not predicable, but condition code specified"); 2527 } 2528 2529 // Add the carry setting operand, if necessary. 2530 // 2531 // FIXME: It would be awesome if we could somehow invent a location such that 2532 // match errors on this operand would print a nice diagnostic about how the 2533 // 's' character in the mnemonic resulted in a CCOut operand. 2534 if (CanAcceptCarrySet) 2535 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 2536 NameLoc)); 2537 2538 // Add the predication code operand, if necessary. 2539 if (CanAcceptPredicationCode) { 2540 Operands.push_back(ARMOperand::CreateCondCode( 2541 ARMCC::CondCodes(PredicationCode), NameLoc)); 2542 } 2543 2544 // Add the processor imod operand, if necessary. 2545 if (ProcessorIMod) { 2546 Operands.push_back(ARMOperand::CreateImm( 2547 MCConstantExpr::Create(ProcessorIMod, getContext()), 2548 NameLoc, NameLoc)); 2549 } else { 2550 // This mnemonic can't ever accept a imod, but the user wrote 2551 // one (or misspelled another mnemonic). 2552 2553 // FIXME: Issue a nice error. 2554 } 2555 2556 // Add the remaining tokens in the mnemonic. 2557 while (Next != StringRef::npos) { 2558 Start = Next; 2559 Next = Name.find('.', Start + 1); 2560 StringRef ExtraToken = Name.slice(Start, Next); 2561 2562 Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 2563 } 2564 2565 // Read the remaining operands. 2566 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2567 // Read the first operand. 2568 if (parseOperand(Operands, Mnemonic)) { 2569 Parser.EatToEndOfStatement(); 2570 return true; 2571 } 2572 2573 while (getLexer().is(AsmToken::Comma)) { 2574 Parser.Lex(); // Eat the comma. 2575 2576 // Parse and remember the operand. 2577 if (parseOperand(Operands, Mnemonic)) { 2578 Parser.EatToEndOfStatement(); 2579 return true; 2580 } 2581 } 2582 } 2583 2584 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2585 Parser.EatToEndOfStatement(); 2586 return TokError("unexpected token in argument list"); 2587 } 2588 2589 Parser.Lex(); // Consume the EndOfStatement 2590 2591 2592 // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2593 // another does not. Specifically, the MOVW instruction does not. So we 2594 // special case it here and remove the defaulted (non-setting) cc_out 2595 // operand if that's the instruction we're trying to match. 2596 // 2597 // We do this post-processing of the explicit operands rather than just 2598 // conditionally adding the cc_out in the first place because we need 2599 // to check the type of the parsed immediate operand. 2600 if (Mnemonic == "mov" && Operands.size() > 4 && 2601 !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2602 static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2603 static_cast<ARMOperand*>(Operands[1])->getReg() == 0) { 2604 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2605 Operands.erase(Operands.begin() + 1); 2606 delete Op; 2607 } 2608 2609 // ARM mode 'blx' need special handling, as the register operand version 2610 // is predicable, but the label operand version is not. So, we can't rely 2611 // on the Mnemonic based checking to correctly figure out when to put 2612 // a CondCode operand in the list. If we're trying to match the label 2613 // version, remove the CondCode operand here. 2614 if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 2615 static_cast<ARMOperand*>(Operands[2])->isImm()) { 2616 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2617 Operands.erase(Operands.begin() + 1); 2618 delete Op; 2619 } 2620 return false; 2621} 2622 2623// Validate context-sensitive operand constraints. 2624// FIXME: We would really like to be able to tablegen'erate this. 2625bool ARMAsmParser:: 2626validateInstruction(MCInst &Inst, 2627 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2628 switch (Inst.getOpcode()) { 2629 case ARM::LDREXD: { 2630 // Rt2 must be Rt + 1. 2631 unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 2632 unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2633 if (Rt2 != Rt + 1) 2634 return Error(Operands[3]->getStartLoc(), 2635 "destination operands must be sequential"); 2636 return false; 2637 } 2638 case ARM::STREXD: { 2639 // Rt2 must be Rt + 1. 2640 unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2641 unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 2642 if (Rt2 != Rt + 1) 2643 return Error(Operands[4]->getStartLoc(), 2644 "source operands must be sequential"); 2645 return false; 2646 } 2647 case ARM::SBFX: 2648 case ARM::UBFX: { 2649 // width must be in range [1, 32-lsb] 2650 unsigned lsb = Inst.getOperand(2).getImm(); 2651 unsigned widthm1 = Inst.getOperand(3).getImm(); 2652 if (widthm1 >= 32 - lsb) 2653 return Error(Operands[5]->getStartLoc(), 2654 "bitfield width must be in range [1,32-lsb]"); 2655 } 2656 } 2657 2658 return false; 2659} 2660 2661bool ARMAsmParser:: 2662MatchAndEmitInstruction(SMLoc IDLoc, 2663 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2664 MCStreamer &Out) { 2665 MCInst Inst; 2666 unsigned ErrorInfo; 2667 MatchResultTy MatchResult; 2668 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2669 switch (MatchResult) { 2670 case Match_Success: 2671 // Context sensitive operand constraints aren't handled by the matcher, 2672 // so check them here. 2673 if (validateInstruction(Inst, Operands)) 2674 return true; 2675 2676 Out.EmitInstruction(Inst); 2677 return false; 2678 case Match_MissingFeature: 2679 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2680 return true; 2681 case Match_InvalidOperand: { 2682 SMLoc ErrorLoc = IDLoc; 2683 if (ErrorInfo != ~0U) { 2684 if (ErrorInfo >= Operands.size()) 2685 return Error(IDLoc, "too few operands for instruction"); 2686 2687 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2688 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2689 } 2690 2691 return Error(ErrorLoc, "invalid operand for instruction"); 2692 } 2693 case Match_MnemonicFail: 2694 return Error(IDLoc, "unrecognized instruction mnemonic"); 2695 case Match_ConversionFail: 2696 return Error(IDLoc, "unable to convert operands to instruction"); 2697 } 2698 2699 llvm_unreachable("Implement any new match types added!"); 2700 return true; 2701} 2702 2703/// parseDirective parses the arm specific directives 2704bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2705 StringRef IDVal = DirectiveID.getIdentifier(); 2706 if (IDVal == ".word") 2707 return parseDirectiveWord(4, DirectiveID.getLoc()); 2708 else if (IDVal == ".thumb") 2709 return parseDirectiveThumb(DirectiveID.getLoc()); 2710 else if (IDVal == ".thumb_func") 2711 return parseDirectiveThumbFunc(DirectiveID.getLoc()); 2712 else if (IDVal == ".code") 2713 return parseDirectiveCode(DirectiveID.getLoc()); 2714 else if (IDVal == ".syntax") 2715 return parseDirectiveSyntax(DirectiveID.getLoc()); 2716 return true; 2717} 2718 2719/// parseDirectiveWord 2720/// ::= .word [ expression (, expression)* ] 2721bool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 2722 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2723 for (;;) { 2724 const MCExpr *Value; 2725 if (getParser().ParseExpression(Value)) 2726 return true; 2727 2728 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2729 2730 if (getLexer().is(AsmToken::EndOfStatement)) 2731 break; 2732 2733 // FIXME: Improve diagnostic. 2734 if (getLexer().isNot(AsmToken::Comma)) 2735 return Error(L, "unexpected token in directive"); 2736 Parser.Lex(); 2737 } 2738 } 2739 2740 Parser.Lex(); 2741 return false; 2742} 2743 2744/// parseDirectiveThumb 2745/// ::= .thumb 2746bool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 2747 if (getLexer().isNot(AsmToken::EndOfStatement)) 2748 return Error(L, "unexpected token in directive"); 2749 Parser.Lex(); 2750 2751 // TODO: set thumb mode 2752 // TODO: tell the MC streamer the mode 2753 // getParser().getStreamer().Emit???(); 2754 return false; 2755} 2756 2757/// parseDirectiveThumbFunc 2758/// ::= .thumbfunc symbol_name 2759bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 2760 const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 2761 bool isMachO = MAI.hasSubsectionsViaSymbols(); 2762 StringRef Name; 2763 2764 // Darwin asm has function name after .thumb_func direction 2765 // ELF doesn't 2766 if (isMachO) { 2767 const AsmToken &Tok = Parser.getTok(); 2768 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 2769 return Error(L, "unexpected token in .thumb_func directive"); 2770 Name = Tok.getString(); 2771 Parser.Lex(); // Consume the identifier token. 2772 } 2773 2774 if (getLexer().isNot(AsmToken::EndOfStatement)) 2775 return Error(L, "unexpected token in directive"); 2776 Parser.Lex(); 2777 2778 // FIXME: assuming function name will be the line following .thumb_func 2779 if (!isMachO) { 2780 Name = Parser.getTok().getString(); 2781 } 2782 2783 // Mark symbol as a thumb symbol. 2784 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2785 getParser().getStreamer().EmitThumbFunc(Func); 2786 return false; 2787} 2788 2789/// parseDirectiveSyntax 2790/// ::= .syntax unified | divided 2791bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 2792 const AsmToken &Tok = Parser.getTok(); 2793 if (Tok.isNot(AsmToken::Identifier)) 2794 return Error(L, "unexpected token in .syntax directive"); 2795 StringRef Mode = Tok.getString(); 2796 if (Mode == "unified" || Mode == "UNIFIED") 2797 Parser.Lex(); 2798 else if (Mode == "divided" || Mode == "DIVIDED") 2799 return Error(L, "'.syntax divided' arm asssembly not supported"); 2800 else 2801 return Error(L, "unrecognized syntax mode in .syntax directive"); 2802 2803 if (getLexer().isNot(AsmToken::EndOfStatement)) 2804 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2805 Parser.Lex(); 2806 2807 // TODO tell the MC streamer the mode 2808 // getParser().getStreamer().Emit???(); 2809 return false; 2810} 2811 2812/// parseDirectiveCode 2813/// ::= .code 16 | 32 2814bool ARMAsmParser::parseDirectiveCode(SMLoc L) { 2815 const AsmToken &Tok = Parser.getTok(); 2816 if (Tok.isNot(AsmToken::Integer)) 2817 return Error(L, "unexpected token in .code directive"); 2818 int64_t Val = Parser.getTok().getIntVal(); 2819 if (Val == 16) 2820 Parser.Lex(); 2821 else if (Val == 32) 2822 Parser.Lex(); 2823 else 2824 return Error(L, "invalid operand to .code directive"); 2825 2826 if (getLexer().isNot(AsmToken::EndOfStatement)) 2827 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2828 Parser.Lex(); 2829 2830 if (Val == 16) { 2831 if (!isThumb()) { 2832 SwitchMode(); 2833 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 2834 } 2835 } else { 2836 if (isThumb()) { 2837 SwitchMode(); 2838 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2839 } 2840 } 2841 2842 return false; 2843} 2844 2845extern "C" void LLVMInitializeARMAsmLexer(); 2846 2847/// Force static initialization. 2848extern "C" void LLVMInitializeARMAsmParser() { 2849 RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 2850 RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 2851 LLVMInitializeARMAsmLexer(); 2852} 2853 2854#define GET_REGISTER_MATCHER 2855#define GET_MATCHER_IMPLEMENTATION 2856#include "ARMGenAsmMatcher.inc" 2857