ARMAsmParser.cpp revision ac79e4c82f201c30a06c2cd05baebd20f5b49888
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" 18642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 21ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 22ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 23ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h" 24c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 25fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 270c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 28345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 30ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 31ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 323a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 33146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 34146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 3516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser { 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 38d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar TargetMachine &TM; 39ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 40ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 41ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 46e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int TryParseRegister(); 47bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 4850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 5050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 51ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &, 52ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode); 53fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 547597212abced110723f2fee985a7d60557c092ecEvan Cheng bool ParsePrefix(ARMMCExpr::VariantKind &RefKind); 559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *ApplyPrefixToExpr(const MCExpr *E, 569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 58a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 65762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 66762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E); 670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool ParseShift(enum ARM_AM::ShiftOpc &St, 680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E); 69ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 70515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 71515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 72515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 73515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 757036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner bool MatchAndEmitInstruction(SMLoc IDLoc, 767c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 77fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out); 78fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 79fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 8016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 81a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 82a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 840692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 850692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 86a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 87a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 88a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 89f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseCoprocNumOperand( 90f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 91f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseCoprocRegOperand( 92f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 93f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy tryParseMemBarrierOptOperand( 948bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 95a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OperandMatchResultTy tryParseProcIFlagsOperand( 968bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 97584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OperandMatchResultTy tryParseMSRMaskOperand( 988bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 99ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes OperandMatchResultTy tryParseMemMode2Operand( 100ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 101ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes OperandMatchResultTy tryParseMemMode3Operand( 102ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 103ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 104ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 105ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 106ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 107ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 108ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 109ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 110ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 111ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 112ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 113f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach 114ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 115d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) 116833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach : TargetAsmParser(T), Parser(_Parser), TM(_TM) { 117833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach // Initialize the set of available features. 118833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach setAvailableFeatures(ComputeAvailableFeatures( 119833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach &TM.getSubtarget<ARMSubtarget>())); 120833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach } 121ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 12238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 1239898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 124ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 125ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 12616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 12716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1283a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 132146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 133762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1348462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 135d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 136fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 137fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 138cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 139706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 1408462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 141584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 142a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 1438462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1448d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 1450f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 1460f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 1470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Shifter, 1488462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 149a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 151762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 15224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 153a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 154a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 155a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1568462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1578462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1588462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 160706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 161706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 162706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 163706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 165fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 166fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 167fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 168a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 169a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 170a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 171a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 172584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 173584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 174584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 175584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 176a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 177a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 178a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 180a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 181a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1848155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 185cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 186cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 18716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1886a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 189a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 190ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode; 191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 1922637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar union { 1932637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar unsigned RegNum; ///< Offset register num, when OffsetIsReg. 1942637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar const MCExpr *Value; ///< Offset value, when !OffsetIsReg. 1952637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar } Offset; 196146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 1970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true 198146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true 19950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Preindexed : 1; 20050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Postindexed : 1; 20150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned OffsetIsReg : 1; 20250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Negative : 1; // only used when OffsetIsReg is true 20350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling unsigned Writeback : 1; 204a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy; 2080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson unsigned RegNum; 2090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } Shift; 210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 21116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 212146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 213146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 214762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 215762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 216762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 217762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 218762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 2198462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 2208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 2218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 222762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 2238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 224762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 225d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 226762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 227762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 228762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 2298d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 2300f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 2310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 23224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 2338d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 234fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 235fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 236fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 237fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 238762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 239762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 240762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 241706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 242706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 243706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 245762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 246762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 247584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 248584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 249584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 250a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 251a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 2520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 2530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson case Shifter: 2540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Shift = o.Shift; 2550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 25816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 259762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 260762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 263a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 2658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 2668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 2678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 2688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 269fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 270fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 271fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 272fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 273fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 275a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 276a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 279a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 2806aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 2817729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 282a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2845fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 2850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 2860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 28724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 2888d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 2898d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 290cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 291cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 292cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 293cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 294cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 295706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 296706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 297706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 298706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 299706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 300a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 301a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 302a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 303a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 304a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 308584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 309584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 3106ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @name Memory Operand Accessors 3116ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @{ 312ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode getMemAddrMode() const { 313ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return Mem.AddrMode; 314ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 3156ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemBaseRegNum() const { 3166ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.BaseRegNum; 3176ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3186ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegNum() const { 3196ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3206ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.RegNum; 3216ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3226ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemOffset() const { 3236ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(!Mem.OffsetIsReg && "Invalid access!"); 3246ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.Offset.Value; 3256ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3266ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar unsigned getMemOffsetRegShifted() const { 3276ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && "Invalid access!"); 3286ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.OffsetRegShifted; 3296ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3306ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar const MCExpr *getMemShiftAmount() const { 3316ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3326ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftAmount; 3336ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc getMemShiftType() const { 3356ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!"); 3366ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar return Mem.ShiftType; 3376ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 3386ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPreindexed() const { return Mem.Preindexed; } 3396ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemPostindexed() const { return Mem.Postindexed; } 3406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; } 3416ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemNegative() const { return Mem.Negative; } 3426ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar bool getMemWriteback() const { return Mem.Writeback; } 3436ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 3446ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar /// @} 3456ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar 346fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 347fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 3488462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 349d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 3503483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 351b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 3528d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 3530f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 3540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 35514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 356706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 35714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 3580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson bool isShifter() const { return Kind == Shifter; } 359ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool isMemMode2() const { 360ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode2) 361ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 362ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 363ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) 364ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 365ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 366ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemNegative() && 367ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 368ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 369ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 370ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 371ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (!CE) return false; 372ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Value = CE->getValue(); 373ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 374ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // The offset must be in the range 0-4095 (imm12). 375ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Value > 4095 || Value < -4095) 376ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 377ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 378ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 379ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 380ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes bool isMemMode3() const { 381ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemAddrMode() != ARMII::AddrMode3) 382ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 383ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 384ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 385ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetRegShifted()) 386ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; // No shift with offset reg allowed 387ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 388ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 389ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 390ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemNegative() && 391ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes !(getMemPostindexed() || getMemPreindexed())) 392ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 393ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 394ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 395ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (!CE) return false; 396ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Value = CE->getValue(); 397ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 398ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // The offset must be in the range 0-255 (imm8). 399ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Value > 255 || Value < -255) 400ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 401ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 402ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 403ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 40487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling bool isMemMode5() const { 4054b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() || 4064b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar getMemNegative()) 40787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 408ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 4094b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 410ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 411ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 41287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling // The offset must be a multiple of 4 in the range 0-1020. 41387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling int64_t Value = CE->getValue(); 41487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); 41587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 416505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes bool isMemMode7() const { 417505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!isMemory() || 418505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPreindexed() || 419505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemPostindexed() || 420505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemOffsetIsReg() || 421505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemNegative() || 422505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes getMemWriteback()) 423505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 424505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 425505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 426505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (!CE) return false; 427505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 428505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes if (CE->getValue()) 429505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return false; 430505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 431505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return true; 432505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 433f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeRegThumb() const { 4344b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback()) 435f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 436d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar return true; 437f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 438f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling bool isMemModeImmThumb() const { 4394b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar if (!isMemory() || getMemOffsetIsReg() || getMemWriteback()) 440ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 441ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 4424b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 443ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 444ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 445ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling // The offset must be a multiple of 4 in the range 0-124. 446ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling uint64_t Value = CE->getValue(); 447ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return ((Value & 0x3) == 0 && Value <= 124); 448ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 449584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 450a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 4513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 4523483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 45314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 45414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 45514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 45614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 4573483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 4583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 4593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 4603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 4613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 4628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 463345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 4648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 46504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 46604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 4678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 4688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 469fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 470fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 471fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 472fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 473fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 474fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 475fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 476fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 477fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 478fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 479d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 480d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 481d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 482d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 483d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 485a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 486a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson void addShifterOperands(MCInst &Inst, unsigned N) const { 4900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 4910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Inst.addOperand(MCOperand::CreateImm( 4920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::getSORegOpc(Shift.ShiftTy, 0))); 4930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 4940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 49587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 4967729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 4975fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 4985fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 4997729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 5007729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 50187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 50287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 5030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 5040f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 5050f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 5060f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 5070f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 5080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 5090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 5100f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 5113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 5123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 5133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 5143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 51516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 516706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 517706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 518706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 519706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 520706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 521505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes void addMemMode7Operands(MCInst &Inst, unsigned N) const { 522505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert(N == 1 && isMemMode7() && "Invalid number of operands!"); 523505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 524505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 525505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 5261866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay (void)CE; 527505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes assert((CE || CE->getValue() == 0) && 528505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes "No offset operand support in mode 7"); 529505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 530505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 531ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes void addMemMode2Operands(MCInst &Inst, unsigned N) const { 532ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(isMemMode2() && "Invalid mode or number of operands!"); 533ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 534ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 535ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 536ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetIsReg()) { 537ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 538ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 539ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 540ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift; 541ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t ShiftAmount = 0; 542ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 543ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (getMemOffsetRegShifted()) { 544ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc = getMemShiftType(); 545ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = 546ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes dyn_cast<MCConstantExpr>(getMemShiftAmount()); 547ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftAmount = CE->getValue(); 548ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 549ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 550ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount, 551ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShOpc, IdxMode))); 552ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return; 553ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 554ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 555ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 556ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 557ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 558ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 559ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // the difference? 560ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 561ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes assert(CE && "Non-constant mode 2 offset operand!"); 562ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int64_t Offset = CE->getValue(); 563ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 564ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (Offset >= 0) 565ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add, 566ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, ARM_AM::no_shift, IdxMode))); 567ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes else 568ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub, 569ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes -Offset, ARM_AM::no_shift, IdxMode))); 570ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 571ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 572ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes void addMemMode3Operands(MCInst &Inst, unsigned N) const { 573ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(isMemMode3() && "Invalid mode or number of operands!"); 574ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 575ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1); 576ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 577ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (getMemOffsetIsReg()) { 578ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 579ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 580ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add; 581ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0, 582ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes IdxMode))); 583ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return; 584ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 585ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 586ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a operand placeholder to always yield the same number of operands. 587ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateReg(0)); 588ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 589ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // FIXME: #-0 is encoded differently than #0. Does the parser preserve 590ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // the difference? 591ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 592ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(CE && "Non-constant mode 3 offset operand!"); 593ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes int64_t Offset = CE->getValue(); 594ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 595ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (Offset >= 0) 596ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add, 597ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Offset, IdxMode))); 598ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes else 599ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub, 600ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes -Offset, IdxMode))); 601ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 602ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 60314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner void addMemMode5Operands(MCInst &Inst, unsigned N) const { 60414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 60516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 6064b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 6074b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar assert(!getMemOffsetIsReg() && "Invalid mode 5 operand"); 60892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 60980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // FIXME: #-0 is encoded differently than #0. Does the parser preserve 61080eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // the difference? 6114b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 612d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert(CE && "Non-constant mode 5 offset operand!"); 613d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 614d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // The MCInst offset operand doesn't include the low two bits (like 615d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar // the instruction encoding). 616d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar int64_t Offset = CE->getValue() / 4; 617d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar if (Offset >= 0) 618d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, 619d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Offset))); 620d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar else 621d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, 622d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar -Offset))); 62314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 6243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 625f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const { 626f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!"); 6274b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 6284b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum())); 629f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 630ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 631f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const { 632f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!"); 6334b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum())); 6344b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset()); 635f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling assert(CE && "Non-constant mode offset operand!"); 636f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 637ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 638ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 639584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 640584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 641584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 642584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 643584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 644a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 645a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 646a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 647a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 648a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 649fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar virtual void dump(raw_ostream &OS) const; 650b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 6513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 6523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 653345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 654345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 655345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 6563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 657345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 658345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 659fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 660fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 661fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 662fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 663fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 664fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 665fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 666fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 667fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 668fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 669fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 670fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 671fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 672fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 673fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 674fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 675d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 676d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 677d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 678d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 679d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 680d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 681d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 682d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 6833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 6843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 685762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 686762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 687762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 688762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 6893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 690a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 69250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 6933a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 694762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 695762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 696762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 6973a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 698a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 699a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy, 7010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 7020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARMOperand *Op = new ARMOperand(Shifter); 7030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->Shift.ShiftTy = ShTy; 7040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 7050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 7060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 7070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 7080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 7097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 7105fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 711cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 7120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 7130f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7140f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling if (ARM::DPRRegClass.contains(Regs.front().first)) 7150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 7160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling else if (ARM::SPRRegClass.contains(Regs.front().first)) 7170f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 7180f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7190f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 7205fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 7217729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 72224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 723cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 724cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 725cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 7268d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 7278d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 7288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 7293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 7303a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 731762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 732762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 733762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 7343a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 735cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 736cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 737ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum, 738ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes bool OffsetIsReg, const MCExpr *Offset, 739ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes int OffsetRegNum, bool OffsetRegShifted, 7400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType, 7413a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *ShiftAmount, bool Preindexed, 7423a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool Postindexed, bool Negative, bool Writeback, 7433a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 744023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((OffsetRegNum == -1 || OffsetIsReg) && 745023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegNum must imply OffsetIsReg!"); 746023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!OffsetRegShifted || OffsetIsReg) && 747023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "OffsetRegShifted must imply OffsetIsReg!"); 748d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar assert((Offset || OffsetIsReg) && 749d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar "Offset must exists unless register offset is used!"); 750023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) && 751023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have shift amount without shifted register offset!"); 752023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar assert((!Offset || !OffsetIsReg) && 753023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar "Cannot have expression offset and register offset!"); 754023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar 7553a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 756ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Op->Mem.AddrMode = AddrMode; 757762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 758762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 7592637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar if (OffsetIsReg) 7602637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.RegNum = OffsetRegNum; 7612637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar else 7622637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar Op->Mem.Offset.Value = Offset; 763762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 764762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 765762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 766762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 767762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 768762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 769762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 77016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 771762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 772762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 7733a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 774a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 775706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 776706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 777706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 778706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 779706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 780706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 781706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 782706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 783a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 784a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 785a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 786a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 787a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 788a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 789a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 790a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 791584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 792584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 793584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 794584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 795584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 796584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 797584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 798584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 799a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 800a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 801a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 802a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 803fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const { 804fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 805fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 8066a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 807fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 808d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 809d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 810d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 811fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 812fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 813fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 814fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 815fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 816fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 817584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 818584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 819584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 820fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 821fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 822fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 823706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 824706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 825706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 826fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 8276ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 828ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << "am:" << ARMII::AddrModeToString(getMemAddrMode()) 829ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes << " base:" << getMemBaseRegNum(); 8306ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) { 8316ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:<register " << getMemOffsetRegNum(); 8326ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetRegShifted()) { 8336ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-type:" << getMemShiftType(); 8346ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset-shift-amount:" << *getMemShiftAmount(); 8356ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 8366ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } else { 8376ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " offset:" << *getMemOffset(); 8386ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar } 8396ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemOffsetIsReg()) 8406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (offset-is-reg)"; 8416ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPreindexed()) 8426ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (pre-indexed)"; 8436ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemPostindexed()) 8446ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (post-indexed)"; 8456ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemNegative()) 8466ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (negative)"; 8476ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar if (getMemWriteback()) 8486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << " (writeback)"; 8496ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 850fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 851a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 852a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 853a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 854a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 855a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 856a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 857a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 858a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 859a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 860fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 86150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 862fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 8630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson case Shifter: 8640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson OS << "<shifter " << getShiftOpcStr(Shift.ShiftTy) << ">"; 8650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 8660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 8670f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 8680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 8698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 8708d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 8715fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 8725fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 8737729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 8747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 8757729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 8768d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 8778d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 8788d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 8798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 8808d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 881fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 882fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 883fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 884fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 885fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 8863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 8873483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 8883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 8893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 8903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 8913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 8923483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 8933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 89469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 89569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 896bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky RegNo = TryParseRegister(); 897bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 898bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 899bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 900bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 9019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 902e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 903e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 9043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 905e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() { 90618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 907a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 908d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 909a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 910a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 9110c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 9120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 9130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 9140c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 9150c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 9160c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 9170c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 9180c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 9190c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 9200c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 9210c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 9220c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 92369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 924b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 925e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 926e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 927d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 9280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// Try to parse a register name. The token must be an Identifier when called, 9290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// and if it is a register name the token is eaten and the register number is 9300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// returned. Otherwise return -1. 9310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// 9320082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::TryParseShiftRegister( 9330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 9340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 9350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 9360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 9370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 9380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 9390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 9400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 9410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 9420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 9430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 9440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 9450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 9460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 9470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 9480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 9490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return true; 9500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 9510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Parser.Lex(); // Eat shift-type operand; 9520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson int RegNum = TryParseRegister(); 9530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (RegNum == -1) 9540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Error(Parser.getTok().getLoc(), "register expected"); 9550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 9560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Operands.push_back(ARMOperand::CreateReg(RegNum,S, Parser.getTok().getLoc())); 9570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Operands.push_back(ARMOperand::CreateShifter(ShiftTy, 9580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 9590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 9600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 9610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 9620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 9630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 96450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 96550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 96650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 967e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 968e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 969e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 97050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 97150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 972e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 973e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int RegNo = TryParseRegister(); 974e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 97550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 976d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 97750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 978a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 979e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 980e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 98150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 98250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 983e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 98499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 98599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 98650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 987a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 988a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 989fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 990fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 991fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 992fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 993e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 994e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 995e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 996e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 997e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 998fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 999e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1000e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1001e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1002e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1003e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1004e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1005e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1006e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1007e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1008e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1009e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1010e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1011e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1012e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1013e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1014e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1015fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1016e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1017e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1018e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1019e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1020e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1021e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1022e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1023e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1024e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1025e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1026e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1027e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1028e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1029e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1030e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1031e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1032f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The 1033fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1035f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1036f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1037e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1038e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1039e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1040e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1041fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1042e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1043f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1044e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1045e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1046fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1047f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1048fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1049fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1050f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The 1051fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1052fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1053f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1054f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1055fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1056fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1057fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1058fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1059fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1060fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1061f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1062fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1063fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1064fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1065f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1066e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1067e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1068c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1069c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 107050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 107150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 107218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1073a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1074e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 107516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 10767729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 10777729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 10785fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1079d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 10807729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1081e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 10827729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1083d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 108418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1085d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1086c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1087c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 108850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1089c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1090e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 10911d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling int RegNum = TryParseRegister(); 1092c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1093c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 109450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1095c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1096d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1097e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1098e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1099e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1100e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1101e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1102e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1103e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1104e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1105e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1106e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1107e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 11087729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 11097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1110e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1111e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 111218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1113c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1114c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 111550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1116c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1117d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1118e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1119e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 112003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1121e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 11225fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1123e717610f53e0465cde198536561a3c00ce29d59fBill Wendling RI = Registers.begin(), RE = Registers.end(); 1124e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 11257caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned HighRegNum = getARMRegisterNumbering(RI->first); 11268e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 11278e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling 11287caebff83d90a59aa74876ff887e822387f479e0Bill Wendling DenseMap<unsigned, bool> RegMap; 11297caebff83d90a59aa74876ff887e822387f479e0Bill Wendling RegMap[HighRegNum] = true; 11307caebff83d90a59aa74876ff887e822387f479e0Bill Wendling 1131e717610f53e0465cde198536561a3c00ce29d59fBill Wendling for (++RI; RI != RE; ++RI) { 11327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling const std::pair<unsigned, SMLoc> &RegInfo = *RI; 11337caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1134e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 11358e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1136e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 113750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1138e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1139e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 11408e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1141e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1142e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1143e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 11448e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling RegMap[Reg] = true; 11458e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1146e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1147e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 114850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 114950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1150d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1151d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1152f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1153f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1154f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1155706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1156706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1157706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1158706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1159706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1160706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1161706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1162706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1163706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1164706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1165706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1166706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1167706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1168706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1169706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1170706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1171706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1172f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1173706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1174706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1175706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1176f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1177706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1178706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 11798bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1180a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1181a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1182a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1183a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1184a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1185a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1186a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1187a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1188a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1189a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1190a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1191a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1192a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1193a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1194a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1195a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1196a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1197a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1198a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1199a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1201a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1202a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1203a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1205a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1206584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1207584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1208584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1209584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1210584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1211584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1212584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1213584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1214584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1215584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1216584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1217584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1218584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1219584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef SpecReg = Mask.slice(Start, Next); 1220584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1221584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1222584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1223584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1224584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1225584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1226584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1227584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1228584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1229584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1230584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvq", 0x8) // same as CPSR_c 1231584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1232584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1233584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1234584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 12354b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1236584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1238584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 12404b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1241584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 1242584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1243584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1244584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1245584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1246584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1247584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1248584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1249584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1250584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1251584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1252584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1253584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1254584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1255584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1256584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1257584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1258584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1259584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1260584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1261584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1262584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1263584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1264584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1265584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1266584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1267584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1268584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1269584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1270a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1271a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1272ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand. 1273ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1274ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1275e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1276ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1277ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode2)) 1278ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_NoMatch; 1279ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1280ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return MatchOperand_Success; 1281ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1282ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1283ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand. 1284ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1285ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1286ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\""); 1287ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1288ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (ParseMemory(Operands, ARMII::AddrMode3)) 1289ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_NoMatch; 1290ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1291ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return MatchOperand_Success; 1292ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1293ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1294ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1295ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1296ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1297ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1298ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1299ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1300ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1301ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1302ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1303ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1304ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1305ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1306ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1307ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1308ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1309ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1310ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 1311ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1312ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1313ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 1314ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 1315ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1316ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 1317ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1318ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1319ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3); 1320ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1321ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 1322ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 1323ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 1324ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1325ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1326ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1327ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1328ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1329ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1330ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1331ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1332ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1333ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1334ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1335ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1336ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1337ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1338ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1339ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1340ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 1341ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 1342ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 1343ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 1344ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1345ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1346ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 1347ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 1348ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 1349ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3); 1350ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 1351ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1352ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 1353ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 1354e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 13559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 135650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// 13579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 13589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 135950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 1360ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1361ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ARMII::AddrMode AddrMode = ARMII::AddrModeNone) { 1362762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 136318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 1364a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 1365762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1366b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 1367a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 136818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 1369550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (BaseRegTok.isNot(AsmToken::Identifier)) { 1370550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 137150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1372550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1373e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int BaseRegNum = TryParseRegister(); 1374e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (BaseRegNum == -1) { 1375550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 137650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1377550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 13790571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 13800571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 13810571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 13820571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar return true; 13830571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 1384a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 1385a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 1386a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 1387a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 1388a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 138905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar ARMOperand *WBOp = 0; 139005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar int OffsetRegNum = -1; 139105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar bool OffsetRegShifted = false; 13920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl; 139305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *ShiftAmount = 0; 139405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar const MCExpr *Offset = 0; 1395a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 13969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 13979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 1398a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 1399a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 1400b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 140105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1402550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 1403550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 140450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 140518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 1406550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 1407550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 140850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1409550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 1410762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 1411b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1412a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 141318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 1414a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 1415ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // None of addrmode3 instruction uses "!" 1416ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3) 1417ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1418ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 141950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling WBOp = ARMOperand::CreateToken(ExclaimTok.getString(), 142050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc()); 1421a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 1422b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 1423ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } else { // In addressing mode 2, pre-indexed mode always end with "!" 1424ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes if (AddrMode == ARMII::AddrMode2) 1425ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Preindexed = false; 1426a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 14270571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar } else { 14280571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The "[Rn" we have so far was not followed by a comma. 14290571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 143080eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // If there's anything other than the right brace, this is a post indexing 143180eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // addressing form. 1432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 1433b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 1434a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 143518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 143603f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1437e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 143880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Postindexed = true; 143980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Writeback = true; 144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1441550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 1442550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 144350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1444550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 144550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1446b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 144750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 1448550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 144916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 1450550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 145150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 145305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar } 1454e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 145505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar // Force Offset to exist if used. 145605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!OffsetIsReg) { 145705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (!Offset) 145805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Offset = MCConstantExpr::Create(0, getContext()); 1459ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } else { 1460ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) { 1461ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Error(E, "shift amount not supported"); 1462ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 1463ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1464a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 146505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 1466ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg, 1467ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Offset, OffsetRegNum, OffsetRegShifted, 1468ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ShiftType, ShiftAmount, Preindexed, 1469ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Postindexed, Negative, Writeback, S, E)); 147005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar if (WBOp) 147105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar Operands.push_back(WBOp); 147205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 147305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar return false; 1474a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 14769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 14779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 14789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 14799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 14809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 14819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 14829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 14839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 1484762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 14850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson enum ARM_AM::ShiftOpc &ShiftType, 14869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 14879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 14889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 1489762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 1490762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 14919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 14929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 14939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 14949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 149518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 1496762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 14979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 1498b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 14999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 15009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 1501b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 15029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 15039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 150418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 15059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 1506e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc CurLoc = OffsetRegTok.getLoc(); 1507e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner OffsetRegNum = TryParseRegister(); 1508e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (OffsetRegNum != -1) { 1509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 1510e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner E = CurLoc; 1511762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 15129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 1513d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 151412f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling // If we parsed a register as the offset then there can be a shift after that. 15159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 15169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 151718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 15189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 1519b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 15209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 152118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1522762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 15233472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 15249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 15259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 15269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 15279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 15289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 152918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 15309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 15319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 153216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1533b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 15349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 15359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 15369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 1537762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 15389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 15399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 15409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 15419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 1542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 1543a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 1544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 1545a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 15460082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St, 15470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const MCExpr *&ShiftAmount, SMLoc &E) { 154818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 1549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 1550a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 155138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 1552a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 15530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 1554a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 15550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 1556a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 15570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 1558a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 15590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 1560a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 15610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 1562a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 1563a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 1564b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 1565a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 15669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 15670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (St == ARM_AM::rrx) 15689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 1569a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 15709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 157118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 15729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 15739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 1574b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 15759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 15769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 15779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 1578a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1579a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 1580a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1581a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 15829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 15839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 1584e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1585fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 1586762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 1587fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1588fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 1589fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 1590f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1591f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 1592fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 1593f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 1594f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 1595f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 1596f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 1597f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 1598fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1599a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 1600146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 1601146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 160250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 160367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Identifier: 160450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling if (!TryParseRegisterWithWriteBack(Operands)) 160550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 16060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (!TryParseShiftRegister(Operands)) 16070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 16080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1609e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1610e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 1611e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 161267b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 161367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 1614515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 1615515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 1616515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 1617762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1618515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 161950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1620762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 162150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 162250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 162350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 1624a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 162550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseMemory(Operands); 1626d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 162750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return ParseRegisterList(Operands); 1628d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 1629079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 1630079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 1631762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 1632b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 1633515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 1634515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 163550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1636762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 163750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 163850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 16399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 16409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 16417597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 16427597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 16437597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 16449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (ParsePrefix(RefKind)) 16459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 16469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 16477597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 16487597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 16499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 16509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 16517597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 16527597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 16539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 16547597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 16559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 16569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 1657a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1658a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 16607597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 16617597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 16627597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) { 16637597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 16649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 16659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 16668a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 16679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 16689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 16699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 16709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 16719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 16729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 16739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 16749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 16759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 16767597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 16779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 16787597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 16799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 16809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 16819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 16829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 16839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 16849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 16859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 16869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 16879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 16889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 16899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 16909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 16919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 16929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 16939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 16949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E, 16959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 16969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 16979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 16989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 16999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 17009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 17029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 17039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 17049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 17059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 17069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 17089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 17099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 17119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 17129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 17149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 17179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 17189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 17209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 17219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant); 17229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 17239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 17249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 17259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 17279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 17299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 17309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 17319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 17329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 17339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 1734352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 1735352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 1736352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 1737badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 1738a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopesstatic StringRef SplitMnemonic(StringRef Mnemonic, 1739a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned &PredicationCode, 1740a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool &CarrySetting, 1741a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned &ProcessorIMod) { 1742352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 1743352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 1744a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 1745352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 1746badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 1747352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 1748352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 17498ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar if (Mnemonic == "teq" || Mnemonic == "vceq" || 17508ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "movs" || 17518ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "svc" || 17528ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 17538ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vmls" || Mnemonic == "vnmls") || 17548ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vacge" || Mnemonic == "vcge" || 17558ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vclt" || 17568ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vacgt" || Mnemonic == "vcgt" || 17578ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vcle" || 17588ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" || 17598ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" || 17608ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar Mnemonic == "vqdmlal")) 1761352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 1762badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 1763352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // First, split out any predication code. 1764badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 1765345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("eq", ARMCC::EQ) 1766345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ne", ARMCC::NE) 1767345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hs", ARMCC::HS) 1768345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lo", ARMCC::LO) 1769345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("mi", ARMCC::MI) 1770345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("pl", ARMCC::PL) 1771345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vs", ARMCC::VS) 1772345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vc", ARMCC::VC) 1773345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hi", ARMCC::HI) 1774345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ls", ARMCC::LS) 1775345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ge", ARMCC::GE) 1776345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lt", ARMCC::LT) 1777345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("gt", ARMCC::GT) 1778345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("le", ARMCC::LE) 1779345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("al", ARMCC::AL) 1780345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Default(~0U); 1781badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar if (CC != ~0U) { 1782badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 1783352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = CC; 178452925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 1785345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1786352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 1787352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 1788352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 1789352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 1790352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" || 1791352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" || 1792352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" || 1793352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) { 1794352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 1795352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 1796352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 1797352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 1798a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 1799a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 1800a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 1801a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 1802a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 1803a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 1804a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 1805a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 1806a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 1808a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 1809a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 1810a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1812a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1813352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 1814352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 18153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 18163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 18173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 18183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 18193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 1820fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 1821fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 1822fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 1823fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool isThumb = TM.getSubtarget<ARMSubtarget>().isThumb(); 1824fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes 1825eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 1826eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 1827eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 1828eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 1829eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mov" || 1830eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 1831eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 1832eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "mvn") { 1833eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 1834eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 1835eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 1836eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 18373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 1838eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 1839eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 1840eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 1841eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 1842e47f3751d7770916f250a00a84316d412e959c00Bruno Cardoso Lopes Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" || 1843a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic == "clrex" || Mnemonic.startswith("cps")) { 18443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 18453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 18463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 18473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 1848fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 1849fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (isThumb) 1850fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 18518dd37f7b7dca7907f9f070dc96359f242e102163Bruno Cardoso Lopes Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 1852fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 1853badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 1854badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 1855badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 1856badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 1857badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1858badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 1859badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 1860badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar StringRef Head = Name.slice(Start, Next); 1861badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 1862352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 1863352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 1864a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 1865352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 1866a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Head = SplitMnemonic(Head, PredicationCode, CarrySetting, 1867a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod); 1868badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 18693a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 18709717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 18713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 18723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 18733771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 18743771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 18753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 18763771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 18773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 18783771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 18793771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode); 18803771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 18813771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 18823771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 18833771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 18843771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 18853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 18863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptCarrySet) { 18873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 18883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 18893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 18903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // This mnemonic can't ever accept a carry set, but the user wrote one (or 18913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // misspelled another mnemonic). 18923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 18933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: Issue a nice error. 18943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 18953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 18963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 18973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 18983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 18993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 19003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 19013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // This mnemonic can't ever accept a predication code, but the user wrote 19023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // one (or misspelled another mnemonic). 19033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 19043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: Issue a nice error. 1905badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 1906345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1907a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 1908a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 1909a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 1910a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 1911a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 1912a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 1913a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 1914a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 1915a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1916a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 1917a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1918a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1919345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 19205747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 19215747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 19225747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 1923a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 1924a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1925a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 19265747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 19275747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 19285747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 19295747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 1930a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 1931fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (ParseOperand(Operands, Head)) { 1932cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 1933cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 1934cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 1935a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1936a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 1937b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 1938a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1939a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 1940fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (ParseOperand(Operands, Head)) { 1941cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 1942cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 1943cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 1944a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1945a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 194616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1947cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 1948cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 194934e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 1950cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 1951146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 195234e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 19539898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 1954ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 1955ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1956fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 1957fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 1958fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1959fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 1960fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 1961fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 1962193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResultTy MatchResult, MatchResult2; 1963193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1964193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult != Match_Success) { 1965193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // If we get a Match_InvalidOperand it might be some arithmetic instruction 1966193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // that does not update the condition codes. So try adding a CCOut operand 1967193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // with a value of reg0. 1968193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult == Match_InvalidOperand) { 1969193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.insert(Operands.begin() + 1, 1970193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateCCOut(0, 1971193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ((ARMOperand*)Operands[0])->getStartLoc())); 1972193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 1973193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult2 == Match_Success) 1974193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = Match_Success; 197544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby else { 197644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 1977193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.erase(Operands.begin() + 1); 197844a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete CCOut; 197944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby } 1980193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 1981193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // If we get a Match_MnemonicFail it might be some arithmetic instruction 1982193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // that updates the condition codes if it ends in 's'. So see if the 1983193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut 1984193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // operand with a value of CPSR. 1985193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby else if(MatchResult == Match_MnemonicFail) { 1986193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // Get the instruction mnemonic, which is the first token. 1987193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken(); 1988193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (Mnemonic.substr(Mnemonic.size()-1) == "s") { 1989193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby // removed the 's' from the mnemonic for matching. 1990193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1); 1991193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc(); 199244a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 199344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin()); 199444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete OldMnemonic; 199544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.insert(Operands.begin(), 1996193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateToken(MnemonicNoS, NameLoc)); 1997193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby Operands.insert(Operands.begin() + 1, 1998193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateCCOut(ARM::CPSR, NameLoc)); 1999193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2000193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby if (MatchResult2 == Match_Success) 2001193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = Match_Success; 2002193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby else { 200344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]); 200444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin()); 200544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete OldMnemonic; 200644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.insert(Operands.begin(), 2007193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby ARMOperand::CreateToken(Mnemonic, NameLoc)); 200844a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby ARMOperand *CCOut = ((ARMOperand*)Operands[1]); 200944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby Operands.erase(Operands.begin() + 1); 201044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby delete CCOut; 2011193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2012193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2013193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2014193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby } 2015193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 2016e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 2017fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 2018fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 2019e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 2020e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2021e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 2022e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 2023e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 2024e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 2025e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 2026e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 202716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2028e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2029e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2030e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 203116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2032e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 2033e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 2034e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 2035e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 2036b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 2037b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 2038fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 203916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2040c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 2041146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 2042fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 2043fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 2044515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 2045ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2046ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 2047ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 2048ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 2049515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 2050515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 2051515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 2052515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 2053515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 2054515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 2055515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 2056515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 2057ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2058ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2059ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2060ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 2061ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 2062ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 2063ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 2064ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 2065ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 2066ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 2067ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 2068ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2069aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2070ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2071ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 2072ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 207316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2074ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 2075ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 2076ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 2077b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2078ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2079ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 2080ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2081b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2082ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 2083ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2084ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2085515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 2086515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 2087515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 2088515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2089515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2090b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2091515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2092515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 2093515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 2094515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2095515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2096515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2097515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2098515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 2099515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 2100515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 210118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2102515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 210383c4018fcca18fe9c281c3943fc58a17621636c4Jim Grosbach return Error(L, "unexpected token in .thumb_func directive"); 2104642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach StringRef Name = Tok.getString(); 2105b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 2106515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 2107515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 2108b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2109515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2110642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 2111642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2112642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 2113515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2114515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2115515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2116515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 2117515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 2118515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 211918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2120515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2121515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 212238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 212358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 2124b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 212558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 21269e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 2127515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2128515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 2129515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2130515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 213118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2132b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2133515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2134515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 2135515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 2136515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2137515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2138515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2139515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 2140515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 2141515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 214218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2143515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 2144515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 214518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 214658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 2147b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 214858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 2149b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2150515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 2151515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 2152515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2153515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 215418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2155b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2156515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 2157fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby // FIXME: We need to be able switch subtargets at this point so that 2158fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby // MatchInstructionImpl() will work when it gets the AvailableFeatures which 2159fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby // includes Feature_IsThumb or not to match the right instructions. This is 2160fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby // blocked on the FIXME in llvm-mc.cpp when creating the TargetMachine. 2161fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby if (Val == 16){ 2162fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby assert(TM.getSubtarget<ARMSubtarget>().isThumb() && 2163fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby "switching between arm/thumb not yet suppported via .code 16)"); 21642a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 2165fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby } 2166fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby else{ 2167fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby assert(!TM.getSubtarget<ARMSubtarget>().isThumb() && 2168fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby "switching between thumb/arm not yet suppported via .code 32)"); 21692a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 2170fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby } 21712a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 2172515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 2173515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 2174515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 217590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 217690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 21779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 2178ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 2179ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 2180ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 218190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 2182ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 21833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 21840692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 21850692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 21863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 2187