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