ARMAsmParser.cpp revision 226633
1185377Ssam//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2187831Ssam// 3185377Ssam// The LLVM Compiler Infrastructure 4185377Ssam// 5185377Ssam// This file is distributed under the University of Illinois Open Source 6185377Ssam// License. See LICENSE.TXT for details. 7185377Ssam// 8185377Ssam//===----------------------------------------------------------------------===// 9185377Ssam 10185377Ssam#include "MCTargetDesc/ARMBaseInfo.h" 11185377Ssam#include "MCTargetDesc/ARMAddressingModes.h" 12185377Ssam#include "MCTargetDesc/ARMMCExpr.h" 13185377Ssam#include "llvm/MC/MCParser/MCAsmLexer.h" 14185377Ssam#include "llvm/MC/MCParser/MCAsmParser.h" 15185377Ssam#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 16185377Ssam#include "llvm/MC/MCAsmInfo.h" 17185377Ssam#include "llvm/MC/MCContext.h" 18187345Ssam#include "llvm/MC/MCStreamer.h" 19185377Ssam#include "llvm/MC/MCExpr.h" 20185377Ssam#include "llvm/MC/MCInst.h" 21185377Ssam#include "llvm/MC/MCInstrDesc.h" 22185377Ssam#include "llvm/MC/MCRegisterInfo.h" 23187831Ssam#include "llvm/MC/MCSubtargetInfo.h" 24187831Ssam#include "llvm/MC/MCTargetAsmParser.h" 25187831Ssam#include "llvm/Support/MathExtras.h" 26187831Ssam#include "llvm/Support/SourceMgr.h" 27185377Ssam#include "llvm/Support/TargetRegistry.h" 28185377Ssam#include "llvm/Support/raw_ostream.h" 29185377Ssam#include "llvm/ADT/BitVector.h" 30185377Ssam#include "llvm/ADT/OwningPtr.h" 31185377Ssam#include "llvm/ADT/STLExtras.h" 32185377Ssam#include "llvm/ADT/SmallVector.h" 33185377Ssam#include "llvm/ADT/StringExtras.h" 34185377Ssam#include "llvm/ADT/StringSwitch.h" 35185377Ssam#include "llvm/ADT/Twine.h" 36185377Ssam 37185377Ssamusing namespace llvm; 38185377Ssam 39185377Ssamnamespace { 40185377Ssam 41185377Ssamclass ARMOperand; 42185380Ssam 43185380Ssamclass ARMAsmParser : public MCTargetAsmParser { 44185380Ssam MCSubtargetInfo &STI; 45185380Ssam MCAsmParser &Parser; 46185377Ssam 47185380Ssam struct { 48185380Ssam ARMCC::CondCodes Cond; // Condition for IT block. 49185377Ssam unsigned Mask:4; // Condition mask for instructions. 50185380Ssam // Starting at first 1 (from lsb). 51185380Ssam // '1' condition as indicated in IT. 52185380Ssam // '0' inverse of condition (else). 53185380Ssam // Count of instructions in IT block is 54185380Ssam // 4 - trailingzeroes(mask) 55185380Ssam 56185380Ssam bool FirstCond; // Explicit flag for when we're parsing the 57185380Ssam // First instruction in the IT block. It's 58185380Ssam // implied in the mask, so needs special 59185380Ssam // handling. 60185380Ssam 61185380Ssam unsigned CurPosition; // Current position in parsing of IT 62185380Ssam // block. In range [0,3]. Initialized 63185380Ssam // according to count of instructions in block. 64185380Ssam // ~0U if no active IT block. 65185380Ssam } ITState; 66185380Ssam bool inITBlock() { return ITState.CurPosition != ~0U;} 67185380Ssam void forwardITPosition() { 68185380Ssam if (!inITBlock()) return; 69185380Ssam // Move to the next instruction in the IT block, if there is one. If not, 70185380Ssam // mark the block as done. 71185380Ssam unsigned TZ = CountTrailingZeros_32(ITState.Mask); 72185380Ssam if (++ITState.CurPosition == 5 - TZ) 73185380Ssam ITState.CurPosition = ~0U; // Done with the IT block after this. 74185380Ssam } 75185380Ssam 76185380Ssam 77185377Ssam MCAsmParser &getParser() const { return Parser; } 78185377Ssam MCAsmLexer &getLexer() const { return Parser.getLexer(); } 79185380Ssam 80185380Ssam void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 81185377Ssam bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 82185377Ssam 83185380Ssam int tryParseRegister(); 84185380Ssam bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 85185377Ssam int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 86185377Ssam bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 87185377Ssam bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 88185377Ssam bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 89185380Ssam bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 90185377Ssam bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 91185377Ssam unsigned &ShiftAmount); 92185377Ssam bool parseDirectiveWord(unsigned Size, SMLoc L); 93185377Ssam bool parseDirectiveThumb(SMLoc L); 94185377Ssam bool parseDirectiveThumbFunc(SMLoc L); 95185377Ssam bool parseDirectiveCode(SMLoc L); 96185377Ssam bool parseDirectiveSyntax(SMLoc L); 97185377Ssam 98185377Ssam StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 99185377Ssam bool &CarrySetting, unsigned &ProcessorIMod, 100185377Ssam StringRef &ITMask); 101185377Ssam void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 102185377Ssam bool &CanAcceptPredicationCode); 103185377Ssam 104185377Ssam bool isThumb() const { 105185377Ssam // FIXME: Can tablegen auto-generate this? 106185377Ssam return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 107185380Ssam } 108185377Ssam bool isThumbOne() const { 109185377Ssam return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 110185377Ssam } 111185377Ssam bool isThumbTwo() const { 112185377Ssam return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 113185377Ssam } 114185377Ssam bool hasV6Ops() const { 115185377Ssam return STI.getFeatureBits() & ARM::HasV6Ops; 116185377Ssam } 117185377Ssam bool hasV7Ops() const { 118185377Ssam return STI.getFeatureBits() & ARM::HasV7Ops; 119185377Ssam } 120185377Ssam void SwitchMode() { 121185377Ssam unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 122185377Ssam setAvailableFeatures(FB); 123185377Ssam } 124185377Ssam bool isMClass() const { 125185377Ssam return STI.getFeatureBits() & ARM::FeatureMClass; 126185377Ssam } 127185377Ssam 128185377Ssam /// @name Auto-generated Match Functions 129185377Ssam /// { 130185377Ssam 131185377Ssam#define GET_ASSEMBLER_HEADER 132185377Ssam#include "ARMGenAsmMatcher.inc" 133185377Ssam 134185377Ssam /// } 135185377Ssam 136185377Ssam OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&); 137185377Ssam OperandMatchResultTy parseCoprocNumOperand( 138185377Ssam SmallVectorImpl<MCParsedAsmOperand*>&); 139185377Ssam OperandMatchResultTy parseCoprocRegOperand( 140185377Ssam SmallVectorImpl<MCParsedAsmOperand*>&); 141185377Ssam OperandMatchResultTy parseCoprocOptionOperand( 142185377Ssam SmallVectorImpl<MCParsedAsmOperand*>&); 143185377Ssam OperandMatchResultTy parseMemBarrierOptOperand( 144185377Ssam SmallVectorImpl<MCParsedAsmOperand*>&); 145185377Ssam OperandMatchResultTy parseProcIFlagsOperand( 146185377Ssam SmallVectorImpl<MCParsedAsmOperand*>&); 147185377Ssam OperandMatchResultTy parseMSRMaskOperand( 148187831Ssam SmallVectorImpl<MCParsedAsmOperand*>&); 149187831Ssam OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 150187831Ssam StringRef Op, int Low, int High); 151185377Ssam OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 152185377Ssam return parsePKHImm(O, "lsl", 0, 31); 153185377Ssam } 154185377Ssam OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 155185377Ssam return parsePKHImm(O, "asr", 1, 32); 156185377Ssam } 157185377Ssam OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 158185377Ssam OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 159185377Ssam OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 160185377Ssam OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 161185377Ssam OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 162185377Ssam OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 163185377Ssam OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&); 164185377Ssam 165185377Ssam // Asm Match Converter Methods 166185377Ssam bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 167185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 168185377Ssam bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 169185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 170185377Ssam bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 171185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 172185377Ssam bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 173185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 174185377Ssam bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 175185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 176185377Ssam bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 177185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 178185377Ssam bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 179185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 180185377Ssam bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 181185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 182185377Ssam bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 183185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 184185377Ssam bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 185185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 186185377Ssam bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 187185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 188185377Ssam bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 189185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 190185377Ssam bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 191185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 192185377Ssam bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 193185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 194185377Ssam bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 195185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 196185377Ssam bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 197185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 198185377Ssam bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 199185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &); 200185377Ssam 201185377Ssam bool validateInstruction(MCInst &Inst, 202185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 203185377Ssam void processInstruction(MCInst &Inst, 204185377Ssam const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 205185377Ssam bool shouldOmitCCOutOperand(StringRef Mnemonic, 206185377Ssam SmallVectorImpl<MCParsedAsmOperand*> &Operands); 207185377Ssam 208185377Ssampublic: 209185377Ssam enum ARMMatchResultTy { 210185377Ssam Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 211185377Ssam Match_RequiresNotITBlock, 212185377Ssam Match_RequiresV6, 213185377Ssam Match_RequiresThumb2 214185377Ssam }; 215185377Ssam 216185377Ssam ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 217185377Ssam : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 218185377Ssam MCAsmParserExtension::Initialize(_Parser); 219185377Ssam 220185377Ssam // Initialize the set of available features. 221185377Ssam setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 222185377Ssam 223185377Ssam // Not in an ITBlock to start with. 224185377Ssam ITState.CurPosition = ~0U; 225185377Ssam } 226185377Ssam 227185377Ssam // Implementation of the MCTargetAsmParser interface: 228185377Ssam bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 229185377Ssam bool ParseInstruction(StringRef Name, SMLoc NameLoc, 230185377Ssam SmallVectorImpl<MCParsedAsmOperand*> &Operands); 231185377Ssam bool ParseDirective(AsmToken DirectiveID); 232185377Ssam 233185377Ssam unsigned checkTargetMatchPredicate(MCInst &Inst); 234185377Ssam 235185380Ssam bool MatchAndEmitInstruction(SMLoc IDLoc, 236185377Ssam SmallVectorImpl<MCParsedAsmOperand*> &Operands, 237185380Ssam MCStreamer &Out); 238185377Ssam}; 239185377Ssam} // end anonymous namespace 240185377Ssam 241185377Ssamnamespace { 242185377Ssam 243185377Ssam/// ARMOperand - Instances of this class represent a parsed ARM machine 244185377Ssam/// instruction. 245185377Ssamclass ARMOperand : public MCParsedAsmOperand { 246185377Ssam enum KindTy { 247185377Ssam k_CondCode, 248185377Ssam k_CCOut, 249185377Ssam k_ITCondMask, 250185377Ssam k_CoprocNum, 251185377Ssam k_CoprocReg, 252185377Ssam k_CoprocOption, 253185377Ssam k_Immediate, 254185377Ssam k_FPImmediate, 255185377Ssam k_MemBarrierOpt, 256185377Ssam k_Memory, 257185377Ssam k_PostIndexRegister, 258185377Ssam k_MSRMask, 259185377Ssam k_ProcIFlags, 260185377Ssam k_VectorIndex, 261185377Ssam k_Register, 262185377Ssam k_RegisterList, 263185377Ssam k_DPRRegisterList, 264185377Ssam k_SPRRegisterList, 265185377Ssam k_ShiftedRegister, 266185377Ssam k_ShiftedImmediate, 267185377Ssam k_ShifterImmediate, 268185377Ssam k_RotateImmediate, 269185377Ssam k_BitfieldDescriptor, 270185377Ssam k_Token 271185380Ssam } Kind; 272185377Ssam 273185377Ssam SMLoc StartLoc, EndLoc; 274185380Ssam SmallVector<unsigned, 8> Registers; 275187831Ssam 276187831Ssam union { 277187831Ssam struct { 278187831Ssam ARMCC::CondCodes Val; 279187831Ssam } CC; 280185380Ssam 281185377Ssam struct { 282185377Ssam unsigned Val; 283185377Ssam } Cop; 284185377Ssam 285185377Ssam struct { 286185377Ssam unsigned Val; 287185380Ssam } CoprocOption; 288185377Ssam 289185377Ssam struct { 290185377Ssam unsigned Mask:4; 291185377Ssam } ITMask; 292185377Ssam 293185377Ssam struct { 294185377Ssam ARM_MB::MemBOpt Val; 295185377Ssam } MBOpt; 296185377Ssam 297185377Ssam struct { 298185377Ssam ARM_PROC::IFlags Val; 299185377Ssam } IFlags; 300185377Ssam 301185377Ssam struct { 302185377Ssam unsigned Val; 303185377Ssam } MMask; 304185377Ssam 305185377Ssam struct { 306185377Ssam const char *Data; 307185377Ssam unsigned Length; 308185377Ssam } Tok; 309185377Ssam 310185377Ssam struct { 311187831Ssam unsigned RegNum; 312185377Ssam } Reg; 313185377Ssam 314185377Ssam struct { 315185377Ssam unsigned Val; 316185377Ssam } VectorIndex; 317185377Ssam 318185377Ssam struct { 319185377Ssam const MCExpr *Val; 320185377Ssam } Imm; 321185377Ssam 322185377Ssam struct { 323185377Ssam unsigned Val; // encoded 8-bit representation 324185377Ssam } FPImm; 325185377Ssam 326185377Ssam /// Combined record for all forms of ARM address expressions. 327185377Ssam struct { 328185377Ssam unsigned BaseRegNum; 329185377Ssam // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 330185377Ssam // was specified. 331187831Ssam const MCConstantExpr *OffsetImm; // Offset immediate value 332187831Ssam unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 333187831Ssam ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 334187831Ssam unsigned ShiftImm; // shift for OffsetReg. 335185377Ssam unsigned Alignment; // 0 = no alignment specified 336187831Ssam // n = alignment in bytes (8, 16, or 32) 337187831Ssam unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 338187831Ssam } Memory; 339187831Ssam 340187831Ssam struct { 341187831Ssam unsigned RegNum; 342187831Ssam bool isAdd; 343185377Ssam ARM_AM::ShiftOpc ShiftTy; 344187831Ssam unsigned ShiftImm; 345187831Ssam } PostIdxReg; 346187831Ssam 347187831Ssam struct { 348187831Ssam bool isASR; 349187831Ssam unsigned Imm; 350185377Ssam } ShifterImm; 351187831Ssam struct { 352187831Ssam ARM_AM::ShiftOpc ShiftTy; 353185377Ssam unsigned SrcReg; 354187831Ssam unsigned ShiftReg; 355187831Ssam unsigned ShiftImm; 356187831Ssam } RegShiftedReg; 357187831Ssam struct { 358187831Ssam ARM_AM::ShiftOpc ShiftTy; 359187831Ssam unsigned SrcReg; 360187831Ssam unsigned ShiftImm; 361187831Ssam } RegShiftedImm; 362187831Ssam struct { 363187831Ssam unsigned Imm; 364185377Ssam } RotImm; 365187831Ssam struct { 366187831Ssam unsigned LSB; 367187831Ssam unsigned Width; 368187831Ssam } Bitfield; 369185377Ssam }; 370185377Ssam 371185377Ssam ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 372185377Ssampublic: 373185377Ssam ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 374185377Ssam Kind = o.Kind; 375185377Ssam StartLoc = o.StartLoc; 376185377Ssam EndLoc = o.EndLoc; 377185377Ssam switch (Kind) { 378185377Ssam case k_CondCode: 379185377Ssam CC = o.CC; 380185377Ssam break; 381187831Ssam case k_ITCondMask: 382185377Ssam ITMask = o.ITMask; 383187831Ssam break; 384185377Ssam case k_Token: 385185377Ssam Tok = o.Tok; 386187831Ssam break; 387185377Ssam case k_CCOut: 388185377Ssam case k_Register: 389185377Ssam Reg = o.Reg; 390187831Ssam break; 391185377Ssam case k_RegisterList: 392185377Ssam case k_DPRRegisterList: 393187831Ssam case k_SPRRegisterList: 394185377Ssam Registers = o.Registers; 395185377Ssam break; 396185377Ssam case k_CoprocNum: 397185377Ssam case k_CoprocReg: 398185377Ssam Cop = o.Cop; 399185377Ssam break; 400185377Ssam case k_CoprocOption: 401185377Ssam CoprocOption = o.CoprocOption; 402185377Ssam break; 403185377Ssam case k_Immediate: 404185377Ssam Imm = o.Imm; 405185377Ssam break; 406185377Ssam case k_FPImmediate: 407185377Ssam FPImm = o.FPImm; 408185377Ssam break; 409185377Ssam case k_MemBarrierOpt: 410185377Ssam MBOpt = o.MBOpt; 411185377Ssam break; 412185377Ssam case k_Memory: 413185377Ssam Memory = o.Memory; 414185377Ssam break; 415187831Ssam case k_PostIndexRegister: 416187831Ssam PostIdxReg = o.PostIdxReg; 417185377Ssam break; 418185377Ssam case k_MSRMask: 419187831Ssam MMask = o.MMask; 420187831Ssam break; 421187831Ssam case k_ProcIFlags: 422187831Ssam IFlags = o.IFlags; 423187831Ssam break; 424187831Ssam case k_ShifterImmediate: 425187831Ssam ShifterImm = o.ShifterImm; 426187831Ssam break; 427187831Ssam case k_ShiftedRegister: 428187831Ssam RegShiftedReg = o.RegShiftedReg; 429187831Ssam break; 430185377Ssam case k_ShiftedImmediate: 431185377Ssam RegShiftedImm = o.RegShiftedImm; 432185377Ssam break; 433185380Ssam case k_RotateImmediate: 434185377Ssam RotImm = o.RotImm; 435185377Ssam break; 436185377Ssam case k_BitfieldDescriptor: 437185377Ssam Bitfield = o.Bitfield; 438185377Ssam break; 439185377Ssam case k_VectorIndex: 440185377Ssam VectorIndex = o.VectorIndex; 441185377Ssam break; 442185377Ssam } 443185377Ssam } 444185377Ssam 445185377Ssam /// getStartLoc - Get the location of the first token of this operand. 446185377Ssam SMLoc getStartLoc() const { return StartLoc; } 447185377Ssam /// getEndLoc - Get the location of the last token of this operand. 448187831Ssam SMLoc getEndLoc() const { return EndLoc; } 449187831Ssam 450187831Ssam ARMCC::CondCodes getCondCode() const { 451187831Ssam assert(Kind == k_CondCode && "Invalid access!"); 452187831Ssam return CC.Val; 453187831Ssam } 454187831Ssam 455187831Ssam unsigned getCoproc() const { 456187831Ssam assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!"); 457187831Ssam return Cop.Val; 458187831Ssam } 459187831Ssam 460187831Ssam StringRef getToken() const { 461187831Ssam assert(Kind == k_Token && "Invalid access!"); 462187831Ssam return StringRef(Tok.Data, Tok.Length); 463187831Ssam } 464187831Ssam 465187831Ssam unsigned getReg() const { 466187831Ssam assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!"); 467187831Ssam return Reg.RegNum; 468187831Ssam } 469187831Ssam 470187831Ssam const SmallVectorImpl<unsigned> &getRegList() const { 471187831Ssam assert((Kind == k_RegisterList || Kind == k_DPRRegisterList || 472187831Ssam Kind == k_SPRRegisterList) && "Invalid access!"); 473187831Ssam return Registers; 474187831Ssam } 475187831Ssam 476187831Ssam const MCExpr *getImm() const { 477187831Ssam assert(Kind == k_Immediate && "Invalid access!"); 478187831Ssam return Imm.Val; 479187831Ssam } 480187831Ssam 481187831Ssam unsigned getFPImm() const { 482187831Ssam assert(Kind == k_FPImmediate && "Invalid access!"); 483187831Ssam return FPImm.Val; 484187831Ssam } 485187831Ssam 486187831Ssam unsigned getVectorIndex() const { 487187831Ssam assert(Kind == k_VectorIndex && "Invalid access!"); 488187831Ssam return VectorIndex.Val; 489187831Ssam } 490187831Ssam 491187831Ssam ARM_MB::MemBOpt getMemBarrierOpt() const { 492187831Ssam assert(Kind == k_MemBarrierOpt && "Invalid access!"); 493187831Ssam return MBOpt.Val; 494187831Ssam } 495187831Ssam 496187831Ssam ARM_PROC::IFlags getProcIFlags() const { 497187831Ssam assert(Kind == k_ProcIFlags && "Invalid access!"); 498187831Ssam return IFlags.Val; 499187831Ssam } 500187831Ssam 501187831Ssam unsigned getMSRMask() const { 502187831Ssam assert(Kind == k_MSRMask && "Invalid access!"); 503185377Ssam return MMask.Val; 504187831Ssam } 505187831Ssam 506187831Ssam bool isCoprocNum() const { return Kind == k_CoprocNum; } 507185377Ssam bool isCoprocReg() const { return Kind == k_CoprocReg; } 508187831Ssam bool isCoprocOption() const { return Kind == k_CoprocOption; } 509187831Ssam bool isCondCode() const { return Kind == k_CondCode; } 510187831Ssam bool isCCOut() const { return Kind == k_CCOut; } 511185377Ssam bool isITMask() const { return Kind == k_ITCondMask; } 512187831Ssam bool isITCondCode() const { return Kind == k_CondCode; } 513187831Ssam bool isImm() const { return Kind == k_Immediate; } 514187831Ssam bool isFPImm() const { return Kind == k_FPImmediate; } 515185377Ssam bool isImm8s4() const { 516187831Ssam if (Kind != k_Immediate) 517187831Ssam return false; 518187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 519185377Ssam if (!CE) return false; 520187831Ssam int64_t Value = CE->getValue(); 521187831Ssam return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020; 522187831Ssam } 523185377Ssam bool isImm0_1020s4() const { 524187831Ssam if (Kind != k_Immediate) 525187831Ssam return false; 526187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 527185377Ssam if (!CE) return false; 528187831Ssam int64_t Value = CE->getValue(); 529187831Ssam return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 530187831Ssam } 531187831Ssam bool isImm0_508s4() const { 532187831Ssam if (Kind != k_Immediate) 533187831Ssam return false; 534187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 535187831Ssam if (!CE) return false; 536187831Ssam int64_t Value = CE->getValue(); 537187831Ssam return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 538187831Ssam } 539187831Ssam bool isImm0_255() const { 540187831Ssam if (Kind != k_Immediate) 541187831Ssam return false; 542187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 543187831Ssam if (!CE) return false; 544187831Ssam int64_t Value = CE->getValue(); 545187831Ssam return Value >= 0 && Value < 256; 546187831Ssam } 547187831Ssam bool isImm0_7() const { 548187831Ssam if (Kind != k_Immediate) 549187831Ssam return false; 550187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 551187831Ssam if (!CE) return false; 552187831Ssam int64_t Value = CE->getValue(); 553187831Ssam return Value >= 0 && Value < 8; 554187831Ssam } 555187831Ssam bool isImm0_15() const { 556187831Ssam if (Kind != k_Immediate) 557187831Ssam return false; 558187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 559187831Ssam if (!CE) return false; 560187831Ssam int64_t Value = CE->getValue(); 561187831Ssam return Value >= 0 && Value < 16; 562187831Ssam } 563187831Ssam bool isImm0_31() const { 564187831Ssam if (Kind != k_Immediate) 565187831Ssam return false; 566187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 567187831Ssam if (!CE) return false; 568187831Ssam int64_t Value = CE->getValue(); 569187831Ssam return Value >= 0 && Value < 32; 570187831Ssam } 571187831Ssam bool isImm1_16() const { 572187831Ssam if (Kind != k_Immediate) 573187831Ssam return false; 574187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 575187831Ssam if (!CE) return false; 576187831Ssam int64_t Value = CE->getValue(); 577187831Ssam return Value > 0 && Value < 17; 578187831Ssam } 579187831Ssam bool isImm1_32() const { 580187831Ssam if (Kind != k_Immediate) 581187831Ssam return false; 582187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 583187831Ssam if (!CE) return false; 584187831Ssam int64_t Value = CE->getValue(); 585185377Ssam return Value > 0 && Value < 33; 586185377Ssam } 587185380Ssam bool isImm0_65535() const { 588185380Ssam if (Kind != k_Immediate) 589185380Ssam return false; 590185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 591185380Ssam if (!CE) return false; 592185380Ssam int64_t Value = CE->getValue(); 593185380Ssam return Value >= 0 && Value < 65536; 594185380Ssam } 595185380Ssam bool isImm0_65535Expr() const { 596185380Ssam if (Kind != k_Immediate) 597185380Ssam return false; 598185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 599185380Ssam // If it's not a constant expression, it'll generate a fixup and be 600185380Ssam // handled later. 601185380Ssam if (!CE) return true; 602185380Ssam int64_t Value = CE->getValue(); 603185380Ssam return Value >= 0 && Value < 65536; 604185380Ssam } 605185380Ssam bool isImm24bit() const { 606185380Ssam if (Kind != k_Immediate) 607185380Ssam return false; 608185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 609185380Ssam if (!CE) return false; 610185380Ssam int64_t Value = CE->getValue(); 611185377Ssam return Value >= 0 && Value <= 0xffffff; 612185377Ssam } 613185377Ssam bool isImmThumbSR() const { 614185377Ssam if (Kind != k_Immediate) 615185377Ssam return false; 616185377Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 617185377Ssam if (!CE) return false; 618185377Ssam int64_t Value = CE->getValue(); 619185377Ssam return Value > 0 && Value < 33; 620185377Ssam } 621185377Ssam bool isPKHLSLImm() const { 622185377Ssam if (Kind != k_Immediate) 623185377Ssam return false; 624185377Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 625185377Ssam if (!CE) return false; 626185377Ssam int64_t Value = CE->getValue(); 627185377Ssam return Value >= 0 && Value < 32; 628185377Ssam } 629187831Ssam bool isPKHASRImm() const { 630185380Ssam if (Kind != k_Immediate) 631187831Ssam return false; 632185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 633187831Ssam if (!CE) return false; 634185380Ssam int64_t Value = CE->getValue(); 635187831Ssam return Value > 0 && Value <= 32; 636185380Ssam } 637187831Ssam bool isARMSOImm() const { 638185380Ssam if (Kind != k_Immediate) 639187831Ssam return false; 640185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 641187831Ssam if (!CE) return false; 642185380Ssam int64_t Value = CE->getValue(); 643187831Ssam return ARM_AM::getSOImmVal(Value) != -1; 644185380Ssam } 645187831Ssam bool isT2SOImm() const { 646185380Ssam if (Kind != k_Immediate) 647185377Ssam return false; 648187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 649185380Ssam if (!CE) return false; 650187831Ssam int64_t Value = CE->getValue(); 651185380Ssam return ARM_AM::getT2SOImmVal(Value) != -1; 652187831Ssam } 653185380Ssam bool isSetEndImm() const { 654185377Ssam if (Kind != k_Immediate) 655187831Ssam return false; 656185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 657187831Ssam if (!CE) return false; 658185380Ssam int64_t Value = CE->getValue(); 659185377Ssam return Value == 1 || Value == 0; 660187831Ssam } 661185380Ssam bool isReg() const { return Kind == k_Register; } 662187831Ssam bool isRegList() const { return Kind == k_RegisterList; } 663185380Ssam bool isDPRRegList() const { return Kind == k_DPRRegisterList; } 664187831Ssam bool isSPRRegList() const { return Kind == k_SPRRegisterList; } 665185380Ssam bool isToken() const { return Kind == k_Token; } 666187831Ssam bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } 667185380Ssam bool isMemory() const { return Kind == k_Memory; } 668187831Ssam bool isShifterImm() const { return Kind == k_ShifterImmediate; } 669185380Ssam bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } 670187831Ssam bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } 671185380Ssam bool isRotImm() const { return Kind == k_RotateImmediate; } 672187831Ssam bool isBitfield() const { return Kind == k_BitfieldDescriptor; } 673185380Ssam bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } 674187831Ssam bool isPostIdxReg() const { 675185380Ssam return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 676187831Ssam } 677185377Ssam bool isMemNoOffset(bool alignOK = false) const { 678185380Ssam if (!isMemory()) 679187831Ssam return false; 680185377Ssam // No offset of any kind. 681185380Ssam return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 && 682187831Ssam (alignOK || Memory.Alignment == 0); 683185377Ssam } 684185380Ssam bool isAlignedMemory() const { 685187831Ssam return isMemNoOffset(true); 686185377Ssam } 687185380Ssam bool isAddrMode2() const { 688187831Ssam if (!isMemory() || Memory.Alignment != 0) return false; 689185380Ssam // Check for register offset. 690185377Ssam if (Memory.OffsetRegNum) return true; 691187831Ssam // Immediate offset in range [-4095, 4095]. 692185380Ssam if (!Memory.OffsetImm) return true; 693187831Ssam int64_t Val = Memory.OffsetImm->getValue(); 694185380Ssam return Val > -4096 && Val < 4096; 695187831Ssam } 696185380Ssam bool isAM2OffsetImm() const { 697187831Ssam if (Kind != k_Immediate) 698185380Ssam return false; 699187831Ssam // Immediate offset in range [-4095, 4095]. 700185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 701187831Ssam if (!CE) return false; 702185380Ssam int64_t Val = CE->getValue(); 703185377Ssam return Val > -4096 && Val < 4096; 704187831Ssam } 705185380Ssam bool isAddrMode3() const { 706187831Ssam if (!isMemory() || Memory.Alignment != 0) return false; 707185380Ssam // No shifts are legal for AM3. 708187831Ssam if (Memory.ShiftType != ARM_AM::no_shift) return false; 709185380Ssam // Check for register offset. 710185377Ssam if (Memory.OffsetRegNum) return true; 711187831Ssam // Immediate offset in range [-255, 255]. 712185380Ssam if (!Memory.OffsetImm) return true; 713185377Ssam int64_t Val = Memory.OffsetImm->getValue(); 714187831Ssam return Val > -256 && Val < 256; 715185380Ssam } 716185377Ssam bool isAM3Offset() const { 717187831Ssam if (Kind != k_Immediate && Kind != k_PostIndexRegister) 718185380Ssam return false; 719187831Ssam if (Kind == k_PostIndexRegister) 720185380Ssam return PostIdxReg.ShiftTy == ARM_AM::no_shift; 721187831Ssam // Immediate offset in range [-255, 255]. 722185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 723187831Ssam if (!CE) return false; 724185380Ssam int64_t Val = CE->getValue(); 725185377Ssam // Special case, #-0 is INT32_MIN. 726187831Ssam return (Val > -256 && Val < 256) || Val == INT32_MIN; 727185380Ssam } 728187831Ssam bool isAddrMode5() const { 729185380Ssam if (!isMemory() || Memory.Alignment != 0) return false; 730187831Ssam // Check for register offset. 731185380Ssam if (Memory.OffsetRegNum) return false; 732187831Ssam // Immediate offset in range [-1020, 1020] and a multiple of 4. 733185380Ssam if (!Memory.OffsetImm) return true; 734187831Ssam int64_t Val = Memory.OffsetImm->getValue(); 735185380Ssam return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) || 736187831Ssam Val == INT32_MIN; 737185380Ssam } 738187831Ssam bool isMemTBB() const { 739185380Ssam if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 740187831Ssam Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 741185380Ssam return false; 742187831Ssam return true; 743185380Ssam } 744187831Ssam bool isMemTBH() const { 745185380Ssam if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 746187831Ssam Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 || 747185380Ssam Memory.Alignment != 0 ) 748187831Ssam return false; 749185380Ssam return true; 750187831Ssam } 751185380Ssam bool isMemRegOffset() const { 752185377Ssam if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0) 753185377Ssam return false; 754185377Ssam return true; 755185377Ssam } 756185377Ssam bool isT2MemRegOffset() const { 757185377Ssam if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 758187831Ssam Memory.Alignment != 0) 759185380Ssam return false; 760187831Ssam // Only lsl #{0, 1, 2, 3} allowed. 761185380Ssam if (Memory.ShiftType == ARM_AM::no_shift) 762187831Ssam return true; 763185380Ssam if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3) 764187831Ssam return false; 765185380Ssam return true; 766187831Ssam } 767185380Ssam bool isMemThumbRR() const { 768187831Ssam // Thumb reg+reg addressing is simple. Just two registers, a base and 769185380Ssam // an offset. No shifts, negations or any other complicating factors. 770187831Ssam if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative || 771185380Ssam Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0) 772187831Ssam return false; 773185380Ssam return isARMLowRegister(Memory.BaseRegNum) && 774187831Ssam (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum)); 775185380Ssam } 776187831Ssam bool isMemThumbRIs4() const { 777185380Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || 778185377Ssam !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 779185377Ssam return false; 780185377Ssam // Immediate offset, multiple of 4 in range [0, 124]. 781185377Ssam if (!Memory.OffsetImm) return true; 782185377Ssam int64_t Val = Memory.OffsetImm->getValue(); 783185377Ssam return Val >= 0 && Val <= 124 && (Val % 4) == 0; 784187831Ssam } 785185380Ssam bool isMemThumbRIs2() const { 786187831Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || 787185380Ssam !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 788187831Ssam return false; 789185380Ssam // Immediate offset, multiple of 4 in range [0, 62]. 790187831Ssam if (!Memory.OffsetImm) return true; 791185380Ssam int64_t Val = Memory.OffsetImm->getValue(); 792185377Ssam return Val >= 0 && Val <= 62 && (Val % 2) == 0; 793187831Ssam } 794185380Ssam bool isMemThumbRIs1() const { 795187831Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || 796185380Ssam !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0) 797187831Ssam return false; 798185380Ssam // Immediate offset in range [0, 31]. 799187831Ssam if (!Memory.OffsetImm) return true; 800185380Ssam int64_t Val = Memory.OffsetImm->getValue(); 801185377Ssam return Val >= 0 && Val <= 31; 802187831Ssam } 803185380Ssam bool isMemThumbSPI() const { 804187831Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || 805185380Ssam Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0) 806187831Ssam return false; 807185380Ssam // Immediate offset, multiple of 4 in range [0, 1020]. 808187831Ssam if (!Memory.OffsetImm) return true; 809185380Ssam int64_t Val = Memory.OffsetImm->getValue(); 810185377Ssam return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 811187831Ssam } 812185380Ssam bool isMemImm8s4Offset() const { 813187831Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 814185380Ssam return false; 815187831Ssam // Immediate offset a multiple of 4 in range [-1020, 1020]. 816185380Ssam if (!Memory.OffsetImm) return true; 817187831Ssam int64_t Val = Memory.OffsetImm->getValue(); 818185380Ssam return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; 819187831Ssam } 820185380Ssam bool isMemImm0_1020s4Offset() const { 821187831Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 822185380Ssam return false; 823185377Ssam // Immediate offset a multiple of 4 in range [0, 1020]. 824187831Ssam if (!Memory.OffsetImm) return true; 825185380Ssam int64_t Val = Memory.OffsetImm->getValue(); 826187831Ssam return Val >= 0 && Val <= 1020 && (Val & 3) == 0; 827185380Ssam } 828187831Ssam bool isMemImm8Offset() const { 829185380Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 830185377Ssam return false; 831187831Ssam // Immediate offset in range [-255, 255]. 832185380Ssam if (!Memory.OffsetImm) return true; 833185377Ssam int64_t Val = Memory.OffsetImm->getValue(); 834185377Ssam return (Val == INT32_MIN) || (Val > -256 && Val < 256); 835185377Ssam } 836185377Ssam bool isMemPosImm8Offset() const { 837187831Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 838185380Ssam return false; 839187831Ssam // Immediate offset in range [0, 255]. 840185380Ssam if (!Memory.OffsetImm) return true; 841187831Ssam int64_t Val = Memory.OffsetImm->getValue(); 842185380Ssam return Val >= 0 && Val < 256; 843187831Ssam } 844185380Ssam bool isMemNegImm8Offset() const { 845185377Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 846185377Ssam return false; 847185377Ssam // Immediate offset in range [-255, -1]. 848185377Ssam if (!Memory.OffsetImm) return true; 849185377Ssam int64_t Val = Memory.OffsetImm->getValue(); 850185380Ssam return Val > -256 && Val < 0; 851187831Ssam } 852185380Ssam bool isMemUImm12Offset() const { 853187831Ssam // If we have an immediate that's not a constant, treat it as a label 854185380Ssam // reference needing a fixup. If it is a constant, it's something else 855185377Ssam // and we reject it. 856187831Ssam if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 857185380Ssam return true; 858187831Ssam 859185380Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 860187831Ssam return false; 861185380Ssam // Immediate offset in range [0, 4095]. 862185377Ssam if (!Memory.OffsetImm) return true; 863187831Ssam int64_t Val = Memory.OffsetImm->getValue(); 864185380Ssam return (Val >= 0 && Val < 4096); 865187831Ssam } 866185380Ssam bool isMemImm12Offset() const { 867185377Ssam // If we have an immediate that's not a constant, treat it as a label 868187831Ssam // reference needing a fixup. If it is a constant, it's something else 869185380Ssam // and we reject it. 870185377Ssam if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm())) 871187831Ssam return true; 872185380Ssam 873185377Ssam if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) 874187831Ssam return false; 875185380Ssam // Immediate offset in range [-4095, 4095]. 876185377Ssam if (!Memory.OffsetImm) return true; 877187831Ssam int64_t Val = Memory.OffsetImm->getValue(); 878185380Ssam return (Val > -4096 && Val < 4096) || (Val == INT32_MIN); 879187831Ssam } 880185380Ssam bool isPostIdxImm8() const { 881185377Ssam if (Kind != k_Immediate) 882187831Ssam return false; 883185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 884185377Ssam if (!CE) return false; 885185377Ssam int64_t Val = CE->getValue(); 886185380Ssam return (Val > -256 && Val < 256) || (Val == INT32_MIN); 887185380Ssam } 888185377Ssam bool isPostIdxImm8s4() const { 889187831Ssam if (Kind != k_Immediate) 890185380Ssam return false; 891187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 892185380Ssam if (!CE) return false; 893187831Ssam int64_t Val = CE->getValue(); 894185380Ssam return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) || 895187831Ssam (Val == INT32_MIN); 896185380Ssam } 897187831Ssam 898185380Ssam bool isMSRMask() const { return Kind == k_MSRMask; } 899187831Ssam bool isProcIFlags() const { return Kind == k_ProcIFlags; } 900185380Ssam 901187831Ssam bool isVectorIndex8() const { 902185380Ssam if (Kind != k_VectorIndex) return false; 903187831Ssam return VectorIndex.Val < 8; 904185380Ssam } 905187831Ssam bool isVectorIndex16() const { 906185380Ssam if (Kind != k_VectorIndex) return false; 907187831Ssam return VectorIndex.Val < 4; 908185380Ssam } 909187831Ssam bool isVectorIndex32() const { 910185380Ssam if (Kind != k_VectorIndex) return false; 911187831Ssam return VectorIndex.Val < 2; 912185380Ssam } 913185377Ssam 914185377Ssam 915185377Ssam 916185377Ssam void addExpr(MCInst &Inst, const MCExpr *Expr) const { 917185377Ssam // Add as immediates when possible. Null MCExpr = 0. 918185377Ssam if (Expr == 0) 919187831Ssam Inst.addOperand(MCOperand::CreateImm(0)); 920185380Ssam else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 921187831Ssam Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 922185380Ssam else 923187831Ssam Inst.addOperand(MCOperand::CreateExpr(Expr)); 924185380Ssam } 925187831Ssam 926185380Ssam void addCondCodeOperands(MCInst &Inst, unsigned N) const { 927185377Ssam assert(N == 2 && "Invalid number of operands!"); 928187831Ssam Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 929185380Ssam unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 930187831Ssam Inst.addOperand(MCOperand::CreateReg(RegNum)); 931185380Ssam } 932187831Ssam 933185380Ssam void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 934187831Ssam assert(N == 1 && "Invalid number of operands!"); 935185380Ssam Inst.addOperand(MCOperand::CreateImm(getCoproc())); 936187831Ssam } 937185380Ssam 938185377Ssam void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 939187831Ssam assert(N == 1 && "Invalid number of operands!"); 940185380Ssam Inst.addOperand(MCOperand::CreateImm(getCoproc())); 941187831Ssam } 942185380Ssam 943187831Ssam void addCoprocOptionOperands(MCInst &Inst, unsigned N) const { 944185380Ssam assert(N == 1 && "Invalid number of operands!"); 945187831Ssam Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val)); 946185380Ssam } 947185377Ssam 948187831Ssam void addITMaskOperands(MCInst &Inst, unsigned N) const { 949185380Ssam assert(N == 1 && "Invalid number of operands!"); 950185377Ssam Inst.addOperand(MCOperand::CreateImm(ITMask.Mask)); 951187831Ssam } 952185380Ssam 953185377Ssam void addITCondCodeOperands(MCInst &Inst, unsigned N) const { 954187831Ssam assert(N == 1 && "Invalid number of operands!"); 955185380Ssam Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 956187831Ssam } 957185380Ssam 958187831Ssam void addCCOutOperands(MCInst &Inst, unsigned N) const { 959185380Ssam assert(N == 1 && "Invalid number of operands!"); 960185377Ssam Inst.addOperand(MCOperand::CreateReg(getReg())); 961187831Ssam } 962185380Ssam 963185377Ssam void addRegOperands(MCInst &Inst, unsigned N) const { 964185377Ssam assert(N == 1 && "Invalid number of operands!"); 965185377Ssam Inst.addOperand(MCOperand::CreateReg(getReg())); 966185377Ssam } 967187831Ssam 968185380Ssam void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 969187831Ssam assert(N == 3 && "Invalid number of operands!"); 970185380Ssam assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 971187831Ssam Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 972185380Ssam Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 973187831Ssam Inst.addOperand(MCOperand::CreateImm( 974185380Ssam ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 975187831Ssam } 976185380Ssam 977187831Ssam void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 978185380Ssam assert(N == 2 && "Invalid number of operands!"); 979187831Ssam assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 980185380Ssam Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 981187831Ssam Inst.addOperand(MCOperand::CreateImm( 982185380Ssam ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 983187831Ssam } 984185380Ssam 985187831Ssam void addShifterImmOperands(MCInst &Inst, unsigned N) const { 986185380Ssam assert(N == 1 && "Invalid number of operands!"); 987185377Ssam Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 988185377Ssam ShifterImm.Imm)); 989185377Ssam } 990185377Ssam 991185377Ssam void addRegListOperands(MCInst &Inst, unsigned N) const { 992185377Ssam assert(N == 1 && "Invalid number of operands!"); 993187831Ssam const SmallVectorImpl<unsigned> &RegList = getRegList(); 994185380Ssam for (SmallVectorImpl<unsigned>::const_iterator 995187831Ssam I = RegList.begin(), E = RegList.end(); I != E; ++I) 996185380Ssam Inst.addOperand(MCOperand::CreateReg(*I)); 997187831Ssam } 998185380Ssam 999187831Ssam void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 1000185380Ssam addRegListOperands(Inst, N); 1001187831Ssam } 1002185380Ssam 1003185377Ssam void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 1004185377Ssam addRegListOperands(Inst, N); 1005185377Ssam } 1006185380Ssam 1007185377Ssam void addRotImmOperands(MCInst &Inst, unsigned N) const { 1008185380Ssam assert(N == 1 && "Invalid number of operands!"); 1009185380Ssam // Encoded as val>>3. The printer handles display as 8, 16, 24. 1010185380Ssam Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 1011185380Ssam } 1012185380Ssam 1013185380Ssam void addBitfieldOperands(MCInst &Inst, unsigned N) const { 1014185380Ssam assert(N == 1 && "Invalid number of operands!"); 1015185380Ssam // Munge the lsb/width into a bitfield mask. 1016185380Ssam unsigned lsb = Bitfield.LSB; 1017185380Ssam unsigned width = Bitfield.Width; 1018185380Ssam // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 1019185380Ssam uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 1020185380Ssam (32 - (lsb + width))); 1021185380Ssam Inst.addOperand(MCOperand::CreateImm(Mask)); 1022185377Ssam } 1023185377Ssam 1024185377Ssam void addImmOperands(MCInst &Inst, unsigned N) const { 1025185377Ssam assert(N == 1 && "Invalid number of operands!"); 1026185380Ssam addExpr(Inst, getImm()); 1027185380Ssam } 1028185380Ssam 1029187831Ssam void addFPImmOperands(MCInst &Inst, unsigned N) const { 1030187831Ssam assert(N == 1 && "Invalid number of operands!"); 1031187831Ssam Inst.addOperand(MCOperand::CreateImm(getFPImm())); 1032185380Ssam } 1033185380Ssam 1034185380Ssam void addImm8s4Operands(MCInst &Inst, unsigned N) const { 1035185380Ssam assert(N == 1 && "Invalid number of operands!"); 1036185380Ssam // FIXME: We really want to scale the value here, but the LDRD/STRD 1037185380Ssam // instruction don't encode operands that way yet. 1038185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1039185380Ssam Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 1040185380Ssam } 1041185380Ssam 1042185380Ssam void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 1043185380Ssam assert(N == 1 && "Invalid number of operands!"); 1044185380Ssam // The immediate is scaled by four in the encoding and is stored 1045185380Ssam // in the MCInst as such. Lop off the low two bits here. 1046185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1047185380Ssam Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 1048185380Ssam } 1049185380Ssam 1050185380Ssam void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 1051185380Ssam assert(N == 1 && "Invalid number of operands!"); 1052185380Ssam // The immediate is scaled by four in the encoding and is stored 1053185377Ssam // in the MCInst as such. Lop off the low two bits here. 1054185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1055185380Ssam Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 1056185380Ssam } 1057185380Ssam 1058185377Ssam void addImm0_255Operands(MCInst &Inst, unsigned N) const { 1059185380Ssam assert(N == 1 && "Invalid number of operands!"); 1060185380Ssam addExpr(Inst, getImm()); 1061185380Ssam } 1062185380Ssam 1063185377Ssam void addImm0_7Operands(MCInst &Inst, unsigned N) const { 1064185380Ssam assert(N == 1 && "Invalid number of operands!"); 1065185380Ssam addExpr(Inst, getImm()); 1066185380Ssam } 1067185380Ssam 1068185377Ssam void addImm0_15Operands(MCInst &Inst, unsigned N) const { 1069185380Ssam assert(N == 1 && "Invalid number of operands!"); 1070185380Ssam addExpr(Inst, getImm()); 1071185380Ssam } 1072185380Ssam 1073185377Ssam void addImm0_31Operands(MCInst &Inst, unsigned N) const { 1074185380Ssam assert(N == 1 && "Invalid number of operands!"); 1075185380Ssam addExpr(Inst, getImm()); 1076185380Ssam } 1077185380Ssam 1078185377Ssam void addImm1_16Operands(MCInst &Inst, unsigned N) const { 1079185380Ssam assert(N == 1 && "Invalid number of operands!"); 1080185380Ssam // The constant encodes as the immediate-1, and we store in the instruction 1081185380Ssam // the bits as encoded, so subtract off one here. 1082185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1083185380Ssam Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1084185380Ssam } 1085185380Ssam 1086185377Ssam void addImm1_32Operands(MCInst &Inst, unsigned N) const { 1087185380Ssam assert(N == 1 && "Invalid number of operands!"); 1088185380Ssam // The constant encodes as the immediate-1, and we store in the instruction 1089185380Ssam // the bits as encoded, so subtract off one here. 1090185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1091185380Ssam Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 1092185377Ssam } 1093185380Ssam 1094185380Ssam void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 1095185380Ssam assert(N == 1 && "Invalid number of operands!"); 1096185380Ssam addExpr(Inst, getImm()); 1097185380Ssam } 1098185380Ssam 1099185380Ssam void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 1100185377Ssam assert(N == 1 && "Invalid number of operands!"); 1101185380Ssam addExpr(Inst, getImm()); 1102185380Ssam } 1103185380Ssam 1104185380Ssam void addImm24bitOperands(MCInst &Inst, unsigned N) const { 1105185380Ssam assert(N == 1 && "Invalid number of operands!"); 1106185380Ssam addExpr(Inst, getImm()); 1107185380Ssam } 1108185377Ssam 1109185380Ssam void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 1110185380Ssam assert(N == 1 && "Invalid number of operands!"); 1111185380Ssam // The constant encodes as the immediate, except for 32, which encodes as 1112185380Ssam // zero. 1113185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1114185380Ssam unsigned Imm = CE->getValue(); 1115185380Ssam Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 1116185377Ssam } 1117185380Ssam 1118185380Ssam void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 1119185380Ssam assert(N == 1 && "Invalid number of operands!"); 1120185380Ssam addExpr(Inst, getImm()); 1121185380Ssam } 1122185380Ssam 1123185380Ssam void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 1124185377Ssam assert(N == 1 && "Invalid number of operands!"); 1125185380Ssam // An ASR value of 32 encodes as 0, so that's how we want to add it to 1126185380Ssam // the instruction as well. 1127185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1128185380Ssam int Val = CE->getValue(); 1129185380Ssam Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 1130185380Ssam } 1131185380Ssam 1132185377Ssam void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 1133185380Ssam assert(N == 1 && "Invalid number of operands!"); 1134185380Ssam addExpr(Inst, getImm()); 1135185380Ssam } 1136185380Ssam 1137185380Ssam void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 1138185380Ssam assert(N == 1 && "Invalid number of operands!"); 1139185380Ssam addExpr(Inst, getImm()); 1140185377Ssam } 1141185380Ssam 1142185380Ssam void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 1143185380Ssam assert(N == 1 && "Invalid number of operands!"); 1144185380Ssam addExpr(Inst, getImm()); 1145185380Ssam } 1146185380Ssam 1147185380Ssam void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 1148185377Ssam assert(N == 1 && "Invalid number of operands!"); 1149185380Ssam Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 1150185380Ssam } 1151185380Ssam 1152185380Ssam void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 1153185380Ssam assert(N == 1 && "Invalid number of operands!"); 1154185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1155185377Ssam } 1156185380Ssam 1157185380Ssam void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const { 1158185380Ssam assert(N == 2 && "Invalid number of operands!"); 1159185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1160185380Ssam Inst.addOperand(MCOperand::CreateImm(Memory.Alignment)); 1161185377Ssam } 1162185380Ssam 1163185380Ssam void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 1164185380Ssam assert(N == 3 && "Invalid number of operands!"); 1165185380Ssam int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1166185380Ssam if (!Memory.OffsetRegNum) { 1167185380Ssam ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1168185380Ssam // Special case for #-0 1169185380Ssam if (Val == INT32_MIN) Val = 0; 1170185380Ssam if (Val < 0) Val = -Val; 1171185380Ssam Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1172185380Ssam } else { 1173185380Ssam // For register offset, we encode the shift type and negation flag 1174185380Ssam // here. 1175185380Ssam Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1176185377Ssam Memory.ShiftImm, Memory.ShiftType); 1177185380Ssam } 1178185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1179185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1180185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1181185380Ssam } 1182185380Ssam 1183185380Ssam void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 1184185380Ssam assert(N == 2 && "Invalid number of operands!"); 1185185377Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1186185380Ssam assert(CE && "non-constant AM2OffsetImm operand!"); 1187185380Ssam int32_t Val = CE->getValue(); 1188185380Ssam ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1189185380Ssam // Special case for #-0 1190185380Ssam if (Val == INT32_MIN) Val = 0; 1191185380Ssam if (Val < 0) Val = -Val; 1192185380Ssam Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 1193185380Ssam Inst.addOperand(MCOperand::CreateReg(0)); 1194185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1195185377Ssam } 1196185380Ssam 1197185380Ssam void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 1198185380Ssam assert(N == 3 && "Invalid number of operands!"); 1199185380Ssam int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1200185380Ssam if (!Memory.OffsetRegNum) { 1201185380Ssam ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1202185377Ssam // Special case for #-0 1203185380Ssam if (Val == INT32_MIN) Val = 0; 1204185380Ssam if (Val < 0) Val = -Val; 1205185380Ssam Val = ARM_AM::getAM3Opc(AddSub, Val); 1206185380Ssam } else { 1207185380Ssam // For register offset, we encode the shift type and negation flag 1208187831Ssam // here. 1209185380Ssam Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 1210185380Ssam } 1211185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1212185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1213185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1214185377Ssam } 1215185380Ssam 1216185380Ssam void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 1217185380Ssam assert(N == 2 && "Invalid number of operands!"); 1218185380Ssam if (Kind == k_PostIndexRegister) { 1219185380Ssam int32_t Val = 1220185380Ssam ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 1221185377Ssam Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1222185377Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1223185380Ssam return; 1224185380Ssam } 1225185380Ssam 1226185380Ssam // Constant offset. 1227185380Ssam const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 1228185380Ssam int32_t Val = CE->getValue(); 1229185380Ssam ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1230185377Ssam // Special case for #-0 1231185377Ssam if (Val == INT32_MIN) Val = 0; 1232185380Ssam if (Val < 0) Val = -Val; 1233185380Ssam Val = ARM_AM::getAM3Opc(AddSub, Val); 1234185380Ssam Inst.addOperand(MCOperand::CreateReg(0)); 1235185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1236185380Ssam } 1237185380Ssam 1238185380Ssam void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 1239185377Ssam assert(N == 2 && "Invalid number of operands!"); 1240185377Ssam // The lower two bits are always zero and as such are not encoded. 1241185380Ssam int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1242185380Ssam ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 1243185380Ssam // Special case for #-0 1244185380Ssam if (Val == INT32_MIN) Val = 0; 1245185380Ssam if (Val < 0) Val = -Val; 1246185380Ssam Val = ARM_AM::getAM5Opc(AddSub, Val); 1247185377Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1248185377Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1249185380Ssam } 1250185380Ssam 1251185380Ssam void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const { 1252185380Ssam assert(N == 2 && "Invalid number of operands!"); 1253185380Ssam int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1254185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1255185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1256185377Ssam } 1257185377Ssam 1258185380Ssam void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const { 1259185380Ssam assert(N == 2 && "Invalid number of operands!"); 1260185380Ssam // The lower two bits are always zero and as such are not encoded. 1261185380Ssam int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0; 1262185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1263185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1264185380Ssam } 1265185380Ssam 1266185380Ssam void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1267185380Ssam assert(N == 2 && "Invalid number of operands!"); 1268185377Ssam int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1269185377Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1270185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1271185380Ssam } 1272185380Ssam 1273185380Ssam void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1274185380Ssam addMemImm8OffsetOperands(Inst, N); 1275185380Ssam } 1276185380Ssam 1277185380Ssam void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const { 1278185380Ssam addMemImm8OffsetOperands(Inst, N); 1279185380Ssam } 1280185380Ssam 1281185380Ssam void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1282185377Ssam assert(N == 2 && "Invalid number of operands!"); 1283185377Ssam // If this is an immediate, it's a label reference. 1284185380Ssam if (Kind == k_Immediate) { 1285185380Ssam addExpr(Inst, getImm()); 1286185380Ssam Inst.addOperand(MCOperand::CreateImm(0)); 1287185380Ssam return; 1288185380Ssam } 1289185380Ssam 1290185380Ssam // Otherwise, it's a normal memory reg+offset. 1291185380Ssam int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1292185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1293185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1294185380Ssam } 1295185380Ssam 1296185380Ssam void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 1297185380Ssam assert(N == 2 && "Invalid number of operands!"); 1298185377Ssam // If this is an immediate, it's a label reference. 1299185377Ssam if (Kind == k_Immediate) { 1300185380Ssam addExpr(Inst, getImm()); 1301185380Ssam Inst.addOperand(MCOperand::CreateImm(0)); 1302185380Ssam return; 1303185380Ssam } 1304185380Ssam 1305185377Ssam // Otherwise, it's a normal memory reg+offset. 1306185380Ssam int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0; 1307185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1308185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1309185380Ssam } 1310185380Ssam 1311185380Ssam void addMemTBBOperands(MCInst &Inst, unsigned N) const { 1312185380Ssam assert(N == 2 && "Invalid number of operands!"); 1313185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1314185377Ssam Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1315185380Ssam } 1316185380Ssam 1317185380Ssam void addMemTBHOperands(MCInst &Inst, unsigned N) const { 1318185380Ssam assert(N == 2 && "Invalid number of operands!"); 1319185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1320185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1321185380Ssam } 1322185380Ssam 1323185377Ssam void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1324185380Ssam assert(N == 3 && "Invalid number of operands!"); 1325185380Ssam unsigned Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 1326185380Ssam Memory.ShiftImm, Memory.ShiftType); 1327185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1328185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1329185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1330185380Ssam } 1331185380Ssam 1332185377Ssam void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const { 1333185380Ssam assert(N == 3 && "Invalid number of operands!"); 1334185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1335185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1336185380Ssam Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm)); 1337185380Ssam } 1338185380Ssam 1339185377Ssam void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 1340185380Ssam assert(N == 2 && "Invalid number of operands!"); 1341185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1342185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum)); 1343185380Ssam } 1344185380Ssam 1345185380Ssam void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 1346185380Ssam assert(N == 2 && "Invalid number of operands!"); 1347185380Ssam int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1348185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1349185377Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1350185380Ssam } 1351185380Ssam 1352185380Ssam void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 1353185380Ssam assert(N == 2 && "Invalid number of operands!"); 1354185380Ssam int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0; 1355185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1356185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1357185380Ssam } 1358185380Ssam 1359185380Ssam void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 1360185377Ssam assert(N == 2 && "Invalid number of operands!"); 1361185380Ssam int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0; 1362185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1363185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1364185380Ssam } 1365185380Ssam 1366185380Ssam void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1367185377Ssam assert(N == 2 && "Invalid number of operands!"); 1368185380Ssam int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0; 1369185380Ssam Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum)); 1370185380Ssam Inst.addOperand(MCOperand::CreateImm(Val)); 1371185380Ssam } 1372185380Ssam 1373185380Ssam void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 1374185377Ssam assert(N == 1 && "Invalid number of operands!"); 1375185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1376185380Ssam assert(CE && "non-constant post-idx-imm8 operand!"); 1377185380Ssam int Imm = CE->getValue(); 1378185380Ssam bool isAdd = Imm >= 0; 1379185380Ssam if (Imm == INT32_MIN) Imm = 0; 1380185380Ssam Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 1381185380Ssam Inst.addOperand(MCOperand::CreateImm(Imm)); 1382185380Ssam } 1383185380Ssam 1384185380Ssam void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const { 1385185380Ssam assert(N == 1 && "Invalid number of operands!"); 1386185380Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 1387185380Ssam assert(CE && "non-constant post-idx-imm8s4 operand!"); 1388185380Ssam int Imm = CE->getValue(); 1389185380Ssam bool isAdd = Imm >= 0; 1390185380Ssam if (Imm == INT32_MIN) Imm = 0; 1391185380Ssam // Immediate is scaled by 4. 1392185380Ssam Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8; 1393185380Ssam Inst.addOperand(MCOperand::CreateImm(Imm)); 1394185380Ssam } 1395185380Ssam 1396185380Ssam void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 1397185380Ssam assert(N == 2 && "Invalid number of operands!"); 1398185380Ssam Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1399185380Ssam Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1400185380Ssam } 1401185380Ssam 1402185380Ssam void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1403185380Ssam assert(N == 2 && "Invalid number of operands!"); 1404185380Ssam Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1405185377Ssam // The sign, shift type, and shift amount are encoded in a single operand 1406185380Ssam // using the AM2 encoding helpers. 1407185380Ssam ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1408185380Ssam unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1409185380Ssam PostIdxReg.ShiftTy); 1410185380Ssam Inst.addOperand(MCOperand::CreateImm(Imm)); 1411185380Ssam } 1412185380Ssam 1413185380Ssam void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1414185380Ssam assert(N == 1 && "Invalid number of operands!"); 1415185380Ssam Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1416185380Ssam } 1417185380Ssam 1418185380Ssam void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1419185380Ssam assert(N == 1 && "Invalid number of operands!"); 1420185380Ssam Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1421185380Ssam } 1422185380Ssam 1423185380Ssam void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { 1424185380Ssam assert(N == 1 && "Invalid number of operands!"); 1425185380Ssam Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1426185380Ssam } 1427185380Ssam 1428185380Ssam void addVectorIndex16Operands(MCInst &Inst, unsigned N) const { 1429185380Ssam assert(N == 1 && "Invalid number of operands!"); 1430185377Ssam Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1431185380Ssam } 1432185380Ssam 1433185380Ssam void addVectorIndex32Operands(MCInst &Inst, unsigned N) const { 1434185380Ssam assert(N == 1 && "Invalid number of operands!"); 1435185380Ssam Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); 1436185380Ssam } 1437185380Ssam 1438185380Ssam virtual void print(raw_ostream &OS) const; 1439185380Ssam 1440185380Ssam static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) { 1441185380Ssam ARMOperand *Op = new ARMOperand(k_ITCondMask); 1442185380Ssam Op->ITMask.Mask = Mask; 1443185380Ssam Op->StartLoc = S; 1444185380Ssam Op->EndLoc = S; 1445185380Ssam return Op; 1446185380Ssam } 1447185380Ssam 1448185380Ssam static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 1449185380Ssam ARMOperand *Op = new ARMOperand(k_CondCode); 1450185380Ssam Op->CC.Val = CC; 1451185380Ssam Op->StartLoc = S; 1452185380Ssam Op->EndLoc = S; 1453185380Ssam return Op; 1454185380Ssam } 1455185380Ssam 1456185380Ssam static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 1457185380Ssam ARMOperand *Op = new ARMOperand(k_CoprocNum); 1458185380Ssam Op->Cop.Val = CopVal; 1459185377Ssam Op->StartLoc = S; 1460185380Ssam Op->EndLoc = S; 1461185380Ssam return Op; 1462185380Ssam } 1463185380Ssam 1464185380Ssam static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 1465185380Ssam ARMOperand *Op = new ARMOperand(k_CoprocReg); 1466185380Ssam Op->Cop.Val = CopVal; 1467185380Ssam Op->StartLoc = S; 1468185380Ssam Op->EndLoc = S; 1469185380Ssam return Op; 1470185380Ssam } 1471185380Ssam 1472185380Ssam static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) { 1473185380Ssam ARMOperand *Op = new ARMOperand(k_CoprocOption); 1474185380Ssam Op->Cop.Val = Val; 1475185380Ssam Op->StartLoc = S; 1476185380Ssam Op->EndLoc = E; 1477185380Ssam return Op; 1478185380Ssam } 1479185380Ssam 1480185380Ssam static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 1481185380Ssam ARMOperand *Op = new ARMOperand(k_CCOut); 1482185380Ssam Op->Reg.RegNum = RegNum; 1483185380Ssam Op->StartLoc = S; 1484185380Ssam Op->EndLoc = S; 1485185380Ssam return Op; 1486185380Ssam } 1487185380Ssam 1488185377Ssam static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 1489185380Ssam ARMOperand *Op = new ARMOperand(k_Token); 1490185380Ssam Op->Tok.Data = Str.data(); 1491185380Ssam Op->Tok.Length = Str.size(); 1492185380Ssam Op->StartLoc = S; 1493187831Ssam Op->EndLoc = S; 1494185380Ssam return Op; 1495185380Ssam } 1496185380Ssam 1497185380Ssam static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 1498185380Ssam ARMOperand *Op = new ARMOperand(k_Register); 1499185380Ssam Op->Reg.RegNum = RegNum; 1500185380Ssam Op->StartLoc = S; 1501185380Ssam Op->EndLoc = E; 1502185380Ssam return Op; 1503185380Ssam } 1504185380Ssam 1505185380Ssam static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1506185380Ssam unsigned SrcReg, 1507185380Ssam unsigned ShiftReg, 1508185380Ssam unsigned ShiftImm, 1509185380Ssam SMLoc S, SMLoc E) { 1510185380Ssam ARMOperand *Op = new ARMOperand(k_ShiftedRegister); 1511185380Ssam Op->RegShiftedReg.ShiftTy = ShTy; 1512185380Ssam Op->RegShiftedReg.SrcReg = SrcReg; 1513185380Ssam Op->RegShiftedReg.ShiftReg = ShiftReg; 1514185380Ssam Op->RegShiftedReg.ShiftImm = ShiftImm; 1515185380Ssam Op->StartLoc = S; 1516185377Ssam Op->EndLoc = E; 1517185380Ssam return Op; 1518185380Ssam } 1519185380Ssam 1520185380Ssam static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 1521187831Ssam unsigned SrcReg, 1522185380Ssam unsigned ShiftImm, 1523185380Ssam SMLoc S, SMLoc E) { 1524185380Ssam ARMOperand *Op = new ARMOperand(k_ShiftedImmediate); 1525185380Ssam Op->RegShiftedImm.ShiftTy = ShTy; 1526185380Ssam Op->RegShiftedImm.SrcReg = SrcReg; 1527185380Ssam Op->RegShiftedImm.ShiftImm = ShiftImm; 1528185380Ssam Op->StartLoc = S; 1529185380Ssam Op->EndLoc = E; 1530185380Ssam return Op; 1531185380Ssam } 1532185380Ssam 1533185380Ssam static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 1534185380Ssam SMLoc S, SMLoc E) { 1535185380Ssam ARMOperand *Op = new ARMOperand(k_ShifterImmediate); 1536185380Ssam Op->ShifterImm.isASR = isASR; 1537185380Ssam Op->ShifterImm.Imm = Imm; 1538185380Ssam Op->StartLoc = S; 1539185380Ssam Op->EndLoc = E; 1540185380Ssam return Op; 1541185380Ssam } 1542185380Ssam 1543185380Ssam static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 1544185380Ssam ARMOperand *Op = new ARMOperand(k_RotateImmediate); 1545185380Ssam Op->RotImm.Imm = Imm; 1546185377Ssam Op->StartLoc = S; 1547185380Ssam Op->EndLoc = E; 1548185380Ssam return Op; 1549185380Ssam } 1550185380Ssam 1551185380Ssam static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1552185380Ssam SMLoc S, SMLoc E) { 1553185380Ssam ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor); 1554185380Ssam Op->Bitfield.LSB = LSB; 1555185380Ssam Op->Bitfield.Width = Width; 1556185380Ssam Op->StartLoc = S; 1557185380Ssam Op->EndLoc = E; 1558185380Ssam return Op; 1559185380Ssam } 1560185380Ssam 1561185380Ssam static ARMOperand * 1562185380Ssam CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1563185380Ssam SMLoc StartLoc, SMLoc EndLoc) { 1564185380Ssam KindTy Kind = k_RegisterList; 1565185380Ssam 1566185380Ssam if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first)) 1567185380Ssam Kind = k_DPRRegisterList; 1568185380Ssam else if (ARMMCRegisterClasses[ARM::SPRRegClassID]. 1569185380Ssam contains(Regs.front().first)) 1570185380Ssam Kind = k_SPRRegisterList; 1571185380Ssam 1572185380Ssam ARMOperand *Op = new ARMOperand(Kind); 1573185380Ssam for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1574185377Ssam I = Regs.begin(), E = Regs.end(); I != E; ++I) 1575185380Ssam Op->Registers.push_back(I->first); 1576185380Ssam array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1577185380Ssam Op->StartLoc = StartLoc; 1578185380Ssam Op->EndLoc = EndLoc; 1579187831Ssam return Op; 1580185380Ssam } 1581185380Ssam 1582185380Ssam static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, 1583185380Ssam MCContext &Ctx) { 1584185380Ssam ARMOperand *Op = new ARMOperand(k_VectorIndex); 1585185380Ssam Op->VectorIndex.Val = Idx; 1586185380Ssam Op->StartLoc = S; 1587185380Ssam Op->EndLoc = E; 1588185380Ssam return Op; 1589185380Ssam } 1590185380Ssam 1591185380Ssam static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 1592185380Ssam ARMOperand *Op = new ARMOperand(k_Immediate); 1593185380Ssam Op->Imm.Val = Val; 1594185380Ssam Op->StartLoc = S; 1595185380Ssam Op->EndLoc = E; 1596185380Ssam return Op; 1597185380Ssam } 1598185377Ssam 1599185380Ssam static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { 1600185380Ssam ARMOperand *Op = new ARMOperand(k_FPImmediate); 1601185380Ssam Op->FPImm.Val = Val; 1602185380Ssam Op->StartLoc = S; 1603187831Ssam Op->EndLoc = S; 1604185380Ssam return Op; 1605185380Ssam } 1606185380Ssam 1607185380Ssam static ARMOperand *CreateMem(unsigned BaseRegNum, 1608185380Ssam const MCConstantExpr *OffsetImm, 1609185380Ssam unsigned OffsetRegNum, 1610185380Ssam ARM_AM::ShiftOpc ShiftType, 1611185380Ssam unsigned ShiftImm, 1612185380Ssam unsigned Alignment, 1613185380Ssam bool isNegative, 1614185380Ssam SMLoc S, SMLoc E) { 1615185380Ssam ARMOperand *Op = new ARMOperand(k_Memory); 1616185380Ssam Op->Memory.BaseRegNum = BaseRegNum; 1617185380Ssam Op->Memory.OffsetImm = OffsetImm; 1618185380Ssam Op->Memory.OffsetRegNum = OffsetRegNum; 1619185380Ssam Op->Memory.ShiftType = ShiftType; 1620185377Ssam Op->Memory.ShiftImm = ShiftImm; 1621185380Ssam Op->Memory.Alignment = Alignment; 1622185380Ssam Op->Memory.isNegative = isNegative; 1623185380Ssam Op->StartLoc = S; 1624185380Ssam Op->EndLoc = E; 1625187831Ssam return Op; 1626185380Ssam } 1627185380Ssam 1628185380Ssam static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1629185380Ssam ARM_AM::ShiftOpc ShiftTy, 1630185380Ssam unsigned ShiftImm, 1631185380Ssam SMLoc S, SMLoc E) { 1632185380Ssam ARMOperand *Op = new ARMOperand(k_PostIndexRegister); 1633185380Ssam Op->PostIdxReg.RegNum = RegNum; 1634185380Ssam Op->PostIdxReg.isAdd = isAdd; 1635185380Ssam Op->PostIdxReg.ShiftTy = ShiftTy; 1636185380Ssam Op->PostIdxReg.ShiftImm = ShiftImm; 1637185380Ssam Op->StartLoc = S; 1638185380Ssam Op->EndLoc = E; 1639185380Ssam return Op; 1640185380Ssam } 1641185380Ssam 1642185380Ssam static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1643185380Ssam ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); 1644185377Ssam Op->MBOpt.Val = Opt; 1645185380Ssam Op->StartLoc = S; 1646185380Ssam Op->EndLoc = S; 1647185380Ssam return Op; 1648185380Ssam } 1649187831Ssam 1650185380Ssam static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1651185380Ssam ARMOperand *Op = new ARMOperand(k_ProcIFlags); 1652185380Ssam Op->IFlags.Val = IFlags; 1653185380Ssam Op->StartLoc = S; 1654185380Ssam Op->EndLoc = S; 1655185380Ssam return Op; 1656185380Ssam } 1657185380Ssam 1658185380Ssam static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1659185380Ssam ARMOperand *Op = new ARMOperand(k_MSRMask); 1660185380Ssam Op->MMask.Val = MMask; 1661185380Ssam Op->StartLoc = S; 1662185380Ssam Op->EndLoc = S; 1663185380Ssam return Op; 1664185380Ssam } 1665185380Ssam}; 1666185380Ssam 1667185380Ssam} // end anonymous namespace. 1668185380Ssam 1669185380Ssamvoid ARMOperand::print(raw_ostream &OS) const { 1670185380Ssam switch (Kind) { 1671185380Ssam case k_FPImmediate: 1672185380Ssam OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm()) 1673185377Ssam << ") >"; 1674185377Ssam break; 1675185377Ssam case k_CondCode: 1676185377Ssam OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1677185377Ssam break; 1678185377Ssam case k_CCOut: 1679185377Ssam OS << "<ccout " << getReg() << ">"; 1680185377Ssam break; 1681187831Ssam case k_ITCondMask: { 1682187831Ssam static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)", 1683187831Ssam "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)", 1684187831Ssam "(tee)", "(eee)" }; 1685187831Ssam assert((ITMask.Mask & 0xf) == ITMask.Mask); 1686187831Ssam OS << "<it-mask " << MaskStr[ITMask.Mask] << ">"; 1687187831Ssam break; 1688187831Ssam } 1689187831Ssam case k_CoprocNum: 1690187831Ssam OS << "<coprocessor number: " << getCoproc() << ">"; 1691187831Ssam break; 1692187831Ssam case k_CoprocReg: 1693187831Ssam OS << "<coprocessor register: " << getCoproc() << ">"; 1694187831Ssam break; 1695187831Ssam case k_CoprocOption: 1696187831Ssam OS << "<coprocessor option: " << CoprocOption.Val << ">"; 1697187831Ssam break; 1698187831Ssam case k_MSRMask: 1699187831Ssam OS << "<mask: " << getMSRMask() << ">"; 1700187831Ssam break; 1701187831Ssam case k_Immediate: 1702187831Ssam getImm()->print(OS); 1703187831Ssam break; 1704187831Ssam case k_MemBarrierOpt: 1705185377Ssam OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1706185377Ssam break; 1707187831Ssam case k_Memory: 1708185377Ssam OS << "<memory " 1709185377Ssam << " base:" << Memory.BaseRegNum; 1710185377Ssam OS << ">"; 1711185377Ssam break; 1712185377Ssam case k_PostIndexRegister: 1713185377Ssam OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1714185377Ssam << PostIdxReg.RegNum; 1715185377Ssam if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1716185377Ssam OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1717185380Ssam << PostIdxReg.ShiftImm; 1718185377Ssam OS << ">"; 1719185377Ssam break; 1720185377Ssam case k_ProcIFlags: { 1721185377Ssam OS << "<ARM_PROC::"; 1722185377Ssam unsigned IFlags = getProcIFlags(); 1723185377Ssam for (int i=2; i >= 0; --i) 1724185377Ssam if (IFlags & (1 << i)) 1725185377Ssam OS << ARM_PROC::IFlagsToString(1 << i); 1726185377Ssam OS << ">"; 1727185377Ssam break; 1728185377Ssam } 1729185377Ssam case k_Register: 1730185377Ssam OS << "<register " << getReg() << ">"; 1731185377Ssam break; 1732185377Ssam case k_ShifterImmediate: 1733185377Ssam OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1734185377Ssam << " #" << ShifterImm.Imm << ">"; 1735185377Ssam break; 1736185377Ssam case k_ShiftedRegister: 1737185377Ssam OS << "<so_reg_reg " 1738185377Ssam << RegShiftedReg.SrcReg 1739185377Ssam << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1740185377Ssam << ", " << RegShiftedReg.ShiftReg << ", " 1741185377Ssam << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1742185377Ssam << ">"; 1743185377Ssam break; 1744185377Ssam case k_ShiftedImmediate: 1745185377Ssam OS << "<so_reg_imm " 1746185377Ssam << RegShiftedImm.SrcReg 1747185377Ssam << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1748185377Ssam << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 1749185377Ssam << ">"; 1750185377Ssam break; 1751185377Ssam case k_RotateImmediate: 1752185377Ssam OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 1753185377Ssam break; 1754185377Ssam case k_BitfieldDescriptor: 1755187831Ssam OS << "<bitfield " << "lsb: " << Bitfield.LSB 1756187831Ssam << ", width: " << Bitfield.Width << ">"; 1757185377Ssam break; 1758187831Ssam case k_RegisterList: 1759187831Ssam case k_DPRRegisterList: 1760185377Ssam case k_SPRRegisterList: { 1761187831Ssam OS << "<register_list "; 1762185377Ssam 1763187831Ssam const SmallVectorImpl<unsigned> &RegList = getRegList(); 1764187831Ssam for (SmallVectorImpl<unsigned>::const_iterator 1765187831Ssam I = RegList.begin(), E = RegList.end(); I != E; ) { 1766185377Ssam OS << *I; 1767187831Ssam if (++I < E) OS << ", "; 1768185377Ssam } 1769185377Ssam 1770187831Ssam OS << ">"; 1771187831Ssam break; 1772185377Ssam } 1773187831Ssam case k_Token: 1774185377Ssam OS << "'" << getToken() << "'"; 1775187831Ssam break; 1776187831Ssam case k_VectorIndex: 1777187831Ssam OS << "<vectorindex " << getVectorIndex() << ">"; 1778185380Ssam break; 1779187831Ssam } 1780185377Ssam} 1781185377Ssam 1782187831Ssam/// @name Auto-generated Match Functions 1783187831Ssam/// { 1784185377Ssam 1785185377Ssamstatic unsigned MatchRegisterName(StringRef Name); 1786185377Ssam 1787187831Ssam/// } 1788187831Ssam 1789187831Ssambool ARMAsmParser::ParseRegister(unsigned &RegNo, 1790187831Ssam SMLoc &StartLoc, SMLoc &EndLoc) { 1791187831Ssam RegNo = tryParseRegister(); 1792185377Ssam 1793187831Ssam return (RegNo == (unsigned)-1); 1794185377Ssam} 1795185377Ssam 1796185377Ssam/// Try to parse a register name. The token must be an Identifier when called, 1797185377Ssam/// and if it is a register name the token is eaten and the register number is 1798185377Ssam/// returned. Otherwise return -1. 1799185377Ssam/// 1800185377Ssamint ARMAsmParser::tryParseRegister() { 1801185377Ssam const AsmToken &Tok = Parser.getTok(); 1802187831Ssam if (Tok.isNot(AsmToken::Identifier)) return -1; 1803185377Ssam 1804185377Ssam // FIXME: Validate register for the current architecture; we have to do 1805185377Ssam // validation later, so maybe there is no need for this here. 1806185377Ssam std::string upperCase = Tok.getString().str(); 1807187831Ssam std::string lowerCase = LowercaseString(upperCase); 1808185377Ssam unsigned RegNum = MatchRegisterName(lowerCase); 1809185377Ssam if (!RegNum) { 1810185377Ssam RegNum = StringSwitch<unsigned>(lowerCase) 1811185377Ssam .Case("r13", ARM::SP) 1812185377Ssam .Case("r14", ARM::LR) 1813185377Ssam .Case("r15", ARM::PC) 1814185377Ssam .Case("ip", ARM::R12) 1815185377Ssam .Default(0); 1816187831Ssam } 1817187831Ssam if (!RegNum) return -1; 1818185377Ssam 1819185377Ssam Parser.Lex(); // Eat identifier token. 1820185377Ssam 1821187831Ssam#if 0 1822185377Ssam // Also check for an index operand. This is only legal for vector registers, 1823187831Ssam // but that'll get caught OK in operand matching, so we don't need to 1824187831Ssam // explicitly filter everything else out here. 1825185377Ssam if (Parser.getTok().is(AsmToken::LBrac)) { 1826187831Ssam SMLoc SIdx = Parser.getTok().getLoc(); 1827187831Ssam Parser.Lex(); // Eat left bracket token. 1828187831Ssam 1829187831Ssam const MCExpr *ImmVal; 1830185377Ssam SMLoc ExprLoc = Parser.getTok().getLoc(); 1831185377Ssam if (getParser().ParseExpression(ImmVal)) 1832187831Ssam return MatchOperand_ParseFail; 1833187831Ssam const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 1834187831Ssam if (!MCE) { 1835187831Ssam TokError("immediate value expected for vector index"); 1836185377Ssam return MatchOperand_ParseFail; 1837187831Ssam } 1838187831Ssam 1839185377Ssam SMLoc E = Parser.getTok().getLoc(); 1840187831Ssam if (Parser.getTok().isNot(AsmToken::RBrac)) { 1841187831Ssam Error(E, "']' expected"); 1842187831Ssam return MatchOperand_ParseFail; 1843187831Ssam } 1844187831Ssam 1845187831Ssam Parser.Lex(); // Eat right bracket token. 1846187831Ssam 1847187831Ssam Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 1848187831Ssam SIdx, E, 1849187831Ssam getContext())); 1850187831Ssam } 1851187831Ssam#endif 1852187831Ssam 1853185377Ssam return RegNum; 1854187831Ssam} 1855187831Ssam 1856187831Ssam// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 1857187831Ssam// If a recoverable error occurs, return 1. If an irrecoverable error 1858187831Ssam// occurs, return -1. An irrecoverable error is one where tokens have been 1859187831Ssam// consumed in the process of trying to parse the shifter (i.e., when it is 1860187831Ssam// indeed a shifter operand, but malformed). 1861187831Ssamint ARMAsmParser::tryParseShiftRegister( 1862187831Ssam SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1863187831Ssam SMLoc S = Parser.getTok().getLoc(); 1864185377Ssam const AsmToken &Tok = Parser.getTok(); 1865187831Ssam assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1866187831Ssam 1867187831Ssam std::string upperCase = Tok.getString().str(); 1868187831Ssam std::string lowerCase = LowercaseString(upperCase); 1869187831Ssam ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 1870187831Ssam .Case("lsl", ARM_AM::lsl) 1871187831Ssam .Case("lsr", ARM_AM::lsr) 1872187831Ssam .Case("asr", ARM_AM::asr) 1873187831Ssam .Case("ror", ARM_AM::ror) 1874185377Ssam .Case("rrx", ARM_AM::rrx) 1875187831Ssam .Default(ARM_AM::no_shift); 1876187831Ssam 1877185377Ssam if (ShiftTy == ARM_AM::no_shift) 1878185377Ssam return 1; 1879187831Ssam 1880187831Ssam Parser.Lex(); // Eat the operator. 1881187831Ssam 1882185377Ssam // The source register for the shift has already been added to the 1883187831Ssam // operand list, so we need to pop it off and combine it into the shifted 1884187831Ssam // register operand instead. 1885185377Ssam OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1886187831Ssam if (!PrevOp->isReg()) 1887187831Ssam return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1888187831Ssam int SrcReg = PrevOp->getReg(); 1889187831Ssam int64_t Imm = 0; 1890185377Ssam int ShiftReg = 0; 1891185377Ssam if (ShiftTy == ARM_AM::rrx) { 1892185377Ssam // RRX Doesn't have an explicit shift amount. The encoder expects 1893187831Ssam // the shift register to be the same as the source register. Seems odd, 1894185377Ssam // but OK. 1895187831Ssam ShiftReg = SrcReg; 1896187831Ssam } else { 1897187831Ssam // Figure out if this is shifted by a constant or a register (for non-RRX). 1898187831Ssam if (Parser.getTok().is(AsmToken::Hash)) { 1899187831Ssam Parser.Lex(); // Eat hash. 1900187831Ssam SMLoc ImmLoc = Parser.getTok().getLoc(); 1901187831Ssam const MCExpr *ShiftExpr = 0; 1902187831Ssam if (getParser().ParseExpression(ShiftExpr)) { 1903187831Ssam Error(ImmLoc, "invalid immediate shift value"); 1904187831Ssam return -1; 1905187831Ssam } 1906187831Ssam // The expression must be evaluatable as an immediate. 1907187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 1908187831Ssam if (!CE) { 1909187831Ssam Error(ImmLoc, "invalid immediate shift value"); 1910187831Ssam return -1; 1911187831Ssam } 1912187831Ssam // Range check the immediate. 1913187831Ssam // lsl, ror: 0 <= imm <= 31 1914187831Ssam // lsr, asr: 0 <= imm <= 32 1915187831Ssam Imm = CE->getValue(); 1916187831Ssam if (Imm < 0 || 1917185377Ssam ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1918187831Ssam ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 1919187831Ssam Error(ImmLoc, "immediate shift value out of range"); 1920187831Ssam return -1; 1921187831Ssam } 1922187831Ssam } else if (Parser.getTok().is(AsmToken::Identifier)) { 1923187831Ssam ShiftReg = tryParseRegister(); 1924185377Ssam SMLoc L = Parser.getTok().getLoc(); 1925185377Ssam if (ShiftReg == -1) { 1926187831Ssam Error (L, "expected immediate or register in shift operand"); 1927187831Ssam return -1; 1928187831Ssam } 1929187831Ssam } else { 1930187831Ssam Error (Parser.getTok().getLoc(), 1931185377Ssam "expected immediate or register in shift operand"); 1932185377Ssam return -1; 1933185377Ssam } 1934187831Ssam } 1935185377Ssam 1936187831Ssam if (ShiftReg && ShiftTy != ARM_AM::rrx) 1937187831Ssam Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1938187831Ssam ShiftReg, Imm, 1939187831Ssam S, Parser.getTok().getLoc())); 1940187831Ssam else 1941187831Ssam Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 1942187831Ssam S, Parser.getTok().getLoc())); 1943185377Ssam 1944185377Ssam return 0; 1945185377Ssam} 1946187831Ssam 1947187831Ssam 1948187831Ssam/// Try to parse a register name. The token must be an Identifier when called. 1949187831Ssam/// If it's a register, an AsmOperand is created. Another AsmOperand is created 1950185377Ssam/// if there is a "writeback". 'true' if it's not a register. 1951185377Ssam/// 1952187831Ssam/// TODO this is likely to change to allow different register types and or to 1953185377Ssam/// parse for a specific register type. 1954187831Ssambool ARMAsmParser:: 1955185377SsamtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1956187831Ssam SMLoc S = Parser.getTok().getLoc(); 1957187831Ssam int RegNo = tryParseRegister(); 1958187831Ssam if (RegNo == -1) 1959185377Ssam return true; 1960187831Ssam 1961187831Ssam Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1962187831Ssam 1963185377Ssam const AsmToken &ExclaimTok = Parser.getTok(); 1964187831Ssam if (ExclaimTok.is(AsmToken::Exclaim)) { 1965187831Ssam Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 1966187831Ssam ExclaimTok.getLoc())); 1967187831Ssam Parser.Lex(); // Eat exclaim token 1968187831Ssam return false; 1969185377Ssam } 1970187831Ssam 1971187831Ssam // Also check for an index operand. This is only legal for vector registers, 1972185377Ssam // but that'll get caught OK in operand matching, so we don't need to 1973185377Ssam // explicitly filter everything else out here. 1974185377Ssam if (Parser.getTok().is(AsmToken::LBrac)) { 1975187831Ssam SMLoc SIdx = Parser.getTok().getLoc(); 1976185377Ssam Parser.Lex(); // Eat left bracket token. 1977185377Ssam 1978185377Ssam const MCExpr *ImmVal; 1979185377Ssam SMLoc ExprLoc = Parser.getTok().getLoc(); 1980185377Ssam if (getParser().ParseExpression(ImmVal)) 1981187831Ssam return MatchOperand_ParseFail; 1982187831Ssam const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); 1983187831Ssam if (!MCE) { 1984185377Ssam TokError("immediate value expected for vector index"); 1985185377Ssam return MatchOperand_ParseFail; 1986185377Ssam } 1987185377Ssam 1988185377Ssam SMLoc E = Parser.getTok().getLoc(); 1989185377Ssam if (Parser.getTok().isNot(AsmToken::RBrac)) { 1990185377Ssam Error(E, "']' expected"); 1991185377Ssam return MatchOperand_ParseFail; 1992185377Ssam } 1993185377Ssam 1994185377Ssam Parser.Lex(); // Eat right bracket token. 1995185377Ssam 1996185377Ssam Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(), 1997185377Ssam SIdx, E, 1998185377Ssam getContext())); 1999185377Ssam } 2000185377Ssam 2001185377Ssam return false; 2002185377Ssam} 2003185377Ssam 2004185377Ssam/// MatchCoprocessorOperandName - Try to parse an coprocessor related 2005185377Ssam/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 2006187831Ssam/// "c5", ... 2007187831Ssamstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 2008187831Ssam // Use the same layout as the tablegen'erated register name matcher. Ugly, 2009187831Ssam // but efficient. 2010187831Ssam switch (Name.size()) { 2011187831Ssam default: break; 2012187831Ssam case 2: 2013187831Ssam if (Name[0] != CoprocOp) 2014185377Ssam return -1; 2015185377Ssam switch (Name[1]) { 2016187831Ssam default: return -1; 2017187831Ssam case '0': return 0; 2018187831Ssam case '1': return 1; 2019187831Ssam case '2': return 2; 2020187831Ssam case '3': return 3; 2021187831Ssam case '4': return 4; 2022187831Ssam case '5': return 5; 2023185377Ssam case '6': return 6; 2024185380Ssam case '7': return 7; 2025185380Ssam case '8': return 8; 2026185377Ssam case '9': return 9; 2027185377Ssam } 2028185377Ssam break; 2029187831Ssam case 3: 2030187831Ssam if (Name[0] != CoprocOp || Name[1] != '1') 2031187831Ssam return -1; 2032185380Ssam switch (Name[2]) { 2033187831Ssam default: return -1; 2034185380Ssam case '0': return 10; 2035187831Ssam case '1': return 11; 2036185380Ssam case '2': return 12; 2037187831Ssam case '3': return 13; 2038185377Ssam case '4': return 14; 2039185377Ssam case '5': return 15; 2040185377Ssam } 2041185377Ssam break; 2042185380Ssam } 2043185380Ssam 2044185377Ssam return -1; 2045185377Ssam} 2046185377Ssam 2047187831Ssam/// parseITCondCode - Try to parse a condition code for an IT instruction. 2048187831SsamARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2049187831SsamparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2050185380Ssam SMLoc S = Parser.getTok().getLoc(); 2051187831Ssam const AsmToken &Tok = Parser.getTok(); 2052185380Ssam if (!Tok.is(AsmToken::Identifier)) 2053187831Ssam return MatchOperand_NoMatch; 2054187831Ssam unsigned CC = StringSwitch<unsigned>(Tok.getString()) 2055187831Ssam .Case("eq", ARMCC::EQ) 2056185380Ssam .Case("ne", ARMCC::NE) 2057187831Ssam .Case("hs", ARMCC::HS) 2058187831Ssam .Case("cs", ARMCC::HS) 2059187831Ssam .Case("lo", ARMCC::LO) 2060187831Ssam .Case("cc", ARMCC::LO) 2061187831Ssam .Case("mi", ARMCC::MI) 2062185377Ssam .Case("pl", ARMCC::PL) 2063185377Ssam .Case("vs", ARMCC::VS) 2064185377Ssam .Case("vc", ARMCC::VC) 2065185377Ssam .Case("hi", ARMCC::HI) 2066185377Ssam .Case("ls", ARMCC::LS) 2067185377Ssam .Case("ge", ARMCC::GE) 2068185377Ssam .Case("lt", ARMCC::LT) 2069185377Ssam .Case("gt", ARMCC::GT) 2070185377Ssam .Case("le", ARMCC::LE) 2071185377Ssam .Case("al", ARMCC::AL) 2072185377Ssam .Default(~0U); 2073185377Ssam if (CC == ~0U) 2074185377Ssam return MatchOperand_NoMatch; 2075185377Ssam Parser.Lex(); // Eat the token. 2076185377Ssam 2077185377Ssam Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S)); 2078185377Ssam 2079185377Ssam return MatchOperand_Success; 2080185377Ssam} 2081185377Ssam 2082185377Ssam/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 2083185377Ssam/// token must be an Identifier when called, and if it is a coprocessor 2084185377Ssam/// number, the token is eaten and the operand is added to the operand list. 2085185377SsamARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2086185377SsamparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2087185377Ssam SMLoc S = Parser.getTok().getLoc(); 2088185377Ssam const AsmToken &Tok = Parser.getTok(); 2089185377Ssam if (Tok.isNot(AsmToken::Identifier)) 2090185377Ssam return MatchOperand_NoMatch; 2091185377Ssam 2092185377Ssam int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 2093185377Ssam if (Num == -1) 2094185377Ssam return MatchOperand_NoMatch; 2095185377Ssam 2096185377Ssam Parser.Lex(); // Eat identifier token. 2097185377Ssam Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 2098185377Ssam return MatchOperand_Success; 2099185377Ssam} 2100185377Ssam 2101185377Ssam/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 2102185377Ssam/// token must be an Identifier when called, and if it is a coprocessor 2103185377Ssam/// number, the token is eaten and the operand is added to the operand list. 2104185377SsamARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2105187831SsamparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2106185377Ssam SMLoc S = Parser.getTok().getLoc(); 2107185377Ssam const AsmToken &Tok = Parser.getTok(); 2108187831Ssam if (Tok.isNot(AsmToken::Identifier)) 2109187831Ssam return MatchOperand_NoMatch; 2110187831Ssam 2111185377Ssam int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 2112187831Ssam if (Reg == -1) 2113185377Ssam return MatchOperand_NoMatch; 2114185377Ssam 2115185377Ssam Parser.Lex(); // Eat identifier token. 2116185377Ssam Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 2117185377Ssam return MatchOperand_Success; 2118185377Ssam} 2119185377Ssam 2120185377Ssam/// parseCoprocOptionOperand - Try to parse an coprocessor option operand. 2121185377Ssam/// coproc_option : '{' imm0_255 '}' 2122185377SsamARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2123185377SsamparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2124187831Ssam SMLoc S = Parser.getTok().getLoc(); 2125187831Ssam 2126187831Ssam // If this isn't a '{', this isn't a coprocessor immediate operand. 2127187831Ssam if (Parser.getTok().isNot(AsmToken::LCurly)) 2128187831Ssam return MatchOperand_NoMatch; 2129187831Ssam Parser.Lex(); // Eat the '{' 2130187831Ssam 2131187831Ssam const MCExpr *Expr; 2132187831Ssam SMLoc Loc = Parser.getTok().getLoc(); 2133187831Ssam if (getParser().ParseExpression(Expr)) { 2134187831Ssam Error(Loc, "illegal expression"); 2135187831Ssam return MatchOperand_ParseFail; 2136187831Ssam } 2137187831Ssam const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 2138187831Ssam if (!CE || CE->getValue() < 0 || CE->getValue() > 255) { 2139187831Ssam Error(Loc, "coprocessor option must be an immediate in range [0, 255]"); 2140187831Ssam return MatchOperand_ParseFail; 2141187831Ssam } 2142187831Ssam int Val = CE->getValue(); 2143187831Ssam 2144187831Ssam // Check for and consume the closing '}' 2145187831Ssam if (Parser.getTok().isNot(AsmToken::RCurly)) 2146187831Ssam return MatchOperand_ParseFail; 2147187831Ssam SMLoc E = Parser.getTok().getLoc(); 2148185377Ssam Parser.Lex(); // Eat the '}' 2149185377Ssam 2150185377Ssam Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E)); 2151185377Ssam return MatchOperand_Success; 2152185377Ssam} 2153187831Ssam 2154187831Ssam// For register list parsing, we need to map from raw GPR register numbering 2155187831Ssam// to the enumeration values. The enumeration values aren't sorted by 2156187831Ssam// register number due to our using "sp", "lr" and "pc" as canonical names. 2157187831Ssamstatic unsigned getNextRegister(unsigned Reg) { 2158187831Ssam // If this is a GPR, we need to do it manually, otherwise we can rely 2159187831Ssam // on the sort ordering of the enumeration since the other reg-classes 2160185377Ssam // are sane. 2161185377Ssam if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2162185377Ssam return Reg + 1; 2163185377Ssam switch(Reg) { 2164185377Ssam default: assert(0 && "Invalid GPR number!"); 2165187831Ssam case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; 2166185377Ssam case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; 2167187831Ssam case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; 2168187831Ssam case ARM::R6: return ARM::R7; case ARM::R7: return ARM::R8; 2169187831Ssam case ARM::R8: return ARM::R9; case ARM::R9: return ARM::R10; 2170187831Ssam case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12; 2171187831Ssam case ARM::R12: return ARM::SP; case ARM::SP: return ARM::LR; 2172185377Ssam case ARM::LR: return ARM::PC; case ARM::PC: return ARM::R0; 2173187831Ssam } 2174187831Ssam} 2175187831Ssam 2176185377Ssam/// Parse a register list. 2177187831Ssambool ARMAsmParser:: 2178187831SsamparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2179187831Ssam assert(Parser.getTok().is(AsmToken::LCurly) && 2180187831Ssam "Token is not a Left Curly Brace"); 2181187831Ssam SMLoc S = Parser.getTok().getLoc(); 2182187831Ssam Parser.Lex(); // Eat '{' token. 2183187831Ssam SMLoc RegLoc = Parser.getTok().getLoc(); 2184187831Ssam 2185187831Ssam // Check the first register in the list to see what register class 2186187831Ssam // this is a list of. 2187187831Ssam int Reg = tryParseRegister(); 2188187831Ssam if (Reg == -1) 2189187831Ssam return Error(RegLoc, "register expected"); 2190187831Ssam 2191187831Ssam MCRegisterClass *RC; 2192187831Ssam if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) 2193187831Ssam RC = &ARMMCRegisterClasses[ARM::GPRRegClassID]; 2194187831Ssam else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) 2195187831Ssam RC = &ARMMCRegisterClasses[ARM::DPRRegClassID]; 2196185377Ssam else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg)) 2197187831Ssam RC = &ARMMCRegisterClasses[ARM::SPRRegClassID]; 2198187831Ssam else 2199187831Ssam return Error(RegLoc, "invalid register in register list"); 2200187831Ssam 2201187831Ssam // The reglist instructions have at most 16 registers, so reserve 2202187831Ssam // space for that many. 2203187831Ssam SmallVector<std::pair<unsigned, SMLoc>, 16> Registers; 2204187831Ssam // Store the first register. 2205187831Ssam Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2206187831Ssam 2207187831Ssam // This starts immediately after the first register token in the list, 2208187831Ssam // so we can see either a comma or a minus (range separator) as a legal 2209187831Ssam // next token. 2210187831Ssam while (Parser.getTok().is(AsmToken::Comma) || 2211187831Ssam Parser.getTok().is(AsmToken::Minus)) { 2212187831Ssam if (Parser.getTok().is(AsmToken::Minus)) { 2213187831Ssam Parser.Lex(); // Eat the comma. 2214187831Ssam SMLoc EndLoc = Parser.getTok().getLoc(); 2215187831Ssam int EndReg = tryParseRegister(); 2216187831Ssam if (EndReg == -1) 2217185377Ssam return Error(EndLoc, "register expected"); 2218187831Ssam // If the register is the same as the start reg, there's nothing 2219187831Ssam // more to do. 2220187831Ssam if (Reg == EndReg) 2221187831Ssam continue; 2222188084Ssam // The register must be in the same register class as the first. 2223187831Ssam if (!RC->contains(EndReg)) 2224187831Ssam return Error(EndLoc, "invalid register in register list"); 2225187831Ssam // Ranges must go from low to high. 2226187831Ssam if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg)) 2227187831Ssam return Error(EndLoc, "bad range in register list"); 2228187831Ssam 2229187831Ssam // Add all the registers in the range to the register list. 2230187831Ssam while (Reg != EndReg) { 2231187831Ssam Reg = getNextRegister(Reg); 2232187831Ssam Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2233187831Ssam } 2234187831Ssam continue; 2235187831Ssam } 2236187831Ssam Parser.Lex(); // Eat the comma. 2237187831Ssam RegLoc = Parser.getTok().getLoc(); 2238187831Ssam int OldReg = Reg; 2239187831Ssam Reg = tryParseRegister(); 2240187831Ssam if (Reg == -1) 2241187831Ssam return Error(RegLoc, "register expected"); 2242187831Ssam // The register must be in the same register class as the first. 2243187831Ssam if (!RC->contains(Reg)) 2244187831Ssam return Error(RegLoc, "invalid register in register list"); 2245187831Ssam // List must be monotonically increasing. 2246187831Ssam if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg)) 2247187831Ssam return Error(RegLoc, "register list not in ascending order"); 2248187831Ssam // VFP register lists must also be contiguous. 2249185377Ssam // It's OK to use the enumeration values directly here rather, as the 2250185377Ssam // VFP register classes have the enum sorted properly. 2251187831Ssam if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] && 2252187831Ssam Reg != OldReg + 1) 2253187831Ssam return Error(RegLoc, "non-contiguous register range"); 2254187831Ssam Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc)); 2255185377Ssam } 2256185377Ssam 2257185377Ssam SMLoc E = Parser.getTok().getLoc(); 2258187831Ssam if (Parser.getTok().isNot(AsmToken::RCurly)) 2259185377Ssam return Error(E, "'}' expected"); 2260187831Ssam Parser.Lex(); // Eat '}' token. 2261187831Ssam 2262187831Ssam Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 2263187831Ssam return false; 2264187831Ssam} 2265185377Ssam 2266187831Ssam/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 2267187831SsamARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2268187831SsamparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2269185377Ssam SMLoc S = Parser.getTok().getLoc(); 2270187831Ssam const AsmToken &Tok = Parser.getTok(); 2271187831Ssam assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2272187831Ssam StringRef OptStr = Tok.getString(); 2273187831Ssam 2274187831Ssam unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 2275187831Ssam .Case("sy", ARM_MB::SY) 2276187831Ssam .Case("st", ARM_MB::ST) 2277187831Ssam .Case("sh", ARM_MB::ISH) 2278187831Ssam .Case("ish", ARM_MB::ISH) 2279187831Ssam .Case("shst", ARM_MB::ISHST) 2280187831Ssam .Case("ishst", ARM_MB::ISHST) 2281187831Ssam .Case("nsh", ARM_MB::NSH) 2282187831Ssam .Case("un", ARM_MB::NSH) 2283185377Ssam .Case("nshst", ARM_MB::NSHST) 2284185377Ssam .Case("unst", ARM_MB::NSHST) 2285187831Ssam .Case("osh", ARM_MB::OSH) 2286187831Ssam .Case("oshst", ARM_MB::OSHST) 2287187831Ssam .Default(~0U); 2288187831Ssam 2289187831Ssam if (Opt == ~0U) 2290187831Ssam return MatchOperand_NoMatch; 2291187831Ssam 2292187831Ssam Parser.Lex(); // Eat identifier token. 2293187831Ssam Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 2294187831Ssam return MatchOperand_Success; 2295187831Ssam} 2296185377Ssam 2297187831Ssam/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 2298187831SsamARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2299187831SsamparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2300187831Ssam SMLoc S = Parser.getTok().getLoc(); 2301187831Ssam const AsmToken &Tok = Parser.getTok(); 2302187831Ssam assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2303187831Ssam StringRef IFlagsStr = Tok.getString(); 2304187831Ssam 2305187831Ssam // An iflags string of "none" is interpreted to mean that none of the AIF 2306187831Ssam // bits are set. Not a terribly useful instruction, but a valid encoding. 2307187831Ssam unsigned IFlags = 0; 2308187831Ssam if (IFlagsStr != "none") { 2309187831Ssam for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 2310187831Ssam unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 2311187831Ssam .Case("a", ARM_PROC::A) 2312187831Ssam .Case("i", ARM_PROC::I) 2313187831Ssam .Case("f", ARM_PROC::F) 2314187831Ssam .Default(~0U); 2315187831Ssam 2316187831Ssam // If some specific iflag is already set, it means that some letter is 2317187831Ssam // present more than once, this is not acceptable. 2318187831Ssam if (Flag == ~0U || (IFlags & Flag)) 2319187831Ssam return MatchOperand_NoMatch; 2320185377Ssam 2321187831Ssam IFlags |= Flag; 2322187831Ssam } 2323187831Ssam } 2324187831Ssam 2325187831Ssam Parser.Lex(); // Eat identifier token. 2326187831Ssam Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 2327187831Ssam return MatchOperand_Success; 2328185377Ssam} 2329187831Ssam 2330185377Ssam/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 2331187831SsamARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2332187831SsamparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2333185377Ssam SMLoc S = Parser.getTok().getLoc(); 2334187831Ssam const AsmToken &Tok = Parser.getTok(); 2335187831Ssam assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 2336185377Ssam StringRef Mask = Tok.getString(); 2337187831Ssam 2338185377Ssam if (isMClass()) { 2339187831Ssam // See ARMv6-M 10.1.1 2340187831Ssam unsigned FlagsVal = StringSwitch<unsigned>(Mask) 2341187831Ssam .Case("apsr", 0) 2342187831Ssam .Case("iapsr", 1) 2343187831Ssam .Case("eapsr", 2) 2344187831Ssam .Case("xpsr", 3) 2345187831Ssam .Case("ipsr", 5) 2346187831Ssam .Case("epsr", 6) 2347185377Ssam .Case("iepsr", 7) 2348187831Ssam .Case("msp", 8) 2349187831Ssam .Case("psp", 9) 2350187831Ssam .Case("primask", 16) 2351187831Ssam .Case("basepri", 17) 2352187831Ssam .Case("basepri_max", 18) 2353185377Ssam .Case("faultmask", 19) 2354187831Ssam .Case("control", 20) 2355185377Ssam .Default(~0U); 2356187831Ssam 2357185377Ssam if (FlagsVal == ~0U) 2358187831Ssam return MatchOperand_NoMatch; 2359187831Ssam 2360187831Ssam if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19) 2361187831Ssam // basepri, basepri_max and faultmask only valid for V7m. 2362185377Ssam return MatchOperand_NoMatch; 2363187831Ssam 2364187831Ssam Parser.Lex(); // Eat identifier token. 2365185377Ssam Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2366187831Ssam return MatchOperand_Success; 2367187831Ssam } 2368185377Ssam 2369187831Ssam // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 2370185377Ssam size_t Start = 0, Next = Mask.find('_'); 2371187831Ssam StringRef Flags = ""; 2372187831Ssam std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 2373187831Ssam if (Next != StringRef::npos) 2374187831Ssam Flags = Mask.slice(Next+1, Mask.size()); 2375187831Ssam 2376187831Ssam // FlagsVal contains the complete mask: 2377187831Ssam // 3-0: Mask 2378187831Ssam // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2379187831Ssam unsigned FlagsVal = 0; 2380187831Ssam 2381187831Ssam if (SpecReg == "apsr") { 2382187831Ssam FlagsVal = StringSwitch<unsigned>(Flags) 2383187831Ssam .Case("nzcvq", 0x8) // same as CPSR_f 2384187831Ssam .Case("g", 0x4) // same as CPSR_s 2385187831Ssam .Case("nzcvqg", 0xc) // same as CPSR_fs 2386187831Ssam .Default(~0U); 2387187831Ssam 2388187831Ssam if (FlagsVal == ~0U) { 2389185377Ssam if (!Flags.empty()) 2390185377Ssam return MatchOperand_NoMatch; 2391185377Ssam else 2392187831Ssam FlagsVal = 8; // No flag 2393187831Ssam } 2394187831Ssam } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 2395187831Ssam if (Flags == "all") // cpsr_all is an alias for cpsr_fc 2396187831Ssam Flags = "fc"; 2397187831Ssam for (int i = 0, e = Flags.size(); i != e; ++i) { 2398187831Ssam unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 2399185377Ssam .Case("c", 1) 2400187831Ssam .Case("x", 2) 2401187831Ssam .Case("s", 4) 2402187831Ssam .Case("f", 8) 2403185377Ssam .Default(~0U); 2404187831Ssam 2405187831Ssam // If some specific flag is already set, it means that some letter is 2406185377Ssam // present more than once, this is not acceptable. 2407 if (FlagsVal == ~0U || (FlagsVal & Flag)) 2408 return MatchOperand_NoMatch; 2409 FlagsVal |= Flag; 2410 } 2411 } else // No match for special register. 2412 return MatchOperand_NoMatch; 2413 2414 // Special register without flags are equivalent to "fc" flags. 2415 if (!FlagsVal) 2416 FlagsVal = 0x9; 2417 2418 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 2419 if (SpecReg == "spsr") 2420 FlagsVal |= 16; 2421 2422 Parser.Lex(); // Eat identifier token. 2423 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 2424 return MatchOperand_Success; 2425} 2426 2427ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2428parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 2429 int Low, int High) { 2430 const AsmToken &Tok = Parser.getTok(); 2431 if (Tok.isNot(AsmToken::Identifier)) { 2432 Error(Parser.getTok().getLoc(), Op + " operand expected."); 2433 return MatchOperand_ParseFail; 2434 } 2435 StringRef ShiftName = Tok.getString(); 2436 std::string LowerOp = LowercaseString(Op); 2437 std::string UpperOp = UppercaseString(Op); 2438 if (ShiftName != LowerOp && ShiftName != UpperOp) { 2439 Error(Parser.getTok().getLoc(), Op + " operand expected."); 2440 return MatchOperand_ParseFail; 2441 } 2442 Parser.Lex(); // Eat shift type token. 2443 2444 // There must be a '#' and a shift amount. 2445 if (Parser.getTok().isNot(AsmToken::Hash)) { 2446 Error(Parser.getTok().getLoc(), "'#' expected"); 2447 return MatchOperand_ParseFail; 2448 } 2449 Parser.Lex(); // Eat hash token. 2450 2451 const MCExpr *ShiftAmount; 2452 SMLoc Loc = Parser.getTok().getLoc(); 2453 if (getParser().ParseExpression(ShiftAmount)) { 2454 Error(Loc, "illegal expression"); 2455 return MatchOperand_ParseFail; 2456 } 2457 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2458 if (!CE) { 2459 Error(Loc, "constant expression expected"); 2460 return MatchOperand_ParseFail; 2461 } 2462 int Val = CE->getValue(); 2463 if (Val < Low || Val > High) { 2464 Error(Loc, "immediate value out of range"); 2465 return MatchOperand_ParseFail; 2466 } 2467 2468 Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 2469 2470 return MatchOperand_Success; 2471} 2472 2473ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2474parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2475 const AsmToken &Tok = Parser.getTok(); 2476 SMLoc S = Tok.getLoc(); 2477 if (Tok.isNot(AsmToken::Identifier)) { 2478 Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2479 return MatchOperand_ParseFail; 2480 } 2481 int Val = StringSwitch<int>(Tok.getString()) 2482 .Case("be", 1) 2483 .Case("le", 0) 2484 .Default(-1); 2485 Parser.Lex(); // Eat the token. 2486 2487 if (Val == -1) { 2488 Error(Tok.getLoc(), "'be' or 'le' operand expected"); 2489 return MatchOperand_ParseFail; 2490 } 2491 Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 2492 getContext()), 2493 S, Parser.getTok().getLoc())); 2494 return MatchOperand_Success; 2495} 2496 2497/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 2498/// instructions. Legal values are: 2499/// lsl #n 'n' in [0,31] 2500/// asr #n 'n' in [1,32] 2501/// n == 32 encoded as n == 0. 2502ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2503parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2504 const AsmToken &Tok = Parser.getTok(); 2505 SMLoc S = Tok.getLoc(); 2506 if (Tok.isNot(AsmToken::Identifier)) { 2507 Error(S, "shift operator 'asr' or 'lsl' expected"); 2508 return MatchOperand_ParseFail; 2509 } 2510 StringRef ShiftName = Tok.getString(); 2511 bool isASR; 2512 if (ShiftName == "lsl" || ShiftName == "LSL") 2513 isASR = false; 2514 else if (ShiftName == "asr" || ShiftName == "ASR") 2515 isASR = true; 2516 else { 2517 Error(S, "shift operator 'asr' or 'lsl' expected"); 2518 return MatchOperand_ParseFail; 2519 } 2520 Parser.Lex(); // Eat the operator. 2521 2522 // A '#' and a shift amount. 2523 if (Parser.getTok().isNot(AsmToken::Hash)) { 2524 Error(Parser.getTok().getLoc(), "'#' expected"); 2525 return MatchOperand_ParseFail; 2526 } 2527 Parser.Lex(); // Eat hash token. 2528 2529 const MCExpr *ShiftAmount; 2530 SMLoc E = Parser.getTok().getLoc(); 2531 if (getParser().ParseExpression(ShiftAmount)) { 2532 Error(E, "malformed shift expression"); 2533 return MatchOperand_ParseFail; 2534 } 2535 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2536 if (!CE) { 2537 Error(E, "shift amount must be an immediate"); 2538 return MatchOperand_ParseFail; 2539 } 2540 2541 int64_t Val = CE->getValue(); 2542 if (isASR) { 2543 // Shift amount must be in [1,32] 2544 if (Val < 1 || Val > 32) { 2545 Error(E, "'asr' shift amount must be in range [1,32]"); 2546 return MatchOperand_ParseFail; 2547 } 2548 // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode. 2549 if (isThumb() && Val == 32) { 2550 Error(E, "'asr #32' shift amount not allowed in Thumb mode"); 2551 return MatchOperand_ParseFail; 2552 } 2553 if (Val == 32) Val = 0; 2554 } else { 2555 // Shift amount must be in [1,32] 2556 if (Val < 0 || Val > 31) { 2557 Error(E, "'lsr' shift amount must be in range [0,31]"); 2558 return MatchOperand_ParseFail; 2559 } 2560 } 2561 2562 E = Parser.getTok().getLoc(); 2563 Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 2564 2565 return MatchOperand_Success; 2566} 2567 2568/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 2569/// of instructions. Legal values are: 2570/// ror #n 'n' in {0, 8, 16, 24} 2571ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2572parseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2573 const AsmToken &Tok = Parser.getTok(); 2574 SMLoc S = Tok.getLoc(); 2575 if (Tok.isNot(AsmToken::Identifier)) 2576 return MatchOperand_NoMatch; 2577 StringRef ShiftName = Tok.getString(); 2578 if (ShiftName != "ror" && ShiftName != "ROR") 2579 return MatchOperand_NoMatch; 2580 Parser.Lex(); // Eat the operator. 2581 2582 // A '#' and a rotate amount. 2583 if (Parser.getTok().isNot(AsmToken::Hash)) { 2584 Error(Parser.getTok().getLoc(), "'#' expected"); 2585 return MatchOperand_ParseFail; 2586 } 2587 Parser.Lex(); // Eat hash token. 2588 2589 const MCExpr *ShiftAmount; 2590 SMLoc E = Parser.getTok().getLoc(); 2591 if (getParser().ParseExpression(ShiftAmount)) { 2592 Error(E, "malformed rotate expression"); 2593 return MatchOperand_ParseFail; 2594 } 2595 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 2596 if (!CE) { 2597 Error(E, "rotate amount must be an immediate"); 2598 return MatchOperand_ParseFail; 2599 } 2600 2601 int64_t Val = CE->getValue(); 2602 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 2603 // normally, zero is represented in asm by omitting the rotate operand 2604 // entirely. 2605 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 2606 Error(E, "'ror' rotate amount must be 8, 16, or 24"); 2607 return MatchOperand_ParseFail; 2608 } 2609 2610 E = Parser.getTok().getLoc(); 2611 Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 2612 2613 return MatchOperand_Success; 2614} 2615 2616ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2617parseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2618 SMLoc S = Parser.getTok().getLoc(); 2619 // The bitfield descriptor is really two operands, the LSB and the width. 2620 if (Parser.getTok().isNot(AsmToken::Hash)) { 2621 Error(Parser.getTok().getLoc(), "'#' expected"); 2622 return MatchOperand_ParseFail; 2623 } 2624 Parser.Lex(); // Eat hash token. 2625 2626 const MCExpr *LSBExpr; 2627 SMLoc E = Parser.getTok().getLoc(); 2628 if (getParser().ParseExpression(LSBExpr)) { 2629 Error(E, "malformed immediate expression"); 2630 return MatchOperand_ParseFail; 2631 } 2632 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2633 if (!CE) { 2634 Error(E, "'lsb' operand must be an immediate"); 2635 return MatchOperand_ParseFail; 2636 } 2637 2638 int64_t LSB = CE->getValue(); 2639 // The LSB must be in the range [0,31] 2640 if (LSB < 0 || LSB > 31) { 2641 Error(E, "'lsb' operand must be in the range [0,31]"); 2642 return MatchOperand_ParseFail; 2643 } 2644 E = Parser.getTok().getLoc(); 2645 2646 // Expect another immediate operand. 2647 if (Parser.getTok().isNot(AsmToken::Comma)) { 2648 Error(Parser.getTok().getLoc(), "too few operands"); 2649 return MatchOperand_ParseFail; 2650 } 2651 Parser.Lex(); // Eat hash token. 2652 if (Parser.getTok().isNot(AsmToken::Hash)) { 2653 Error(Parser.getTok().getLoc(), "'#' expected"); 2654 return MatchOperand_ParseFail; 2655 } 2656 Parser.Lex(); // Eat hash token. 2657 2658 const MCExpr *WidthExpr; 2659 if (getParser().ParseExpression(WidthExpr)) { 2660 Error(E, "malformed immediate expression"); 2661 return MatchOperand_ParseFail; 2662 } 2663 CE = dyn_cast<MCConstantExpr>(WidthExpr); 2664 if (!CE) { 2665 Error(E, "'width' operand must be an immediate"); 2666 return MatchOperand_ParseFail; 2667 } 2668 2669 int64_t Width = CE->getValue(); 2670 // The LSB must be in the range [1,32-lsb] 2671 if (Width < 1 || Width > 32 - LSB) { 2672 Error(E, "'width' operand must be in the range [1,32-lsb]"); 2673 return MatchOperand_ParseFail; 2674 } 2675 E = Parser.getTok().getLoc(); 2676 2677 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2678 2679 return MatchOperand_Success; 2680} 2681 2682ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2683parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2684 // Check for a post-index addressing register operand. Specifically: 2685 // postidx_reg := '+' register {, shift} 2686 // | '-' register {, shift} 2687 // | register {, shift} 2688 2689 // This method must return MatchOperand_NoMatch without consuming any tokens 2690 // in the case where there is no match, as other alternatives take other 2691 // parse methods. 2692 AsmToken Tok = Parser.getTok(); 2693 SMLoc S = Tok.getLoc(); 2694 bool haveEaten = false; 2695 bool isAdd = true; 2696 int Reg = -1; 2697 if (Tok.is(AsmToken::Plus)) { 2698 Parser.Lex(); // Eat the '+' token. 2699 haveEaten = true; 2700 } else if (Tok.is(AsmToken::Minus)) { 2701 Parser.Lex(); // Eat the '-' token. 2702 isAdd = false; 2703 haveEaten = true; 2704 } 2705 if (Parser.getTok().is(AsmToken::Identifier)) 2706 Reg = tryParseRegister(); 2707 if (Reg == -1) { 2708 if (!haveEaten) 2709 return MatchOperand_NoMatch; 2710 Error(Parser.getTok().getLoc(), "register expected"); 2711 return MatchOperand_ParseFail; 2712 } 2713 SMLoc E = Parser.getTok().getLoc(); 2714 2715 ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2716 unsigned ShiftImm = 0; 2717 if (Parser.getTok().is(AsmToken::Comma)) { 2718 Parser.Lex(); // Eat the ','. 2719 if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 2720 return MatchOperand_ParseFail; 2721 } 2722 2723 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2724 ShiftImm, S, E)); 2725 2726 return MatchOperand_Success; 2727} 2728 2729ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2730parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2731 // Check for a post-index addressing register operand. Specifically: 2732 // am3offset := '+' register 2733 // | '-' register 2734 // | register 2735 // | # imm 2736 // | # + imm 2737 // | # - imm 2738 2739 // This method must return MatchOperand_NoMatch without consuming any tokens 2740 // in the case where there is no match, as other alternatives take other 2741 // parse methods. 2742 AsmToken Tok = Parser.getTok(); 2743 SMLoc S = Tok.getLoc(); 2744 2745 // Do immediates first, as we always parse those if we have a '#'. 2746 if (Parser.getTok().is(AsmToken::Hash)) { 2747 Parser.Lex(); // Eat the '#'. 2748 // Explicitly look for a '-', as we need to encode negative zero 2749 // differently. 2750 bool isNegative = Parser.getTok().is(AsmToken::Minus); 2751 const MCExpr *Offset; 2752 if (getParser().ParseExpression(Offset)) 2753 return MatchOperand_ParseFail; 2754 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2755 if (!CE) { 2756 Error(S, "constant expression expected"); 2757 return MatchOperand_ParseFail; 2758 } 2759 SMLoc E = Tok.getLoc(); 2760 // Negative zero is encoded as the flag value INT32_MIN. 2761 int32_t Val = CE->getValue(); 2762 if (isNegative && Val == 0) 2763 Val = INT32_MIN; 2764 2765 Operands.push_back( 2766 ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2767 2768 return MatchOperand_Success; 2769 } 2770 2771 2772 bool haveEaten = false; 2773 bool isAdd = true; 2774 int Reg = -1; 2775 if (Tok.is(AsmToken::Plus)) { 2776 Parser.Lex(); // Eat the '+' token. 2777 haveEaten = true; 2778 } else if (Tok.is(AsmToken::Minus)) { 2779 Parser.Lex(); // Eat the '-' token. 2780 isAdd = false; 2781 haveEaten = true; 2782 } 2783 if (Parser.getTok().is(AsmToken::Identifier)) 2784 Reg = tryParseRegister(); 2785 if (Reg == -1) { 2786 if (!haveEaten) 2787 return MatchOperand_NoMatch; 2788 Error(Parser.getTok().getLoc(), "register expected"); 2789 return MatchOperand_ParseFail; 2790 } 2791 SMLoc E = Parser.getTok().getLoc(); 2792 2793 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2794 0, S, E)); 2795 2796 return MatchOperand_Success; 2797} 2798 2799/// cvtT2LdrdPre - Convert parsed operands to MCInst. 2800/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2801/// when they refer multiple MIOperands inside a single one. 2802bool ARMAsmParser:: 2803cvtT2LdrdPre(MCInst &Inst, unsigned Opcode, 2804 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2805 // Rt, Rt2 2806 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2807 ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2808 // Create a writeback register dummy placeholder. 2809 Inst.addOperand(MCOperand::CreateReg(0)); 2810 // addr 2811 ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 2812 // pred 2813 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2814 return true; 2815} 2816 2817/// cvtT2StrdPre - Convert parsed operands to MCInst. 2818/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2819/// when they refer multiple MIOperands inside a single one. 2820bool ARMAsmParser:: 2821cvtT2StrdPre(MCInst &Inst, unsigned Opcode, 2822 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2823 // Create a writeback register dummy placeholder. 2824 Inst.addOperand(MCOperand::CreateReg(0)); 2825 // Rt, Rt2 2826 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2827 ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2828 // addr 2829 ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2); 2830 // pred 2831 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2832 return true; 2833} 2834 2835/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 2836/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2837/// when they refer multiple MIOperands inside a single one. 2838bool ARMAsmParser:: 2839cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 2840 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2841 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2842 2843 // Create a writeback register dummy placeholder. 2844 Inst.addOperand(MCOperand::CreateImm(0)); 2845 2846 ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 2847 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2848 return true; 2849} 2850 2851/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst. 2852/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2853/// when they refer multiple MIOperands inside a single one. 2854bool ARMAsmParser:: 2855cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode, 2856 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2857 // Create a writeback register dummy placeholder. 2858 Inst.addOperand(MCOperand::CreateImm(0)); 2859 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2860 ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2); 2861 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2862 return true; 2863} 2864 2865/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2866/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2867/// when they refer multiple MIOperands inside a single one. 2868bool ARMAsmParser:: 2869cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2870 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2871 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2872 2873 // Create a writeback register dummy placeholder. 2874 Inst.addOperand(MCOperand::CreateImm(0)); 2875 2876 ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2877 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2878 return true; 2879} 2880 2881/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2882/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2883/// when they refer multiple MIOperands inside a single one. 2884bool ARMAsmParser:: 2885cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2886 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2887 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2888 2889 // Create a writeback register dummy placeholder. 2890 Inst.addOperand(MCOperand::CreateImm(0)); 2891 2892 ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2893 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2894 return true; 2895} 2896 2897 2898/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2899/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2900/// when they refer multiple MIOperands inside a single one. 2901bool ARMAsmParser:: 2902cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2903 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2904 // Create a writeback register dummy placeholder. 2905 Inst.addOperand(MCOperand::CreateImm(0)); 2906 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2907 ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2908 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2909 return true; 2910} 2911 2912/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2913/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2914/// when they refer multiple MIOperands inside a single one. 2915bool ARMAsmParser:: 2916cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2917 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2918 // Create a writeback register dummy placeholder. 2919 Inst.addOperand(MCOperand::CreateImm(0)); 2920 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2921 ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2922 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2923 return true; 2924} 2925 2926/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2927/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2928/// when they refer multiple MIOperands inside a single one. 2929bool ARMAsmParser:: 2930cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2931 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2932 // Create a writeback register dummy placeholder. 2933 Inst.addOperand(MCOperand::CreateImm(0)); 2934 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2935 ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2936 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2937 return true; 2938} 2939 2940/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 2941/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2942/// when they refer multiple MIOperands inside a single one. 2943bool ARMAsmParser:: 2944cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 2945 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2946 // Rt 2947 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2948 // Create a writeback register dummy placeholder. 2949 Inst.addOperand(MCOperand::CreateImm(0)); 2950 // addr 2951 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2952 // offset 2953 ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 2954 // pred 2955 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2956 return true; 2957} 2958 2959/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2960/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2961/// when they refer multiple MIOperands inside a single one. 2962bool ARMAsmParser:: 2963cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 2964 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2965 // Rt 2966 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2967 // Create a writeback register dummy placeholder. 2968 Inst.addOperand(MCOperand::CreateImm(0)); 2969 // addr 2970 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2971 // offset 2972 ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 2973 // pred 2974 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2975 return true; 2976} 2977 2978/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 2979/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2980/// when they refer multiple MIOperands inside a single one. 2981bool ARMAsmParser:: 2982cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 2983 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2984 // Create a writeback register dummy placeholder. 2985 Inst.addOperand(MCOperand::CreateImm(0)); 2986 // Rt 2987 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2988 // addr 2989 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2990 // offset 2991 ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 2992 // pred 2993 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2994 return true; 2995} 2996 2997/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2998/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2999/// when they refer multiple MIOperands inside a single one. 3000bool ARMAsmParser:: 3001cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 3002 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3003 // Create a writeback register dummy placeholder. 3004 Inst.addOperand(MCOperand::CreateImm(0)); 3005 // Rt 3006 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3007 // addr 3008 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 3009 // offset 3010 ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 3011 // pred 3012 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3013 return true; 3014} 3015 3016/// cvtLdrdPre - Convert parsed operands to MCInst. 3017/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3018/// when they refer multiple MIOperands inside a single one. 3019bool ARMAsmParser:: 3020cvtLdrdPre(MCInst &Inst, unsigned Opcode, 3021 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3022 // Rt, Rt2 3023 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3024 ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3025 // Create a writeback register dummy placeholder. 3026 Inst.addOperand(MCOperand::CreateImm(0)); 3027 // addr 3028 ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 3029 // pred 3030 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3031 return true; 3032} 3033 3034/// cvtStrdPre - Convert parsed operands to MCInst. 3035/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3036/// when they refer multiple MIOperands inside a single one. 3037bool ARMAsmParser:: 3038cvtStrdPre(MCInst &Inst, unsigned Opcode, 3039 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3040 // Create a writeback register dummy placeholder. 3041 Inst.addOperand(MCOperand::CreateImm(0)); 3042 // Rt, Rt2 3043 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3044 ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3045 // addr 3046 ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 3047 // pred 3048 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3049 return true; 3050} 3051 3052/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 3053/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3054/// when they refer multiple MIOperands inside a single one. 3055bool ARMAsmParser:: 3056cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 3057 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3058 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 3059 // Create a writeback register dummy placeholder. 3060 Inst.addOperand(MCOperand::CreateImm(0)); 3061 ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 3062 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 3063 return true; 3064} 3065 3066/// cvtThumbMultiple- Convert parsed operands to MCInst. 3067/// Needed here because the Asm Gen Matcher can't handle properly tied operands 3068/// when they refer multiple MIOperands inside a single one. 3069bool ARMAsmParser:: 3070cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 3071 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3072 // The second source operand must be the same register as the destination 3073 // operand. 3074 if (Operands.size() == 6 && 3075 (((ARMOperand*)Operands[3])->getReg() != 3076 ((ARMOperand*)Operands[5])->getReg()) && 3077 (((ARMOperand*)Operands[3])->getReg() != 3078 ((ARMOperand*)Operands[4])->getReg())) { 3079 Error(Operands[3]->getStartLoc(), 3080 "destination register must match source register"); 3081 return false; 3082 } 3083 ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 3084 ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 3085 ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 3086 // If we have a three-operand form, use that, else the second source operand 3087 // is just the destination operand again. 3088 if (Operands.size() == 6) 3089 ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 3090 else 3091 Inst.addOperand(Inst.getOperand(0)); 3092 ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 3093 3094 return true; 3095} 3096 3097/// Parse an ARM memory expression, return false if successful else return true 3098/// or an error. The first token must be a '[' when called. 3099bool ARMAsmParser:: 3100parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3101 SMLoc S, E; 3102 assert(Parser.getTok().is(AsmToken::LBrac) && 3103 "Token is not a Left Bracket"); 3104 S = Parser.getTok().getLoc(); 3105 Parser.Lex(); // Eat left bracket token. 3106 3107 const AsmToken &BaseRegTok = Parser.getTok(); 3108 int BaseRegNum = tryParseRegister(); 3109 if (BaseRegNum == -1) 3110 return Error(BaseRegTok.getLoc(), "register expected"); 3111 3112 // The next token must either be a comma or a closing bracket. 3113 const AsmToken &Tok = Parser.getTok(); 3114 if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 3115 return Error(Tok.getLoc(), "malformed memory operand"); 3116 3117 if (Tok.is(AsmToken::RBrac)) { 3118 E = Tok.getLoc(); 3119 Parser.Lex(); // Eat right bracket token. 3120 3121 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 3122 0, 0, false, S, E)); 3123 3124 // If there's a pre-indexing writeback marker, '!', just add it as a token 3125 // operand. It's rather odd, but syntactically valid. 3126 if (Parser.getTok().is(AsmToken::Exclaim)) { 3127 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3128 Parser.Lex(); // Eat the '!'. 3129 } 3130 3131 return false; 3132 } 3133 3134 assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 3135 Parser.Lex(); // Eat the comma. 3136 3137 // If we have a ':', it's an alignment specifier. 3138 if (Parser.getTok().is(AsmToken::Colon)) { 3139 Parser.Lex(); // Eat the ':'. 3140 E = Parser.getTok().getLoc(); 3141 3142 const MCExpr *Expr; 3143 if (getParser().ParseExpression(Expr)) 3144 return true; 3145 3146 // The expression has to be a constant. Memory references with relocations 3147 // don't come through here, as they use the <label> forms of the relevant 3148 // instructions. 3149 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 3150 if (!CE) 3151 return Error (E, "constant expression expected"); 3152 3153 unsigned Align = 0; 3154 switch (CE->getValue()) { 3155 default: 3156 return Error(E, "alignment specifier must be 64, 128, or 256 bits"); 3157 case 64: Align = 8; break; 3158 case 128: Align = 16; break; 3159 case 256: Align = 32; break; 3160 } 3161 3162 // Now we should have the closing ']' 3163 E = Parser.getTok().getLoc(); 3164 if (Parser.getTok().isNot(AsmToken::RBrac)) 3165 return Error(E, "']' expected"); 3166 Parser.Lex(); // Eat right bracket token. 3167 3168 // Don't worry about range checking the value here. That's handled by 3169 // the is*() predicates. 3170 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, 3171 ARM_AM::no_shift, 0, Align, 3172 false, S, E)); 3173 3174 // If there's a pre-indexing writeback marker, '!', just add it as a token 3175 // operand. 3176 if (Parser.getTok().is(AsmToken::Exclaim)) { 3177 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3178 Parser.Lex(); // Eat the '!'. 3179 } 3180 3181 return false; 3182 } 3183 3184 // If we have a '#', it's an immediate offset, else assume it's a register 3185 // offset. 3186 if (Parser.getTok().is(AsmToken::Hash)) { 3187 Parser.Lex(); // Eat the '#'. 3188 E = Parser.getTok().getLoc(); 3189 3190 bool isNegative = getParser().getTok().is(AsmToken::Minus); 3191 const MCExpr *Offset; 3192 if (getParser().ParseExpression(Offset)) 3193 return true; 3194 3195 // The expression has to be a constant. Memory references with relocations 3196 // don't come through here, as they use the <label> forms of the relevant 3197 // instructions. 3198 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 3199 if (!CE) 3200 return Error (E, "constant expression expected"); 3201 3202 // If the constant was #-0, represent it as INT32_MIN. 3203 int32_t Val = CE->getValue(); 3204 if (isNegative && Val == 0) 3205 CE = MCConstantExpr::Create(INT32_MIN, getContext()); 3206 3207 // Now we should have the closing ']' 3208 E = Parser.getTok().getLoc(); 3209 if (Parser.getTok().isNot(AsmToken::RBrac)) 3210 return Error(E, "']' expected"); 3211 Parser.Lex(); // Eat right bracket token. 3212 3213 // Don't worry about range checking the value here. That's handled by 3214 // the is*() predicates. 3215 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 3216 ARM_AM::no_shift, 0, 0, 3217 false, S, E)); 3218 3219 // If there's a pre-indexing writeback marker, '!', just add it as a token 3220 // operand. 3221 if (Parser.getTok().is(AsmToken::Exclaim)) { 3222 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3223 Parser.Lex(); // Eat the '!'. 3224 } 3225 3226 return false; 3227 } 3228 3229 // The register offset is optionally preceded by a '+' or '-' 3230 bool isNegative = false; 3231 if (Parser.getTok().is(AsmToken::Minus)) { 3232 isNegative = true; 3233 Parser.Lex(); // Eat the '-'. 3234 } else if (Parser.getTok().is(AsmToken::Plus)) { 3235 // Nothing to do. 3236 Parser.Lex(); // Eat the '+'. 3237 } 3238 3239 E = Parser.getTok().getLoc(); 3240 int OffsetRegNum = tryParseRegister(); 3241 if (OffsetRegNum == -1) 3242 return Error(E, "register expected"); 3243 3244 // If there's a shift operator, handle it. 3245 ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 3246 unsigned ShiftImm = 0; 3247 if (Parser.getTok().is(AsmToken::Comma)) { 3248 Parser.Lex(); // Eat the ','. 3249 if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 3250 return true; 3251 } 3252 3253 // Now we should have the closing ']' 3254 E = Parser.getTok().getLoc(); 3255 if (Parser.getTok().isNot(AsmToken::RBrac)) 3256 return Error(E, "']' expected"); 3257 Parser.Lex(); // Eat right bracket token. 3258 3259 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 3260 ShiftType, ShiftImm, 0, isNegative, 3261 S, E)); 3262 3263 // If there's a pre-indexing writeback marker, '!', just add it as a token 3264 // operand. 3265 if (Parser.getTok().is(AsmToken::Exclaim)) { 3266 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 3267 Parser.Lex(); // Eat the '!'. 3268 } 3269 3270 return false; 3271} 3272 3273/// parseMemRegOffsetShift - one of these two: 3274/// ( lsl | lsr | asr | ror ) , # shift_amount 3275/// rrx 3276/// return true if it parses a shift otherwise it returns false. 3277bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 3278 unsigned &Amount) { 3279 SMLoc Loc = Parser.getTok().getLoc(); 3280 const AsmToken &Tok = Parser.getTok(); 3281 if (Tok.isNot(AsmToken::Identifier)) 3282 return true; 3283 StringRef ShiftName = Tok.getString(); 3284 if (ShiftName == "lsl" || ShiftName == "LSL") 3285 St = ARM_AM::lsl; 3286 else if (ShiftName == "lsr" || ShiftName == "LSR") 3287 St = ARM_AM::lsr; 3288 else if (ShiftName == "asr" || ShiftName == "ASR") 3289 St = ARM_AM::asr; 3290 else if (ShiftName == "ror" || ShiftName == "ROR") 3291 St = ARM_AM::ror; 3292 else if (ShiftName == "rrx" || ShiftName == "RRX") 3293 St = ARM_AM::rrx; 3294 else 3295 return Error(Loc, "illegal shift operator"); 3296 Parser.Lex(); // Eat shift type token. 3297 3298 // rrx stands alone. 3299 Amount = 0; 3300 if (St != ARM_AM::rrx) { 3301 Loc = Parser.getTok().getLoc(); 3302 // A '#' and a shift amount. 3303 const AsmToken &HashTok = Parser.getTok(); 3304 if (HashTok.isNot(AsmToken::Hash)) 3305 return Error(HashTok.getLoc(), "'#' expected"); 3306 Parser.Lex(); // Eat hash token. 3307 3308 const MCExpr *Expr; 3309 if (getParser().ParseExpression(Expr)) 3310 return true; 3311 // Range check the immediate. 3312 // lsl, ror: 0 <= imm <= 31 3313 // lsr, asr: 0 <= imm <= 32 3314 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 3315 if (!CE) 3316 return Error(Loc, "shift amount must be an immediate"); 3317 int64_t Imm = CE->getValue(); 3318 if (Imm < 0 || 3319 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 3320 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 3321 return Error(Loc, "immediate shift value out of range"); 3322 Amount = Imm; 3323 } 3324 3325 return false; 3326} 3327 3328/// parseFPImm - A floating point immediate expression operand. 3329ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 3330parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3331 SMLoc S = Parser.getTok().getLoc(); 3332 3333 if (Parser.getTok().isNot(AsmToken::Hash)) 3334 return MatchOperand_NoMatch; 3335 Parser.Lex(); // Eat the '#'. 3336 3337 // Handle negation, as that still comes through as a separate token. 3338 bool isNegative = false; 3339 if (Parser.getTok().is(AsmToken::Minus)) { 3340 isNegative = true; 3341 Parser.Lex(); 3342 } 3343 const AsmToken &Tok = Parser.getTok(); 3344 if (Tok.is(AsmToken::Real)) { 3345 APFloat RealVal(APFloat::IEEEdouble, Tok.getString()); 3346 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 3347 // If we had a '-' in front, toggle the sign bit. 3348 IntVal ^= (uint64_t)isNegative << 63; 3349 int Val = ARM_AM::getFP64Imm(APInt(64, IntVal)); 3350 Parser.Lex(); // Eat the token. 3351 if (Val == -1) { 3352 TokError("floating point value out of range"); 3353 return MatchOperand_ParseFail; 3354 } 3355 Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 3356 return MatchOperand_Success; 3357 } 3358 if (Tok.is(AsmToken::Integer)) { 3359 int64_t Val = Tok.getIntVal(); 3360 Parser.Lex(); // Eat the token. 3361 if (Val > 255 || Val < 0) { 3362 TokError("encoded floating point value out of range"); 3363 return MatchOperand_ParseFail; 3364 } 3365 Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext())); 3366 return MatchOperand_Success; 3367 } 3368 3369 TokError("invalid floating point immediate"); 3370 return MatchOperand_ParseFail; 3371} 3372/// Parse a arm instruction operand. For now this parses the operand regardless 3373/// of the mnemonic. 3374bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3375 StringRef Mnemonic) { 3376 SMLoc S, E; 3377 3378 // Check if the current operand has a custom associated parser, if so, try to 3379 // custom parse the operand, or fallback to the general approach. 3380 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 3381 if (ResTy == MatchOperand_Success) 3382 return false; 3383 // If there wasn't a custom match, try the generic matcher below. Otherwise, 3384 // there was a match, but an error occurred, in which case, just return that 3385 // the operand parsing failed. 3386 if (ResTy == MatchOperand_ParseFail) 3387 return true; 3388 3389 switch (getLexer().getKind()) { 3390 default: 3391 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 3392 return true; 3393 case AsmToken::Identifier: { 3394 // If this is VMRS, check for the apsr_nzcv operand. 3395 if (!tryParseRegisterWithWriteBack(Operands)) 3396 return false; 3397 int Res = tryParseShiftRegister(Operands); 3398 if (Res == 0) // success 3399 return false; 3400 else if (Res == -1) // irrecoverable error 3401 return true; 3402 if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") { 3403 S = Parser.getTok().getLoc(); 3404 Parser.Lex(); 3405 Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S)); 3406 return false; 3407 } 3408 3409 // Fall though for the Identifier case that is not a register or a 3410 // special name. 3411 } 3412 case AsmToken::Integer: // things like 1f and 2b as a branch targets 3413 case AsmToken::Dot: { // . as a branch target 3414 // This was not a register so parse other operands that start with an 3415 // identifier (like labels) as expressions and create them as immediates. 3416 const MCExpr *IdVal; 3417 S = Parser.getTok().getLoc(); 3418 if (getParser().ParseExpression(IdVal)) 3419 return true; 3420 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 3421 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 3422 return false; 3423 } 3424 case AsmToken::LBrac: 3425 return parseMemory(Operands); 3426 case AsmToken::LCurly: 3427 return parseRegisterList(Operands); 3428 case AsmToken::Hash: { 3429 // #42 -> immediate. 3430 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 3431 S = Parser.getTok().getLoc(); 3432 Parser.Lex(); 3433 bool isNegative = Parser.getTok().is(AsmToken::Minus); 3434 const MCExpr *ImmVal; 3435 if (getParser().ParseExpression(ImmVal)) 3436 return true; 3437 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal); 3438 if (!CE) { 3439 Error(S, "constant expression expected"); 3440 return MatchOperand_ParseFail; 3441 } 3442 int32_t Val = CE->getValue(); 3443 if (isNegative && Val == 0) 3444 ImmVal = MCConstantExpr::Create(INT32_MIN, getContext()); 3445 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 3446 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 3447 return false; 3448 } 3449 case AsmToken::Colon: { 3450 // ":lower16:" and ":upper16:" expression prefixes 3451 // FIXME: Check it's an expression prefix, 3452 // e.g. (FOO - :lower16:BAR) isn't legal. 3453 ARMMCExpr::VariantKind RefKind; 3454 if (parsePrefix(RefKind)) 3455 return true; 3456 3457 const MCExpr *SubExprVal; 3458 if (getParser().ParseExpression(SubExprVal)) 3459 return true; 3460 3461 const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 3462 getContext()); 3463 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 3464 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 3465 return false; 3466 } 3467 } 3468} 3469 3470// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 3471// :lower16: and :upper16:. 3472bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 3473 RefKind = ARMMCExpr::VK_ARM_None; 3474 3475 // :lower16: and :upper16: modifiers 3476 assert(getLexer().is(AsmToken::Colon) && "expected a :"); 3477 Parser.Lex(); // Eat ':' 3478 3479 if (getLexer().isNot(AsmToken::Identifier)) { 3480 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 3481 return true; 3482 } 3483 3484 StringRef IDVal = Parser.getTok().getIdentifier(); 3485 if (IDVal == "lower16") { 3486 RefKind = ARMMCExpr::VK_ARM_LO16; 3487 } else if (IDVal == "upper16") { 3488 RefKind = ARMMCExpr::VK_ARM_HI16; 3489 } else { 3490 Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 3491 return true; 3492 } 3493 Parser.Lex(); 3494 3495 if (getLexer().isNot(AsmToken::Colon)) { 3496 Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 3497 return true; 3498 } 3499 Parser.Lex(); // Eat the last ':' 3500 return false; 3501} 3502 3503/// \brief Given a mnemonic, split out possible predication code and carry 3504/// setting letters to form a canonical mnemonic and flags. 3505// 3506// FIXME: Would be nice to autogen this. 3507// FIXME: This is a bit of a maze of special cases. 3508StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 3509 unsigned &PredicationCode, 3510 bool &CarrySetting, 3511 unsigned &ProcessorIMod, 3512 StringRef &ITMask) { 3513 PredicationCode = ARMCC::AL; 3514 CarrySetting = false; 3515 ProcessorIMod = 0; 3516 3517 // Ignore some mnemonics we know aren't predicated forms. 3518 // 3519 // FIXME: Would be nice to autogen this. 3520 if ((Mnemonic == "movs" && isThumb()) || 3521 Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 3522 Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 3523 Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 3524 Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 3525 Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 3526 Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 3527 Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 3528 return Mnemonic; 3529 3530 // First, split out any predication code. Ignore mnemonics we know aren't 3531 // predicated but do have a carry-set and so weren't caught above. 3532 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 3533 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 3534 Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 3535 Mnemonic != "sbcs" && Mnemonic != "rscs") { 3536 unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 3537 .Case("eq", ARMCC::EQ) 3538 .Case("ne", ARMCC::NE) 3539 .Case("hs", ARMCC::HS) 3540 .Case("cs", ARMCC::HS) 3541 .Case("lo", ARMCC::LO) 3542 .Case("cc", ARMCC::LO) 3543 .Case("mi", ARMCC::MI) 3544 .Case("pl", ARMCC::PL) 3545 .Case("vs", ARMCC::VS) 3546 .Case("vc", ARMCC::VC) 3547 .Case("hi", ARMCC::HI) 3548 .Case("ls", ARMCC::LS) 3549 .Case("ge", ARMCC::GE) 3550 .Case("lt", ARMCC::LT) 3551 .Case("gt", ARMCC::GT) 3552 .Case("le", ARMCC::LE) 3553 .Case("al", ARMCC::AL) 3554 .Default(~0U); 3555 if (CC != ~0U) { 3556 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 3557 PredicationCode = CC; 3558 } 3559 } 3560 3561 // Next, determine if we have a carry setting bit. We explicitly ignore all 3562 // the instructions we know end in 's'. 3563 if (Mnemonic.endswith("s") && 3564 !(Mnemonic == "cps" || Mnemonic == "mls" || 3565 Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 3566 Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 3567 Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 3568 Mnemonic == "vrsqrts" || Mnemonic == "srs" || 3569 (Mnemonic == "movs" && isThumb()))) { 3570 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 3571 CarrySetting = true; 3572 } 3573 3574 // The "cps" instruction can have a interrupt mode operand which is glued into 3575 // the mnemonic. Check if this is the case, split it and parse the imod op 3576 if (Mnemonic.startswith("cps")) { 3577 // Split out any imod code. 3578 unsigned IMod = 3579 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 3580 .Case("ie", ARM_PROC::IE) 3581 .Case("id", ARM_PROC::ID) 3582 .Default(~0U); 3583 if (IMod != ~0U) { 3584 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 3585 ProcessorIMod = IMod; 3586 } 3587 } 3588 3589 // The "it" instruction has the condition mask on the end of the mnemonic. 3590 if (Mnemonic.startswith("it")) { 3591 ITMask = Mnemonic.slice(2, Mnemonic.size()); 3592 Mnemonic = Mnemonic.slice(0, 2); 3593 } 3594 3595 return Mnemonic; 3596} 3597 3598/// \brief Given a canonical mnemonic, determine if the instruction ever allows 3599/// inclusion of carry set or predication code operands. 3600// 3601// FIXME: It would be nice to autogen this. 3602void ARMAsmParser:: 3603getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 3604 bool &CanAcceptPredicationCode) { 3605 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 3606 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 3607 Mnemonic == "add" || Mnemonic == "adc" || 3608 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 3609 Mnemonic == "orr" || Mnemonic == "mvn" || 3610 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 3611 Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" || 3612 (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" || 3613 Mnemonic == "mla" || Mnemonic == "smlal" || 3614 Mnemonic == "umlal" || Mnemonic == "umull"))) { 3615 CanAcceptCarrySet = true; 3616 } else 3617 CanAcceptCarrySet = false; 3618 3619 if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 3620 Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 3621 Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 3622 Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 3623 Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" || 3624 (Mnemonic == "clrex" && !isThumb()) || 3625 (Mnemonic == "nop" && isThumbOne()) || 3626 ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" || 3627 Mnemonic == "ldc2" || Mnemonic == "ldc2l" || 3628 Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) || 3629 ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && 3630 !isThumb()) || 3631 Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { 3632 CanAcceptPredicationCode = false; 3633 } else 3634 CanAcceptPredicationCode = true; 3635 3636 if (isThumb()) { 3637 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 3638 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 3639 CanAcceptPredicationCode = false; 3640 } 3641} 3642 3643bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 3644 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3645 // FIXME: This is all horribly hacky. We really need a better way to deal 3646 // with optional operands like this in the matcher table. 3647 3648 // The 'mov' mnemonic is special. One variant has a cc_out operand, while 3649 // another does not. Specifically, the MOVW instruction does not. So we 3650 // special case it here and remove the defaulted (non-setting) cc_out 3651 // operand if that's the instruction we're trying to match. 3652 // 3653 // We do this as post-processing of the explicit operands rather than just 3654 // conditionally adding the cc_out in the first place because we need 3655 // to check the type of the parsed immediate operand. 3656 if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() && 3657 !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 3658 static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 3659 static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3660 return true; 3661 3662 // Register-register 'add' for thumb does not have a cc_out operand 3663 // when there are only two register operands. 3664 if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 3665 static_cast<ARMOperand*>(Operands[3])->isReg() && 3666 static_cast<ARMOperand*>(Operands[4])->isReg() && 3667 static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3668 return true; 3669 // Register-register 'add' for thumb does not have a cc_out operand 3670 // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do 3671 // have to check the immediate range here since Thumb2 has a variant 3672 // that can handle a different range and has a cc_out operand. 3673 if (((isThumb() && Mnemonic == "add") || 3674 (isThumbTwo() && Mnemonic == "sub")) && 3675 Operands.size() == 6 && 3676 static_cast<ARMOperand*>(Operands[3])->isReg() && 3677 static_cast<ARMOperand*>(Operands[4])->isReg() && 3678 static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 3679 static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 3680 (static_cast<ARMOperand*>(Operands[5])->isReg() || 3681 static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4())) 3682 return true; 3683 // For Thumb2, add/sub immediate does not have a cc_out operand for the 3684 // imm0_4095 variant. That's the least-preferred variant when 3685 // selecting via the generic "add" mnemonic, so to know that we 3686 // should remove the cc_out operand, we have to explicitly check that 3687 // it's not one of the other variants. Ugh. 3688 if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && 3689 Operands.size() == 6 && 3690 static_cast<ARMOperand*>(Operands[3])->isReg() && 3691 static_cast<ARMOperand*>(Operands[4])->isReg() && 3692 static_cast<ARMOperand*>(Operands[5])->isImm()) { 3693 // Nest conditions rather than one big 'if' statement for readability. 3694 // 3695 // If either register is a high reg, it's either one of the SP 3696 // variants (handled above) or a 32-bit encoding, so we just 3697 // check against T3. 3698 if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 3699 !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) && 3700 static_cast<ARMOperand*>(Operands[5])->isT2SOImm()) 3701 return false; 3702 // If both registers are low, we're in an IT block, and the immediate is 3703 // in range, we should use encoding T1 instead, which has a cc_out. 3704 if (inITBlock() && 3705 isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && 3706 isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) && 3707 static_cast<ARMOperand*>(Operands[5])->isImm0_7()) 3708 return false; 3709 3710 // Otherwise, we use encoding T4, which does not have a cc_out 3711 // operand. 3712 return true; 3713 } 3714 3715 // The thumb2 multiply instruction doesn't have a CCOut register, so 3716 // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to 3717 // use the 16-bit encoding or not. 3718 if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && 3719 static_cast<ARMOperand*>(Operands[1])->getReg() == 0 && 3720 static_cast<ARMOperand*>(Operands[3])->isReg() && 3721 static_cast<ARMOperand*>(Operands[4])->isReg() && 3722 static_cast<ARMOperand*>(Operands[5])->isReg() && 3723 // If the registers aren't low regs, the destination reg isn't the 3724 // same as one of the source regs, or the cc_out operand is zero 3725 // outside of an IT block, we have to use the 32-bit encoding, so 3726 // remove the cc_out operand. 3727 (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) || 3728 !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) || 3729 !inITBlock() || 3730 (static_cast<ARMOperand*>(Operands[3])->getReg() != 3731 static_cast<ARMOperand*>(Operands[5])->getReg() && 3732 static_cast<ARMOperand*>(Operands[3])->getReg() != 3733 static_cast<ARMOperand*>(Operands[4])->getReg()))) 3734 return true; 3735 3736 3737 3738 // Register-register 'add/sub' for thumb does not have a cc_out operand 3739 // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 3740 // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 3741 // right, this will result in better diagnostics (which operand is off) 3742 // anyway. 3743 if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 3744 (Operands.size() == 5 || Operands.size() == 6) && 3745 static_cast<ARMOperand*>(Operands[3])->isReg() && 3746 static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 3747 static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 3748 return true; 3749 3750 return false; 3751} 3752 3753/// Parse an arm instruction mnemonic followed by its operands. 3754bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 3755 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3756 // Create the leading tokens for the mnemonic, split by '.' characters. 3757 size_t Start = 0, Next = Name.find('.'); 3758 StringRef Mnemonic = Name.slice(Start, Next); 3759 3760 // Split out the predication code and carry setting flag from the mnemonic. 3761 unsigned PredicationCode; 3762 unsigned ProcessorIMod; 3763 bool CarrySetting; 3764 StringRef ITMask; 3765 Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 3766 ProcessorIMod, ITMask); 3767 3768 // In Thumb1, only the branch (B) instruction can be predicated. 3769 if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 3770 Parser.EatToEndOfStatement(); 3771 return Error(NameLoc, "conditional execution not supported in Thumb1"); 3772 } 3773 3774 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 3775 3776 // Handle the IT instruction ITMask. Convert it to a bitmask. This 3777 // is the mask as it will be for the IT encoding if the conditional 3778 // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case 3779 // where the conditional bit0 is zero, the instruction post-processing 3780 // will adjust the mask accordingly. 3781 if (Mnemonic == "it") { 3782 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2); 3783 if (ITMask.size() > 3) { 3784 Parser.EatToEndOfStatement(); 3785 return Error(Loc, "too many conditions on IT instruction"); 3786 } 3787 unsigned Mask = 8; 3788 for (unsigned i = ITMask.size(); i != 0; --i) { 3789 char pos = ITMask[i - 1]; 3790 if (pos != 't' && pos != 'e') { 3791 Parser.EatToEndOfStatement(); 3792 return Error(Loc, "illegal IT block condition mask '" + ITMask + "'"); 3793 } 3794 Mask >>= 1; 3795 if (ITMask[i - 1] == 't') 3796 Mask |= 8; 3797 } 3798 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc)); 3799 } 3800 3801 // FIXME: This is all a pretty gross hack. We should automatically handle 3802 // optional operands like this via tblgen. 3803 3804 // Next, add the CCOut and ConditionCode operands, if needed. 3805 // 3806 // For mnemonics which can ever incorporate a carry setting bit or predication 3807 // code, our matching model involves us always generating CCOut and 3808 // ConditionCode operands to match the mnemonic "as written" and then we let 3809 // the matcher deal with finding the right instruction or generating an 3810 // appropriate error. 3811 bool CanAcceptCarrySet, CanAcceptPredicationCode; 3812 getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 3813 3814 // If we had a carry-set on an instruction that can't do that, issue an 3815 // error. 3816 if (!CanAcceptCarrySet && CarrySetting) { 3817 Parser.EatToEndOfStatement(); 3818 return Error(NameLoc, "instruction '" + Mnemonic + 3819 "' can not set flags, but 's' suffix specified"); 3820 } 3821 // If we had a predication code on an instruction that can't do that, issue an 3822 // error. 3823 if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 3824 Parser.EatToEndOfStatement(); 3825 return Error(NameLoc, "instruction '" + Mnemonic + 3826 "' is not predicable, but condition code specified"); 3827 } 3828 3829 // Add the carry setting operand, if necessary. 3830 if (CanAcceptCarrySet) { 3831 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size()); 3832 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 3833 Loc)); 3834 } 3835 3836 // Add the predication code operand, if necessary. 3837 if (CanAcceptPredicationCode) { 3838 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() + 3839 CarrySetting); 3840 Operands.push_back(ARMOperand::CreateCondCode( 3841 ARMCC::CondCodes(PredicationCode), Loc)); 3842 } 3843 3844 // Add the processor imod operand, if necessary. 3845 if (ProcessorIMod) { 3846 Operands.push_back(ARMOperand::CreateImm( 3847 MCConstantExpr::Create(ProcessorIMod, getContext()), 3848 NameLoc, NameLoc)); 3849 } 3850 3851 // Add the remaining tokens in the mnemonic. 3852 while (Next != StringRef::npos) { 3853 Start = Next; 3854 Next = Name.find('.', Start + 1); 3855 StringRef ExtraToken = Name.slice(Start, Next); 3856 3857 // For now, we're only parsing Thumb1 (for the most part), so 3858 // just ignore ".n" qualifiers. We'll use them to restrict 3859 // matching when we do Thumb2. 3860 if (ExtraToken != ".n") { 3861 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start); 3862 Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc)); 3863 } 3864 } 3865 3866 // Read the remaining operands. 3867 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3868 // Read the first operand. 3869 if (parseOperand(Operands, Mnemonic)) { 3870 Parser.EatToEndOfStatement(); 3871 return true; 3872 } 3873 3874 while (getLexer().is(AsmToken::Comma)) { 3875 Parser.Lex(); // Eat the comma. 3876 3877 // Parse and remember the operand. 3878 if (parseOperand(Operands, Mnemonic)) { 3879 Parser.EatToEndOfStatement(); 3880 return true; 3881 } 3882 } 3883 } 3884 3885 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3886 SMLoc Loc = getLexer().getLoc(); 3887 Parser.EatToEndOfStatement(); 3888 return Error(Loc, "unexpected token in argument list"); 3889 } 3890 3891 Parser.Lex(); // Consume the EndOfStatement 3892 3893 // Some instructions, mostly Thumb, have forms for the same mnemonic that 3894 // do and don't have a cc_out optional-def operand. With some spot-checks 3895 // of the operand list, we can figure out which variant we're trying to 3896 // parse and adjust accordingly before actually matching. We shouldn't ever 3897 // try to remove a cc_out operand that was explicitly set on the the 3898 // mnemonic, of course (CarrySetting == true). Reason number #317 the 3899 // table driven matcher doesn't fit well with the ARM instruction set. 3900 if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) { 3901 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3902 Operands.erase(Operands.begin() + 1); 3903 delete Op; 3904 } 3905 3906 // ARM mode 'blx' need special handling, as the register operand version 3907 // is predicable, but the label operand version is not. So, we can't rely 3908 // on the Mnemonic based checking to correctly figure out when to put 3909 // a k_CondCode operand in the list. If we're trying to match the label 3910 // version, remove the k_CondCode operand here. 3911 if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 3912 static_cast<ARMOperand*>(Operands[2])->isImm()) { 3913 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3914 Operands.erase(Operands.begin() + 1); 3915 delete Op; 3916 } 3917 3918 // The vector-compare-to-zero instructions have a literal token "#0" at 3919 // the end that comes to here as an immediate operand. Convert it to a 3920 // token to play nicely with the matcher. 3921 if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 3922 Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 3923 static_cast<ARMOperand*>(Operands[5])->isImm()) { 3924 ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3925 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3926 if (CE && CE->getValue() == 0) { 3927 Operands.erase(Operands.begin() + 5); 3928 Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3929 delete Op; 3930 } 3931 } 3932 // VCMP{E} does the same thing, but with a different operand count. 3933 if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && 3934 static_cast<ARMOperand*>(Operands[4])->isImm()) { 3935 ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); 3936 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3937 if (CE && CE->getValue() == 0) { 3938 Operands.erase(Operands.begin() + 4); 3939 Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3940 delete Op; 3941 } 3942 } 3943 // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 3944 // end. Convert it to a token here. 3945 if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 3946 static_cast<ARMOperand*>(Operands[5])->isImm()) { 3947 ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3948 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3949 if (CE && CE->getValue() == 0) { 3950 Operands.erase(Operands.begin() + 5); 3951 Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3952 delete Op; 3953 } 3954 } 3955 3956 return false; 3957} 3958 3959// Validate context-sensitive operand constraints. 3960 3961// return 'true' if register list contains non-low GPR registers, 3962// 'false' otherwise. If Reg is in the register list or is HiReg, set 3963// 'containsReg' to true. 3964static bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 3965 unsigned HiReg, bool &containsReg) { 3966 containsReg = false; 3967 for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 3968 unsigned OpReg = Inst.getOperand(i).getReg(); 3969 if (OpReg == Reg) 3970 containsReg = true; 3971 // Anything other than a low register isn't legal here. 3972 if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 3973 return true; 3974 } 3975 return false; 3976} 3977 3978// Check if the specified regisgter is in the register list of the inst, 3979// starting at the indicated operand number. 3980static bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) { 3981 for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 3982 unsigned OpReg = Inst.getOperand(i).getReg(); 3983 if (OpReg == Reg) 3984 return true; 3985 } 3986 return false; 3987} 3988 3989// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 3990// the ARMInsts array) instead. Getting that here requires awkward 3991// API changes, though. Better way? 3992namespace llvm { 3993extern MCInstrDesc ARMInsts[]; 3994} 3995static MCInstrDesc &getInstDesc(unsigned Opcode) { 3996 return ARMInsts[Opcode]; 3997} 3998 3999// FIXME: We would really like to be able to tablegen'erate this. 4000bool ARMAsmParser:: 4001validateInstruction(MCInst &Inst, 4002 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4003 MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 4004 SMLoc Loc = Operands[0]->getStartLoc(); 4005 // Check the IT block state first. 4006 // NOTE: In Thumb mode, the BKPT instruction has the interesting property of 4007 // being allowed in IT blocks, but not being predicable. It just always 4008 // executes. 4009 if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) { 4010 unsigned bit = 1; 4011 if (ITState.FirstCond) 4012 ITState.FirstCond = false; 4013 else 4014 bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1; 4015 // The instruction must be predicable. 4016 if (!MCID.isPredicable()) 4017 return Error(Loc, "instructions in IT block must be predicable"); 4018 unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm(); 4019 unsigned ITCond = bit ? ITState.Cond : 4020 ARMCC::getOppositeCondition(ITState.Cond); 4021 if (Cond != ITCond) { 4022 // Find the condition code Operand to get its SMLoc information. 4023 SMLoc CondLoc; 4024 for (unsigned i = 1; i < Operands.size(); ++i) 4025 if (static_cast<ARMOperand*>(Operands[i])->isCondCode()) 4026 CondLoc = Operands[i]->getStartLoc(); 4027 return Error(CondLoc, "incorrect condition in IT block; got '" + 4028 StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) + 4029 "', but expected '" + 4030 ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'"); 4031 } 4032 // Check for non-'al' condition codes outside of the IT block. 4033 } else if (isThumbTwo() && MCID.isPredicable() && 4034 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != 4035 ARMCC::AL && Inst.getOpcode() != ARM::tB && 4036 Inst.getOpcode() != ARM::t2B) 4037 return Error(Loc, "predicated instructions must be in IT block"); 4038 4039 switch (Inst.getOpcode()) { 4040 case ARM::LDRD: 4041 case ARM::LDRD_PRE: 4042 case ARM::LDRD_POST: 4043 case ARM::LDREXD: { 4044 // Rt2 must be Rt + 1. 4045 unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 4046 unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4047 if (Rt2 != Rt + 1) 4048 return Error(Operands[3]->getStartLoc(), 4049 "destination operands must be sequential"); 4050 return false; 4051 } 4052 case ARM::STRD: { 4053 // Rt2 must be Rt + 1. 4054 unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 4055 unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4056 if (Rt2 != Rt + 1) 4057 return Error(Operands[3]->getStartLoc(), 4058 "source operands must be sequential"); 4059 return false; 4060 } 4061 case ARM::STRD_PRE: 4062 case ARM::STRD_POST: 4063 case ARM::STREXD: { 4064 // Rt2 must be Rt + 1. 4065 unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 4066 unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 4067 if (Rt2 != Rt + 1) 4068 return Error(Operands[3]->getStartLoc(), 4069 "source operands must be sequential"); 4070 return false; 4071 } 4072 case ARM::SBFX: 4073 case ARM::UBFX: { 4074 // width must be in range [1, 32-lsb] 4075 unsigned lsb = Inst.getOperand(2).getImm(); 4076 unsigned widthm1 = Inst.getOperand(3).getImm(); 4077 if (widthm1 >= 32 - lsb) 4078 return Error(Operands[5]->getStartLoc(), 4079 "bitfield width must be in range [1,32-lsb]"); 4080 return false; 4081 } 4082 case ARM::tLDMIA: { 4083 // If we're parsing Thumb2, the .w variant is available and handles 4084 // most cases that are normally illegal for a Thumb1 LDM 4085 // instruction. We'll make the transformation in processInstruction() 4086 // if necessary. 4087 // 4088 // Thumb LDM instructions are writeback iff the base register is not 4089 // in the register list. 4090 unsigned Rn = Inst.getOperand(0).getReg(); 4091 bool hasWritebackToken = 4092 (static_cast<ARMOperand*>(Operands[3])->isToken() && 4093 static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 4094 bool listContainsBase; 4095 if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo()) 4096 return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 4097 "registers must be in range r0-r7"); 4098 // If we should have writeback, then there should be a '!' token. 4099 if (!listContainsBase && !hasWritebackToken && !isThumbTwo()) 4100 return Error(Operands[2]->getStartLoc(), 4101 "writeback operator '!' expected"); 4102 // If we should not have writeback, there must not be a '!'. This is 4103 // true even for the 32-bit wide encodings. 4104 if (listContainsBase && hasWritebackToken) 4105 return Error(Operands[3]->getStartLoc(), 4106 "writeback operator '!' not allowed when base register " 4107 "in register list"); 4108 4109 break; 4110 } 4111 case ARM::t2LDMIA_UPD: { 4112 if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg())) 4113 return Error(Operands[4]->getStartLoc(), 4114 "writeback operator '!' not allowed when base register " 4115 "in register list"); 4116 break; 4117 } 4118 case ARM::tPOP: { 4119 bool listContainsBase; 4120 if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 4121 return Error(Operands[2]->getStartLoc(), 4122 "registers must be in range r0-r7 or pc"); 4123 break; 4124 } 4125 case ARM::tPUSH: { 4126 bool listContainsBase; 4127 if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 4128 return Error(Operands[2]->getStartLoc(), 4129 "registers must be in range r0-r7 or lr"); 4130 break; 4131 } 4132 case ARM::tSTMIA_UPD: { 4133 bool listContainsBase; 4134 if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo()) 4135 return Error(Operands[4]->getStartLoc(), 4136 "registers must be in range r0-r7"); 4137 break; 4138 } 4139 } 4140 4141 return false; 4142} 4143 4144void ARMAsmParser:: 4145processInstruction(MCInst &Inst, 4146 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 4147 switch (Inst.getOpcode()) { 4148 case ARM::LDMIA_UPD: 4149 // If this is a load of a single register via a 'pop', then we should use 4150 // a post-indexed LDR instruction instead, per the ARM ARM. 4151 if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 4152 Inst.getNumOperands() == 5) { 4153 MCInst TmpInst; 4154 TmpInst.setOpcode(ARM::LDR_POST_IMM); 4155 TmpInst.addOperand(Inst.getOperand(4)); // Rt 4156 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4157 TmpInst.addOperand(Inst.getOperand(1)); // Rn 4158 TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 4159 TmpInst.addOperand(MCOperand::CreateImm(4)); 4160 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4161 TmpInst.addOperand(Inst.getOperand(3)); 4162 Inst = TmpInst; 4163 } 4164 break; 4165 case ARM::STMDB_UPD: 4166 // If this is a store of a single register via a 'push', then we should use 4167 // a pre-indexed STR instruction instead, per the ARM ARM. 4168 if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 4169 Inst.getNumOperands() == 5) { 4170 MCInst TmpInst; 4171 TmpInst.setOpcode(ARM::STR_PRE_IMM); 4172 TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 4173 TmpInst.addOperand(Inst.getOperand(4)); // Rt 4174 TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 4175 TmpInst.addOperand(MCOperand::CreateImm(-4)); 4176 TmpInst.addOperand(Inst.getOperand(2)); // CondCode 4177 TmpInst.addOperand(Inst.getOperand(3)); 4178 Inst = TmpInst; 4179 } 4180 break; 4181 case ARM::tADDi8: 4182 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 4183 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 4184 // to encoding T2 if <Rd> is specified and encoding T2 is preferred 4185 // to encoding T1 if <Rd> is omitted." 4186 if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 4187 Inst.setOpcode(ARM::tADDi3); 4188 break; 4189 case ARM::tSUBi8: 4190 // If the immediate is in the range 0-7, we want tADDi3 iff Rd was 4191 // explicitly specified. From the ARM ARM: "Encoding T1 is preferred 4192 // to encoding T2 if <Rd> is specified and encoding T2 is preferred 4193 // to encoding T1 if <Rd> is omitted." 4194 if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) 4195 Inst.setOpcode(ARM::tSUBi3); 4196 break; 4197 case ARM::tB: 4198 // A Thumb conditional branch outside of an IT block is a tBcc. 4199 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 4200 Inst.setOpcode(ARM::tBcc); 4201 break; 4202 case ARM::t2B: 4203 // A Thumb2 conditional branch outside of an IT block is a t2Bcc. 4204 if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) 4205 Inst.setOpcode(ARM::t2Bcc); 4206 break; 4207 case ARM::t2Bcc: 4208 // If the conditional is AL or we're in an IT block, we really want t2B. 4209 if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) 4210 Inst.setOpcode(ARM::t2B); 4211 break; 4212 case ARM::tBcc: 4213 // If the conditional is AL, we really want tB. 4214 if (Inst.getOperand(1).getImm() == ARMCC::AL) 4215 Inst.setOpcode(ARM::tB); 4216 break; 4217 case ARM::tLDMIA: { 4218 // If the register list contains any high registers, or if the writeback 4219 // doesn't match what tLDMIA can do, we need to use the 32-bit encoding 4220 // instead if we're in Thumb2. Otherwise, this should have generated 4221 // an error in validateInstruction(). 4222 unsigned Rn = Inst.getOperand(0).getReg(); 4223 bool hasWritebackToken = 4224 (static_cast<ARMOperand*>(Operands[3])->isToken() && 4225 static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 4226 bool listContainsBase; 4227 if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) || 4228 (!listContainsBase && !hasWritebackToken) || 4229 (listContainsBase && hasWritebackToken)) { 4230 // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 4231 assert (isThumbTwo()); 4232 Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA); 4233 // If we're switching to the updating version, we need to insert 4234 // the writeback tied operand. 4235 if (hasWritebackToken) 4236 Inst.insert(Inst.begin(), 4237 MCOperand::CreateReg(Inst.getOperand(0).getReg())); 4238 } 4239 break; 4240 } 4241 case ARM::tSTMIA_UPD: { 4242 // If the register list contains any high registers, we need to use 4243 // the 32-bit encoding instead if we're in Thumb2. Otherwise, this 4244 // should have generated an error in validateInstruction(). 4245 unsigned Rn = Inst.getOperand(0).getReg(); 4246 bool listContainsBase; 4247 if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) { 4248 // 16-bit encoding isn't sufficient. Switch to the 32-bit version. 4249 assert (isThumbTwo()); 4250 Inst.setOpcode(ARM::t2STMIA_UPD); 4251 } 4252 break; 4253 } 4254 case ARM::t2MOVi: { 4255 // If we can use the 16-bit encoding and the user didn't explicitly 4256 // request the 32-bit variant, transform it here. 4257 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4258 Inst.getOperand(1).getImm() <= 255 && 4259 ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL && 4260 Inst.getOperand(4).getReg() == ARM::CPSR) || 4261 (inITBlock() && Inst.getOperand(4).getReg() == 0)) && 4262 (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4263 static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 4264 // The operands aren't in the same order for tMOVi8... 4265 MCInst TmpInst; 4266 TmpInst.setOpcode(ARM::tMOVi8); 4267 TmpInst.addOperand(Inst.getOperand(0)); 4268 TmpInst.addOperand(Inst.getOperand(4)); 4269 TmpInst.addOperand(Inst.getOperand(1)); 4270 TmpInst.addOperand(Inst.getOperand(2)); 4271 TmpInst.addOperand(Inst.getOperand(3)); 4272 Inst = TmpInst; 4273 } 4274 break; 4275 } 4276 case ARM::t2MOVr: { 4277 // If we can use the 16-bit encoding and the user didn't explicitly 4278 // request the 32-bit variant, transform it here. 4279 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4280 isARMLowRegister(Inst.getOperand(1).getReg()) && 4281 Inst.getOperand(2).getImm() == ARMCC::AL && 4282 Inst.getOperand(4).getReg() == ARM::CPSR && 4283 (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4284 static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 4285 // The operands aren't the same for tMOV[S]r... (no cc_out) 4286 MCInst TmpInst; 4287 TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); 4288 TmpInst.addOperand(Inst.getOperand(0)); 4289 TmpInst.addOperand(Inst.getOperand(1)); 4290 TmpInst.addOperand(Inst.getOperand(2)); 4291 TmpInst.addOperand(Inst.getOperand(3)); 4292 Inst = TmpInst; 4293 } 4294 break; 4295 } 4296 case ARM::t2SXTH: 4297 case ARM::t2SXTB: 4298 case ARM::t2UXTH: 4299 case ARM::t2UXTB: { 4300 // If we can use the 16-bit encoding and the user didn't explicitly 4301 // request the 32-bit variant, transform it here. 4302 if (isARMLowRegister(Inst.getOperand(0).getReg()) && 4303 isARMLowRegister(Inst.getOperand(1).getReg()) && 4304 Inst.getOperand(2).getImm() == 0 && 4305 (!static_cast<ARMOperand*>(Operands[2])->isToken() || 4306 static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) { 4307 unsigned NewOpc; 4308 switch (Inst.getOpcode()) { 4309 default: llvm_unreachable("Illegal opcode!"); 4310 case ARM::t2SXTH: NewOpc = ARM::tSXTH; break; 4311 case ARM::t2SXTB: NewOpc = ARM::tSXTB; break; 4312 case ARM::t2UXTH: NewOpc = ARM::tUXTH; break; 4313 case ARM::t2UXTB: NewOpc = ARM::tUXTB; break; 4314 } 4315 // The operands aren't the same for thumb1 (no rotate operand). 4316 MCInst TmpInst; 4317 TmpInst.setOpcode(NewOpc); 4318 TmpInst.addOperand(Inst.getOperand(0)); 4319 TmpInst.addOperand(Inst.getOperand(1)); 4320 TmpInst.addOperand(Inst.getOperand(3)); 4321 TmpInst.addOperand(Inst.getOperand(4)); 4322 Inst = TmpInst; 4323 } 4324 break; 4325 } 4326 case ARM::t2IT: { 4327 // The mask bits for all but the first condition are represented as 4328 // the low bit of the condition code value implies 't'. We currently 4329 // always have 1 implies 't', so XOR toggle the bits if the low bit 4330 // of the condition code is zero. The encoding also expects the low 4331 // bit of the condition to be encoded as bit 4 of the mask operand, 4332 // so mask that in if needed 4333 MCOperand &MO = Inst.getOperand(1); 4334 unsigned Mask = MO.getImm(); 4335 unsigned OrigMask = Mask; 4336 unsigned TZ = CountTrailingZeros_32(Mask); 4337 if ((Inst.getOperand(0).getImm() & 1) == 0) { 4338 assert(Mask && TZ <= 3 && "illegal IT mask value!"); 4339 for (unsigned i = 3; i != TZ; --i) 4340 Mask ^= 1 << i; 4341 } else 4342 Mask |= 0x10; 4343 MO.setImm(Mask); 4344 4345 // Set up the IT block state according to the IT instruction we just 4346 // matched. 4347 assert(!inITBlock() && "nested IT blocks?!"); 4348 ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm()); 4349 ITState.Mask = OrigMask; // Use the original mask, not the updated one. 4350 ITState.CurPosition = 0; 4351 ITState.FirstCond = true; 4352 break; 4353 } 4354 } 4355} 4356 4357unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 4358 // 16-bit thumb arithmetic instructions either require or preclude the 'S' 4359 // suffix depending on whether they're in an IT block or not. 4360 unsigned Opc = Inst.getOpcode(); 4361 MCInstrDesc &MCID = getInstDesc(Opc); 4362 if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 4363 assert(MCID.hasOptionalDef() && 4364 "optionally flag setting instruction missing optional def operand"); 4365 assert(MCID.NumOperands == Inst.getNumOperands() && 4366 "operand count mismatch!"); 4367 // Find the optional-def operand (cc_out). 4368 unsigned OpNo; 4369 for (OpNo = 0; 4370 !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 4371 ++OpNo) 4372 ; 4373 // If we're parsing Thumb1, reject it completely. 4374 if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 4375 return Match_MnemonicFail; 4376 // If we're parsing Thumb2, which form is legal depends on whether we're 4377 // in an IT block. 4378 if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR && 4379 !inITBlock()) 4380 return Match_RequiresITBlock; 4381 if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR && 4382 inITBlock()) 4383 return Match_RequiresNotITBlock; 4384 } 4385 // Some high-register supporting Thumb1 encodings only allow both registers 4386 // to be from r0-r7 when in Thumb2. 4387 else if (Opc == ARM::tADDhirr && isThumbOne() && 4388 isARMLowRegister(Inst.getOperand(1).getReg()) && 4389 isARMLowRegister(Inst.getOperand(2).getReg())) 4390 return Match_RequiresThumb2; 4391 // Others only require ARMv6 or later. 4392 else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 4393 isARMLowRegister(Inst.getOperand(0).getReg()) && 4394 isARMLowRegister(Inst.getOperand(1).getReg())) 4395 return Match_RequiresV6; 4396 return Match_Success; 4397} 4398 4399bool ARMAsmParser:: 4400MatchAndEmitInstruction(SMLoc IDLoc, 4401 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 4402 MCStreamer &Out) { 4403 MCInst Inst; 4404 unsigned ErrorInfo; 4405 unsigned MatchResult; 4406 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 4407 switch (MatchResult) { 4408 default: break; 4409 case Match_Success: 4410 // Context sensitive operand constraints aren't handled by the matcher, 4411 // so check them here. 4412 if (validateInstruction(Inst, Operands)) { 4413 // Still progress the IT block, otherwise one wrong condition causes 4414 // nasty cascading errors. 4415 forwardITPosition(); 4416 return true; 4417 } 4418 4419 // Some instructions need post-processing to, for example, tweak which 4420 // encoding is selected. 4421 processInstruction(Inst, Operands); 4422 4423 // Only move forward at the very end so that everything in validate 4424 // and process gets a consistent answer about whether we're in an IT 4425 // block. 4426 forwardITPosition(); 4427 4428 Out.EmitInstruction(Inst); 4429 return false; 4430 case Match_MissingFeature: 4431 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 4432 return true; 4433 case Match_InvalidOperand: { 4434 SMLoc ErrorLoc = IDLoc; 4435 if (ErrorInfo != ~0U) { 4436 if (ErrorInfo >= Operands.size()) 4437 return Error(IDLoc, "too few operands for instruction"); 4438 4439 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 4440 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 4441 } 4442 4443 return Error(ErrorLoc, "invalid operand for instruction"); 4444 } 4445 case Match_MnemonicFail: 4446 return Error(IDLoc, "invalid instruction"); 4447 case Match_ConversionFail: 4448 // The converter function will have already emited a diagnostic. 4449 return true; 4450 case Match_RequiresNotITBlock: 4451 return Error(IDLoc, "flag setting instruction only valid outside IT block"); 4452 case Match_RequiresITBlock: 4453 return Error(IDLoc, "instruction only valid inside IT block"); 4454 case Match_RequiresV6: 4455 return Error(IDLoc, "instruction variant requires ARMv6 or later"); 4456 case Match_RequiresThumb2: 4457 return Error(IDLoc, "instruction variant requires Thumb2"); 4458 } 4459 4460 llvm_unreachable("Implement any new match types added!"); 4461 return true; 4462} 4463 4464/// parseDirective parses the arm specific directives 4465bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 4466 StringRef IDVal = DirectiveID.getIdentifier(); 4467 if (IDVal == ".word") 4468 return parseDirectiveWord(4, DirectiveID.getLoc()); 4469 else if (IDVal == ".thumb") 4470 return parseDirectiveThumb(DirectiveID.getLoc()); 4471 else if (IDVal == ".thumb_func") 4472 return parseDirectiveThumbFunc(DirectiveID.getLoc()); 4473 else if (IDVal == ".code") 4474 return parseDirectiveCode(DirectiveID.getLoc()); 4475 else if (IDVal == ".syntax") 4476 return parseDirectiveSyntax(DirectiveID.getLoc()); 4477 return true; 4478} 4479 4480/// parseDirectiveWord 4481/// ::= .word [ expression (, expression)* ] 4482bool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 4483 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4484 for (;;) { 4485 const MCExpr *Value; 4486 if (getParser().ParseExpression(Value)) 4487 return true; 4488 4489 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 4490 4491 if (getLexer().is(AsmToken::EndOfStatement)) 4492 break; 4493 4494 // FIXME: Improve diagnostic. 4495 if (getLexer().isNot(AsmToken::Comma)) 4496 return Error(L, "unexpected token in directive"); 4497 Parser.Lex(); 4498 } 4499 } 4500 4501 Parser.Lex(); 4502 return false; 4503} 4504 4505/// parseDirectiveThumb 4506/// ::= .thumb 4507bool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 4508 if (getLexer().isNot(AsmToken::EndOfStatement)) 4509 return Error(L, "unexpected token in directive"); 4510 Parser.Lex(); 4511 4512 // TODO: set thumb mode 4513 // TODO: tell the MC streamer the mode 4514 // getParser().getStreamer().Emit???(); 4515 return false; 4516} 4517 4518/// parseDirectiveThumbFunc 4519/// ::= .thumbfunc symbol_name 4520bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 4521 const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 4522 bool isMachO = MAI.hasSubsectionsViaSymbols(); 4523 StringRef Name; 4524 4525 // Darwin asm has function name after .thumb_func direction 4526 // ELF doesn't 4527 if (isMachO) { 4528 const AsmToken &Tok = Parser.getTok(); 4529 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 4530 return Error(L, "unexpected token in .thumb_func directive"); 4531 Name = Tok.getString(); 4532 Parser.Lex(); // Consume the identifier token. 4533 } 4534 4535 if (getLexer().isNot(AsmToken::EndOfStatement)) 4536 return Error(L, "unexpected token in directive"); 4537 Parser.Lex(); 4538 4539 // FIXME: assuming function name will be the line following .thumb_func 4540 if (!isMachO) { 4541 Name = Parser.getTok().getString(); 4542 } 4543 4544 // Mark symbol as a thumb symbol. 4545 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 4546 getParser().getStreamer().EmitThumbFunc(Func); 4547 return false; 4548} 4549 4550/// parseDirectiveSyntax 4551/// ::= .syntax unified | divided 4552bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 4553 const AsmToken &Tok = Parser.getTok(); 4554 if (Tok.isNot(AsmToken::Identifier)) 4555 return Error(L, "unexpected token in .syntax directive"); 4556 StringRef Mode = Tok.getString(); 4557 if (Mode == "unified" || Mode == "UNIFIED") 4558 Parser.Lex(); 4559 else if (Mode == "divided" || Mode == "DIVIDED") 4560 return Error(L, "'.syntax divided' arm asssembly not supported"); 4561 else 4562 return Error(L, "unrecognized syntax mode in .syntax directive"); 4563 4564 if (getLexer().isNot(AsmToken::EndOfStatement)) 4565 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4566 Parser.Lex(); 4567 4568 // TODO tell the MC streamer the mode 4569 // getParser().getStreamer().Emit???(); 4570 return false; 4571} 4572 4573/// parseDirectiveCode 4574/// ::= .code 16 | 32 4575bool ARMAsmParser::parseDirectiveCode(SMLoc L) { 4576 const AsmToken &Tok = Parser.getTok(); 4577 if (Tok.isNot(AsmToken::Integer)) 4578 return Error(L, "unexpected token in .code directive"); 4579 int64_t Val = Parser.getTok().getIntVal(); 4580 if (Val == 16) 4581 Parser.Lex(); 4582 else if (Val == 32) 4583 Parser.Lex(); 4584 else 4585 return Error(L, "invalid operand to .code directive"); 4586 4587 if (getLexer().isNot(AsmToken::EndOfStatement)) 4588 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 4589 Parser.Lex(); 4590 4591 if (Val == 16) { 4592 if (!isThumb()) 4593 SwitchMode(); 4594 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 4595 } else { 4596 if (isThumb()) 4597 SwitchMode(); 4598 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 4599 } 4600 4601 return false; 4602} 4603 4604extern "C" void LLVMInitializeARMAsmLexer(); 4605 4606/// Force static initialization. 4607extern "C" void LLVMInitializeARMAsmParser() { 4608 RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 4609 RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 4610 LLVMInitializeARMAsmLexer(); 4611} 4612 4613#define GET_REGISTER_MATCHER 4614#define GET_MATCHER_IMPLEMENTATION 4615#include "ARMGenAsmMatcher.inc" 4616