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