ARMAsmParser.cpp revision e8606dc7c878d4562da5e3e5609b9d7d734d498c
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" 1192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling#include "ARMAddressingModes.h" 127597212abced110723f2fee985a7d60557c092ecEvan Cheng#include "ARMMCExpr.h" 13b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h" 143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.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 34ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#define GET_SUBTARGETINFO_ENUM 35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "ARMGenSubtargetInfo.inc" 36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser { 44ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 52ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 53e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int TryParseRegister(); 54bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 5550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 5750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 58ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &, 59ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode); 60fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 617597212abced110723f2fee985a7d60557c092ecEvan Cheng bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); 629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *ApplyPrefixToExpr(const MCExpr *E, 639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 65a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 72762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 73762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E); 740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool ParseShift(enum ARM_AM::ShiftOpc &St, 750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E); 76ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 79515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 80515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 81515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 827036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner bool MatchAndEmitInstruction(SMLoc IDLoc, 837c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 84fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out); 85fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 86fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 8716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 88ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 89ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 91ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 92ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 93ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 94ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 9532869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 96ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 97ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 9832869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 99ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 1023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1030692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 1040692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 107a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseCoprocNumOperand( 109f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 110f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseCoprocRegOperand( 111f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 112f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseMemBarrierOptOperand( 1138bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 114a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OperandMatchResultTy tryParseProcIFlagsOperand( 1158bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 116584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OperandMatchResultTy tryParseMSRMaskOperand( 1178bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes OperandMatchResultTy tryParseMemMode2Operand( 119ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 120ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes OperandMatchResultTy tryParseMemMode3Operand( 121ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 123ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 124ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 125ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 128ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 129ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 130ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 131ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 132f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach 133ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 134ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 135ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng : TargetAsmParser(), STI(_STI), Parser(_Parser) { 136ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 13732869205052430f45d598fba25ab878d8b29da2dEvan Cheng 138ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 139ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 141ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 14238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 1439898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 144ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 145ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 14616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 14716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1483a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 152146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 153762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1548462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 155d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 156fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 157fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 158cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 159706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 1608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 161584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 162a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 1638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 1650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 1660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 167e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 1680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Shifter, 1698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 171a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 17324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 174a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 175a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 176a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 181706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 182706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 183706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 184706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 185fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 186fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 187fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 188fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 189a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 190a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 191a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 192a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 193584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 194584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 195584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 196584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 201a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 203a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 204a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2058155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 206cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 207cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 20816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2096a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 211ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode; 212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2132637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar union { 2142637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar unsigned RegNum; ///< Offset register num, when OffsetIsReg. 2152637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar const MCExpr *Value; ///< Offset value, when !OffsetIsReg. 2162637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar } Offset; 217146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 2180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true 219146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true 22050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Preindexed : 1; 22150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Postindexed : 1; 22250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned OffsetIsReg : 1; 22350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Negative : 1; // only used when OffsetIsReg is true 22450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Writeback : 1; 225a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy; 229e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 2300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } Shift; 231e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 232e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 233e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 234e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 235e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 236e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } ShiftedReg; 237a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 23816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 239146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 240146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 241762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 242762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 243762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 245762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 2468462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 2478462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 2488462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 249762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 2508462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 251762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 252d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 2568d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 2570f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 2580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 25924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 2608d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 261fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 262fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 263fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 264fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 268706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 269706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 270706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 271762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 272762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 274584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 276584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 277a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 278a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 2790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 2800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson case Shifter: 2810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Shift = o.Shift; 2820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 283e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 284e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedReg = o.ShiftedReg; 285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 28816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 2958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 2968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 2978462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 2988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 299fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 300fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 301fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 302fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 303fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3106aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3145fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 31724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 320cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 321cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 322cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 323cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 324cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 325706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 326706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 327706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 328706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 329706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @name Memory Operand Accessors 3416ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @{ 342ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode getMemAddrMode() const { 343ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return Mem.AddrMode; 344ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 3456ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemBaseRegNum() const { 3466ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.BaseRegNum; 3476ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegNum() const { 3496ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3506ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.RegNum; 3516ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3526ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemOffset() const { 3536ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(!Mem.OffsetIsReg && "Invalid access!"); 3546ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.Value; 3556ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegShifted() const { 3576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.OffsetRegShifted; 3596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemShiftAmount() const { 3616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftAmount; 3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc getMemShiftType() const { 3656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftType; 3676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPreindexed() const { return Mem.Preindexed; } 3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPostindexed() const { return Mem.Postindexed; } 3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; } 3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemNegative() const { return Mem.Negative; } 3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemWriteback() const { return Mem.Writeback; } 3736ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @} 3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 376fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 377fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 3788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 379d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 3803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 3816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 3826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 3836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 3846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 3856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 3866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 3876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 3886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 3896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 3906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 3916b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 3926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 3936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 3946b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 3956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 3966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 397b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 3988d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 3990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 4000f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 40114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 402706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 40314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 4040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool isShifter() const { return Kind == Shifter; } 405e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach bool isShiftedReg() const { return Kind == ShiftedRegister; } 406ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool isMemMode2() const { 407ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode2) 408ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 409ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 410ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) 411ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 412ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 413ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemNegative() && 414ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 415ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 416ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 417ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 418ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (!CE) return false; 419ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Value = CE->getValue(); 420ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 421ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // The offset must be in the range 0-4095 (imm12). 422ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Value > 4095 || Value < -4095) 423ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 424ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 425ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 426ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 427ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool isMemMode3() const { 428ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode3) 429ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 430ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 431ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 432ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetRegShifted()) 433ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; // No shift with offset reg allowed 434ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 435ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 436ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 437ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemNegative() && 438ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 439ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 440ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 441ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 442ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (!CE) return false; 443ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Value = CE->getValue(); 444ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 445ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // The offset must be in the range 0-255 (imm8). 446ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Value > 255 || Value < -255) 447ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 448ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 449ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 450ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 45187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling bool isMemMode5() const { 4524b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || 4534b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar getMemNegative()) 45487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 455ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 4564b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 457ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 458ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 45987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling // The offset must be a multiple of 4 in the range 0-1020. 46087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling int64_t Value = CE->getValue(); 46187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); 46287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 463505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes bool isMemMode7() const { 464505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!isMemory() || 465505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPreindexed() || 466505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPostindexed() || 467505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemOffsetIsReg() || 468505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemNegative() || 469505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemWriteback()) 470505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 471505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 472505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 473505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!CE) return false; 474505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 475505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (CE->getValue()) 476505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 477505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 478505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return true; 479505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 480f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeRegThumb() const { 4814b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback()) 482f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 483d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar return true; 484f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 485f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeImmThumb() const { 4864b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback()) 487ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 488ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 4894b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 490ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 491ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 492ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // The offset must be a multiple of 4 in the range 0-124. 493ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling uint64_t Value = CE->getValue(); 494ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return ((Value & 0x3) == 0 && Value <= 124); 495ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 496584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 497a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 4983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 4993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 50014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 50114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 50214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 50314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 5043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 5053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 5063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 5073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 5083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 5098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 510345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 5118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 51204f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 51304f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 5148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 5158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 516fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 517fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 518fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 519fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 520fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 521fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 522fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 523fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 524fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 525fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 526d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 527d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 528d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 529d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 530d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 531a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 532a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 533a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 534a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 535a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 536e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach void addShiftedRegOperands(MCInst &Inst, unsigned N) const { 537e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 538e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!"); 539e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert((ShiftedReg.ShiftReg == 0 || 540e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) == 0) && 541e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "Invalid shifted register operand!"); 542e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg)); 543e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg)); 544e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 545e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm))); 546e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 547e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 5480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson void addShifterOperands(MCInst &Inst, unsigned N) const { 5490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 5500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Inst.addOperand(MCOperand::CreateImm( 5510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::getSORegOpc(Shift.ShiftTy, 0))); 5520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 5530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 55487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 5557729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 5565fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 5575fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 5587729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 5597729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 56087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 56187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 5620f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 5630f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 5640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 5650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 5660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 5670f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 5680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 5690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 5703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 5716b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 5726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 5736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 5746b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 5756b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 5766b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 5776b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 5786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 5796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 5806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 5813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 5823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 5833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 58416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 585706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 586706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 587706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 588706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 589706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 590505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes void addMemMode7Operands(MCInst &Inst, unsigned N) const { 591505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert(N == 1 && isMemMode7() && "Invalid number of operands!"); 592505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 593505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 594505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 5951866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay (void)CE; 596505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert((CE || CE->getValue() == 0) && 597505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes "No offset operand support in mode 7"); 598505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 599505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 600ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes void addMemMode2Operands(MCInst &Inst, unsigned N) const { 601ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(isMemMode2() && "Invalid mode or number of operands!"); 602ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 603ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 604ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 605ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) { 606ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 607ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 608ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 609ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; 610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t ShiftAmount = 0; 611ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 612ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetRegShifted()) { 613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc = getMemShiftType(); 614ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = 615ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes dyn_cast<MCConstantExpr>(getMemShiftAmount()); 616ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftAmount = CE->getValue(); 617ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 618ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 619ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, 620ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc, IdxMode))); 621ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return; 622ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 623ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 624ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 625ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 626ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 627ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 628ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // the difference? 629ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 630ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(CE && "Non-constant mode 2 offset operand!"); 631ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Offset = CE->getValue(); 632ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 633ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Offset >= 0) 634ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, 635ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, ARM_AM::no_shift, IdxMode))); 636ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes else 637ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, 638ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes -Offset, ARM_AM::no_shift, IdxMode))); 639ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 640ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 641ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes void addMemMode3Operands(MCInst &Inst, unsigned N) const { 642ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(isMemMode3() && "Invalid mode or number of operands!"); 643ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 644ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 645ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 646ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 647ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 648ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 649ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 650ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0, 651ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes IdxMode))); 652ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return; 653ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 654ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 655ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 656ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 657ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 658ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 659ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // the difference? 660ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 661ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(CE && "Non-constant mode 3 offset operand!"); 662ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Offset = CE->getValue(); 663ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 664ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Offset >= 0) 665ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add, 666ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Offset, IdxMode))); 667ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes else 668ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub, 669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes -Offset, IdxMode))); 670ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 671ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 67214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner void addMemMode5Operands(MCInst &Inst, unsigned N) const { 67314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 67416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 6754b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 6764b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar assert(!getMemOffsetIsReg() && "Invalid mode 5 operand"); 67792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 67880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // FIXME: #-0 is encoded differently than #0. Does the parser preserve 67980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // the difference? 6804b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 681d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert(CE && "Non-constant mode 5 offset operand!"); 682d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 683d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // The MCInst offset operand doesn't include the low two bits (like 684d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // the instruction encoding). 685d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar int64_t Offset = CE->getValue() / 4; 686d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar if (Offset >= 0) 687d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, 688d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Offset))); 689d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar else 690d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, 691d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar -Offset))); 69214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 6933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 694f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const { 695f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!"); 6964b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 6974b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 698f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 699ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 700f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const { 701f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!"); 7024b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 7034b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 704f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(CE && "Non-constant mode offset operand!"); 705f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 706ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 707ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 708584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 709584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 710584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 711584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 712584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 713a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 714a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 715a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 716a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 717a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 718b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 719b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 7203a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 7213a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 722345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 723345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 724345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 7253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 726345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 727345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 728fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 729fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 730fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 731fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 732fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 733fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 734fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 736fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 737fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 738fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 739fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 740fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 741fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 742fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 743fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 744d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 745d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 746d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 747d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 748d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 749d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 750d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 751d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 7523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 7533a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 754762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 755762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 756762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 757762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 7583a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 759a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 760a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 76150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 7623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 763762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 764762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 765762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 7663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 767a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 768a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 769e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 770e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 771e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 772e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 773e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 774e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 775e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->ShiftedReg.ShiftTy = ShTy; 776e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->ShiftedReg.SrcReg = SrcReg; 777e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->ShiftedReg.ShiftReg = ShiftReg; 778e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->ShiftedReg.ShiftImm = ShiftImm; 779e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 780e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 781e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 782e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 783e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 7840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy, 7850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 7860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARMOperand *Op = new ARMOperand(Shifter); 7870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->Shift.ShiftTy = ShTy; 7880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 7890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 7900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 7910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 7920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 7937729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 7945fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 795cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 7960f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 7970f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling if (ARM::DPRRegClass.contains(Regs.front().first)) 7990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 8000f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling else if (ARM::SPRRegClass.contains(Regs.front().first)) 8010f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 8020f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 8030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 8045fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 8057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 80624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 807cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 808cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 809cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 8108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 8118d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 8128d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 8133a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 8143a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 815762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 816762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 817762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 8183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 819cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 820cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, 822ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool OffsetIsReg, const MCExpr *Offset, 823ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int OffsetRegNum, bool OffsetRegShifted, 8240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType, 8253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *ShiftAmount, bool Preindexed, 8263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool Postindexed, bool Negative, bool Writeback, 8273a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 828023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((OffsetRegNum == -1 || OffsetIsReg) && 829023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegNum must imply OffsetIsReg!"); 830023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!OffsetRegShifted || OffsetIsReg) && 831023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegShifted must imply OffsetIsReg!"); 832d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert((Offset || OffsetIsReg) && 833d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar "Offset must exists unless register offset is used!"); 834023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) && 835023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have shift amount without shifted register offset!"); 836023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!Offset || !OffsetIsReg) && 837023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have expression offset and register offset!"); 838023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar 8393a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 840ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Op->Mem.AddrMode = AddrMode; 841762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 842762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 8432637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar if (OffsetIsReg) 8442637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.RegNum = OffsetRegNum; 8452637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar else 8462637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.Value = Offset; 847762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 848762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 849762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 850762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 851762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 852762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 853762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 85416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 855762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 856762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 8573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 858a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 859706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 860706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 861706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 862706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 863706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 864706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 865706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 866706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 867a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 868a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 869a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 870a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 871a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 872a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 874a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 875584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 876584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 877584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 878584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 879584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 880584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 881584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 882584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 883a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 884a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 885a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 886a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 887b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 888fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 889fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 8906a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 891fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 892d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 893d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 894d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 895fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 896fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 897fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 898fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 899fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 900fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 901584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 902584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 903584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 904fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 905fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 906fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 907706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 908706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 909706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 910fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 9116ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 912ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << "am:" << ARMII::AddrModeToString(getMemAddrMode()) 913ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << " base:" << getMemBaseRegNum(); 9146ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) { 9156ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:<register " << getMemOffsetRegNum(); 9166ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetRegShifted()) { 9176ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-type:" << getMemShiftType(); 9186ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-amount:" << *getMemShiftAmount(); 9196ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 9206ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } else { 9216ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:" << *getMemOffset(); 9226ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 9236ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) 9246ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (offset-is-reg)"; 9256ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPreindexed()) 9266ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (pre-indexed)"; 9276ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPostindexed()) 9286ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (post-indexed)"; 9296ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemNegative()) 9306ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (negative)"; 9316ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemWriteback()) 9326ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (writeback)"; 9336ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 934fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 935a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 936a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 937a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 938a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 939a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 940a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 941a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 942a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 943a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 944fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 94550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 946fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 9470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson case Shifter: 948e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">"; 949e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 950e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 951e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach OS << "<so_reg" 952e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ShiftedReg.SrcReg 953e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm)) 954e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ", " << ShiftedReg.ShiftReg << ", " 955e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) 956e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 9570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 9580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 9590f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 9600f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 9618d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 9628d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 9635fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 9645fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 9657729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 9667729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 9677729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 9688d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 9698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 9708d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 9718d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 9728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 973fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 974fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 975fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 976fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 977fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 9783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 9803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 9813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 9833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9843483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 9853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 98669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 98769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 988bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky RegNo = TryParseRegister(); 989bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 990bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 991bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 992bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 9939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 994e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 995e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 9963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 997e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() { 99818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 999a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1000d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1001a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1002a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 10030c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 10040c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 10050c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 10060c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 10070c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 10080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 10090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 10100c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 10110c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 10120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 10130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 10140c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 101569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1016b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1017e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1018e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1019d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 10200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// Try to parse a register name. The token must be an Identifier when called, 10210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// and if it is a register name the token is eaten and the register number is 10220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// returned. Otherwise return -1. 10230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// 10240082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::TryParseShiftRegister( 10250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 10260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 10270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 10280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 10290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 10310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 10320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 10330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 10340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 10350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 10360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 10370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 10380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 10390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 10410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return true; 10420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1043e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1044e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1045e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1046e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1047e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1048e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *PrevOp = (ARMOperand*)Operands.pop_back_val(); 1049e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1050e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1051e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1052e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1053e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1054e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1059e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1060e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1061e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1062e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1063e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1064e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 1065e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (getParser().ParseExpression(ShiftExpr)) 1066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(ImmLoc, "invalid immediate shift value"); 1067e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1068e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 1069e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!CE) 1070e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(ImmLoc, "invalid immediate shift value"); 1071e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1072e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1073e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1074e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1075e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1076e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1077e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 1078e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(ImmLoc, "immediate shift value out of range"); 1079e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1080e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 1081e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = TryParseRegister(); 1082e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 1083e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftReg == -1) 1084e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error (L, "expected immediate or register in shift operand"); 1085e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else 1086e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error (Parser.getTok().getLoc(), 1087e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 1088e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1089e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 10900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1091e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1092e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg, Imm, 10930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 10940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 10960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 10970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 10980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 109950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 110050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 110150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1102e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1103e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1104e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 110550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 110650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1107e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 1108e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int RegNo = TryParseRegister(); 1109e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 111050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1111d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 111250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1113a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1114e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1115e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 111650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 111750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1118e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 111999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 112099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 112150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1122a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1123a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1124fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1125fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1126fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1127fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1128e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1129e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1130e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1131e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1132e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1133fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1134e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1135e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1136e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1137e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1138e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1139e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1140e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1141e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1142e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1143e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1144e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1145e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1146e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1147e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1148e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1149e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1150fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1151e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1152e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1153e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1154e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1155e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1156e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1157e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1158e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1159e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1160e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1161e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1162e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1163e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1164e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1165e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1166e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1167f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The 1168fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1169fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1170f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1171f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1172e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1173e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1174e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1175e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1176fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1177e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1178f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1179e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1180e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1181fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1182f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1183fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1184fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1185f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The 1186fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1187fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1188f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1189f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1190fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1191fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1192fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1193fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1195fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1196f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1197fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1198fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1199fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1200f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1203c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1204c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 120550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 120650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 120718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1208a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1209e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 121016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 12117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 12127729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 12135fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1214d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 12157729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1216e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 12177729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1218d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 121918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1220d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1221c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1222c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 122350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1224c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1225e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 12261d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling int RegNum = TryParseRegister(); 1227c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1228c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 122950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1230c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1231d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1232e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1233e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1234e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1235e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1236e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1237e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1238e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1239e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1240e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1241e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1242e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 12437729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 12447729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1245e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1246e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 124718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1248c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1249c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 125050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1251c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1252d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1253e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1254e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 125503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1256e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 12575fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1258e717610f53e0465cde198536561a3c00ce29d59fBill Wendling RI = Registers.begin(), RE = Registers.end(); 1259e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 12607caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned HighRegNum = getARMRegisterNumbering(RI->first); 12618e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 12628e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling 12637caebff83d90a59aa74876ff887e822387f479e0Bill Wendling DenseMap<unsigned, bool> RegMap; 12647caebff83d90a59aa74876ff887e822387f479e0Bill Wendling RegMap[HighRegNum] = true; 12657caebff83d90a59aa74876ff887e822387f479e0Bill Wendling 1266e717610f53e0465cde198536561a3c00ce29d59fBill Wendling for (++RI; RI != RE; ++RI) { 12677729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling const std::pair<unsigned, SMLoc> &RegInfo = *RI; 12687caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1269e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 12708e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1271e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 127250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1273e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1274e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 12758e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1276e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1277e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1278e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 12798e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling RegMap[Reg] = true; 12808e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1281e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1282e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 128350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 128450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1285d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1286d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1287f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1288f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1289f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1290706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1291706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1292706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1293706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1294706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1295706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1296706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1297706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1298706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1299706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1300706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1301706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1302706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1303706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1304706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1305706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1306706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1307f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1308706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1309706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1310706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1311f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1312706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1313706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 13148bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1315a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1317a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1324a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1325a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1335a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1336a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1337a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1338a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1339a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1340a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1341584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1342584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1343584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1344584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1345584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1346584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1347584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1348584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1349584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1350584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1351584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1352584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1353584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1354584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef SpecReg = Mask.slice(Start, Next); 1355584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1356584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1357584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1358584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1359584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1360584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1361584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1362584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1363584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1364584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1365584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvq", 0x8) // same as CPSR_c 1366584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1367584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1368584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1369584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 13704b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1371584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1372584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1373584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1374584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 13754b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1376584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 137756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 137856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1379584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1380584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1381584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1382584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1383584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1384584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1385584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1386584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1387584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1388584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1389584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1390584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1391584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1392584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1393584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1394584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1395584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1396584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1397584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1398584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1399584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1400584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1401584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1402584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1403584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1404584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1405584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1406584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1407a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1408a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1409ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand. 1410ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1411ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1412e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1413ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1414ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode2)) 1415ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_NoMatch; 1416ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1417ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_Success; 1418ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1419ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1420ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand. 1421ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1422ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1423ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1424ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1425ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode3)) 1426ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_NoMatch; 1427ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1428ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_Success; 1429ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1430ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1431ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1432ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1433ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1434ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1435ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1436ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1437ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1438ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1439ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1440ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1441ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1442ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1443ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1444ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1445ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1446ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1447ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1448ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1449ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1450ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1451ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1452ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1453ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1454ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1455ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1456ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1457ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1458ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1459ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1460ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1461ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1462ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1463ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1464ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1465ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1466ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1467ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1468ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1469ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1470ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1471ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1472ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1473ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1474ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1475ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1476ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1477ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1478ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1479ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1480ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1481ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1482ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1483ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1484ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1485ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1486ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1487ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1488ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1489ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1490ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1491e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 14929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 149350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// 14949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 14959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 149650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 1497ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1498ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { 1499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 150018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 1501a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 1502762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1503b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 1504a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 150518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 1506550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (BaseRegTok.isNot(AsmToken::Identifier)) { 1507550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 150850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1510e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int BaseRegNum = TryParseRegister(); 1511e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (BaseRegNum == -1) { 1512550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 151350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1514550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1515a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 15160571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 15170571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 15180571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 15190571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar return true; 15200571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 1521a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 1522a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 1523a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 1524a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 1525a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 152605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar ARMOperand *WBOp = 0; 152705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar int OffsetRegNum = -1; 152805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar bool OffsetRegShifted = false; 15290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl; 153005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *ShiftAmount = 0; 153105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *Offset = 0; 1532a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 15339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 15349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 1535a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 1536a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 1537b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 153805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1539550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 1540550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 154150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 154218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 1543550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 1544550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 154550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1546550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1547762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 1548b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 155018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 1551a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 1552ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // None of addrmode3 instruction uses "!" 1553ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3) 1554ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1555ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 155650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling WBOp = ARMOperand::CreateToken(ExclaimTok.getString(), 155750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc()); 1558a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 1559b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 1560ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } else { // In addressing mode 2, pre-indexed mode always end with "!" 1561ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (AddrMode == ARMII::AddrMode2) 1562ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Preindexed = false; 1563a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 15640571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar } else { 15650571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The "[Rn" we have so far was not followed by a comma. 15660571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 156780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // If there's anything other than the right brace, this is a post indexing 156880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // addressing form. 1569762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 1570b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1571a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 157218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 157303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1574e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 157580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Postindexed = true; 157680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Writeback = true; 157750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1578550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 1579550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 158050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1581550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 158250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1583b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 158450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1585550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 158616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 1587550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 158850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1589a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 159005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar } 1591e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 159205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar // Force Offset to exist if used. 159305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!OffsetIsReg) { 159405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!Offset) 159505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Offset = MCConstantExpr::Create(0, getContext()); 1596ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } else { 1597ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) { 1598ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Error(E, "shift amount not supported"); 1599ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1600ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1601a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 160205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1603ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, 1604ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, OffsetRegNum, OffsetRegShifted, 1605ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftType, ShiftAmount, Preindexed, 1606ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Postindexed, Negative, Writeback, S, E)); 160705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (WBOp) 160805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Operands.push_back(WBOp); 160905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 161005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar return false; 1611a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1612a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 16139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 16149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 16159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 16169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 16179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 16189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 16199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 16209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 1621762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 16220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 16239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 16249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 16259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 1626762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 1627762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 16289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 16299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 16309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 16319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 163218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 1633762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 16349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 1635b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 16369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 16379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 1638b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 16399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 16409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 164118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 16429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 1643e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc CurLoc = OffsetRegTok.getLoc(); 1644e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner OffsetRegNum = TryParseRegister(); 1645e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (OffsetRegNum != -1) { 1646550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 1647e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner E = CurLoc; 1648762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 16499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 1650d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 165112f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling // If we parsed a register as the offset then there can be a shift after that. 16529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 16539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 165418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 16559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 1656b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 16579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 165818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1659762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 16603472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 16619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 16629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 16639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 16649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 16659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 166618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 16679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 16689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 166916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1670b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 16719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 16729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 16739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 1674762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 16759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 16769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 16779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 16789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 1679a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 1680a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 1681a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 1682a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 16830082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St, 16840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E) { 168518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1686a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 1687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 168838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 1689a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 16900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 1691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 16920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 1693a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 16940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 1695a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 16960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 1697a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 16980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 1699a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 1700a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 1701b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 1702a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 17039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 17040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (St == ARM_AM::rrx) 17059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 1706a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 17079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 170818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 17099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 17109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 1711b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 17129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 17139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 17149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 1715a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1716a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 1717a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1718a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 17199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 17209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 1721e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1722fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 1723762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 1724fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1725fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 1726fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 1727f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1728f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 1729fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 1730f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 1731f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 1732f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 1733f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 1734f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 1735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1736a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 1737146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 1738146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 173950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 174067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Identifier: 174150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling if (!TryParseRegisterWithWriteBack(Operands)) 174250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 17430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (!TryParseShiftRegister(Operands)) 17440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 17450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1746e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1747e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 1748e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 174967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 175067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 1751515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 1752515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 1753515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 1754762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1755515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 175650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1757762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 175850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 175950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 176050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 1761a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 176250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseMemory(Operands); 1763d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 176450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseRegisterList(Operands); 1765d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 1766079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 1767079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 1768762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1769b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 1770515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 1771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 177250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1773762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 177450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 177550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 17769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 17779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 17787597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 17797597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 17807597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 17819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (ParsePrefix(RefKind)) 17829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 17839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17847597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 17857597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 17869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 17879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17887597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 17897597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 17909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 17917597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 17929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 17939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 1794a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1795a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1796a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 17977597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 17987597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 17997597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) { 18007597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 18019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 18038a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 18049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 18059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 18079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 18089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 18099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 18109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 18129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 18137597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 18149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 18157597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 18169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 18179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 18189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 18199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 18209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 18219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 18239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 18249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 18259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 18269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 18279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 18289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 18299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 18319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E, 18329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 18339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 18349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 18359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 18369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 18379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 18399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 18409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 18419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 18429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 18439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 18459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 18469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 18489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 18499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 18519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 18529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 18549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 18559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 18579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 18589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant); 18599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 18609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 18619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 18629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 18649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 18659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 18669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 18679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 18689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 18699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 18709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 1871352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 1872352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 1873352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 1874badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 1875a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopesstatic StringRef SplitMnemonic(StringRef Mnemonic, 1876a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned &PredicationCode, 1877a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool &CarrySetting, 1878a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned &ProcessorIMod) { 1879352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 1880352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 1881a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 1882352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 1883badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 1884352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 1885352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 18868ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar if (Mnemonic == "teq" || Mnemonic == "vceq" || 18878ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "movs" || 18888ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "svc" || 18898ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 18908ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vmls" || Mnemonic == "vnmls") || 18918ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vacge" || Mnemonic == "vcge" || 18928ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vclt" || 18938ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vacgt" || Mnemonic == "vcgt" || 18948ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vcle" || 18958ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" || 18968ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" || 1897d1f0bbee189ea7cd18d03c4f9f55d0a33b070814Jim Grosbach Mnemonic == "vqdmlal" || Mnemonic == "bics")) 1898352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 1899badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 19003f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 19013f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 19023f00e317064560ad11168d22030416d853829f6eJim Grosbach if (Mnemonic != "adcs") { 19033f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 19043f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 19053f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 19063f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 19073f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 19083f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 19093f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 19103f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 19113f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 19123f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 19133f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 19143f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 19153f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 19163f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 19173f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 19183f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 19193f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 19203f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 19213f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 19223f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 19233f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 19243f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 19253f00e317064560ad11168d22030416d853829f6eJim Grosbach } 192652925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 1927345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1928352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 1929352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 1930352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 1931352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 1932352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" || 1933352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" || 1934352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" || 1935352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) { 1936352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 1937352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 1938352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 1939352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 1940a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 1941a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 1942a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 1943a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 1944a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 1945a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 1946a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 1947a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 1948a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1949a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 1950a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 1951a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 1952a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1953a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1954a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1955352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 1956352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 19573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 19583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 19593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 19603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 19613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 1962fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 1963fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 1964fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 1965eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 1966eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 1967eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 1968eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 1969be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 1970eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 1971eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 1972be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "eor" || Mnemonic == "smlal" || 1973ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 1974eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 1975eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 1976eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 1977eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 19783771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 1979eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 1980eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 1981eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 1982eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 1983e47f3751d7770916f250a00a84316d412e959c00Bruno Cardoso Lopes Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" || 1984a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic == "clrex" || Mnemonic.startswith("cps")) { 19853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 19863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 19873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 19883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 1989fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 1990ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 1991fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 199263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 1993fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 1994badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 1995badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 1996badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 1997badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 1998badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1999badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 2000badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 2001badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar StringRef Head = Name.slice(Start, Next); 2002badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2003352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 2004352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 2005a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 2006352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 2007a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Head = SplitMnemonic(Head, PredicationCode, CarrySetting, 2008a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod); 2009badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 20103a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 20119717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 20123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 20133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 20143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 20153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 20163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 20173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 20183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 20193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 20203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode); 20213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 20223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 20233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 20243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 20253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 20263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 20273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptCarrySet) { 20283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 20293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 20303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 20313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // This mnemonic can't ever accept a carry set, but the user wrote one (or 20323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // misspelled another mnemonic). 20333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 20343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: Issue a nice error. 20353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 20363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 20373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 20383771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 20393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 20403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 20413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 20423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // This mnemonic can't ever accept a predication code, but the user wrote 20433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // one (or misspelled another mnemonic). 20443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 20453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: Issue a nice error. 2046badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 2047345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2048a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 2049a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 2050a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 2051a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 2052a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 2053a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 2054a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 2055a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 2056a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2057a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 2058a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2059a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2060345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 20615747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 20625747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 20635747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 2064a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 2065a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2066a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 20675747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 20685747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 20695747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 20705747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 2071a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 2072fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (ParseOperand(Operands, Head)) { 2073cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2074cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2075cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2076a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2077a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 2078b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 2079a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2080a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 2081fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (ParseOperand(Operands, Head)) { 2082cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2083cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2084cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2085a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2086a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 208716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2088cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2089cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 209034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 2091cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2092146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 209334e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 20949898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 2095ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2096ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2097fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 2098fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 2099fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2100fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 2101fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 2102fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 2103193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResultTy MatchResult, MatchResult2; 2104193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2105193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult != Match_Success) { 2106193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // If we get a Match_InvalidOperand it might be some arithmetic instruction 2107193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // that does not update the condition codes. So try adding a CCOut operand 2108193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // with a value of reg0. 2109193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult == Match_InvalidOperand) { 2110193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.insert(Operands.begin() + 1, 2111193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateCCOut(0, 2112193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ((ARMOperand*)Operands[0])->getStartLoc())); 2113193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2114193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult2 == Match_Success) 2115193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = Match_Success; 211644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby else { 211744a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 2118193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.erase(Operands.begin() + 1); 211944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete CCOut; 212044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby } 2121193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2122193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // If we get a Match_MnemonicFail it might be some arithmetic instruction 2123193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // that updates the condition codes if it ends in 's'. So see if the 2124193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut 2125193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // operand with a value of CPSR. 2126eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng else if (MatchResult == Match_MnemonicFail) { 2127193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // Get the instruction mnemonic, which is the first token. 2128193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken(); 2129193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (Mnemonic.substr(Mnemonic.size()-1) == "s") { 2130193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // removed the 's' from the mnemonic for matching. 2131193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1); 2132193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc(); 213344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 213444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin()); 213544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete OldMnemonic; 213644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.insert(Operands.begin(), 2137193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateToken(MnemonicNoS, NameLoc)); 2138193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.insert(Operands.begin() + 1, 2139193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateCCOut(ARM::CPSR, NameLoc)); 2140193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2141193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult2 == Match_Success) 2142193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = Match_Success; 2143193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby else { 214444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 214544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin()); 214644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete OldMnemonic; 214744a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.insert(Operands.begin(), 2148193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateToken(Mnemonic, NameLoc)); 214944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 215044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin() + 1); 215144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete CCOut; 2152193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2153193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2154193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2155193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2156193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 2157e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 2158fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 2159fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 2160e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 2161e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2162e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 2163e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 2164e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 2165e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 2166e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 2167e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 216816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2169e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2170e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2171e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 217216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2173e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 2174e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 2175e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 2176e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 2177b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 2178b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 2179fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 218016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2181c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 2182146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 2183fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 2184fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 2185515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 2186ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2187ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 2188ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 2189ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 2190515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 2191515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 2192515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 2193515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 2194515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 2195515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 2196515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 2197515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 2198ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2199ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2200ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2201ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 2202ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 2203ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 2204ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 2205ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 2206ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 2207ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 2208ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2209ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2210aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2211ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2212ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 2213ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 221416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2215ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 2216ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 2217ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 2218b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2219ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2220ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2221ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2222b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2223ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 2224ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2225ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2226515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 2227515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 2228515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 2229515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2230515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2231b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2232515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2233515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 2234515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 2235515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2236515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2237515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2238515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2239515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 2240515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 2241515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 22426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 22436469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 22446469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 22456469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 22466469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 22476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 22486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 22496469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 22506469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 22516469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 22526469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 22536469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 22546469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 22556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2256515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2257515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2258b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2259515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 22606469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 22616469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 22626469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 22636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 22646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 2265642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 2266642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2267642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 2268515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2269515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2270515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2271515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 2272515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 2273515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 227418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2275515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2276515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 227738e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 227858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 2279b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 228058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 22819e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 2282515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2283515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 2284515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2285515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 228618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2287b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2288515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2289515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 2290515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2291515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2292515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2293515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2294515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 2295515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 2296515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 229718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2298515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 2299515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 230018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 230158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 2302b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 230358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 2304b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2305515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2306515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 2307515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2308515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 230918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2310b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2311515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 231232869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 2313ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if (!isThumb()) 2314ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 23152a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 231632869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 2317ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if (isThumb()) 2318ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 23192a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2320eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 23212a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 2322515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2323515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2324515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 232590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 232690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 23279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 2328ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 2329ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 2330ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 233190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 2332ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 23333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 23340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 23350692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 23363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 2337