ARMAsmParser.cpp revision 92a202213bb4c20301abf6ab64e46df3695e60bf
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 10ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "ARM.h" 11b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h" 123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h" 13ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 14ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 16c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 17c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 186469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 19642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 21ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 22ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h" 26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 27fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2875ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.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 40ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser { 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 107f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseCoprocNumOperand( 108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 109f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseCoprocRegOperand( 110f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 111f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseMemBarrierOptOperand( 1128bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 113a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OperandMatchResultTy tryParseProcIFlagsOperand( 1148bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 115584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OperandMatchResultTy tryParseMSRMaskOperand( 1168bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 117ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes OperandMatchResultTy tryParseMemMode2Operand( 118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 119ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes OperandMatchResultTy tryParseMemMode3Operand( 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 } 129ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 130ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 133ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 134ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 135ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 136ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 137ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 138ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 139f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach 140ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 141ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 142ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng : TargetAsmParser(), STI(_STI), Parser(_Parser) { 143ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 14432869205052430f45d598fba25ab878d8b29da2dEvan Cheng 145ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 146ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 147ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 148ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 14938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 1509898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 151ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 152ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 15316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 15416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1553a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 157a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 158a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 159146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 162d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 163fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 165cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 166706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 1678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 168584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 169a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 1708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1718d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 1720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 1730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 174e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 17592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 1760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Shifter, 1778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 178a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 18124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 184a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1858462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 189706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 190706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 192706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 193fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 195fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 196fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 197a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 198a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 199a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 201584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 202584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 203584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 204584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 205a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 207a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2138155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 214cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 215cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 21616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2176a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 219ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode; 220a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2212637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar union { 2222637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar unsigned RegNum; ///< Offset register num, when OffsetIsReg. 2232637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar const MCExpr *Value; ///< Offset value, when !OffsetIsReg. 2242637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar } Offset; 225146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 2260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true 227146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true 22850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Preindexed : 1; 22950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Postindexed : 1; 23050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned OffsetIsReg : 1; 23150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Negative : 1; // only used when OffsetIsReg is true 23250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Writeback : 1; 233a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy; 237e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 2380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } Shift; 239e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } ShiftedReg; 24592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 24692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 24792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 24892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 24992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } ShiftedImm; 250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 25116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 252146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 253146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 2598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 2608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 2618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 2638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 265d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 2698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 2700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 2710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 27224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 2738d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 274fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 275fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 276fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 277fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 281706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 282706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 283706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 284762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 290a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 291a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 2920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 2930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson case Shifter: 2940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Shift = o.Shift; 2950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 296e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 297e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedReg = o.ShiftedReg; 298e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 29992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 30092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImm = o.ShiftedImm; 30192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 30416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 305762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 306762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 308762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 315fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 316fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 317fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 318fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 319fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3266aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3277729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3305fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 33324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3348d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 336cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 337cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 338cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 339cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 340cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 341706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 342706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 343706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 344706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 345706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 346a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 347a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 348a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 349a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 350a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 351584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 352584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 353584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 354584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 355584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @name Memory Operand Accessors 3576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @{ 358ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode getMemAddrMode() const { 359ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return Mem.AddrMode; 360ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 3616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemBaseRegNum() const { 3626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.BaseRegNum; 3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegNum() const { 3656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.RegNum; 3676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemOffset() const { 3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(!Mem.OffsetIsReg && "Invalid access!"); 3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.Value; 3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegShifted() const { 3736ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.OffsetRegShifted; 3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3766ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemShiftAmount() const { 3776ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftAmount; 3796ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc getMemShiftType() const { 3816ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3826ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftType; 3836ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3846ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPreindexed() const { return Mem.Preindexed; } 3856ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPostindexed() const { return Mem.Postindexed; } 3866ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; } 3876ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemNegative() const { return Mem.Negative; } 3886ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemWriteback() const { return Mem.Writeback; } 3896ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 3906ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @} 3916ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 392fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 393fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 3948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 395d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 3963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 3976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 3986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 3996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 4046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 40583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 40683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 40783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 40883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 40983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 41083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 41183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 41283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 41383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 41483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 41583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 41683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 41783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 41883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 41983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 42083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 421fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 422fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 423fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 424fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 425fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 426fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 427fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 428fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 429ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 430ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 431ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 432ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 433ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 434ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 435ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 436ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 437ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 438ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 439f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 440f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 441f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 442f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 443f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 444f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 445f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 446f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 447f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 448f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 449f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 450f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 451f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 452f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 453f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 454f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 4556bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 4566bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 4576bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 4586bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4596bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 4606bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 4616bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 4626bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 4636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 4646b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4656b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4666b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4676b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 4706b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 471b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 4728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 4730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 4740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 47514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 476706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 47714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 4780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool isShifter() const { return Kind == Shifter; } 479e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach bool isShiftedReg() const { return Kind == ShiftedRegister; } 48092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson bool isShiftedImm() const { return Kind == ShiftedImmediate; } 481ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool isMemMode2() const { 482ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode2) 483ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 484ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 485ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) 486ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 487ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 488ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemNegative() && 489ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 490ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 491ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 492ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 493ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (!CE) return false; 494ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Value = CE->getValue(); 495ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 496ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // The offset must be in the range 0-4095 (imm12). 497ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Value > 4095 || Value < -4095) 498ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 499ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 500ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 501ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 502ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool isMemMode3() const { 503ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode3) 504ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 505ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 506ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 507ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetRegShifted()) 508ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; // No shift with offset reg allowed 509ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 510ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 511ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 512ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemNegative() && 513ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 514ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 515ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 516ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 517ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (!CE) return false; 518ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Value = CE->getValue(); 519ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 520ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // The offset must be in the range 0-255 (imm8). 521ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Value > 255 || Value < -255) 522ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 523ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 524ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 525ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 52687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling bool isMemMode5() const { 5274b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || 5284b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar getMemNegative()) 52987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 530ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 5314b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 532ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 533ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 53487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling // The offset must be a multiple of 4 in the range 0-1020. 53587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling int64_t Value = CE->getValue(); 53687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); 53787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 538505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes bool isMemMode7() const { 539505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!isMemory() || 540505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPreindexed() || 541505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPostindexed() || 542505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemOffsetIsReg() || 543505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemNegative() || 544505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemWriteback()) 545505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 546505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 547505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 548505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!CE) return false; 549505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 550505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (CE->getValue()) 551505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 552505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 553505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return true; 554505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 555f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeRegThumb() const { 5564b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback()) 557f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 558d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar return true; 559f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 560f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeImmThumb() const { 5614b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback()) 562ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 563ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 5644b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 565ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 566ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 567ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // The offset must be a multiple of 4 in the range 0-124. 568ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling uint64_t Value = CE->getValue(); 569ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return ((Value & 0x3) == 0 && Value <= 124); 570ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 571584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 572a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 5733483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 5743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 57514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 57614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 57714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 57814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 5793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 5803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 5813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 5823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 5833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 5848462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 585345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 5868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 58704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 58804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 5898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 5908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 591fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 592fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 593fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 594fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 595fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 596fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 597fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 598fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 599fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 600fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 601d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 602d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 603d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 604d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 605d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 606a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 608a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 609a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 610a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 611e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach void addShiftedRegOperands(MCInst &Inst, unsigned N) const { 612e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 613e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!"); 614e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg)); 615e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg)); 616e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 617e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm))); 618e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 619e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 62092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson void addShiftedImmOperands(MCInst &Inst, unsigned N) const { 62192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson assert(N == 3 && "Invalid number of operands!"); 62292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson assert(isShiftedImm() && "addShiftedImmOperands() on non ShiftedImm!"); 62392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg)); 62492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftedImm.ShiftTy == ARM_AM::rrx) 62592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg)); 62692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 62792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateReg(0)); 62892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 62992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::getSORegOpc(ShiftedImm.ShiftTy, ShiftedImm.ShiftImm))); 63092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 63192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 63292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 6330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson void addShifterOperands(MCInst &Inst, unsigned N) const { 6340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 6350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Inst.addOperand(MCOperand::CreateImm( 6360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::getSORegOpc(Shift.ShiftTy, 0))); 6370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 6380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 63987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 6407729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 6415fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 6425fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 6437729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 6447729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 64587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 64687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 6470f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 6480f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 6490f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 6500f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 6510f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 6520f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 6530f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 6540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 6553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 6566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 6576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 6586b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 6596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 6606b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 6616b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 6626b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 6636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 6646b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 66583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 66683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 66783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 66883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 66983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 67083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 67183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 67283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 67383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 67483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 675fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 676fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 677fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 678fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 679fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 680ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 681ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 682ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 683ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 684ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 685f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 686f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 687f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 688f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 689f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 690f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 691f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 692f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 693f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 694f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 695f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 696f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 697f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 698f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 6996bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 7006bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 7016bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 7026bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 7036bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 7046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 7053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 7063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 7073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 70816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 709706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 710706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 711706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 712706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 713706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 714505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes void addMemMode7Operands(MCInst &Inst, unsigned N) const { 715505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert(N == 1 && isMemMode7() && "Invalid number of operands!"); 716505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 717505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 718505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 7191866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay (void)CE; 720505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert((CE || CE->getValue() == 0) && 721505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes "No offset operand support in mode 7"); 722505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 723505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 724ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes void addMemMode2Operands(MCInst &Inst, unsigned N) const { 725ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(isMemMode2() && "Invalid mode or number of operands!"); 726ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 727ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 728ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 729ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) { 730ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 731ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 732ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 733ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; 734ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t ShiftAmount = 0; 735ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 736ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetRegShifted()) { 737ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc = getMemShiftType(); 738ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = 739ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes dyn_cast<MCConstantExpr>(getMemShiftAmount()); 740ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftAmount = CE->getValue(); 741ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 742ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 743ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, 744ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc, IdxMode))); 745ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return; 746ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 747ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 748ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 749ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 750ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 751ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 752ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // the difference? 753ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 754ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(CE && "Non-constant mode 2 offset operand!"); 755ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Offset = CE->getValue(); 756ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 757ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Offset >= 0) 758ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, 759ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, ARM_AM::no_shift, IdxMode))); 760ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes else 761ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, 762ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes -Offset, ARM_AM::no_shift, IdxMode))); 763ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 764ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 765ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes void addMemMode3Operands(MCInst &Inst, unsigned N) const { 766ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(isMemMode3() && "Invalid mode or number of operands!"); 767ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 768ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 769ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 770ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 771ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 772ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 773ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 774ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0, 775ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes IdxMode))); 776ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return; 777ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 778ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 779ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 780ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 781ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 782ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 783ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // the difference? 784ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 785ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(CE && "Non-constant mode 3 offset operand!"); 786ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Offset = CE->getValue(); 787ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 788ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Offset >= 0) 789ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add, 790ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Offset, IdxMode))); 791ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes else 792ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub, 793ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes -Offset, IdxMode))); 794ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 795ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 79614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner void addMemMode5Operands(MCInst &Inst, unsigned N) const { 79714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 79816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 7994b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 8004b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar assert(!getMemOffsetIsReg() && "Invalid mode 5 operand"); 80192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 80280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // FIXME: #-0 is encoded differently than #0. Does the parser preserve 80380eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // the difference? 8044b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 805d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert(CE && "Non-constant mode 5 offset operand!"); 806d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 807d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // The MCInst offset operand doesn't include the low two bits (like 808d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // the instruction encoding). 809d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar int64_t Offset = CE->getValue() / 4; 810d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar if (Offset >= 0) 811d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, 812d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Offset))); 813d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar else 814d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, 815d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar -Offset))); 81614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 8173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 818f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const { 819f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!"); 8204b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 8214b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 822f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 823ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 824f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const { 825f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!"); 8264b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 8274b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 828f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(CE && "Non-constant mode offset operand!"); 829f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 830ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 831ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 832584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 833584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 834584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 835584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 836584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 837a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 838a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 839a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 840a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 841a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 842b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 843b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 8443a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 8453a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 846345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 847345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 848345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 8493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 850345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 851345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 852fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 853fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 854fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 855fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 856fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 857fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 858fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 859fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 860fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 861fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 862fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 863fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 864fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 865fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 866fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 867fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 868d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 869d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 870d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 871d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 872d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 873d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 874d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 875d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 8763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 8773a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 878762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 879762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 880762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 881762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 8823a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 883a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 884a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 88550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 8863a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 887762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 888762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 889762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 8903a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 891a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 892a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 893e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 894e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 895e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 896e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 897e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 898e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 899e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->ShiftedReg.ShiftTy = ShTy; 900e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->ShiftedReg.SrcReg = SrcReg; 901e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->ShiftedReg.ShiftReg = ShiftReg; 902e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->ShiftedReg.ShiftImm = ShiftImm; 903e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 904e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 905e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 906e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 907e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 90892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 90992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 91092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 91192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 91292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 91392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->ShiftedImm.ShiftTy = ShTy; 91492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->ShiftedImm.SrcReg = SrcReg; 91592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->ShiftedImm.ShiftImm = ShiftImm; 91692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 91792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 91892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 91992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 92092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 9210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy, 9220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 9230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARMOperand *Op = new ARMOperand(Shifter); 9240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->Shift.ShiftTy = ShTy; 9250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 9260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 9270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 9280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 9290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 9307729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 9315fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 932cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 9330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 9340f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9350f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling if (ARM::DPRRegClass.contains(Regs.front().first)) 9360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 9370f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling else if (ARM::SPRRegClass.contains(Regs.front().first)) 9380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 9390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 9400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 9415fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 9427729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 94324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 944cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 945cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 946cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 9478d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 9488d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 9498d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 9503a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 9513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 952762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 953762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 954762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 9553a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 956cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 957cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 958ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, 959ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool OffsetIsReg, const MCExpr *Offset, 960ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int OffsetRegNum, bool OffsetRegShifted, 9610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType, 9623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *ShiftAmount, bool Preindexed, 9633a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool Postindexed, bool Negative, bool Writeback, 9643a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 965023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((OffsetRegNum == -1 || OffsetIsReg) && 966023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegNum must imply OffsetIsReg!"); 967023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!OffsetRegShifted || OffsetIsReg) && 968023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegShifted must imply OffsetIsReg!"); 969d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert((Offset || OffsetIsReg) && 970d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar "Offset must exists unless register offset is used!"); 971023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) && 972023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have shift amount without shifted register offset!"); 973023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!Offset || !OffsetIsReg) && 974023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have expression offset and register offset!"); 975023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar 9763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 977ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Op->Mem.AddrMode = AddrMode; 978762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 979762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 9802637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar if (OffsetIsReg) 9812637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.RegNum = OffsetRegNum; 9822637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar else 9832637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.Value = Offset; 984762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 985762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 986762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 987762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 988762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 989762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 990762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 99116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 992762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 993762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 9943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 995a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 996706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 997706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 998706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 999706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1000706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1001706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1002706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1003706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1004a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1005a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1006a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1007a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1008a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1009a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1010a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1011a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1012584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1013584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1014584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1015584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1016584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1017584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1018584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1019584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1020a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1021a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1022a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1023a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1024b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1025fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 1026fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 10276a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1028fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1029d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1030d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1031d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 1032fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1033fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1035fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1036fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1037fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1038584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1039584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1040584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1041fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1042fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1043fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1044706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1045706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1046706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1047fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 10486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 1049ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << "am:" << ARMII::AddrModeToString(getMemAddrMode()) 1050ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << " base:" << getMemBaseRegNum(); 10516ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) { 10526ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:<register " << getMemOffsetRegNum(); 10536ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetRegShifted()) { 10546ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-type:" << getMemShiftType(); 10556ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-amount:" << *getMemShiftAmount(); 10566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 10576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } else { 10586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:" << *getMemOffset(); 10596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 10606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) 10616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (offset-is-reg)"; 10626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPreindexed()) 10636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (pre-indexed)"; 10646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPostindexed()) 10656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (post-indexed)"; 10666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemNegative()) 10676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (negative)"; 10686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemWriteback()) 10696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (writeback)"; 10706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1071fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1072a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1073a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1074a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1075a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1076a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1077a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1078a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1079a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1080a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1081fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 108250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1083fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 10840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson case Shifter: 1085e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">"; 1086e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1087e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 108892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1089e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ShiftedReg.SrcReg 1090e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm)) 1091e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ", " << ShiftedReg.ShiftReg << ", " 1092e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) 1093e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 10940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 109592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 109692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 109792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ShiftedImm.SrcReg 109892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedImm.ShiftImm)) 109992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ", " << ARM_AM::getSORegOffset(ShiftedImm.ShiftImm) 110092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 110192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 11020f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 11030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 11040f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 11058d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 11068d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 11075fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 11085fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 11097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 11107729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 11117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 11128d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 11138d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 11148d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 11158d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 11168d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1117fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1118fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1119fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1120fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1121fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 11223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 11233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 11243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 11253483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 11263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 11273483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 11283483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 11293483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 113069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 113169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 1132bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky RegNo = TryParseRegister(); 1133bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1134bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1135bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1136bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 11379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1138e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1139e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 11403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 1141e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() { 114218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1144d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1145a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1146a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 11470c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 11480c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 11490c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 11500c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 11510c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 11520c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 11530c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 11540c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 11550c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 11560c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 11570c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 11580c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 115969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1160b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1161e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1162e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1163d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 116419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 116519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 116619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 116719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 116819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 116919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbachint ARMAsmParser::TryParseShiftRegister( 11700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 11710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 11720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 11730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 11740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 11750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 11760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 11770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 11780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 11790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 11800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 11810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 11820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 11830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 11840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 11850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 118619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 11870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1188e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1189e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1190e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1191e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1192e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1193eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1194e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1195e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1196e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1197e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1198e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1199e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1200e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1201e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1202e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1203e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1204e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1205e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1206e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1207e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1208e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1209e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 121019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 121119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 121219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 121319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1214e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1215e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 121619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 121719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 121819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 121919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1220e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1221e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1222e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1223e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1224e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1225e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1226e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 122719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 122819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1229e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1230e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 1231e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = TryParseRegister(); 1232e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 123319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 123419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 123519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 123619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 123719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 123819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1239e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 124019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 124119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 124492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 124592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg, Imm, 12470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 124892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 124992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 125092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 12510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 125219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 12530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 12540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 12550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 125650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 125750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 125850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1259e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1260e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1261e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 126250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 126350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1264e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 1265e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int RegNo = TryParseRegister(); 1266e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 126750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1268d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 126950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1270a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1271e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1272e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 127350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 127450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1275e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 127699e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 127799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 127850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1279a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1280a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1281fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1282fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1283fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1284fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1285e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1286e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1287e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1288e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1289e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1290fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1291e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1292e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1293e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1294e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1295e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1296e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1297e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1298e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1299e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1300e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1301e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1302e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1303e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1304e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1305e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1306e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1307fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1308e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1309e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1310e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1311e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1312e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1313e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1314e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1315e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1316e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1317e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1318e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1319e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1320e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1321e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1322e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1323e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1324f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The 1325fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1326fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1327f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1328f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1329e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1330e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1331e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1332e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1333fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1334e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1335f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1336e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1337e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1338fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1339f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1340fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1341fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1342f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The 1343fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1344fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1345f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1346f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1347fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1348fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1349fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1350fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1351fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1352fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1353f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1354fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1355fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1356fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1357f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1358e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1359e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1360c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1361c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 136250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 136350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 136418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1365a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1366e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 136716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 13687729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 13697729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 13705fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1371d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 13727729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1373e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 13747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1375d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 137618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1377d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1378c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1379c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 138050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1381c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1382e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 13831d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling int RegNum = TryParseRegister(); 1384c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1385c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 138650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1387c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1388d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1389e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1390e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1391e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1392e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1393e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1394e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1395e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1396e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1397e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1398e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1399e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 14007729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 14017729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1402e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1403e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 140418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1405c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1406c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 140750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1408c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1409d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1410e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1411e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 141203f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1413e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 14145fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1415e717610f53e0465cde198536561a3c00ce29d59fBill Wendling RI = Registers.begin(), RE = Registers.end(); 1416e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14177caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned HighRegNum = getARMRegisterNumbering(RI->first); 14188e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 14198e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling 14207caebff83d90a59aa74876ff887e822387f479e0Bill Wendling DenseMap<unsigned, bool> RegMap; 14217caebff83d90a59aa74876ff887e822387f479e0Bill Wendling RegMap[HighRegNum] = true; 14227caebff83d90a59aa74876ff887e822387f479e0Bill Wendling 1423e717610f53e0465cde198536561a3c00ce29d59fBill Wendling for (++RI; RI != RE; ++RI) { 14247729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling const std::pair<unsigned, SMLoc> &RegInfo = *RI; 14257caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1426e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14278e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1428e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 142950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1430e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1431e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14328e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1433e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1434e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1435e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 14368e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling RegMap[Reg] = true; 14378e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1438e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1439e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 144150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1442d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1443d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1444f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1445f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1446f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1447706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1448706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1449706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1450706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1451706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1452706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1453706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1454706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1455032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 1456706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1457032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 1458706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1459706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1460032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 1461706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1462032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 1463706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1464706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1465706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1466706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1467706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1468f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1469706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1470706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1471706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1472f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1473706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1474706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 14758bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1476a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1477a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1478a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1479a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1480a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1481a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1482a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1483a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1484a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1485a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1486a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1487a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1488a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1489a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1490a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1491a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1492a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1493a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1494a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1495a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1496a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1497a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1498a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1499a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1500a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1501a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1502584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1503584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1504584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1505584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1506584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1507584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1508584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1509584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1510584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1511584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1512584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1513584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1514584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1515b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1516584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1517584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1518584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1519584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1520584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1521584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1522584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1523584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1524584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1525584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1526b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 1527584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1528584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1529584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1530584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 15314b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1532584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1533584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1534584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1535584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 15364b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1537584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 153856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 153956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1540584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1541584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1543584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1544584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1545584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1549584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1550584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1551584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1552584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1553584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1554584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1555584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1556584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1557584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1558584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1559584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1560584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1561584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1562584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1563584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1564584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1565584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1566584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1567584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1568a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1569a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1570ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand. 1571ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1572ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1573e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1574ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1575ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode2)) 1576ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_NoMatch; 1577ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1578ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_Success; 1579ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1580ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1581ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand. 1582ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1583ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1584ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1585ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1586ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode3)) 1587ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_NoMatch; 1588ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1589ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_Success; 1590ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1591ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1592f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1593f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1594f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 1595f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1596f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1597f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1598f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1599f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1600f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 1601f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 1602f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 1603f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 1604f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1605f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1606f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1607f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 1608f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1609f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 1610f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1611f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1612f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1613f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1614f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 1615f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1616f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 1617f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 1618f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1619f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 1620f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1621f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1622f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1623f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 1624f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 1625f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1626f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1627f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1628f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 1629f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 1630f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1631f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1632f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1633f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1634f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1635f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 1636f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 1637f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1638ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1639ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1640ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1641ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1642ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1643ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1644ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1645ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1646ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1647ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1648ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1649ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1650ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1651ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1652ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1653ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1654ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1655ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1656ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1657ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1658ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1659ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1660ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1661ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1662ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1663ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1664ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1665ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1666ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1667ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1668ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1670ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1671ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1672ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1673ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1674ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1675ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1676ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1677ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1678ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1679ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1680ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1681ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1682ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1683ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1684ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1685ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1686ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1687ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1688ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1689ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1690ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1691ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1692ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1693ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1694ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1695ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1696ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1697ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1698e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 16999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 170050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// 17019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 17029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 170350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 1704ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1705ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { 1706762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 170718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 1708a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 1709762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1710b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 1711a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 171218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 1713550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (BaseRegTok.isNot(AsmToken::Identifier)) { 1714550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 171550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1716550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1717e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int BaseRegNum = TryParseRegister(); 1718e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (BaseRegNum == -1) { 1719550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 172050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1721550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1722a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 17230571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 17240571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 17250571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 17260571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar return true; 17270571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 1728a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 1729a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 1730a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 1731a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 1732a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 173305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar ARMOperand *WBOp = 0; 173405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar int OffsetRegNum = -1; 173505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar bool OffsetRegShifted = false; 17360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl; 173705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *ShiftAmount = 0; 173805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *Offset = 0; 1739a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 17409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 17419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 1742a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 1743a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 1744b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 174505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1746550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 1747550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 174850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 174918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 1750550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 1751550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 175250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1753550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1754762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 1755b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1756a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 175718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 1758a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 1759ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // None of addrmode3 instruction uses "!" 1760ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3) 1761ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1762ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 176350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling WBOp = ARMOperand::CreateToken(ExclaimTok.getString(), 176450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc()); 1765a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 1766b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 1767ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } else { // In addressing mode 2, pre-indexed mode always end with "!" 1768ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (AddrMode == ARMII::AddrMode2) 1769ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Preindexed = false; 1770a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 17710571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar } else { 17720571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The "[Rn" we have so far was not followed by a comma. 17730571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 177480eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // If there's anything other than the right brace, this is a post indexing 177580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // addressing form. 1776762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 1777b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1778a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 177918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 178003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1781e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 178280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Postindexed = true; 178380eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Writeback = true; 178450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1785550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 1786550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 178750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1788550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 178950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1790b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 179150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1792550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 179316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 1794550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 179550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1796a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 179705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar } 1798e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 179905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar // Force Offset to exist if used. 180005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!OffsetIsReg) { 180105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!Offset) 180205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Offset = MCConstantExpr::Create(0, getContext()); 1803ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } else { 1804ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) { 1805ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Error(E, "shift amount not supported"); 1806ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1807ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1808a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 180905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1810ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, 1811ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, OffsetRegNum, OffsetRegShifted, 1812ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftType, ShiftAmount, Preindexed, 1813ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Postindexed, Negative, Writeback, S, E)); 181405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (WBOp) 181505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Operands.push_back(WBOp); 181605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 181705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar return false; 1818a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1819a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 18209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 18219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 18229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 18239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 18249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 18259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 18269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 18279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 1828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 18290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 18309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 18319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 18329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 1833762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 1834762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 18359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 18369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 18379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 18389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 183918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 1840762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 18419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 1842b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 18439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 18449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 1845b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 18469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 18479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 184818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 18499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 1850e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc CurLoc = OffsetRegTok.getLoc(); 1851e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner OffsetRegNum = TryParseRegister(); 1852e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (OffsetRegNum != -1) { 1853550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 1854e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner E = CurLoc; 1855762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 18569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 1857d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 185812f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling // If we parsed a register as the offset then there can be a shift after that. 18599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 18609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 186118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 18629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 1863b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 18649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 186518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1866762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 18673472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 18689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 18699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 18709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 18719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 18729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 187318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 18749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 18759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 187616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1877b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 18789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 18799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 18809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 1881762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 18829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 18839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 18849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 18859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 1886a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 1887a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 1888a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 1889a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 18900082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St, 18910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E) { 189218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1893a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 1894a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 189538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 1896a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 18970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 1898a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 18990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 1900a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 19010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 1902a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 19030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 1904a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 19050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 1906a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 1907a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 1908b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 1909a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 19109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 19110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (St == ARM_AM::rrx) 19129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 1913a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 19149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 191518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 19169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 19179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 1918b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 19199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 19209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 19219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 1922a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1923a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 1924a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1925a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 19269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 19279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 1928e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1929fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 1930762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 1931fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1932fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 1933fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 1934f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1935f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 1936fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 1937f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 1938f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 1939f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 1940f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 1941f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 1942fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1943a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 1944146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 1945146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 194650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 194719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 194850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling if (!TryParseRegisterWithWriteBack(Operands)) 194950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 195019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach int Res = TryParseShiftRegister(Operands); 195119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 19520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 195319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 195419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 1955e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1956e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 1957e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 195819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 195967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 196067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 1961515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 1962515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 1963515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 1964762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1965515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 196650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1967762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 196850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 196950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 197050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 1971a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 197250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseMemory(Operands); 1973d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 197450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseRegisterList(Operands); 1975d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 1976079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 1977079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 1978762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1979b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 1980515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 1981515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 198250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1983762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 198450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 198550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 19869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 19879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 19887597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 19897597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 19907597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 19919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (ParsePrefix(RefKind)) 19929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 19939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 19947597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 19957597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 19969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 19979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 19987597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 19997597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 20009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 20017597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 20029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 20039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 2004a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2005a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2006a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 20077597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 20087597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 20097597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) { 20107597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 20119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 20138a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 20149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 20159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 20179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 20189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 20199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 20209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 20229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 20237597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 20249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 20257597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 20269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 20279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 20289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 20299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 20309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 20319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 20339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 20349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 20359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 20369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 20379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 20389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 20399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 20419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E, 20429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 20439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 20449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 20459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 20469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 20479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 20499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 20509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 20519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 20529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 20539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 20559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 20569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 20589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 20599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 20619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 20629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 20649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 20659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 20679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 20689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant); 20699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 20709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 20719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 20729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 20749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 20759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 20769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 20779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 20789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 20799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 20809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 2081352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 2082352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 2083352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 2084badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 20855f16057d1e4b711d492091bc555693a03d4a1b6eJim GrosbachStringRef ARMAsmParser::SplitMnemonic(StringRef Mnemonic, 20865f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 20875f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 20885f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &ProcessorIMod) { 2089352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 2090352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 2091a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 2092352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2093badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 2094352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 2095352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 20965f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 20975f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 20985f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 20995f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 21005f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 21015f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 21025f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 21035f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2104352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2105badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 21063f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 21073f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 2108ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 2109ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach Mnemonic != "muls") { 21103f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 21113f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 21123f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 21133f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 21143f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 21153f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 21163f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 21173f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 21183f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 21193f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 21203f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 21213f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 21223f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 21233f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 21243f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 21253f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 21263f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 21273f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 21283f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 21293f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 21303f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 21313f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 21323f00e317064560ad11168d22030416d853829f6eJim Grosbach } 213352925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 2134345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2135352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 2136352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 2137352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 2138352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 21395f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 21405f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 21415f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 21425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vrsqrts" || (Mnemonic == "movs" && isThumb()))) { 2143352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2144352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 2145352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 2146352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2147a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 2148a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 2149a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 2150a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 2151a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 2152a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2153a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 2154a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 2155a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2156a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 2157a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2158a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 2159a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2160a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2161a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2162352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2163352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 21643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 21653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 21663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 21673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 21683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 2169fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 2170fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2171fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 2172eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2173eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2174eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2175eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2176be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2177eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2178eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 2179be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "eor" || Mnemonic == "smlal" || 2180ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 2181eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 2182eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 2183eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 2184eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 21853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 2186eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2187eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2188eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2189eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 21905f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 21915f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 21923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 21933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 21943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 21953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 2196fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 2197ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 2198fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 219963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2200fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 2201badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 2202badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2203badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 2204badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2205badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2206badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 2207badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 2208ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 2209badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2210352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 2211352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 2212a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 2213352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 2214ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Mnemonic = SplitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2215a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod); 2216badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2217ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2218ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2219ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 2220ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 22219717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 22223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 22233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 22243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 22253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 22263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 22273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 22283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 22293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 2230ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach GetMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 22313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 223233c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 223333c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 223433c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 223533c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 2236ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 223733c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 223833c16a27370939de39679245c3dff72383c210bdJim Grosbach } 223933c16a27370939de39679245c3dff72383c210bdJim Grosbach 22403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 22413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 22423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 22433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 22443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 224533c16a27370939de39679245c3dff72383c210bdJim Grosbach if (CanAcceptCarrySet) 22463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 22473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 22483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 22493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 22503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 22513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 22523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 22533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 22543771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // This mnemonic can't ever accept a predication code, but the user wrote 22553771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // one (or misspelled another mnemonic). 22563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 22573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: Issue a nice error. 2258badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 2259345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2260a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 2261a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 2262a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 2263a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 2264a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 2265a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 2266a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 2267a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 2268a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2269a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 2270a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2271a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2272345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 22735747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 22745747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 22755747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 2276a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 2277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2278a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 22795747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 22805747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 22815747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 22825747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 2283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 2284ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (ParseOperand(Operands, Mnemonic)) { 2285cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2286cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2287cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2288a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2289a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 2290b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 2291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 2293ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (ParseOperand(Operands, Mnemonic)) { 2294cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2295cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2296cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 229916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2300cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2301cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 230234e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 2303cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2304146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 230534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 2306ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2307ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2308ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2309ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 2310ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 2311ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // operand if that's the instruction we're trying to match. 2312ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // 2313ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // We do this post-processing of the explicit operands rather than just 2314ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // conditionally adding the cc_out in the first place because we need 2315ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // to check the type of the parsed immediate operand. 2316ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Mnemonic == "mov" && Operands.size() > 4 && 2317ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2318731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2319731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) { 2320ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2321ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 2322ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 2323ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 2324ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2325ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2326ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 23279898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 2328ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2329ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2330fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 2331fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 2332fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2333fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 2334fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 2335fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 23365a18700470f0831b9b2af78862672561dd980345Jim Grosbach MatchResultTy MatchResult; 2337193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2338193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 2339e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 2340fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 2341fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 2342e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 2343e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2344e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 2345e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 2346e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 2347e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 2348e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 2349e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 235016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2351e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2352e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2353e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 235416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2355e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 2356e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 2357e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 2358e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 2359b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 2360b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 2361fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 236216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2363c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 2364146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 2365fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 2366fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 2367515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 2368ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2369ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 2370ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 2371ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 2372515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 2373515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 2374515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 2375515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 2376515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 2377515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 2378515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 2379515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 2380ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2381ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2382ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2383ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 2384ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 2385ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 2386ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 2387ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 2388ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 2389ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 2390ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2391ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2392aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2393ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2394ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 2395ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 239616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2397ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 2398ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 2399ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 2400b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2401ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2402ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2403ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2404b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2405ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 2406ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2407ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2408515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 2409515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 2410515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 2411515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2412515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2413b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2414515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2415515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 2416515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 2417515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2418515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2419515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2420515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2421515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 2422515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 2423515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 24246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 24256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 24266469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 24276469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 24286469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 24296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 24306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 24316469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 24326469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 24336469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 24346469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 24356469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 24366469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 24376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2438515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2439515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2440b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2441515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 24426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 24436469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 24446469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 24456469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 24466469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2447642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 2448642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2449642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 2450515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2451515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2452515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2453515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 2454515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 2455515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 245618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2457515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2458515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 245938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 246058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 2461b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 246258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 24639e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 2464515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2465515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 2466515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2467515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 246818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2469b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2470515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2471515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 2472515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2473515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2474515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2475515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2476515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 2477515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 2478515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 247918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2480515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 2481515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 248218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 248358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 2484b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 248558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 2486b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2487515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2488515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 2489515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2490515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 249118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2492b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2493515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 249432869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 2495ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if (!isThumb()) 2496ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 24972a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 249832869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 2499ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if (isThumb()) 2500ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 25012a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2502eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 25032a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 2504515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2505515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2506515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 250790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 250890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 25099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 2510ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 2511ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 2512ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 251390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 2514ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 25153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 25160692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 25170692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 25183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 2519