ARMAsmParser.cpp revision ed8384806e56952c44f8a717c1ef54a8468d2c8d
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// The LLVM Compiler Infrastructure 4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source 6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details. 7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===// 9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 2194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h" 22ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2394b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 25c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 26fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2775ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 2894b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h" 29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 31345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 34ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 35ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 363a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 37146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 38146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 3916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4094b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 41ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 50e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int TryParseRegister(); 51bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 5250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 5319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach int TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 5450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 55ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &, 56ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode); 57fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 587597212abced110723f2fee985a7d60557c092ecEvan Cheng bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); 599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *ApplyPrefixToExpr(const MCExpr *E, 609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 62a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 69762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 70762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E); 710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool ParseShift(enum ARM_AM::ShiftOpc &St, 720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E); 73ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 797036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner bool MatchAndEmitInstruction(SMLoc IDLoc, 807c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 81fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out); 825f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach StringRef SplitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 835f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, unsigned &ProcessorIMod); 84fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 85fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 8616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 87ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 88ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 89ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 90ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 91ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 92ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 93ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 9432869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 95ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 96ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 9732869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 98ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 99a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1020692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1030692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 104a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 10743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 110f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 11143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1128bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 11343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1148bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 11543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1168bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 11743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemMode2Operand( 118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 11943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemMode3Operand( 120ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 121f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 122f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 123f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 124f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 125f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 126f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 127f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 128f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 129c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 130580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 133ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 134ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 135ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 136ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 137ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 138ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 139ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 140ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 141f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach 142ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 143ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 14494b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 145ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 14632869205052430f45d598fba25ab878d8b29da2dEvan Cheng 147ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 148ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 149ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 150ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 15138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 1529898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 153ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 154ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 15516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 15616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 157275944afb55086d0b4b20d4d831de7c1c7507925Evan Chengnamespace llvm { 158275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng // FIXME: TableGen this? 159275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng extern MCRegisterClass ARMMCRegisterClasses[]; // In ARMGenRegisterInfo.inc. 160275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng} 161275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng 1623a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1633a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 164a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 165a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 166146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 167762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 169d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 170fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 171fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 172cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 173706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 1748462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 175584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 176a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 1778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1788d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 1790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 1800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 181e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 18292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 183580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImmediate, 1848462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 185a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 186a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 187762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 18824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 189a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 190a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1928462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 196706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 197706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 198706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 199706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 200fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 201fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 202fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 203fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 205a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 206a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 207a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 208584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 209584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 210584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 211584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 214a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 217a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 219a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2208155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 221cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 222cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 22316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2246a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 225a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 226ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode; 227a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2282637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar union { 2292637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar unsigned RegNum; ///< Offset register num, when OffsetIsReg. 2302637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar const MCExpr *Value; ///< Offset value, when !OffsetIsReg. 2312637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar } Offset; 232146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 2330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true 234146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true 23550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Preindexed : 1; 23650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Postindexed : 1; 23750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned OffsetIsReg : 1; 23850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Negative : 1; // only used when OffsetIsReg is true 23950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Writeback : 1; 240a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 243580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 245580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 248e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 249e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 250e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 251af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 25292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 25392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 25492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 25592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 256af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 257a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 25816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 259146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 260146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 2668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 2678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 2688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 2708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 271762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 272d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 274762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 275762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 2768d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 2770f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 2780f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 27924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 2808d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 281fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 282fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 283fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 284fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 288706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 289706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 290706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 293762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 294584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 297a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 298a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 2990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 300580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 301580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 3020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 303e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 304af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 305e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 30692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 307af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 30892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 310762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 31116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 313762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 314762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 315762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3178462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3188462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3198462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 322fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 323fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 324fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 325fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 326fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 327a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3336aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3347729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 336a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3375fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 34024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 343cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 344cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 345cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 346cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 347cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 348706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 349706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 350706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 351706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 352706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 353a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 354a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 355a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 356a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 357a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 358584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 359584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 360584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 361584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 362584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @name Memory Operand Accessors 3646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @{ 365ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode getMemAddrMode() const { 366ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return Mem.AddrMode; 367ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemBaseRegNum() const { 3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.BaseRegNum; 3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegNum() const { 3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3736ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.RegNum; 3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemOffset() const { 3766ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(!Mem.OffsetIsReg && "Invalid access!"); 3776ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.Value; 3786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3796ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegShifted() const { 3806ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3816ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.OffsetRegShifted; 3826ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3836ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemShiftAmount() const { 3846ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3856ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftAmount; 3866ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc getMemShiftType() const { 3886ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3896ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftType; 3906ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3916ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPreindexed() const { return Mem.Preindexed; } 3926ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPostindexed() const { return Mem.Postindexed; } 3936ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; } 3946ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemNegative() const { return Mem.Negative; } 3956ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemWriteback() const { return Mem.Writeback; } 3966ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 3976ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @} 3986ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 399fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 400fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 4018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 402d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 4033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 4046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 4056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4106b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 4116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 41283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 41383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 41483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 41583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 41683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 41783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 41883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 41983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 42083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 42183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 42283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 42383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 42483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 42583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 42683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 42783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 4287c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 4297c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (Kind != Immediate) 4307c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 4317c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4327c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 4337c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 4347c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 4357c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 436f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 437f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (Kind != Immediate) 438f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 439f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 440f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 441f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 442f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 443f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 4444a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 4454a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (Kind != Immediate) 4464a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 4474a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4484a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 4494a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 4504a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 4514a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 452fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 453fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 454fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 455fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 456fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 457fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 458fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 459fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 460ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 461ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 462ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 463ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 464ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 465ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 466ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 467ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 468ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 469ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 470ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 471ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (Kind != Immediate) 472ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 473ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 474ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 475ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 476ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 477ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 478f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 479f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 480f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 481f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 482f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 483f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 484f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 485f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 486f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 487f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 488f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 489f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 490f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 491f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 492f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 493f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 4946bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 4956bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 4966bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 4976bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4986bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 4996bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 5006bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 5016bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 5026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 5036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 5046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 5096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 510c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 511c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Kind != Immediate) 512c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 513c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 514c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 515c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 516c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 517c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 518b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 5198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 5200f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 5210f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 52214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 523706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 52414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 525580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isShifterImm() const { return Kind == ShifterImmediate; } 526af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 527af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 528ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool isMemMode2() const { 529ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode2) 530ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 531ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 532ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) 533ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 534ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 535ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemNegative() && 536ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 537ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 538ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 539ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 540ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (!CE) return false; 541ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Value = CE->getValue(); 542ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 543ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // The offset must be in the range 0-4095 (imm12). 544ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Value > 4095 || Value < -4095) 545ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 546ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 547ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 548ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 549ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool isMemMode3() const { 550ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode3) 551ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 552ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 553ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 554ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetRegShifted()) 555ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; // No shift with offset reg allowed 556ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 557ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 558ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 559ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemNegative() && 560ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 561ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 562ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 563ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 564ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (!CE) return false; 565ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Value = CE->getValue(); 566ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 567ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // The offset must be in the range 0-255 (imm8). 568ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Value > 255 || Value < -255) 569ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 570ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 571ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 572ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 57387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling bool isMemMode5() const { 5744b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || 5754b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar getMemNegative()) 57687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 577ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 5784b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 579ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 580ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 58187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling // The offset must be a multiple of 4 in the range 0-1020. 58287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling int64_t Value = CE->getValue(); 58387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); 58487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 585505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes bool isMemMode7() const { 586505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!isMemory() || 587505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPreindexed() || 588505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPostindexed() || 589505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemOffsetIsReg() || 590505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemNegative() || 591505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemWriteback()) 592505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 593505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 594505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 595505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!CE) return false; 596505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 597505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (CE->getValue()) 598505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 599505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 600505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return true; 601505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 602f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeRegThumb() const { 6034b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback()) 604f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 605d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar return true; 606f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 607f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeImmThumb() const { 6084b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback()) 609ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 610ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 6114b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 612ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 613ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 614ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // The offset must be a multiple of 4 in the range 0-124. 615ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling uint64_t Value = CE->getValue(); 616ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return ((Value & 0x3) == 0 && Value <= 124); 617ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 618584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 619a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 6203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 6213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 62214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 62314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 62414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 62514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 6263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 6273483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 6283483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 6293483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 6303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 6318462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 632345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 6338462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 63404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 63504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 6368462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 6378462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 638fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 639fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 640fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 641fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 642fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 643fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 644fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 645fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 646fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 647fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 648d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 649d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 650d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 651d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 652d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 655a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 656a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 657a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 658af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 659e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 660af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 661af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 662af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 663e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 664af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 665e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 666e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 667af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 668152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 669af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 670af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 67192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 672af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 67392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 67492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 67592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 676580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 6770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 678580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 679580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 6800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 6810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 68287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 6837729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 6845fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 6855fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 6867729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 6877729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 68887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 68987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 6900f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 6910f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 6920f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 6930f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 6940f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 6950f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 6960f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 6970f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 6983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 6996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 7016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 7026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 7036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 7046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 7066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 7076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 70883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 70983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 71083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 71183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 71283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 71383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 7147c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7157c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 7167c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 7177c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 7187c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 71983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 72083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 72183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 72283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 723f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 724f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 725f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 726f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 727f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 728f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 729f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 730f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 7314a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 7324a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 7334a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 7344a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 7354a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7364a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 7374a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 7384a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 739fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 740fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 741fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 742fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 743fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 744ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 745ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 746ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 747ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 748ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 749ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 750ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 751ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 752ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 753ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 754f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 755f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 756f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 757f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 758f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 759f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 761f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 766f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 767f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 7686bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 7696bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 7706bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 7716bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 7726bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 7736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 7743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 7753483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 7763483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 77716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 778c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 779c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 780c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 781c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 782c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 783706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 784706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 785706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 786706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 787706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 788505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes void addMemMode7Operands(MCInst &Inst, unsigned N) const { 789505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert(N == 1 && isMemMode7() && "Invalid number of operands!"); 790505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 791505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 792505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 7931866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay (void)CE; 794505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert((CE || CE->getValue() == 0) && 795505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes "No offset operand support in mode 7"); 796505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 797505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 798ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes void addMemMode2Operands(MCInst &Inst, unsigned N) const { 799ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(isMemMode2() && "Invalid mode or number of operands!"); 800ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 801ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 802ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 803ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) { 804ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 805ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 806ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 807ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; 808ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t ShiftAmount = 0; 809ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 810ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetRegShifted()) { 811ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc = getMemShiftType(); 812ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = 813ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes dyn_cast<MCConstantExpr>(getMemShiftAmount()); 814ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftAmount = CE->getValue(); 815ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 816ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 817ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, 818ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc, IdxMode))); 819ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return; 820ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 822ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 823ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 824ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 825ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 826ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // the difference? 827ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 828ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(CE && "Non-constant mode 2 offset operand!"); 829ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Offset = CE->getValue(); 830ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 831ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Offset >= 0) 832ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, 833ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, ARM_AM::no_shift, IdxMode))); 834ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes else 835ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, 836ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes -Offset, ARM_AM::no_shift, IdxMode))); 837ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 838ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 839ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes void addMemMode3Operands(MCInst &Inst, unsigned N) const { 840ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(isMemMode3() && "Invalid mode or number of operands!"); 841ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 842ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 843ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 844ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 845ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 846ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 847ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 848ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0, 849ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes IdxMode))); 850ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return; 851ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 852ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 853ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 854ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 855ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 856ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 857ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // the difference? 858ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 859ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(CE && "Non-constant mode 3 offset operand!"); 860ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Offset = CE->getValue(); 861ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 862ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Offset >= 0) 863ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add, 864ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Offset, IdxMode))); 865ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes else 866ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub, 867ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes -Offset, IdxMode))); 868ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 869ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 87014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner void addMemMode5Operands(MCInst &Inst, unsigned N) const { 87114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 87216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 8734b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 8744b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar assert(!getMemOffsetIsReg() && "Invalid mode 5 operand"); 87592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 87680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // FIXME: #-0 is encoded differently than #0. Does the parser preserve 87780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // the difference? 8784b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 879d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert(CE && "Non-constant mode 5 offset operand!"); 880d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 881d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // The MCInst offset operand doesn't include the low two bits (like 882d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // the instruction encoding). 883d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar int64_t Offset = CE->getValue() / 4; 884d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar if (Offset >= 0) 885d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, 886d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Offset))); 887d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar else 888d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, 889d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar -Offset))); 89014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 8913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 892f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const { 893f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!"); 8944b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 8954b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 896f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 897ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 898f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const { 899f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!"); 9004b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 9014b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 902f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(CE && "Non-constant mode offset operand!"); 903f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 904ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 905ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 906584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 907584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 908584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 909584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 910584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 911a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 912a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 913a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 914a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 915a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 916b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 917b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 9183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 9193a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 920345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 921345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 922345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 9233a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 924345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 925345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 926fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 927fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 928fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 929fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 930fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 931fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 932fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 933fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 934fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 935fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 936fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 937fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 938fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 939fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 940fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 941fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 942d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 943d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 944d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 945d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 946d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 947d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 948d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 949d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 9503a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 9513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 952762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 953762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 954762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 955762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 9563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 957a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 958a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 95950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 9603a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 961762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 962762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 963762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 9643a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 965a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 966a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 967e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 968e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 969e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 970e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 971e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 972e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 973af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 974af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 975af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 976af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 977e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 978e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 979e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 980e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 981e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 98292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 98392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 98492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 98592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 98692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 987af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 988af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 989af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 99092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 99192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 99292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 99392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 99492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 995580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 9960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 997580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ARMOperand *Op = new ARMOperand(ShifterImmediate); 998580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 999580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 10000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 10010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 10020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 10030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 10040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 10065fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1007cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 10080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 10090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1010275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 1011275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 10120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 1013275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 1014275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 10150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 10160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 10170f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 10185fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 10197729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 102024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1021cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1022cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1023cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 10248d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 10258d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 10268d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 10273a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 10283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 1029762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1030762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1031762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 10323a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1033cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1034cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 1035ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, 1036ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool OffsetIsReg, const MCExpr *Offset, 1037ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int OffsetRegNum, bool OffsetRegShifted, 10380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType, 10393a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *ShiftAmount, bool Preindexed, 10403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool Postindexed, bool Negative, bool Writeback, 10413a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 1042023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((OffsetRegNum == -1 || OffsetIsReg) && 1043023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegNum must imply OffsetIsReg!"); 1044023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!OffsetRegShifted || OffsetIsReg) && 1045023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegShifted must imply OffsetIsReg!"); 1046d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert((Offset || OffsetIsReg) && 1047d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar "Offset must exists unless register offset is used!"); 1048023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) && 1049023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have shift amount without shifted register offset!"); 1050023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!Offset || !OffsetIsReg) && 1051023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have expression offset and register offset!"); 1052023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar 10533a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 1054ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Op->Mem.AddrMode = AddrMode; 1055762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 1056762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 10572637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar if (OffsetIsReg) 10582637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.RegNum = OffsetRegNum; 10592637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar else 10602637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.Value = Offset; 1061762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 1062762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 1063762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 1064762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 1065762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 1066762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 1067762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 106816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1069762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1070762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 10713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1072a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1073706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1074706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1075706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1076706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1077706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1078706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1079706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1080706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1081a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1082a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1083a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1084a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1085a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1086a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1087a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1088a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1089584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1090584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1091584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1092584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1093584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1094584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1095584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1096584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1097a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1098a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1099a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1101b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1102fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 1103fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 11046a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1105fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1106d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1107d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1108d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 1109fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1110fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1111fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1112fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1113fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1114fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1115584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1116584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1117584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1118fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1119fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1120fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1121706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1122706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1123706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1124fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 11256ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 1126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << "am:" << ARMII::AddrModeToString(getMemAddrMode()) 1127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << " base:" << getMemBaseRegNum(); 11286ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) { 11296ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:<register " << getMemOffsetRegNum(); 11306ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetRegShifted()) { 11316ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-type:" << getMemShiftType(); 11326ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-amount:" << *getMemShiftAmount(); 11336ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 11346ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } else { 11356ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:" << *getMemOffset(); 11366ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 11376ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) 11386ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (offset-is-reg)"; 11396ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPreindexed()) 11406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (pre-indexed)"; 11416ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPostindexed()) 11426ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (post-indexed)"; 11436ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemNegative()) 11446ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (negative)"; 11456ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemWriteback()) 11466ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (writeback)"; 11476ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1148fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1149a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1150a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1151a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1152a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1153a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1154a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1155a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1156a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1157a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1158fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 115950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1160fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1161580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 1162580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1163580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1164e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1165e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 116692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1167af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1168af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1169af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1170af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1171e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 11720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 117392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 117492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1175af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1176af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1177af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 117892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 117992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 11800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 11810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 11820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 11838d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 11848d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 11855fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 11865fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 11877729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 11887729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 11897729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 11908d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 11918d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 11928d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 11938d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 11948d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1195fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1196fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1197fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1198fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1199fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 12003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 12023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 12033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 12053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 12063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 12073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 120869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 120969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 1210bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky RegNo = TryParseRegister(); 1211bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1212bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1213bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1214bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 12159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1216e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1217e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 12183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 1219e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() { 122018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1221a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1222d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1223a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1224a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 12250c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 12260c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 12270c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 12280c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 12290c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 12300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 12310c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 12320c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 12330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 12340c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 12350c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 12360c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 123769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1238b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1239e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1240e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1241d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 124219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 124319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 124419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 124519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 124619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 124719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbachint ARMAsmParser::TryParseShiftRegister( 12480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 12490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 12500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 12510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 12520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 12530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 12540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 12550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 12560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 12570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 12580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 12590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 12600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 12610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 12620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 12630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 126419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 12650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1266e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1267e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1268e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1269e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1270e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1271eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1272e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1273e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1274e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1275e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1276e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1277e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1278e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1280e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1281e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1282e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1283e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1284e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1286e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1287e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 128819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 128919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 129019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 129119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1292e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1293e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 129419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 129519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 129619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 129719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1298e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1299e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1300e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1301e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1302e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1303e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1304e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 130519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 130619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1307e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1308e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 1309e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = TryParseRegister(); 1310e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 131119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 131219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 131319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 131419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 131519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 131619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1317e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 131819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 131919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1320e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1321e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 132292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 132392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1324af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 13250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 132692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 132792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 132892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 13290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 133019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 13310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 13320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 13330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 133450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 133550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 133650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1337e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1338e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1339e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 134050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 134150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1342e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 1343e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int RegNo = TryParseRegister(); 1344e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 134550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1346d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 134750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1348a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1349e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1350e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 135150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 135250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1353e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 135499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 135599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 135650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1357a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1358a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1359fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1360fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1361fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1362fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1363e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1364e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1365e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1366e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1367e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1368fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1369e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1370e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1371e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1372e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1373e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1374e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1375e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1376e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1377e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1378e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1379e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1380e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1381e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1382e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1383e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1384e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1385fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1386e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1387e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1388e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1389e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1390e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1391e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1392e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1393e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1394e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1395e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1396e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1397e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1398e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1399e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1400e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1401e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 140243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1403fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1404fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1405f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 140643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1407e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1408e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1409e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1410e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1411fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1412e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1413f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1414e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1415e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1416fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1417f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1418fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1419fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 142043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1421fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1422fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1423f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 142443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1425fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1426fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1427fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1428fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1429fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1430fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1431f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1432fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1433fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1434fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1435f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1436e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1437e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1438c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1439c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 144150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 144218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1443a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1444e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 144516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 14467729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 14477729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 14485fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1449d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 14507729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1451e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 14527729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1453d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 145418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1455d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1456c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1457c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 145850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1459c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1460e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14611d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling int RegNum = TryParseRegister(); 1462c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1463c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 146450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1465c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1466d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1467e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1468e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1469e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1470e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1471e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1472e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1473e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1474e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1475e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1476e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1477e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 14787729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 14797729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1480e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1481e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 148218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1483c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1484c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 148550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1486c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1487d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1488e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1489e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 149003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1491e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 14925fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1493e717610f53e0465cde198536561a3c00ce29d59fBill Wendling RI = Registers.begin(), RE = Registers.end(); 1494e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14957caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned HighRegNum = getARMRegisterNumbering(RI->first); 14968e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 14978e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling 14987caebff83d90a59aa74876ff887e822387f479e0Bill Wendling DenseMap<unsigned, bool> RegMap; 14997caebff83d90a59aa74876ff887e822387f479e0Bill Wendling RegMap[HighRegNum] = true; 15007caebff83d90a59aa74876ff887e822387f479e0Bill Wendling 1501e717610f53e0465cde198536561a3c00ce29d59fBill Wendling for (++RI; RI != RE; ++RI) { 15027729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling const std::pair<unsigned, SMLoc> &RegInfo = *RI; 15037caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1504e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15058e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1506e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 150750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1508e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1509e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15108e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1511e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1512e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1513e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15148e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling RegMap[Reg] = true; 15158e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1516e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1517e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 151850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 151950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1520d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1521d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 152243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1523f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 152443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1525706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1526706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1527706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1528706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1529706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1530706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1531706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1532706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1533032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 1534706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1535032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 1536706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1537706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1538032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 1539706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1540032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 1541706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1542706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1543706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1544706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1545706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1546f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1547706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1548706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1549706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1550f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1551706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1552706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 155343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1554a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 155543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1556a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1557a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1558a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1559a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1560a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1561a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1562a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1563a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1564a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1565a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1566a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1567a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1568a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1569a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1570a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1571a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1572a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1573a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1574a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1575a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1576a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1577a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1578a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1579a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1580584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1581584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 158243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1583584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 158443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1585584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1586584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1587584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1588584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1589584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1590584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1591584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1592584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1593b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1594584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1595584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1596584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1597584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1600584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1601584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1603584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1604b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 1605584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1606584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1607584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1608584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 16094b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1610584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1611584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1612584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1613584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 16144b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1615584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 161656926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 161756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1618584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1619584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1620584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1621584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1622584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1623584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1624584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1625584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1626584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1627584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1628584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1629584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1630584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1631584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1632584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1633584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1634584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1635584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1636584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1637584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1638584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1639584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1640584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1641584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1642584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1643584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1644584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1645584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1646a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1647a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 164843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemMode2Operand - Try to parse memory addressing mode 2 operand. 1649ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 165043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1651e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1652ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1653ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode2)) 1654ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_NoMatch; 1655ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1656ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_Success; 1657ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1658ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 165943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemMode3Operand - Try to parse memory addressing mode 3 operand. 1660ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 166143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1662ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1663ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1664ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode3)) 1665ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_NoMatch; 1666ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1667ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_Success; 1668ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1670f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1671f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1672f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 1673f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1674f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1675f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1676f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1677f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1678f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 1679f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 1680f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 1681f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 1682f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1683f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1684f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1685f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 1686f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1687f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 1688f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1689f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1690f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1691f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1692f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 1693f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1694f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 1695f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 1696f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1697f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 1698f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1699f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1700f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1701f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 1702f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 1703f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1704f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1705f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1706f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 1707f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 1708f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1709f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1710f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1711f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1712f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1713f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 1714f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 1715f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1716c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1717c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1718c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1719c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 1720c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1721c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1722c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1723c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1724c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 1725c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 1726c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 1727c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 1728c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 1729c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1730c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 1731c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1732c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1733c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1734c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1735c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 1736c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 1737c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 1738c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 1739c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1740580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1741580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 1742580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 1743580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 1744580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 1745580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1746580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1747580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 1748580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 1749580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1750580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1751580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1752580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1753580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 1754580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 1755580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 1756580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 1757580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 1758580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 1759580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 1760580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1761580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1762580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1763580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 1764580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1765580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 1766580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1767580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1768580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1769580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1770580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 1771580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1772580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 1773580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 1774580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1775580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 1776580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1777580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1778580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1779580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 1780580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 1781580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1782580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1783580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1784580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 1785580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 1786580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1787580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 1788580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 1789580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1790580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1791580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // asr #32 encoded as asr #0. 1792580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 1793580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 1794580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1795580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 1796580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 1797580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1798580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1799580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1800580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1801580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 1802580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 1803580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1804580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 1805580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 1806580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1807ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1808ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1809ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1810ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1811ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1812ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1813ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1814ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1815ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1816ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1817ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1818ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1819ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1820ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1822ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1823ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1824ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1825ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1826ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1827ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1828ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1829ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1830ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1831ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1832ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1833ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1834ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1835ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1836ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1837ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1838ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1839ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1840ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1841ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1842ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1843ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1844ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1845ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1846ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1847ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1848ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1849ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1850ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1851ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1852ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1853ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1854ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1855ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1856ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1857ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1858ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1859ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1860ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1861ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1862ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1863ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1864ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1865ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1866ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1867e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 18689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 186950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// 18709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 18719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 187250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 1873ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1874ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { 1875762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 187618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 1877a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 1878762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1879b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 1880a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 188118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 1882550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (BaseRegTok.isNot(AsmToken::Identifier)) { 1883550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 188450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1885550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1886e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int BaseRegNum = TryParseRegister(); 1887e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (BaseRegNum == -1) { 1888550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 188950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1890550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1891a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 18920571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 18930571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 18940571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 18950571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar return true; 18960571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 1897a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 1898a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 1899a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 1900a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 1901a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 190205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar ARMOperand *WBOp = 0; 190305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar int OffsetRegNum = -1; 190405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar bool OffsetRegShifted = false; 19050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl; 190605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *ShiftAmount = 0; 190705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *Offset = 0; 1908a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 19099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 19109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 1911a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 1912a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 1913b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 191405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1915550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 1916550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 191750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 191818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 1919550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 1920550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 192150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1922550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1923762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 1924b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1925a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 192618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 1927a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 1928ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // None of addrmode3 instruction uses "!" 1929ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3) 1930ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1931ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 193250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling WBOp = ARMOperand::CreateToken(ExclaimTok.getString(), 193350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc()); 1934a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 1935b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 1936ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } else { // In addressing mode 2, pre-indexed mode always end with "!" 1937ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (AddrMode == ARMII::AddrMode2) 1938ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Preindexed = false; 1939a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 19400571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar } else { 19410571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The "[Rn" we have so far was not followed by a comma. 19420571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 194380eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // If there's anything other than the right brace, this is a post indexing 194480eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // addressing form. 1945762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 1946b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1947a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 194818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 194903f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1950e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 195180eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Postindexed = true; 195280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Writeback = true; 195350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1954550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 1955550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 195650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1957550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 195850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1959b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 196050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1961550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 196216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 1963550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 196450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1965a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 196605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar } 1967e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 196805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar // Force Offset to exist if used. 196905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!OffsetIsReg) { 197005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!Offset) 197105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Offset = MCConstantExpr::Create(0, getContext()); 1972ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } else { 1973ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) { 1974ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Error(E, "shift amount not supported"); 1975ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1976ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1977a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 197805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1979ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, 1980ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, OffsetRegNum, OffsetRegShifted, 1981ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftType, ShiftAmount, Preindexed, 1982ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Postindexed, Negative, Writeback, S, E)); 198305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (WBOp) 198405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Operands.push_back(WBOp); 198505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 198605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar return false; 1987a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1988a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 19899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 19909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 19919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 19929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 19939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 19949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 19959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 19969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 1997762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 19980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 19999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 20009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 20019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 2002762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 2003762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 20049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 20059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 20069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 20079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 200818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 2009762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 20109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 2011b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 20129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 20139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 2014b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 20159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 20169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 201718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 20189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 2019e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc CurLoc = OffsetRegTok.getLoc(); 2020e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner OffsetRegNum = TryParseRegister(); 2021e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (OffsetRegNum != -1) { 2022550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 2023e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner E = CurLoc; 2024762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 20259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 2026d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 202712f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling // If we parsed a register as the offset then there can be a shift after that. 20289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 20299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 203018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 20319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 2032b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 20339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 203418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2035762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 20363472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 20379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 20389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 20399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 20409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 20419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 204218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 20439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 20449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 204516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2046b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 20479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 20489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 20499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 2050762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 20519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 20529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 20539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 20549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 2055a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 2056a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 2057a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 2058a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 20590082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St, 20600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E) { 206118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2062a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2063a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 206438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 2065a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 20660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 2067a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 20680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 2069a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 20700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 2071a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 20720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 2073a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 20740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 2075a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 2076a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 2077b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 2078a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 20799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 20800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (St == ARM_AM::rrx) 20819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 2082a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 20839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 208418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 20859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 20869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 2087b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 20889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 20899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 20909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 2091a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2092a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 2093a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2094a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 20959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 20969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 2097e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2098fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 2099762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 2100fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2101fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 2102fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 2103f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2104f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 2105fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 2106f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 2107f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 2108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 2109f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 2110f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 2111fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2112a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 2113146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 2114146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 211550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 211619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 211750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling if (!TryParseRegisterWithWriteBack(Operands)) 211850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 211919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach int Res = TryParseShiftRegister(Operands); 212019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 21210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 212219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 212319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 2124e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2125e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 2126e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 212719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 212867b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 212967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 2130515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 2131515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 2132515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 2133762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2134515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 213550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2136762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 213750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 213850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 213950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 2140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 214150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseMemory(Operands); 2142d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 214350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseRegisterList(Operands); 2144d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 2145079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 2146079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2147762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2148b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2149515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 2150515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 215150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2152762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 215350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 215450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 21559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 21569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 21577597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 21587597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 21597597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 21609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (ParsePrefix(RefKind)) 21619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 21629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 21637597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 21647597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 21659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 21669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 21677597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 21687597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 21699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 21707597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 21719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 21729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 2173a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2174a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2175a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 21767597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 21777597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 21787597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) { 21797597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 21809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 21819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 21828a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 21839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 21849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 21859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 21869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 21879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 21889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 21899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 21909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 21919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 21927597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 21939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 21947597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 21959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 21969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 21979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 21989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 21999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 22009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 22029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 22039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 22049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 22059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 22069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 22079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 22089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 22109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E, 22119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 22129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 22139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 22149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 22159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 22169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 22189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 22199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 22209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 22219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 22229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 22249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 22259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 22279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 22289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 22309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 22319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 22339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 22349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 22369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 22379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant); 22389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 22399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 22409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 22419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 22439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 22449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 22459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 22469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 22479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 22489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 22499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 2250352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 2251352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 2252352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 2253badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 22545f16057d1e4b711d492091bc555693a03d4a1b6eJim GrosbachStringRef ARMAsmParser::SplitMnemonic(StringRef Mnemonic, 22555f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 22565f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 22575f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &ProcessorIMod) { 2258352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 2259352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 2260a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 2261352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2262badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 2263352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 2264352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 22655f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 22665f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 22675f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 22685f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 22695f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 22705f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 22715f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 22725f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2273352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2274badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 22753f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 22763f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 2277ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 2278bf2845c0d8a77d24e9971871badeba8cee7b2648Jim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls") { 22793f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 22803f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 22813f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 22823f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 22833f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 22843f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 22853f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 22863f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 22873f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 22883f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 22893f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 22903f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 22913f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 22923f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 22933f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 22943f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 22953f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 22963f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 22973f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 22983f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 22993f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 23003f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 23013f00e317064560ad11168d22030416d853829f6eJim Grosbach } 230252925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 2303345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2304352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 2305352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 2306352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 2307352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 23085f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 23095f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 23105f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 23115f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vrsqrts" || (Mnemonic == "movs" && isThumb()))) { 2312352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2313352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 2314352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 2315352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 2317a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 2318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 2319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 2320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 2321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 2323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 2324a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2325a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 2326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 2328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2331352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2332352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 23333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 23343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 23353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 23363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 23373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 2338fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 2339fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2340fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 2341eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2342eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2343eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2344eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2345be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2346eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2347eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 2348be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "eor" || Mnemonic == "smlal" || 2349ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 2350eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 2351eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 2352eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 2353eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 23543771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 2355eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2356eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2357eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2358eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 23595f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2360c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Mnemonic == "setend" || 23615f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 23623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 23633771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 23643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 23653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 2366fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 2367ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 2368fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 236963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2370fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 2371badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 2372badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2373badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 2374badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2375badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2376badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 2377badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 2378ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 2379badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2380352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 2381352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 2382a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 2383352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 2384ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Mnemonic = SplitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2385c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach ProcessorIMod); 2386badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2387ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2388ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2389ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 2390ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 23919717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 23923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 23933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 23943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 23953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 23963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 23973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 23983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 23993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 2400ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach GetMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 24013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 240233c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 240333c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 240433c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 240533c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 2406ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 240733c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 240833c16a27370939de39679245c3dff72383c210bdJim Grosbach } 2409c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 2410c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 2411c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 2412c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 2413c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 2414c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 2415c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 241633c16a27370939de39679245c3dff72383c210bdJim Grosbach 24173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 24183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 24193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 24203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 24213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 242233c16a27370939de39679245c3dff72383c210bdJim Grosbach if (CanAcceptCarrySet) 24233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 24243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 24253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 24263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 24273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 24283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 24293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 2430badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 2431345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2432a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 2433a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 2434a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 2435a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 2436a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 2437a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 2438a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 2439a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 2440a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2441a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 2442a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2443a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2444345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 24455747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 24465747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 24475747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 2448a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 2449a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2450a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 24515747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 24525747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 24535747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 24545747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 2455a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 2456ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (ParseOperand(Operands, Mnemonic)) { 2457cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2458cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2459cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2461a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 2462b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 2463a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2464a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 2465ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (ParseOperand(Operands, Mnemonic)) { 2466cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2467cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2468cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2469a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2470a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 247116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2472cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2473cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 247434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 2475cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2476146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 247734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 2478ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2479ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2480ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2481ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 2482ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 2483ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // operand if that's the instruction we're trying to match. 2484ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // 2485ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // We do this post-processing of the explicit operands rather than just 2486ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // conditionally adding the cc_out in the first place because we need 2487ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // to check the type of the parsed immediate operand. 2488ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Mnemonic == "mov" && Operands.size() > 4 && 2489ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2490731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2491731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) { 2492ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2493ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 2494ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 2495ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 2496ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 24979898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 2498ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2499ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2500fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 2501fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 2502fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2503fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 2504fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 2505fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 25065a18700470f0831b9b2af78862672561dd980345Jim Grosbach MatchResultTy MatchResult; 2507193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2508193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 2509e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 2510fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 2511fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 2512e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 2513e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2514e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 2515e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 2516e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 2517e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 2518e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 2519e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 252016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2521e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2522e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2523e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 252416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2525e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 2526e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 2527e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 2528e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 2529b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 2530b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 2531fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 253216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2533c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 2534146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 2535fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 2536fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 2537515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 2538ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2539ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 2540ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 2541ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 2542515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 2543515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 2544515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 2545515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 2546515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 2547515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 2548515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 2549515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 2550ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2551ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2552ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2553ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 2554ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 2555ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 2556ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 2557ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 2558ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 2559ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 2560ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2561ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2562aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2563ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2564ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 2565ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 256616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2567ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 2568ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 2569ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 2570b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2571ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2572ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2573ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2574b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2575ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 2576ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2577ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2578515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 2579515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 2580515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 2581515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2582515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2583b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2584515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2585515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 2586515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 2587515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2588515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2589515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2590515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2591515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 2592515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 2593515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 25946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 25956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 25966469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 25976469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 25986469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 25996469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 26006469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 26016469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 26026469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 26036469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 26046469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 26056469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 26066469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 26076469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2608515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2609515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2610b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2611515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 26126469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 26136469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 26146469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 26156469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 26166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2617642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 2618642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2619642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 2620515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2621515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2622515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2623515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 2624515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 2625515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 262618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2627515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2628515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 262938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 263058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 2631b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 263258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 26339e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 2634515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2635515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 2636515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2637515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 263818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2639b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2640515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2641515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 2642515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2643515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2644515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2645515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2646515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 2647515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 2648515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 264918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2650515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 2651515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 265218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 265358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 2654b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 265558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 2656b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2657515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2658515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 2659515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2660515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 266118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2662b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2663515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 266432869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 2665ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if (!isThumb()) 2666ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 26672a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 266832869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 2669ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if (isThumb()) 2670ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 26712a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2672eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 26732a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 2674515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2675515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2676515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 267790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 267890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 26799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 2680ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 268194b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 268294b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 268390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 2684ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 26853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 26860692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 26870692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 26883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 2689